Browse Source

Channel logging implemented

master
Dirk Alders 3 years ago
parent
commit
b1230c9aad
1 changed files with 84 additions and 31 deletions
  1. 84
    31
      __init__.py

+ 84
- 31
__init__.py View File

50
 """The Tested Interpreter-Versions"""
50
 """The Tested Interpreter-Versions"""
51
 
51
 
52
 
52
 
53
-class RegistrationError(BaseException):
54
-    pass
55
-
56
-
57
 class callback_storage(dict):
53
 class callback_storage(dict):
58
-    def __init__(self):
54
+    DEFAULT_CHANNEL_NAME = 'all_others'
55
+
56
+    def __init__(self, channel_name):
57
+        self.init_channel_name(channel_name)
59
         dict.__init__(self)
58
         dict.__init__(self)
60
 
59
 
60
+    def init_channel_name(self, channel_name):
61
+        if channel_name is None:
62
+            self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__ + '.' + self.DEFAULT_CHANNEL_NAME)
63
+        else:
64
+            self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__ + '.' + channel_name)
65
+
61
     def get(self, service_id, data_id):
66
     def get(self, service_id, data_id):
62
         if service_id is not None and data_id is not None:
67
         if service_id is not None and data_id is not None:
63
             try:
68
             try:
81
         return (None, None, None)
86
         return (None, None, None)
82
 
87
 
83
     def add(self, service_id, data_id, callback, *args, **kwargs):
88
     def add(self, service_id, data_id, callback, *args, **kwargs):
84
-        if self.get(service_id, data_id) != (None, None, None):
85
-            raise RegistrationError("Callback for service_id (%s) and data_id (%s) already exists" % (repr(service_id), repr(data_id)))
89
+        cb_data = self.get(service_id, data_id)
90
+        if cb_data != (None, None, None):
91
+            self.logger.warning("Overwriting existing callback %s for service_id (%s) and data_id (%s) to %s!", repr(cb_data[0].__name__), repr(service_id), repr(data_id), repr(callback.__name__))
86
         if service_id not in self:
92
         if service_id not in self:
87
             self[service_id] = {}
93
             self[service_id] = {}
88
         self[service_id][data_id] = (callback, args, kwargs)
94
         self[service_id][data_id] = (callback, args, kwargs)
137
 
143
 
138
     .. literalinclude:: ../../socket_protocol/_examples_/socket_protocol__struct_json_protocol_client.log
144
     .. literalinclude:: ../../socket_protocol/_examples_/socket_protocol__struct_json_protocol_client.log
139
     """
145
     """
140
-    LOG_PREFIX = 'SJP:'
146
+    DEFAULT_CHANNEL_NAME = 'all_others'
141
 
147
 
142
     SID_AUTH_SEED_REQUEST = 1
148
     SID_AUTH_SEED_REQUEST = 1
143
     SID_AUTH_KEY_REQUEST = 2
149
     SID_AUTH_KEY_REQUEST = 2
144
     SID_AUTH_KEY_CHECK_REQUEST = 3
150
     SID_AUTH_KEY_CHECK_REQUEST = 3
145
     SID_AUTH_KEY_CHECK_RESPONSE = 4
151
     SID_AUTH_KEY_CHECK_RESPONSE = 4
152
+    SID_CHANNEL_NAME_REQUEST = 5
153
+    SID_CHANNEL_NAME_RESPONSE = 6
146
     SID_READ_REQUEST = 10
154
     SID_READ_REQUEST = 10
147
     SID_READ_RESPONSE = 11
155
     SID_READ_RESPONSE = 11
148
     SID_WRITE_REQUEST = 20
156
     SID_WRITE_REQUEST = 20
