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()
Exemple #2
0
    def __init__(self, security_client, 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 = security_client.registration_id

        self._pipeline = (
            pipeline_stages_base.PipelineRootStage(
                pipeline_configuration=pipeline_configuration).append_stage(
                    pipeline_stages_provisioning.UseSecurityClientStage()).
            append_stage(
                pipeline_stages_provisioning.RegistrationStage()).append_stage(
                    pipeline_stages_provisioning.PollingStatusStage()).
            append_stage(
                pipeline_stages_base.CoordinateRequestAndResponseStage()
            ).append_stage(pipeline_stages_provisioning_mqtt.
                           ProvisioningMQTTTranslationStage()).append_stage(
                               pipeline_stages_base.ReconnectStage()).
            append_stage(pipeline_stages_base.AutoConnectStage()).append_stage(
                pipeline_stages_base.ConnectionLockStage()).append_stage(
                    pipeline_stages_base.RetryStage()).append_stage(
                        pipeline_stages_base.OpTimeoutStage()).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()

        if isinstance(security_client, X509SecurityClient):
            op = pipeline_ops_provisioning.SetX509SecurityClientOperation(
                security_client=security_client, callback=callback)
        elif isinstance(security_client, SymmetricKeySecurityClient):
            op = pipeline_ops_provisioning.SetSymmetricKeySecurityClientOperation(
                security_client=security_client, callback=callback)
        else:
            logger.error(
                "Provisioning not equipped to handle other security client.")

        self._pipeline.run_op(op)
        callback.wait_for_completion()