コード例 #1
0
    async def send_message_to_output(self, message, output_name):
        """Sends an event/message to the given module output.

        These are outgoing events and are meant to be "output events"

        If the connection to the service has not previously been opened by a call to connect, this
        function will open the connection before sending the event.

        :param message: Message to send to the given output. Anything passed that is not an
            instance of the Message class will be converted to Message object.
        :type message: :class:`azure.iot.device.Message` or str
        :param str output_name: Name of the output to send the event to.

        :raises: :class:`azure.iot.device.exceptions.CredentialError` if credentials are invalid
            and a connection cannot be established.
        :raises: :class:`azure.iot.device.exceptions.ConnectionFailedError` if a establishing a
            connection results in failure.
        :raises: :class:`azure.iot.device.exceptions.ConnectionDroppedError` if connection is lost
            during execution.
        :raises: :class:`azure.iot.device.exceptions.ClientError` if there is an unexpected failure
            during execution.
        :raises: ValueError if the message fails size validation.
        """
        if not isinstance(message, Message):
            message = Message(message)

        if message.get_size() > device_constant.TELEMETRY_MESSAGE_SIZE_LIMIT:
            raise ValueError("Size of message can not exceed 256 KB.")

        message.output_name = output_name

        logger.info("Sending message to output:" + output_name + "...")
        send_output_message_async = async_adapter.emulate_async(
            self._mqtt_pipeline.send_output_message)

        callback = async_adapter.AwaitableCallback()
        await send_output_message_async(message, callback=callback)
        await handle_result(callback)

        logger.info("Successfully sent message to output: " + output_name)
コード例 #2
0
    async def shutdown(self):
        """Shut down the client for graceful exit.

        Once this method is called, any attempts at further client calls will result in a
        ClientError being raised

        :raises: :class:`azure.iot.device.exceptions.ClientError` if there is an unexpected failure
            during execution.
        """
        logger.info("Initiating client shutdown")
        # Note that client disconnect does the following:
        #   - Disconnects the pipeline
        #   - Resolves all pending handler calls
        #   - Stops handler threads
        await self.disconnect()

        # Note that shutting down does the following:
        #   - Disconnects the MQTT pipeline
        #   - Stops MQTT pipeline threads
        logger.debug("Beginning pipeline shutdown operation")
        shutdown_async = async_adapter.emulate_async(self._mqtt_pipeline.shutdown)
        callback = async_adapter.AwaitableCallback()
        await shutdown_async(callback=callback)
        await handle_result(callback)
        logger.debug("Completed pipeline shutdown operation")

        # Yes, that means the pipeline is disconnected twice (well, actually three times if you
        # consider that the client-level disconnect causes two pipeline-level disconnects for
        # reasons explained in comments in the client's .disconnect() method).
        #
        # This last disconnect that occurs as a result of the pipeline shutdown is a bit different
        # from the first though, in that it's more "final" and can't simply just be reconnected.

        # Note also that only the MQTT pipeline is shut down. The reason is twofold:
        #   1. There are no known issues related to graceful exit if the HTTP pipeline is not
        #      explicitly shut down
        #   2. The HTTP pipeline is planned for eventual removal from the client
        # In light of these two facts, it seemed irrelevant to spend time implementing shutdown
        # capability for HTTP pipeline.
        logger.info("Client shutdown complete")
コード例 #3
0
    async def invoke_method(self, method_params, device_id, module_id=None):
        """Invoke a method from your client onto a device or module client, and receive the response to the method call.

        :param dict method_params: Should contain a method_name, payload, connect_timeout_in_seconds, response_timeout_in_seconds.
        :param str device_id: Device ID of the target device where the method will be invoked.
        :param str module_id: Module ID of the target module where the method will be invoked. (Optional)

        :returns: method_result should contain a status, and a payload
        :rtype: dict
        """
        invoke_method_async = async_adapter.emulate_async(
            self._http_pipeline.invoke_method)
        callback = async_adapter.AwaitableCallback(
            return_arg_name="invoke_method_response")
        await invoke_method_async(device_id,
                                  method_params,
                                  callback=callback,
                                  module_id=module_id)

        method_response = await handle_result(callback)
        logger.info("Successfully invoked method")
        return method_response