153
     SID_RESPONSE_DICT = {SID_AUTH_SEED_REQUEST: SID_AUTH_KEY_REQUEST,
161
     SID_RESPONSE_DICT = {SID_AUTH_SEED_REQUEST: SID_AUTH_KEY_REQUEST,
154
                          SID_AUTH_KEY_REQUEST: SID_AUTH_KEY_CHECK_REQUEST,
162
                          SID_AUTH_KEY_REQUEST: SID_AUTH_KEY_CHECK_REQUEST,
155
                          SID_AUTH_KEY_CHECK_REQUEST: SID_AUTH_KEY_CHECK_RESPONSE,
163
                          SID_AUTH_KEY_CHECK_REQUEST: SID_AUTH_KEY_CHECK_RESPONSE,
164
+                         SID_CHANNEL_NAME_REQUEST: SID_CHANNEL_NAME_RESPONSE,
156
                          SID_READ_REQUEST: SID_READ_RESPONSE,
165
                          SID_READ_REQUEST: SID_READ_RESPONSE,
157
                          SID_WRITE_REQUEST: SID_WRITE_RESPONSE,
166
                          SID_WRITE_REQUEST: SID_WRITE_RESPONSE,
158
                          SID_EXECUTE_REQUEST: SID_EXECUTE_RESPONSE}
167
                          SID_EXECUTE_REQUEST: SID_EXECUTE_RESPONSE}
183
                          AUTH_STATE_KEY_TRANSFERRED: 'Key has been sent',
192
                          AUTH_STATE_KEY_TRANSFERRED: 'Key has been sent',
184
                          AUTH_STATE_TRUSTED_CLIENT: 'Trusted Client'}
193
                          AUTH_STATE_TRUSTED_CLIENT: 'Trusted Client'}
185
 
194
 
186
-    def __init__(self, comm_instance, secret=None, auto_auth=False):
195
+    def __init__(self, comm_instance, secret=None, auto_auth=False, channel_name=None):
196
+        self.__comm_inst__ = comm_instance
187
         self.__secret__ = secret
197
         self.__secret__ = secret
188
         self.__auto_auth__ = auto_auth
198
         self.__auto_auth__ = auto_auth
199
+        #
200
+        self.__callbacks__ = callback_storage(channel_name)
201
+        self.__init_channel_name__(channel_name)
202
+        #
189
         self.__clean_receive_buffer__()
203
         self.__clean_receive_buffer__()
190
-        self.__callbacks__ = callback_storage()
191
         self.__callbacks__.add(self.SID_AUTH_SEED_REQUEST, 0, self.__authentificate_create_seed__)
204
         self.__callbacks__.add(self.SID_AUTH_SEED_REQUEST, 0, self.__authentificate_create_seed__)
192
         self.__callbacks__.add(self.SID_AUTH_KEY_REQUEST, 0, self.__authentificate_create_key__)
205
         self.__callbacks__.add(self.SID_AUTH_KEY_REQUEST, 0, self.__authentificate_create_key__)
193
         self.__callbacks__.add(self.SID_AUTH_KEY_CHECK_REQUEST, 0, self.__authentificate_check_key__)
206
         self.__callbacks__.add(self.SID_AUTH_KEY_CHECK_REQUEST, 0, self.__authentificate_check_key__)
194
         self.__callbacks__.add(self.SID_AUTH_KEY_CHECK_RESPONSE, 0, self.__authentificate_process_feedback__)
207
         self.__callbacks__.add(self.SID_AUTH_KEY_CHECK_RESPONSE, 0, self.__authentificate_process_feedback__)
208
+        self.__callbacks__.add(self.SID_CHANNEL_NAME_REQUEST, 0, self.__channel_name_request__)
209
+        self.__callbacks__.add(self.SID_CHANNEL_NAME_RESPONSE, 0, self.__channel_name_response__)
195
         self.__authentification_state_reset__()
210
         self.__authentification_state_reset__()
196
         self.__seed__ = None
211
         self.__seed__ = None
197
-        self.__comm_inst__ = comm_instance
198
         self.__comm_inst__.register_callback(self.__data_available_callback__)
212
         self.__comm_inst__.register_callback(self.__data_available_callback__)
199
         self.__comm_inst__.register_connect_callback(self.__connection_established__)
213
         self.__comm_inst__.register_connect_callback(self.__connection_established__)
200
         self.__comm_inst__.register_disconnect_callback(self.__authentification_state_reset__)
214
         self.__comm_inst__.register_disconnect_callback(self.__authentification_state_reset__)
201
 
215
 
