def test_event_callback_manager_with_double_registration(self): cbm = callback_manager._EventCallbackManager() cbm.add_callback("/test", MockEventCallback) cbm.add_callback("/test", MockEventCallback) self.assertEqual(1, len(cbm.callbacks_by_channel)) cbm.remove_callback("/test", MockEventCallback) self.assertEqual(0, len(cbm.callbacks_by_channel))
def test_event_callback_manager_with_invalid_callback_instance(self): cbm = callback_manager._EventCallbackManager() callback = MockRequestCallback() with self.assertRaises(ValueError): cbm.add_callback("/test", callback) self.assertEqual(None, cbm.callbacks_by_channel.get("/test")) self.assertEqual(0, len(cbm.callbacks_by_channel))
def test_event_callback_manager_with_valid_callback(self): cbm = callback_manager._EventCallbackManager() cbm.add_callback("/test", MockEventCallback) self.assertEqual(1, len(cbm.callbacks_by_channel.get("/test"))) self.assertEqual(1, len(cbm.callbacks_by_channel)) cbm.add_callback(callback=MockEventCallback) self.assertEqual(1, len(cbm.callbacks_by_channel.get(""))) self.assertEqual(2, len(cbm.callbacks_by_channel)) cbm.remove_callback("/test", MockEventCallback) self.assertEqual(None, cbm.callbacks_by_channel.get("/test")) self.assertEqual(1, len(cbm.callbacks_by_channel)) cbm.remove_callback(callback=MockEventCallback) self.assertEqual(None, cbm.callbacks_by_channel.get("")) self.assertEqual(0, len(cbm.callbacks_by_channel))
def __init__(self, config): """ Constructor parameters: :param config: The :class:`dxlclient.client_config.DxlClientConfig` object containing the configuration settings for the client. """ super(DxlClient, self).__init__() if config is None or not isinstance(config, DxlClientConfig): raise ValueError("Client configuration not specified") # The client configuration self._config = config # The lock for the client configuration self._config_lock = threading.RLock() # The condition associated with the client configuration self._config_lock_condition = threading.Condition(self._config_lock) # The flag for the connection state self._connected = False # The lock for the flag for the connection state self._connected_lock = threading.RLock() # The condition for the flag on connection state self._connected_wait_condition = threading.Condition( self._connected_lock) # The current broker the client is connected to self._current_broker = None # The lock for the current broker the client is connected to self._current_broker_lock = threading.RLock() # The default wait time for a synchronous request self._default_wait = self._DEFAULT_WAIT # The wait for policy delay (in seconds) self._wait_for_policy_delay = self._DEFAULT_WAIT_FOR_POLICY_DELAY # The minimum amount of threads in a thread pool self._core_pool_size = self._DEFAULT_MIN_POOL_SIZE # The maximum amount of threads in a thread pool self._maximum_pool_size = self._DEFAULT_MAX_POOL_SIZE # The quality of server (QOS) for messages self._qos = self._DEFAULT_QOS # The "reply-to" prefix. self is typically used for setting up response # channels for requests, etc. self._reply_to_topic = self._REPLY_TO_PREFIX + self._config._client_id # The request callbacks manager self._request_callbacks = callback_manager._RequestCallbackManager() # The response callbacks manager self._response_callbacks = callback_manager._ResponseCallbackManager() # The event callbacks manager self._event_callbacks = callback_manager._EventCallbackManager() # The current list of subscriptions self._subscriptions = set() # The lock for the current list of subscriptions self._subscriptions_lock = threading.RLock() # The underlying MQTT client instance self._client = mqtt.Client(client_id=self._config._client_id, clean_session=True, userdata=self, protocol=mqtt.MQTTv31) # The MQTT client connect callback self._client.on_connect = _on_connect # The MQTT client disconnect callback self._client.on_disconnect = _on_disconnect # The MQTT client message callback self._client.on_message = _on_message # The MQTT client log callback if logger.isEnabledFor(logging.DEBUG): self._client.on_log = _on_log # pylint: disable=no-member # The MQTT client TLS configuration self._client.tls_set(config.broker_ca_bundle, certfile=config.cert_file, keyfile=config.private_key, cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_SSLv23, ciphers=None) # The MQTT client TLS configuration to bypass hostname validation self._client.tls_insecure_set(True) # Generate a message pool prefix self._message_pool_prefix = "DxlMessagePool-" + UuidGenerator.generate_id_as_string( ) # The thread pool for message handling self._thread_pool = ThreadPool( num_threads=config.incoming_message_thread_pool_size, queue_size=config.incoming_message_queue_size, thread_prefix=self._message_pool_prefix) # Subscribe to the client reply channel self.subscribe(self._reply_to_topic) # The request manager (manages synchronous and asynchronous request callbacks, # notifications, etc.). self._request_manager = RequestManager(client=self) # The service manager (manages services request callbacks, notifications, etc.). self._service_manager = _ServiceManager(client=self) # The loop thread self._thread = None # The loop thread terminate flag self._thread_terminate = False # The lock for the connect thread self._connect_wait_lock = threading.RLock() # The condition associated with the client configuration self._connect_wait_condition = threading.Condition( self._connect_wait_lock) self._destroy_lock = threading.RLock() self._destroyed = False