コード例 #4
0
    async def notify_blob_upload_status(self, correlation_id, is_success,
                                        status_code, status_description):
        """When the upload is complete, the device sends a POST request to the IoT Hub endpoint with information on the status of an upload to blob attempt. This is used by IoT Hub to notify listening clients.

        :param str correlation_id: Provided by IoT Hub on get_storage_info_for_blob request.
        :param bool is_success: A boolean that indicates whether the file was uploaded successfully.
        :param int status_code: A numeric status code that is the status for the upload of the fiel to storage.
        :param str status_description: A description that corresponds to the status_code.
        """
        notify_blob_upload_status_async = async_adapter.emulate_async(
            self._http_pipeline.notify_blob_upload_status)

        callback = async_adapter.AwaitableCallback()
        await notify_blob_upload_status_async(
            correlation_id=correlation_id,
            is_success=is_success,
            status_code=status_code,
            status_description=status_description,
            callback=callback,
        )
        await handle_result(callback)
        logger.info("Successfully notified blob upload status")
コード例 #5
0
    async def register(self):
        """
        Register the device with the provisioning service.

        Before returning the client will also disconnect from the provisioning service.
        If a registration attempt is made while a previous registration is in progress it may
        throw an error.

        :returns: RegistrationResult indicating the result of the registration.
        :rtype: :class:`azure.iot.device.RegistrationResult`
        """
        logger.info("Registering with Provisioning Service...")
        register_async = async_adapter.emulate_async(
            self._polling_machine.register)

        callback = async_adapter.AwaitableCallback(return_arg_name="result")
        await register_async(payload=self._provisioning_payload,
                             callback=callback)
        result = await callback.completion()

        log_on_register_complete(result)
        return result
コード例 #6
0
    async def _disable_feature(self, feature_name):
        """Disable an Azure IoT Hub feature

        :param feature_name: The name of the feature to enable.
            See azure.iot.device.common.pipeline.constant for possible values.
        """
        logger.info("Disabling feature: {}...".format(feature_name))
        if self._mqtt_pipeline.feature_enabled[feature_name]:
            # Disable the feature if not already disabled
            disable_feature_async = async_adapter.emulate_async(
                self._mqtt_pipeline.disable_feature)

            callback = async_adapter.AwaitableCallback()
            await disable_feature_async(feature_name, callback=callback)
            await handle_result(callback)

            logger.info(
                "Successfully disabled feature: {}".format(feature_name))
        else:
            # This branch shouldn't be reached, but in case it is, log it
            logger.info(
                "Feature ({}) already enabled - skipping".format(feature_name))
コード例 #7
0
    async def send_d2c_message(self, message):
        """Sends a message to the default events endpoint on the Azure IoT Hub or Azure IoT Edge Hub instance.

        If the connection to the service has not previously been opened by a call to connect, this
        function will open the connection before sending the event.

        :param message: The actual message to send. Anything passed that is not an instance of the
        Message class will be converted to Message object.
        """
        if not isinstance(message, Message):
            message = Message(message)

        logger.info("Sending message to Hub...")
        send_d2c_message_async = async_adapter.emulate_async(self._iothub_pipeline.send_d2c_message)

        def sync_callback():
            logger.info("Successfully sent message to Hub")

        callback = async_adapter.AwaitableCallback(sync_callback)

        await send_d2c_message_async(message, callback=callback)
        await callback.completion()