216
+    def __init_channel_name__(self, channel_name):
217
+        self.__comm_inst__.init_channel_name(channel_name)
218
+        self.__callbacks__.init_channel_name(channel_name)
219
+        if channel_name is None:
220
+            self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__ + '.' + self.DEFAULT_CHANNEL_NAME)
221
+        else:
222
+            self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__ + '.' + channel_name)
223
+
224
+    @property
225
+    def __channel_name__(self):
226
+        cn = self.logger.name.split('.')[-1]
227
+        if cn != self.DEFAULT_CHANNEL_NAME:
228
+            return cn
229
+
230
+    def __log_prefix__(self):
231
+        return ' SP client:' if self.__comm_inst__.IS_CLIENT else ' SP server:'
232
+
202
     def connected(self):
233
     def connected(self):
203
         return self.__comm_inst__.is_connected()
234
         return self.__comm_inst__.is_connected()
204
 
235
 
210
 
241
 
211
     def __connection_established__(self):
242
     def __connection_established__(self):
212
         self.__clean_receive_buffer__()
243
         self.__clean_receive_buffer__()
244
+        if not self.__comm_inst__.IS_CLIENT:
245
+            self.send(self.SID_CHANNEL_NAME_REQUEST, 0, self.__channel_name__)
213
         if self.__auto_auth__ and self.__comm_inst__.IS_CLIENT and self.__secret__ is not None:
246
         if self.__auto_auth__ and self.__comm_inst__.IS_CLIENT and self.__secret__ is not None:
214
             self.authentificate()
247
             self.authentificate()
215
 
248
 
249
+    def __channel_name_request__(self, msg):
250
+        data = msg.get_data()
251
+        if data is None:
252
+            return self.STATUS_OKAY, self.__channel_name__
253
+        else:
254
+            prev_channel_name = self.__channel_name__
255
+            self.__init_channel_name__(data)
256
+            if prev_channel_name is not None and prev_channel_name != data:
257
+                self.logger.warning('%s overwriting user defined channel name from %s to %s', self.__log_prefix__(), repr(prev_channel_name), repr(data))
258
+            elif prev_channel_name is None:
259
+                self.logger.info('%s channel name is now %s', self.__log_prefix__(), repr(self.__channel_name__))
260
+            return self.STATUS_OKAY, None
261
+
262
+    def __channel_name_response__(self, msg):
263
+        data = msg.get_data()
264
+        if self.__channel_name__ is None and data is not None:
265
+            self.__init_channel_name__(data)
266
+            self.logger.info('%s channel name is now %s', self.__log_prefix__(), repr(self.__channel_name__))
267
+        return self.STATUS_OKAY, None
268
+
216
     def __authentification_state_reset__(self):
269
     def __authentification_state_reset__(self):
217
-        logger.info("%s Resetting authentification state to AUTH_STATE_UNKNOWN_CLIENT", self.LOG_PREFIX)
270
+        self.logger.info("%s Resetting authentification state to AUTH_STATE_UNKNOWN_CLIENT", self.__log_prefix__())
218
         self.__authentification_state__ = self.AUTH_STATE_UNKNOWN_CLIENT
271
         self.__authentification_state__ = self.AUTH_STATE_UNKNOWN_CLIENT
219
 
272
 
220
     def __analyse_frame__(self, frame):
273
     def __analyse_frame__(self, frame):
253
     def __data_available_callback__(self, comm_inst):
306
     def __data_available_callback__(self, comm_inst):
254
         frame = comm_inst.receive()
307
         frame = comm_inst.receive()
255
         if not self.__check_frame_checksum__(frame):
308
         if not self.__check_frame_checksum__(frame):
256
-            logger.warning("%s Received message has a wrong checksum and will be ignored: %s.", self.LOG_PREFIX, stringtools.hexlify(frame))
309
+            self.logger.warning("%s Received message has a wrong checksum and will be ignored: %s.", self.__log_prefix__(), stringtools.hexlify(frame))
257
         else:
310
         else:
258
             msg = self.__analyse_frame__(frame)
311
             msg = self.__analyse_frame__(frame)
