Browse Source

Add ability to log all MAX responses.
Improve error logging on parse errors of MAX response parts.

Andrew Klopper 8 years ago
parent
commit
242683d58b

+ 2 - 1
BulkPrintingAPI/appsettings.Development.json

12
     "Port": 4006,
12
     "Port": 4006,
13
     "ConnectTimeout": 10000,
13
     "ConnectTimeout": 10000,
14
     "ReceiveTimeout": 10000,
14
     "ReceiveTimeout": 10000,
15
-    "SendTimeout":  10000
15
+    "SendTimeout": 10000,
16
+    "LogResponses":  true
16
   }
17
   }
17
 }
18
 }

+ 1 - 1
BulkPrintingAPI/appsettings.json

5
   "Logging": {
5
   "Logging": {
6
     "IncludeScopes": false,
6
     "IncludeScopes": false,
7
     "LogLevel": {
7
     "LogLevel": {
8
-      "Default": "Warning"
8
+      "Default": "Debug"
9
     }
9
     }
10
   },
10
   },
11
   "TokenAuthentication": {
11
   "TokenAuthentication": {

+ 103 - 38
MAXClient/Client.cs

21
         private int _userId;
21
         private int _userId;
22
         private string _username;
22
         private string _username;
23
         private string _password;
23
         private string _password;
24
+        private bool _logResponses;
24
 
25
 
25
         private TcpClient _connection = null;
26
         private TcpClient _connection = null;
26
         private NetworkStream _connectionStream = null;
27
         private NetworkStream _connectionStream = null;
28
 
29
 
29
         private bool _disposed = false;
30
         private bool _disposed = false;
30
 
31
 
31
-        public Client(ILogger logger, string host, int port, int vendorId, string serialNumber, int userId, string username, string password)
32
+        public Client(ILogger logger, bool logResponses, string host, int port, int vendorId, string serialNumber, int userId, string username, string password)
32
         {
33
         {
33
             _logger = logger;
34
             _logger = logger;
34
             _host = host;
35
             _host = host;
38
             _userId = userId;
39
             _userId = userId;
39
             _username = username;
40
             _username = username;
40
             _password = password;
41
             _password = password;
42
+            _logResponses = logResponses;
41
 
43
 
42
             ConnectTimeout = 10000;
44
             ConnectTimeout = 10000;
43
             ReceiveTimeout = 10000;
45
             ReceiveTimeout = 10000;
44
             SendTimeout = 10000;
46
             SendTimeout = 10000;
45
         }
47
         }
46
 
48
 
47
-        public Client(ILogger logger, string host, int port, LoginCredentials credentials)
48
-            : this(logger, host, port, credentials.Vendor.Id, credentials.Vendor.SerialNumber,
49
+        public Client(ILogger logger, bool logResponses, string host, int port, LoginCredentials credentials)
50
+            : this(logger, logResponses, host, port, credentials.Vendor.Id, credentials.Vendor.SerialNumber,
49
                   credentials.User.Id, credentials.User.Username, credentials.Password)
51
                   credentials.User.Id, credentials.User.Username, credentials.Password)
50
         {
52
         {
51
         }
53
         }
120
                 Username = _username,
122
                 Username = _username,
121
                 FirstName = parts[4],
123
                 FirstName = parts[4],
122
                 Surname = parts[3],
124
                 Surname = parts[3],
123
-                Enabled = bool.Parse(parts[6]),
124
-                Level = (User.UserLevel)int.Parse(parts[1]),
125
-                System = int.Parse(parts[2]),
126
-                LastLogin = DateTime.Parse(parts[5])
125
+                Enabled = ParseBool(parts[6], "User.Enabled(6)", response),
126
+                Level = (User.UserLevel)ParseInt(parts[1], "User.Level(1)", response),
127
+                System = ParseInt(parts[2], "User.System(2)", response),
128
+                LastLogin = ParseDateTime(parts[5], "User.LastLogin(5)", response)
127
             };
129
             };
128
 
130
 
129
             if (user.Level == User.UserLevel.CustomUser)
131
             if (user.Level == User.UserLevel.CustomUser)