コード例 #8
0
    async def register(self):
        """
        Register the device with the provisioning service.

        Before returning the client will also disconnect from the provisioning service.
        If a registration attempt is made while a previous registration is in progress it may
        throw an error.

        :returns: RegistrationResult indicating the result of the registration.
        :rtype: :class:`azure.iot.device.RegistrationResult`

        :raises: :class:`azure.iot.device.exceptions.CredentialError` if credentials are invalid
            and a connection cannot be established.
        :raises: :class:`azure.iot.device.exceptions.ConnectionFailedError` if a establishing a
            connection results in failure.
        :raises: :class:`azure.iot.device.exceptions.ConnectionDroppedError` if connection is lost
            during execution.
        :raises: :class:`azure.iot.device.exceptions.ClientError` if there is an unexpected failure
            during execution.

        """
        logger.info("Registering with Provisioning Service...")

        if not self._provisioning_pipeline.responses_enabled[
                dps_constant.REGISTER]:
            await self._enable_responses()

        register_async = async_adapter.emulate_async(
            self._provisioning_pipeline.register)

        register_complete = async_adapter.AwaitableCallback(
            return_arg_name="result")
        await register_async(payload=self._provisioning_payload,
                             callback=register_complete)
        result = await handle_result(register_complete)

        log_on_register_complete(result)
        return result
コード例 #9
0
    async def send_message(self, message):
        """Sends a message to the default events endpoint on the Azure IoT Hub or Azure IoT Edge Hub instance.

        If the connection to the service has not previously been opened by a call to connect, this
        function will open the connection before sending the event.

        :param message: The actual message to send. Anything passed that is not an instance of the
            Message class will be converted to Message object.
        :type message: :class:`azure.iot.device.Message` or str

        :raises: :class:`azure.iot.device.exceptions.CredentialError` if credentials are invalid
            and a connection cannot be established.
        :raises: :class:`azure.iot.device.exceptions.ConnectionFailedError` if a establishing a
            connection results in failure.
        :raises: :class:`azure.iot.device.exceptions.ConnectionDroppedError` if connection is lost
            during execution.
        :raises: :class:`azure.iot.device.exceptions.OperationTimeout` if connection attempt
            times out
        :raises: :class:`azure.iot.device.exceptions.NoConnectionError` if the client is not
            connected (and there is no auto-connect enabled)
        :raises: :class:`azure.iot.device.exceptions.ClientError` if there is an unexpected failure
            during execution.
        :raises: ValueError if the message fails size validation.
        """
        if not isinstance(message, Message):
            message = Message(message)

        if message.get_size() > device_constant.TELEMETRY_MESSAGE_SIZE_LIMIT:
            raise ValueError("Size of telemetry message can not exceed 256 KB.")

        logger.info("Sending message to Hub...")
        send_message_async = async_adapter.emulate_async(self._mqtt_pipeline.send_message)

        callback = async_adapter.AwaitableCallback()
        await send_message_async(message, callback=callback)
        await handle_result(callback)

        logger.info("Successfully sent message to Hub")
コード例 #10
0
    async def update_sastoken(self, sastoken):
        """
        Update the client's SAS Token used for authentication, then reauthorizes the connection.

        This API can only be used if the client was initially created with a SAS Token.

        :param str sastoken: The new SAS Token string for the client to use

        :raises: ValueError if the sastoken parameter is invalid
        :raises: :class:`azure.iot.device.exceptions.CredentialError` if credentials are invalid
            and a connection cannot be re-established.
        :raises: :class:`azure.iot.device.exceptions.ConnectionFailedError` if a re-establishing
            the connection results in failure.
        :raises: :class:`azure.iot.device.exceptions.ConnectionDroppedError` if connection is lost
            during execution.
        :raises: :class:`azure.iot.device.exceptions.OperationTimeout` if the reauthorization
            attempt times out.
        :raises: :class:`azure.iot.device.exceptions.ClientError` if the client was not initially
            created with a SAS token.
        :raises: :class:`azure.iot.device.exceptions.ClientError` if there is an unexpected failure
            during execution.
        """
        self._replace_user_supplied_sastoken(sastoken)

        # Reauthorize the connection
        logger.info("Reauthorizing connection with Hub...")
        reauth_connection_async = async_adapter.emulate_async(
            self._mqtt_pipeline.reauthorize_connection
        )
        callback = async_adapter.AwaitableCallback()
        await reauth_connection_async(callback=callback)
        await handle_result(callback)
        # NOTE: Currently due to the MQTT3 implemenation, the pipeline reauthorization will return
        # after the disconnect. It does not wait for the reconnect to complete. This means that
        # any errors that may occur as part of the connect will not return via this callback.
        # They will instead go to the background exception handler.

        logger.info("Successfully reauthorized connection to Hub")