259
-            logger.info(
312
+            self.logger.info(
260
                 '%s RX <- status: %s, service_id: %s, data_id: %s, data: "%s"',
313
                 '%s RX <- status: %s, service_id: %s, data_id: %s, data: "%s"',
261
-                self.LOG_PREFIX,
314
+                self.__log_prefix__(),
262
                 repr(msg.get_status()),
315
                 repr(msg.get_status()),
263
                 repr(msg.get_service_id()),
316
                 repr(msg.get_service_id()),
264
                 repr(msg.get_data_id()),
317
                 repr(msg.get_data_id()),
272
                 if self.__secret__ is not None and not self.check_authentification_state() and msg.get_service_id() not in self.SID_AUTH_LIST:
325
                 if self.__secret__ is not None and not self.check_authentification_state() and msg.get_service_id() not in self.SID_AUTH_LIST:
273
                     status = self.STATUS_AUTH_REQUIRED
326
                     status = self.STATUS_AUTH_REQUIRED
274
                     data = None
327
                     data = None
275
-                    logger.warning("%s Received message needs authentification: %s. Sending negative response.", self.LOG_PREFIX, self.AUTH_STATUS_NAMES.get(self.__authentification_state__, 'Unknown authentification status!'))
328
+                    self.logger.warning("%s Received message needs authentification: %s. Sending negative response.", self.__log_prefix__(), self.AUTH_STATUS_NAMES.get(self.__authentification_state__, 'Unknown authentification status!'))
276
                 elif callback is None:
329
                 elif callback is None:
277
-                    logger.warning("%s Received message with no registered callback. Sending negative response.", self.LOG_PREFIX)
330
+                    self.logger.warning("%s Received message with no registered callback. Sending negative response.", self.__log_prefix__())
278
                     status = self.STATUS_BUFFERING_UNHANDLED_REQUEST
331
                     status = self.STATUS_BUFFERING_UNHANDLED_REQUEST
279
                     data = None
332
                     data = None
280
                 else:
333
                 else:
281
                     try:
334
                     try:
282
-                        logger.debug("%s Executing callback %s to process received data", self.LOG_PREFIX, callback.__name__)
335
+                        self.logger.debug("%s Executing callback %s to process received data", self.__log_prefix__(), callback.__name__)
283
                         status, data = callback(msg, *args, **kwargs)
336
                         status, data = callback(msg, *args, **kwargs)
284
                     except TypeError:
337
                     except TypeError:
285
                         raise TypeError('Check return value of callback function {callback_name} for service_id  {service_id} and data_id {data_id}'.format(callback_name=callback.__name__, service_id=repr(msg.get_service_id()), data_id=repr(msg.get_data_id())))
338
                         raise TypeError('Check return value of callback function {callback_name} for service_id  {service_id} and data_id {data_id}'.format(callback_name=callback.__name__, service_id=repr(msg.get_service_id()), data_id=repr(msg.get_data_id())))
289
                 # RESPONSE RECEIVED
342
                 # RESPONSE RECEIVED
290
                 #
343
                 #
291
                 if msg.get_status() not in [self.STATUS_OKAY]:
344
                 if msg.get_status() not in [self.STATUS_OKAY]:
292
-                    logger.warning("%s Received message has a peculiar status: %s", self.LOG_PREFIX, self.STATUS_NAMES.get(msg.get_status(), 'Unknown status response!'))
345
+                    self.logger.warning("%s Received message has a peculiar status: %s", self.__log_prefix__(), self.STATUS_NAMES.get(msg.get_status(), 'Unknown status response!'))
293
                 if callback is None:
346
                 if callback is None:
294
                     status = self.STATUS_OKAY
347
                     status = self.STATUS_OKAY
295
                     data = None
348
                     data = None
296
                     self.__buffer_received_data__(msg)
349
                     self.__buffer_received_data__(msg)
297
                 else:
350
                 else:
298
                     try:
351
                     try:
299
-                        logger.debug("%s Executing callback %s to process received data", self.LOG_PREFIX, callback.__name__)
352
+                        self.logger.debug("%s Executing callback %s to process received data", self.__log_prefix__(), callback.__name__)
300
                         status, data = callback(msg, *args, **kwargs)
353
                         status, data = callback(msg, *args, **kwargs)
301
                     except TypeError:
354
                     except TypeError:
302
                         raise TypeError('Check return value of callback function {callback_name} for service_id  {service_id} and data_id {data_id}'.format(callback_name=callback.__name__, service_id=repr(msg.get_service_id()), data_id=repr(msg.get_data_id())))
355
                         raise TypeError('Check return value of callback function {callback_name} for service_id  {service_id} and data_id {data_id}'.format(callback_name=callback.__name__, service_id=repr(msg.get_service_id()), data_id=repr(msg.get_data_id())))
307
         if not msg.get_data_id() in self.__msg_buffer__[msg.get_service_id()]:
360
         if not msg.get_data_id() in self.__msg_buffer__[msg.get_service_id()]:
308
             self.__msg_buffer__[msg.get_service_id()][msg.get_data_id()] = []
361
             self.__msg_buffer__[msg.get_service_id()][msg.get_data_id()] = []
309
         self.__msg_buffer__[msg.get_service_id()][msg.get_data_id()].append(msg)
362
         self.__msg_buffer__[msg.get_service_id()][msg.get_data_id()].append(msg)
310
-        logger.debug("%s Message data is stored in buffer and is now ready to be retrieved by receive method", self.LOG_PREFIX)
363
+        self.logger.debug("%s Message data is stored in buffer and is now ready to be retrieved by receive method", self.__log_prefix__())
311
 
364
 
312
     def __clean_receive_buffer__(self):
365
     def __clean_receive_buffer__(self):
313
-        logger.debug("%s Cleaning up receive-buffer", self.LOG_PREFIX)
366
+        self.logger.debug("%s Cleaning up receive-buffer", self.__log_prefix__())
314
         self.__msg_buffer__ = {}
367
         self.__msg_buffer__ = {}
315
 
368
 
316
     def receive(self, service_id, data_id, timeout=1):
369
     def receive(self, service_id, data_id, timeout=1):
324
             cnt += 1
377
             cnt += 1
325
             time.sleep(0.1)
378
             time.sleep(0.1)
326
         if data is None and cnt >= timeout * 10:
379
         if data is None and cnt >= timeout * 10:
327
-            logger.warning('%s TIMEOUT (%ss): Requested data (service_id: %s; data_id: %s) not in buffer.', self.LOG_PREFIX, repr(timeout), repr(service_id), repr(data_id))
380
+            self.logger.warning('%s TIMEOUT (%ss): Requested data (service_id: %s; data_id: %s) not in buffer.', self.__log_prefix__(), repr(timeout), repr(service_id), repr(data_id))
328
         return data
381
         return data
329
 
382
 
330
     def __mk_msg__(self, status, service_id, data_id, data):
383
     def __mk_msg__(self, status, service_id, data_id, data):
349
 
402
 
350
         This methods sends out a message with the given content.
403
         This methods sends out a message with the given content.
351
         """
404
         """
352
-        logger.log(log_lvl, '%s TX -> status: %d, service_id: %d, data_id: %d, data: "%s"', self.LOG_PREFIX, status, service_id, data_id, repr(data))
405
+        self.logger.log(log_lvl, '%s TX -> status: %d, service_id: %d, data_id: %d, data: "%s"', self.__log_prefix__(), status, service_id, data_id, repr(data))
353
         return self.__comm_inst__.send(self.__build_frame__(service_id, data_id, data, status), timeout=timeout, log_lvl=logging.DEBUG)
406
         return self.__comm_inst__.send(self.__build_frame__(service_id, data_id, data, status), timeout=timeout, log_lvl=logging.DEBUG)
354
 
407
 
355
     def register_callback(self, service_id, data_id, callback, *args, **kwargs):
408
     def register_callback(self, service_id, data_id, callback, *args, **kwargs):
393
         """
446
         """
394
         if self.__secret__ is not None:
447
         if self.__secret__ is not None:
395
             self.__authentification_state__ = self.AUTH_STATE_SEED_REQUESTED
448
             self.__authentification_state__ = self.AUTH_STATE_SEED_REQUESTED
396
-            logger.info("%s Requesting seed for authentification", self.LOG_PREFIX)
449
+            self.logger.info("%s Requesting seed for authentification", self.__log_prefix__())
397
             self.send(self.SID_AUTH_SEED_REQUEST, 0, None)
450
             self.send(self.SID_AUTH_SEED_REQUEST, 0, None)
398
             cnt = 0
451
             cnt = 0
399
             while cnt < timeout * 10:
452
             while cnt < timeout * 10:
419
             return hashlib.sha512(seed.encode('utf-8') + self.__secret__.encode('utf-8')).hexdigest()
472
             return hashlib.sha512(seed.encode('utf-8') + self.__secret__.encode('utf-8')).hexdigest()
420
 
473
 
421
     def __authentificate_create_seed__(self, msg):
474
     def __authentificate_create_seed__(self, msg):
422
-        logger.info("%s Got seed request, sending seed for authentification", self.LOG_PREFIX)
475
+        self.logger.info("%s Got seed request, sending seed for authentification", self.__log_prefix__())
423
         self.__authentification_state__ = self.AUTH_STATE_SEED_TRANSFERRED
476
         self.__authentification_state__ = self.AUTH_STATE_SEED_TRANSFERRED
424
         if sys.version_info >= (3, 0):
477
         if sys.version_info >= (3, 0):
425
             self.__seed__ = binascii.hexlify(os.urandom(32)).decode('utf-8')
478
             self.__seed__ = binascii.hexlify(os.urandom(32)).decode('utf-8')
428
         return self.STATUS_OKAY, self.__seed__
481
         return self.STATUS_OKAY, self.__seed__
429
 
482
 
430
     def __authentificate_create_key__(self, msg):
483
     def __authentificate_create_key__(self, msg):
431
-        logger.info("%s Got seed, sending key for authentification", self.LOG_PREFIX)
484
+        self.logger.info("%s Got seed, sending key for authentification", self.__log_prefix__())
432
         self.__authentification_state__ = self.AUTH_STATE_KEY_TRANSFERRED
485
         self.__authentification_state__ = self.AUTH_STATE_KEY_TRANSFERRED
433
         seed = msg.get_data()
486
         seed = msg.get_data()
434
         key = self.__authentificate_salt_and_hash__(seed)
487
         key = self.__authentificate_salt_and_hash__(seed)
438
         key = msg.get_data()
491
         key = msg.get_data()
439
         if key == self.__authentificate_salt_and_hash__(self.__seed__):
492
         if key == self.__authentificate_salt_and_hash__(self.__seed__):
440
             self.__authentification_state__ = self.AUTH_STATE_TRUSTED_CLIENT
493
             self.__authentification_state__ = self.AUTH_STATE_TRUSTED_CLIENT
441
-            logger.info("%s Got correct key, sending positive authentification feedback", self.LOG_PREFIX)
494
+            self.logger.info("%s Got correct key, sending positive authentification feedback", self.__log_prefix__())
442
             return self.STATUS_OKAY, True
495
             return self.STATUS_OKAY, True
443
         else:
496
         else:
444
             self.__authentification_state__ = self.AUTH_STATE_UNKNOWN_CLIENT
497
             self.__authentification_state__ = self.AUTH_STATE_UNKNOWN_CLIENT
445
-            logger.info("%s Got incorrect key, sending negative authentification feedback", self.LOG_PREFIX)
498
+            self.logger.info("%s Got incorrect key, sending negative authentification feedback", self.__log_prefix__())
446
             return self.STATUS_OKAY, False
499
             return self.STATUS_OKAY, False
447
 
500
 
448
     def __authentificate_process_feedback__(self, msg):
501
     def __authentificate_process_feedback__(self, msg):
449
         feedback = msg.get_data()
502
         feedback = msg.get_data()
450
         if feedback:
503
         if feedback:
451
             self.__authentification_state__ = self.AUTH_STATE_TRUSTED_CLIENT
504
             self.__authentification_state__ = self.AUTH_STATE_TRUSTED_CLIENT
452
-            logger.info("%s Got positive authentification feedback", self.LOG_PREFIX)
505
+            self.logger.info("%s Got positive authentification feedback", self.__log_prefix__())
453
         else:
506
         else:
454
             self.__authentification_state__ = self.AUTH_STATE_UNKNOWN_CLIENT
507
             self.__authentification_state__ = self.AUTH_STATE_UNKNOWN_CLIENT
455
-            logger.warning("%s Got negative authentification feedback", self.LOG_PREFIX)
508
+            self.logger.warning("%s Got negative authentification feedback", self.__log_prefix__())
456
         return self.STATUS_OKAY, None
509
         return self.STATUS_OKAY, None
457
 
510
 
458
 
511
 

Loading…
Cancel
Save