130
             {
132
             {
131
-                user.CanPrintOffline = bool.Parse(parts[7]);
132
-                user.OfflinePrintValue = decimal.Parse(parts[8]);
133
-                user.CanPrintOnline = bool.Parse(parts[9]);
134
-                user.OnlinePrintValue = decimal.Parse(parts[10]);
135
-                user.CanReprintOffline = bool.Parse(parts[11]);
136
-                user.OfflineReprintValue = decimal.Parse(parts[12]);
137
-                user.CanReprintOnline = bool.Parse(parts[13]);
138
-                user.OnlineReprintValue = decimal.Parse(parts[14]);
139
-                user.BulkExport = bool.Parse(parts[15]);
140
-                user.BulkExportMaxValue = decimal.Parse(parts[16]);
141
-                user.BulkOrder = bool.Parse(parts[17]);
142
-                user.BulkOrderMaxValue = decimal.Parse(parts[18]);
143
-                user.BulkViewPins = bool.Parse(parts[19]);
144
-                user.BulkReExport = bool.Parse(parts[20]);
133
+                user.CanPrintOffline = ParseBool(parts[7], "User.CanPrintOffline(7)", response);
134
+                user.OfflinePrintValue = ParseDecimal(parts[8], "User.OfflinePrintValue(8)", response);
135
+                user.CanPrintOnline = ParseBool(parts[9], "User.CanPrintOnline(9)", response);
136
+                user.OnlinePrintValue = ParseDecimal(parts[10], "User.OnlinePrintValue(10)", response);
137
+                user.CanReprintOffline = ParseBool(parts[11], "User.CanReprintOffline(11)", response);
138
+                user.OfflineReprintValue = ParseDecimal(parts[12], "User.OfflineReprintValue(12)", response);
139
+                user.CanReprintOnline = ParseBool(parts[13], "User.CanReprintOnline(13)", response);
140
+                user.OnlineReprintValue = ParseDecimal(parts[14], "User.OnlineReprintValue(14)", response);
141
+                user.BulkExport = ParseBool(parts[15], "User.BulkExport(15)", response);
142
+                user.BulkExportMaxValue = ParseDecimal(parts[16], "User.BulkExportMaxValue(16)", response);
143
+                user.BulkOrder = ParseBool(parts[17], "User.BulkOrder(17)", response);
144
+                user.BulkOrderMaxValue = ParseDecimal(parts[18], "User.BulkOrderMaxValue(18)", response);
145
+                user.BulkViewPins = ParseBool(parts[19], "User.BulkViewPins(19)", response);
146
+                user.BulkReExport = ParseBool(parts[20], "User.BulkReExport(20)", response);
145
             }
147
             }
146
 
148
 
147
             return user;
149
             return user;
184
 
186
 
185
         private string Decrypt(string cipherText)
187
         private string Decrypt(string cipherText)
186
         {
188
         {
187
-            return Utils.TripleDESDecrypt(cipherText, _des);
189
+            var response = Utils.TripleDESDecrypt(cipherText, _des);
190
+            if (_logResponses)
191
+            {
192
+                _logger.LogDebug("Decrypted response for {0}: {1}", LoginCredentials.Format(_userId, _username, _vendorId, _serialNumber), response);
193
+            }
194
+            return response;
188
         }
195
         }
189
 
196
 
190
         private string Encrypt(string plainText)
197
         private string Encrypt(string plainText)
246
             var parts = response.Split('|');
253
             var parts = response.Split('|');
247
             return new Account()
254
             return new Account()
248
             {
255
             {
249
-                Id = int.Parse(parts[1]),
256
+                Id = ParseInt(parts[1], "Account.Id(1)", response),
250
                 Name = parts[2],
257
                 Name = parts[2],
251
-                Balance = decimal.Parse(parts[3]),
252
-                Status = (Account.AccountStatus)int.Parse(parts[4]),
258
+                Balance = ParseDecimal(parts[3], "Account.Balance(3)", response),
259
+                Status = (Account.AccountStatus)ParseInt(parts[4], "Account.AccountStatus(4)", response),
253
                 Reference = parts[5],
260
                 Reference = parts[5],
254
                 Warehouse = new Warehouse()
261
                 Warehouse = new Warehouse()
255
                 {
262
                 {
256
-                    Id = int.Parse(parts[6]),
263
+                    Id = ParseInt(parts[6], "Account.Warehouse.Id(6)", response),
257
                     Name = parts[7]
264
                     Name = parts[7]
258
                 }
265
                 }
259
             };
266
             };