コード例 #11
0
    async def connect(self):
        """Connects the client to an Azure IoT Hub or Azure IoT Edge Hub instance.

        The destination is chosen based on the credentials passed via the auth_provider parameter
        that was provided when this object was initialized.

        :raises: :class:`azure.iot.device.exceptions.CredentialError` if credentials are invalid
            and a connection cannot be established.
        :raises: :class:`azure.iot.device.exceptions.ConnectionFailedError` if a establishing a
            connection results in failure.
        :raises: :class:`azure.iot.device.exceptions.ConnectionDroppedError` if connection is lost
            during execution.
        :raises: :class:`azure.iot.device.exceptions.ClientError` if there is an unexpected failure
            during execution.
        """
        logger.info("Connecting to Hub...")
        connect_async = async_adapter.emulate_async(self._mqtt_pipeline.connect)

        callback = async_adapter.AwaitableCallback()
        await connect_async(callback=callback)
        await handle_result(callback)

        logger.info("Successfully connected to Hub")
コード例 #12
0
    async def patch_twin_reported_properties(self, reported_properties_patch):
        """
        Update reported properties with the Azure IoT Hub or Azure IoT Edge Hub service.

        If the service returns an error on the patch operation, this function will raise the
        appropriate error.

        :param reported_properties_patch: Twin Reported Properties patch as a JSON dict
        :type reported_properties_patch: dict

        :raises: :class:`azure.iot.device.exceptions.CredentialError` if credentials are invalid
            and a connection cannot be established.
        :raises: :class:`azure.iot.device.exceptions.ConnectionFailedError` if a establishing a
            connection results in failure.
        :raises: :class:`azure.iot.device.exceptions.ConnectionDroppedError` if connection is lost
            during execution.
        :raises: :class:`azure.iot.device.exceptions.OperationTimeout` if connection attempt
            times out
        :raises: :class:`azure.iot.device.exceptions.NoConnectionError` if the client is not
            connected (and there is no auto-connect enabled)
        :raises: :class:`azure.iot.device.exceptions.ClientError` if there is an unexpected failure
            during execution.
        """
        logger.info("Patching twin reported properties")

        if not self._mqtt_pipeline.feature_enabled[constant.TWIN]:
            await self._enable_feature(constant.TWIN)

        patch_twin_async = async_adapter.emulate_async(
            self._mqtt_pipeline.patch_twin_reported_properties
        )

        callback = async_adapter.AwaitableCallback()
        await patch_twin_async(patch=reported_properties_patch, callback=callback)
        await handle_result(callback)

        logger.info("Successfully sent twin patch")
コード例 #13
0
    async def patch_twin_reported_properties(self, reported_properties_patch):
        """
        Update reported properties with the Azure IoT Hub or Azure IoT Edge Hub service.

        If the service returns an error on the patch operation, this function will raise the
        appropriate error.

        :param reported_properties_patch:
        :type reported_properties_patch: dict, str, int, float, bool, or None (JSON compatible values)
        """
        logger.info("Patching twin reported properties")

        if not self._iothub_pipeline.feature_enabled[constant.TWIN]:
            await self._enable_feature(constant.TWIN)

        patch_twin_async = async_adapter.emulate_async(
            self._iothub_pipeline.patch_twin_reported_properties
        )

        callback = async_adapter.AwaitableCallback()
        await patch_twin_async(patch=reported_properties_patch, callback=callback)
        await callback.completion()

        logger.info("Successfully sent twin patch")
コード例 #14
0
 async def test_coroutine_has_input_function_docstring(self, mock_function):
     async_fn = async_adapter.emulate_async(mock_function)
     assert async_fn.__doc__ == mock_function.__doc__
コード例 #15
0
 async def test_returns_coroutine(self, mock_function):
     async_fn = async_adapter.emulate_async(mock_function)
     assert inspect.iscoroutinefunction(async_fn)