def __init__(self, pipeline_configuration): """ Constructor for instantiating a pipeline adapter object. :param auth_provider: The authentication provider :param pipeline_configuration: The configuration generated based on user inputs """ self._pipeline = (pipeline_stages_base.PipelineRootStage( pipeline_configuration).append_stage( pipeline_stages_base.SasTokenRenewalStage()).append_stage( pipeline_stages_iothub_http.IoTHubHTTPTranslationStage( )).append_stage(pipeline_stages_http.HTTPTransportStage())) callback = EventedCallback() op = pipeline_ops_base.InitializePipelineOperation(callback=callback) self._pipeline.run_op(op) callback.wait_for_completion()
def __init__(self, pipeline_configuration): """ Constructor for instantiating a pipeline :param security_client: The security client which stores credentials """ self.responses_enabled = {provisioning_constants.REGISTER: False} # Event Handlers - Will be set by Client after instantiation of pipeline self.on_connected = None self.on_disconnected = None self.on_message_received = None self._registration_id = pipeline_configuration.registration_id self._pipeline = ( # # The root is always the root. By definition, it's the first stage in the pipeline. # pipeline_stages_base.PipelineRootStage( pipeline_configuration=pipeline_configuration) # # SasTokenRenewalStage comes near the root by default because it should be as close # to the top of the pipeline as possible, and does not need to be after anything. # .append_stage(pipeline_stages_base.SasTokenRenewalStage()) # # RegistrationStage needs to come early because this is the stage that converts registration # or query requests into request and response objects which are used by later stages # .append_stage(pipeline_stages_provisioning.RegistrationStage()) # # PollingStatusStage needs to come after RegistrationStage because RegistrationStage counts # on PollingStatusStage to poll until the registration is complete. # .append_stage(pipeline_stages_provisioning.PollingStatusStage()) # # CoordinateRequestAndResponseStage needs to be after RegistrationStage and PollingStatusStage # because these 2 stages create the request ops that CoordinateRequestAndResponseStage # is coordinating. It needs to be before ProvisioningMQTTTranslationStage because that stage # operates on ops that CoordinateRequestAndResponseStage produces # .append_stage( pipeline_stages_base.CoordinateRequestAndResponseStage()) # # ProvisioningMQTTTranslationStage comes here because this is the point where we can translate # all operations directly into MQTT. After this stage, only pipeline_stages_base stages # are allowed because ProvisioningMQTTTranslationStage removes all the provisioning-ness from the ops # .append_stage(pipeline_stages_provisioning_mqtt. ProvisioningMQTTTranslationStage()) # # AutoConnectStage comes here because only MQTT ops have the need_connection flag set # and this is the first place in the pipeline wherer we can guaranetee that all network # ops are MQTT ops. # .append_stage(pipeline_stages_base.AutoConnectStage()) # # ReconnectStage needs to be after AutoConnectStage because ReconnectStage sets/clears # the virtually_conencted flag and we want an automatic connection op to set this flag so # we can reconnect autoconnect operations. # .append_stage(pipeline_stages_base.ReconnectStage()) # # ConnectionLockStage needs to be after ReconnectStage because we want any ops that # ReconnectStage creates to go through the ConnectionLockStage gate # .append_stage(pipeline_stages_base.ConnectionLockStage()) # # RetryStage needs to be near the end because it's retrying low-level MQTT operations. # .append_stage(pipeline_stages_base.RetryStage()) # # OpTimeoutStage needs to be after RetryStage because OpTimeoutStage returns the timeout # errors that RetryStage is watching for. # .append_stage(pipeline_stages_base.OpTimeoutStage()) # # MQTTTransportStage needs to be at the very end of the pipeline because this is where # operations turn into network traffic # .append_stage(pipeline_stages_mqtt.MQTTTransportStage())) def _on_pipeline_event(event): logger.warning("Dropping unknown pipeline event {}".format( event.name)) def _on_connected(): if self.on_connected: self.on_connected("connected") def _on_disconnected(): if self.on_disconnected: self.on_disconnected("disconnected") self._pipeline.on_pipeline_event_handler = _on_pipeline_event self._pipeline.on_connected_handler = _on_connected self._pipeline.on_disconnected_handler = _on_disconnected callback = EventedCallback() op = pipeline_ops_base.InitializePipelineOperation(callback=callback) self._pipeline.run_op(op) callback.wait_for_completion()
def __init__(self, pipeline_configuration): """ Constructor for instantiating a pipeline adapter object :param auth_provider: The authentication provider :param pipeline_configuration: The configuration generated based on user inputs """ self.feature_enabled = { constant.C2D_MSG: False, constant.INPUT_MSG: False, constant.METHODS: False, constant.TWIN: False, constant.TWIN_PATCHES: False, } # Event Handlers - Will be set by Client after instantiation of this object self.on_connected = None self.on_disconnected = None self.on_c2d_message_received = None self.on_input_message_received = None self.on_method_request_received = None self.on_twin_patch_received = None # Currently a single timeout stage and a single retry stage for MQTT retry only. # Later, a higher level timeout and a higher level retry stage. self._pipeline = ( # # The root is always the root. By definition, it's the first stage in the pipeline. # pipeline_stages_base.PipelineRootStage(pipeline_configuration) # # SasTokenRenewalStage comes near the root by default because it should be as close # to the top of the pipeline as possible, and does not need to be after anything. # .append_stage(pipeline_stages_base.SasTokenRenewalStage()) # # EnsureDesiredPropertiesStage needs to be above TwinRequestResponseStage because it # sends GetTwinOperation ops and that stage handles those ops. # .append_stage( pipeline_stages_iothub.EnsureDesiredPropertiesStage()) # # TwinRequestResponseStage comes near the root by default because it doesn't need to be # after anything # .append_stage(pipeline_stages_iothub.TwinRequestResponseStage()) # # CoordinateRequestAndResponseStage needs to be after TwinRequestResponseStage because # TwinRequestResponseStage creates the request ops that CoordinateRequestAndResponseStage # is coordinating. It needs to be before IoTHubMQTTTranslationStage because that stage # operates on ops that CoordinateRequestAndResponseStage produces # .append_stage( pipeline_stages_base.CoordinateRequestAndResponseStage()) # # IoTHubMQTTTranslationStage comes here because this is the point where we can translate # all operations directly into MQTT. After this stage, only pipeline_stages_base stages # are allowed because IoTHubMQTTTranslationStage removes all the IoTHub-ness from the ops # .append_stage( pipeline_stages_iothub_mqtt.IoTHubMQTTTranslationStage()) # # AutoConnectStage comes here because only MQTT ops have the need_connection flag set # and this is the first place in the pipeline wherer we can guaranetee that all network # ops are MQTT ops. # .append_stage(pipeline_stages_base.AutoConnectStage()) # # ReconnectStage needs to be after AutoConnectStage because ReconnectStage sets/clears # the virtually_conencted flag and we want an automatic connection op to set this flag so # we can reconnect autoconnect operations. This is important, for example, if a # send_message causes the transport to automatically connect, but that connection fails. # When that happens, the ReconenctState will hold onto the ConnectOperation until it # succeeds, and only then will return success to the AutoConnectStage which will # allow the publish to continue. # .append_stage(pipeline_stages_base.ReconnectStage()) # # ConnectionLockStage needs to be after ReconnectStage because we want any ops that # ReconnectStage creates to go through the ConnectionLockStage gate # .append_stage(pipeline_stages_base.ConnectionLockStage()) # # RetryStage needs to be near the end because it's retrying low-level MQTT operations. # .append_stage(pipeline_stages_base.RetryStage()) # # OpTimeoutStage needs to be after RetryStage because OpTimeoutStage returns the timeout # errors that RetryStage is watching for. # .append_stage(pipeline_stages_base.OpTimeoutStage()) # # MQTTTransportStage needs to be at the very end of the pipeline because this is where # operations turn into network traffic # .append_stage(pipeline_stages_mqtt.MQTTTransportStage())) def _on_pipeline_event(event): if isinstance(event, pipeline_events_iothub.C2DMessageEvent): if self.on_c2d_message_received: self.on_c2d_message_received(event.message) else: logger.error( "C2D message event received with no handler. dropping." ) elif isinstance(event, pipeline_events_iothub.InputMessageEvent): if self.on_input_message_received: self.on_input_message_received(event.message) else: logger.error( "input message event received with no handler. dropping." ) elif isinstance(event, pipeline_events_iothub.MethodRequestEvent): if self.on_method_request_received: self.on_method_request_received(event.method_request) else: logger.error( "Method request event received with no handler. Dropping." ) elif isinstance( event, pipeline_events_iothub.TwinDesiredPropertiesPatchEvent): if self.on_twin_patch_received: self.on_twin_patch_received(event.patch) else: logger.error( "Twin patch event received with no handler. Dropping.") else: logger.error("Dropping unknown pipeline event {}".format( event.name)) def _on_connected(): if self.on_connected: self.on_connected() def _on_disconnected(): if self.on_disconnected: self.on_disconnected() # Set internal event handlers self._pipeline.on_pipeline_event_handler = _on_pipeline_event self._pipeline.on_connected_handler = _on_connected self._pipeline.on_disconnected_handler = _on_disconnected # Initialize the pipeline callback = EventedCallback() op = pipeline_ops_base.InitializePipelineOperation(callback=callback) self._pipeline.run_op(op) callback.wait_for_completion() # Set the running flag self._running = True