268
             var response = ExpectResponse(Decrypt(await ReadMessageAsync().ConfigureAwait(false)), "OK");
275
             var response = ExpectResponse(Decrypt(await ReadMessageAsync().ConfigureAwait(false)), "OK");
269
 
276
 
270
             var parts = response.Split('|');
277
             var parts = response.Split('|');
271
-            var count = int.Parse(parts[1]);
278
+            var count = ParseInt(parts[1], "Products.Count(1)", response);
272
 
279
 
273
             var catalogue = new ProductCatalogue();
280
             var catalogue = new ProductCatalogue();
274
             
281
             
280
                 response = ExpectResponse(Decrypt(await ReadMessageAsync().ConfigureAwait(false)), "OK");
287
                 response = ExpectResponse(Decrypt(await ReadMessageAsync().ConfigureAwait(false)), "OK");
281
 
288
 
282
                 parts = response.Split('|');
289
                 parts = response.Split('|');
283
-                int networkId = int.Parse(parts[4]);
290
+                int networkId = ParseInt(parts[4], "Product.NetworkId(4)", response);
284
                 Network network;
291
                 Network network;
285
                 if (! catalogue.NetworkMap.TryGetValue(networkId, out network))
292
                 if (! catalogue.NetworkMap.TryGetValue(networkId, out network))
286
                 {
293
                 {
289
 
296
 
290
                 catalogue.AddProduct(
297
                 catalogue.AddProduct(
291
                     network: network,
298
                     network: network,
292
-                    id: int.Parse(parts[1]),
293
-                    faceValue: decimal.Parse(parts[2]),
299
+                    id: ParseInt(parts[1], "Product.Id(1)", response),
300
+                    faceValue: ParseDecimal(parts[2], "Product.FaceValue(2)", response),
294
                     description: parts[3],
301
                     description: parts[3],
295
-                    voucherType: (Batch.Vouchertype)int.Parse(parts[6]),
296
-                    discountPercentage: decimal.Parse(parts[7])
302
+                    voucherType: (Batch.Vouchertype)ParseInt(parts[6], "Product.VoucherType(6)", response),
303
+                    discountPercentage: ParseDecimal(parts[7], "Product.DiscountPercentage(7)", response)
297
                 );
304
                 );
298
             }
305
             }
299
 
306
 
300
             return catalogue;
307
             return catalogue;
301
         }
308
         }
302
 
309
 
310
+        private bool LogParseError(string value, string valueName, string valueType, string fullResponse)
311
+        {
312
+            _logger.LogError(
313
+                "Failed to parse value: valueType={0} valueName={1} value={2} fullResponse={3} {4}",
314
+                valueType,
315
+                valueName,
316
+                value,
317
+                fullResponse,
318
+                LoginCredentials.Format(_userId, _username, _vendorId, _serialNumber)
319
+            );
320
+            throw new Exception(String.Format("Invalid value for {0}", valueName));
321
+        }
322
+
323
+        private bool ParseBool(string value, string valueName, string fullResponse)
324
+        {
325
+            bool ret;
326
+            if (! bool.TryParse(value, out ret))
327
+            {
328
+                LogParseError(value, valueName, "bool", fullResponse);
329
+            }
330
+            return ret;
331
+        }
332
+
333
+        private DateTime ParseDateTime(string value, string valueName, string fullResponse)
334
+        {
335
+            DateTime ret;
336
+            if (!DateTime.TryParse(value, out ret))
337
+            {
338
+                LogParseError(value, valueName, "DateTime", fullResponse);
339
+            }
340
+            return ret;
341
+        }
342
+
343
+        private decimal ParseDecimal(string value, string valueName, string fullResponse)
344
+        {
345
+            decimal ret;
346
+            if (!decimal.TryParse(value, out ret))
347
+            {
348
+                LogParseError(value, valueName, "decimal", fullResponse);
349
+            }
350
+            return ret;
351
+        }
352
+
353
+        private int ParseInt(string value, string valueName, string fullResponse)
354
+        {
355
+            int ret;
356
+            if (!int.TryParse(value, out ret))
357
+            {
358
+                LogParseError(value, valueName, "int", fullResponse);
359
+            }
360
+            return ret;
361
+        }
362
+
303
         public async Task<OrderResponse> PlaceOrderAsync(int accountId, Product product, int quantity,
363
         public async Task<OrderResponse> PlaceOrderAsync(int accountId, Product product, int quantity,
304
             string customerReference, string internalReference, Guid? orderGuid, byte[] key)
364
             string customerReference, string internalReference, Guid? orderGuid, byte[] key)
305
         {
365
         {
333
             {
393
             {
334
                 Batch = new Batch()
394
                 Batch = new Batch()
335
                 {
395
                 {
336
-                    Id = int.Parse(parts[1]),
396
+                    Id = ParseInt(parts[1], "Batch.Id(1)", response),
337
                     OrderReference = parts[2],
397
                     OrderReference = parts[2],
338
-                    RequestedQuantity = int.Parse(parts[3]),
339
-                    DeliveredQuantity = int.Parse(parts[4]),
340
-                    Cost = decimal.Parse(parts[5]),
398
+                    RequestedQuantity = ParseInt(parts[3], "Batch.RequestQuantity(3)", response),
399
+                    DeliveredQuantity = ParseInt(parts[4], "Batch.DeliveredQuantity(4)", response),
400
+                    Cost = ParseDecimal(parts[5], "Batch.Cost(5)", response),
341
                     InternalReference = internalReference,
401
                     InternalReference = internalReference,
342
                     OrderGuid = orderGuid,
402
                     OrderGuid = orderGuid,
343
                     AccountId = accountId,
403
                     AccountId = accountId,
353
                     OrderedById = _userId,
413
                     OrderedById = _userId,
354
                     ReadyForDownload = false
414
                     ReadyForDownload = false
355
                 },
415
                 },
356
-                RemainingBalance = decimal.Parse(parts[6])
416
+                RemainingBalance = ParseDecimal(parts[6], "Batch.RemainingBalance(6)", response)
357
             };
417
             };
358
         }
418
         }
359
 
419
 
379
             {
439
             {
380
                 throw new Exception("Invalid message size");
440
                 throw new Exception("Invalid message size");
381
             }
441
             }
382
-            return Encoding.ASCII.GetString(await ReadBytesAsync(size).ConfigureAwait(false));
442
+            var response = Encoding.ASCII.GetString(await ReadBytesAsync(size).ConfigureAwait(false));
443
+            if (_logResponses)
444
+            {
445
+                _logger.LogDebug("Response for {0}: {1}", LoginCredentials.Format(_userId, _username, _vendorId, _serialNumber), response);
446
+            }
447
+            return response;
383
         }
448
         }
384
 
449
 
385
         public int ReceiveTimeout { get; set; }
450
         public int ReceiveTimeout { get; set; }

+ 4 - 2
MAXClient/ClientFactory.cs

13
         public Client GetClient(ILogger logger, int vendorId, string serialNumber, int userId,
13
         public Client GetClient(ILogger logger, int vendorId, string serialNumber, int userId,
14
             string username, string password)
14
             string username, string password)
15
         {
15
         {
16
-            var client = new Client(logger, Host, Port, vendorId, serialNumber, userId,
16
+            var client = new Client(logger, LogResponses, Host, Port, vendorId, serialNumber, userId,
17
                 username, password);
17
                 username, password);
18
             client.ConnectTimeout = ConnectTimeout;
18
             client.ConnectTimeout = ConnectTimeout;
19
             client.ReceiveTimeout = ReceiveTimeout;
19
             client.ReceiveTimeout = ReceiveTimeout;
23
 
23
 
24
         public Client GetClient(ILogger logger, LoginCredentials credentials)
24
         public Client GetClient(ILogger logger, LoginCredentials credentials)
25
         {
25
         {
26
-            var client = new Client(logger, Host, Port, credentials);
26
+            var client = new Client(logger, LogResponses, Host, Port, credentials);
27
             client.ConnectTimeout = ConnectTimeout;
27
             client.ConnectTimeout = ConnectTimeout;
28
             client.ReceiveTimeout = ReceiveTimeout;
28
             client.ReceiveTimeout = ReceiveTimeout;
29
             client.SendTimeout = SendTimeout;
29
             client.SendTimeout = SendTimeout;
39
         public int ReceiveTimeout { get; set; }
39
         public int ReceiveTimeout { get; set; }
40
 
40
 
41
         public int SendTimeout { get; set; }
41
         public int SendTimeout { get; set; }
42
+
43
+        public bool LogResponses { get; set; }
42
     }
44
     }
43
 }
45
 }