async def send_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.
        :param output_name: Name of the output to send the event to.
        """
        if not isinstance(message, Message):
            message = Message(message)

        message.output_name = output_name

        logger.info("Sending message to output:" + output_name + "...")
        send_output_event_async = async_adapter.emulate_async(
            self._pipeline.send_output_event)

        def sync_callback():
            logger.info("Successfully sent message to output: " + output_name)

        callback = async_adapter.AwaitableCallback(sync_callback)

        await send_output_event_async(message, callback=callback)
        await callback.completion()
    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.
        :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.
        """
        if not isinstance(message, Message):
            message = Message(message)

        message.output_name = output_name

        logger.info("Sending message to output:" + output_name + "...")
        send_output_event_async = async_adapter.emulate_async(
            self._iothub_pipeline.send_output_event)

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

        logger.info("Successfully sent message to output: " + output_name)
    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.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")
Example #4
0
 def test_setting_message_as_security_message(self):
     s = "After all this time? Always"
     ctype = "application/json"
     encoding = "utf-16"
     msg = Message(s, None, encoding, ctype)
     assert msg.iothub_interface_id is None
     msg.set_as_security_message()
     assert msg.iothub_interface_id == constant.SECURITY_MESSAGE_INTERFACE_ID
    def _handle_pipeline_event(self, event):
        """
        Pipeline Event handler function to convert incoming MQTT messages into the appropriate IoTHub
        events, based on the topic of the message
        """
        # TODO: should we always be decoding the payload? Seems strange to only sometimes do it.
        # Is there value to the user getting the original bytestring from the wire?
        if isinstance(event, pipeline_events_mqtt.IncomingMQTTMessageEvent):
            topic = event.topic
            device_id = self.nucleus.pipeline_configuration.device_id
            module_id = self.nucleus.pipeline_configuration.module_id

            if mqtt_topic_iothub.is_c2d_topic(topic, device_id):
                message = Message(event.payload)
                mqtt_topic_iothub.extract_message_properties_from_topic(topic, message)
                self.send_event_up(pipeline_events_iothub.C2DMessageEvent(message))

            elif mqtt_topic_iothub.is_input_topic(topic, device_id, module_id):
                message = Message(event.payload)
                mqtt_topic_iothub.extract_message_properties_from_topic(topic, message)
                message.input_name = mqtt_topic_iothub.get_input_name_from_topic(topic)
                self.send_event_up(pipeline_events_iothub.InputMessageEvent(message))

            elif mqtt_topic_iothub.is_method_topic(topic):
                request_id = mqtt_topic_iothub.get_method_request_id_from_topic(topic)
                method_name = mqtt_topic_iothub.get_method_name_from_topic(topic)
                method_received = MethodRequest(
                    request_id=request_id,
                    name=method_name,
                    payload=json.loads(event.payload.decode("utf-8")),
                )
                self.send_event_up(pipeline_events_iothub.MethodRequestEvent(method_received))

            elif mqtt_topic_iothub.is_twin_response_topic(topic):
                request_id = mqtt_topic_iothub.get_twin_request_id_from_topic(topic)
                status_code = int(mqtt_topic_iothub.get_twin_status_code_from_topic(topic))
                self.send_event_up(
                    pipeline_events_base.ResponseEvent(
                        request_id=request_id, status_code=status_code, response_body=event.payload
                    )
                )

            elif mqtt_topic_iothub.is_twin_desired_property_patch_topic(topic):
                self.send_event_up(
                    pipeline_events_iothub.TwinDesiredPropertiesPatchEvent(
                        patch=json.loads(event.payload.decode("utf-8"))
                    )
                )

            else:
                logger.debug("Unknown topic: {} passing up to next handler".format(topic))
                self.send_event_up(event)

        else:
            # all other messages get passed up
            self.send_event_up(event)
Example #6
0
    def _handle_pipeline_event(self, event):
        """
        Pipeline Event handler function to convert incoming MQTT messages into the appropriate IoTHub
        events, based on the topic of the message
        """
        if isinstance(event, pipeline_events_mqtt.IncomingMQTTMessageEvent):
            topic = event.topic

            if mqtt_topic_iothub.is_c2d_topic(topic, self.device_id):
                message = Message(event.payload)
                mqtt_topic_iothub.extract_properties_from_topic(topic, message)
                self.send_event_up(pipeline_events_iothub.C2DMessageEvent(message))

            elif mqtt_topic_iothub.is_input_topic(topic, self.device_id, self.module_id):
                message = Message(event.payload)
                mqtt_topic_iothub.extract_properties_from_topic(topic, message)
                input_name = mqtt_topic_iothub.get_input_name_from_topic(topic)
                self.send_event_up(pipeline_events_iothub.InputMessageEvent(input_name, message))

            elif mqtt_topic_iothub.is_method_topic(topic):
                request_id = mqtt_topic_iothub.get_method_request_id_from_topic(topic)
                method_name = mqtt_topic_iothub.get_method_name_from_topic(topic)
                method_received = MethodRequest(
                    request_id=request_id,
                    name=method_name,
                    payload=json.loads(event.payload.decode("utf-8")),
                )
                self.send_event_up(pipeline_events_iothub.MethodRequestEvent(method_received))

            elif mqtt_topic_iothub.is_twin_response_topic(topic):
                request_id = mqtt_topic_iothub.get_twin_request_id_from_topic(topic)
                status_code = int(mqtt_topic_iothub.get_twin_status_code_from_topic(topic))
                self.send_event_up(
                    pipeline_events_base.ResponseEvent(
                        request_id=request_id, status_code=status_code, response_body=event.payload
                    )
                )

            elif mqtt_topic_iothub.is_twin_desired_property_patch_topic(topic):
                self.send_event_up(
                    pipeline_events_iothub.TwinDesiredPropertiesPatchEvent(
                        patch=json.loads(event.payload.decode("utf-8"))
                    )
                )

            else:
                logger.debug("Unknown topic: {} passing up to next handler".format(topic))
                self.send_event_up(event)

        else:
            # all other messages get passed up
            super(IoTHubMQTTTranslationStage, self)._handle_pipeline_event(event)
 def test_send_to_output_calls_transport(self, client, transport):
     message = Message("this is a message")
     output_name = "some_output"
     client.send_to_output(message, output_name)
     assert transport.send_output_event.call_count == 1
     assert transport.send_output_event.call_args[0][0] is message
     assert message.output_name == output_name
class TestMessage(object):

    data_str = "After all this time? Always"
    data_int = 987
    data_obj = Message(data_str)

    @pytest.mark.parametrize("data", [data_str, data_int, data_obj],
                             ids=["String", "Integer", "Message"])
    def test_instantiates_from_data(self, data):
        msg = Message(data)
        assert msg.data == data

    def test_instantiates_with_optional_message_id(self):
        s = "After all this time? Always"
        message_id = "Postage12323"
        msg = Message(s, message_id)
        assert msg.message_id == message_id

    def test_instantiates_with_optional_contenttype_encoding(self):
        s = "After all this time? Always"
        type = "application/json"
        encoding = "utf-16"
        msg = Message(s, None, encoding, type)
        assert msg.content_encoding == encoding
        assert msg.content_type == type
Example #9
0
 def test_instantiates_with_optional_contenttype_encoding(self):
     s = "After all this time? Always"
     ctype = "application/json"
     encoding = "utf-16"
     msg = Message(s, None, encoding, ctype)
     assert msg.content_encoding == encoding
     assert msg.content_type == ctype
Example #10
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.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 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)
    def test_receive_c2d_message_returns_message_from_c2d_inbox(
            self, mocker, client):
        message = Message("this is a message")
        inbox_mock = mocker.MagicMock(autospec=SyncClientInbox)
        inbox_mock.get.return_value = message
        manager_get_inbox_mock = mocker.patch.object(client._inbox_manager,
                                                     "get_c2d_message_inbox",
                                                     return_value=inbox_mock)

        received_message = client.receive_c2d_message()
        assert manager_get_inbox_mock.call_count == 1
        assert inbox_mock.get.call_count == 1
        assert received_message is message
Example #12
0
    def _handle_pipeline_event(self, event):
        """
        Pipeline Event handler function to convert incoming Mqtt messages into the appropriate IotHub
        events, based on the topic of the message
        """
        if isinstance(event, pipeline_events_mqtt.IncomingMessage):
            topic = event.topic

            if mqtt_topic.is_c2d_topic(topic):
                message = Message(event.payload)
                mqtt_topic.extract_properties_from_topic(topic, message)
                self.handle_pipeline_event(
                    pipeline_events_iothub.C2DMessageEvent(message))

            elif mqtt_topic.is_input_topic(topic):
                message = Message(event.payload)
                mqtt_topic.extract_properties_from_topic(topic, message)
                input_name = mqtt_topic.get_input_name_from_topic(topic)
                self.handle_pipeline_event(
                    pipeline_events_iothub.InputMessageEvent(
                        input_name, message))

            elif mqtt_topic.is_method_topic(topic):
                rid = mqtt_topic.get_method_request_id_from_topic(topic)
                method_name = mqtt_topic.get_method_name_from_topic(topic)
                method_received = MethodRequest(request_id=rid,
                                                name=method_name,
                                                payload=json.loads(
                                                    event.payload))
                self._handle_pipeline_event(
                    pipeline_events_iothub.MethodRequest(method_received))

            else:
                logger.warning(
                    "Warning: dropping message with topic {}".format(topic))

        else:
            # all other messages get passed up
            PipelineStage._handle_pipeline_event(self, event)
Example #13
0
class TestMessage(object):

    data_str = "After all this time? Always"
    data_int = 987
    data_obj = Message(data_str)

    @pytest.mark.it("Instantiates from data type")
    @pytest.mark.parametrize(
        "data", [data_str, data_int, data_obj], ids=["String", "Integer", "Message"]
    )
    def test_instantiates_from_data(self, data):
        msg = Message(data)
        assert msg.data == data

    @pytest.mark.it("Instantiates with optional message id")
    def test_instantiates_with_optional_message_id(self):
        s = "After all this time? Always"
        message_id = "Postage12323"
        msg = Message(s, message_id)
        assert msg.message_id == message_id

    @pytest.mark.it("Instantiates with optional content type encoding")
    def test_instantiates_with_optional_contenttype_encoding(self):
        s = "After all this time? Always"
        ctype = "application/json"
        encoding = "utf-16"
        msg = Message(s, None, encoding, ctype)
        assert msg.content_encoding == encoding
        assert msg.content_type == ctype

    @pytest.mark.it("Setting message as security message")
    def test_setting_message_as_security_message(self):
        s = "After all this time? Always"
        ctype = "application/json"
        encoding = "utf-16"
        msg = Message(s, None, encoding, ctype)
        assert msg.iothub_interface_id is None
        msg.set_as_security_message()
        assert msg.iothub_interface_id == constant.SECURITY_MESSAGE_INTERFACE_ID

    @pytest.mark.it(
        "Uses string representation of data/payload attribute as string representation of Message"
    )
    @pytest.mark.parametrize(
        "data", [data_str, data_int, data_obj], ids=["String", "Integer", "Message"]
    )
    def test_str_rep(self, data):
        msg = Message(data)
        assert str(msg) == str(data)
Example #14
0
    async def test_receive_input_message_returns_message_from_input_inbox(
            self, mocker, client):
        message = Message("this is a message")
        inbox_mock = mocker.MagicMock(autospec=AsyncClientInbox)
        inbox_mock.get.return_value = await create_completed_future(message)
        manager_get_inbox_mock = mocker.patch.object(client._inbox_manager,
                                                     "get_input_message_inbox",
                                                     return_value=inbox_mock)

        input_name = "some_input"
        received_message = await client.receive_input_message(input_name)
        assert manager_get_inbox_mock.call_count == 1
        assert manager_get_inbox_mock.call_args == mocker.call(input_name)
        assert inbox_mock.get.call_count == 1
        assert received_message is message
    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.
        """
        if not isinstance(message, Message):
            message = Message(message)

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

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

        logger.info("Successfully sent message to Hub")
Example #16
0
async def input_listener(module_client):

    if "ALERT_RULES" in os.environ:
        alert_rules = json.loads(os.environ.get("ALERT_RULES"))
    else:
        with open('./src/rules.json') as f:
            alert_rules = json.loads(f.read())

    for rules in alert_rules:
        if 'operator' not in rules or rules['operator'] not in [
                "eq", "neq", "lt", "lte", "gt", "gte"
        ]:
            EdgeLogger.logger.error("Unknown operator {} in rule {}".format(
                rules['operator'], json.dumps(rules)))

    while True:
        try:
            input_message = await module_client.receive_message_on_input(
                constantes.INPUT_NAME)  # blocking call
            EdgeLogger().logger.info(
                "Receive message {}".format(input_message))
            alerts = alerting(
                json.loads(input_message.data)[constantes.DATA_KEY],
                alert_rules)

            await module_client.send_message_to_output(input_message,
                                                       constantes.OUTPUT_NAME)
            if len(alerts) > 0:
                message = {"type": "alert", "alerte": alerts}

                EdgeLogger().logger.info("Send alerts : {}".format(
                    json.dumps(message)))

                await module_client.send_message_to_output(
                    Message(json.dumps(message)), constantes.OUTPUT_NAME)

        except Exception as error:
            EdgeLogger().logger.error(error)
Example #17
0
 def test_instantiates_with_optional_output_name(self):
     output_name = "some_output"
     msg = Message("some message", output_name=output_name)
     assert msg.output_name == output_name
Example #18
0
 def test_instantiates_from_data(self, data):
     msg = Message(data)
     assert msg.data == data
Example #19
0
 def test_instantiates_with_optional_message_id(self):
     s = "After all this time? Always"
     message_id = "Postage12323"
     msg = Message(s, message_id)
     assert msg.message_id == message_id
 def message(self):
     return Message("some message")
Example #21
0
class TestMessage(object):

    data_str = "After all this time? Always"
    data_int = 987
    data_obj = Message(data_str)

    @pytest.mark.it("Instantiates from data type")
    @pytest.mark.parametrize("data", [data_str, data_int, data_obj],
                             ids=["String", "Integer", "Message"])
    def test_instantiates_from_data(self, data):
        msg = Message(data)
        assert msg.data == data

    @pytest.mark.it("Instantiates with optional provided message id")
    def test_instantiates_with_optional_message_id(self):
        s = "After all this time? Always"
        message_id = "Postage12323"
        msg = Message(s, message_id)
        assert msg.message_id == message_id

    @pytest.mark.it(
        "Instantiates with optional provided content type and content encoding"
    )
    def test_instantiates_with_optional_contenttype_encoding(self):
        s = "After all this time? Always"
        ctype = "application/json"
        encoding = "utf-16"
        msg = Message(s, None, encoding, ctype)
        assert msg.content_encoding == encoding
        assert msg.content_type == ctype

    @pytest.mark.it("Instantiates with optional provided output name")
    def test_instantiates_with_optional_output_name(self):
        output_name = "some_output"
        msg = Message("some message", output_name=output_name)
        assert msg.output_name == output_name

    @pytest.mark.it("Instantiates with no custom properties set")
    def test_default_custom_properties(self):
        msg = Message("some message")
        assert msg.custom_properties == {}

    @pytest.mark.it("Instantiates with no set expiry time")
    def test_default_expiry_time(self):
        msg = Message("some message")
        assert msg.expiry_time_utc is None

    @pytest.mark.it("Instantiates with no set correlation id")
    def test_default_corr_id(self):
        msg = Message("some message")
        assert msg.correlation_id is None

    @pytest.mark.it("Instantiates with no set user id")
    def test_default_user_id(self):
        msg = Message("some message")
        assert msg.user_id is None

    @pytest.mark.it("Instantiates with no set input name")
    def test_default_input_name(self):
        msg = Message("some message")
        assert msg.input_name is None

    @pytest.mark.it(
        "Instantiates with no set iothub_interface_id (i.e. not as a security message)"
    )
    def test_default_security_msg_status(self):
        msg = Message("some message")
        assert msg.iothub_interface_id is None

    @pytest.mark.it(
        "Maintains iothub_interface_id (security message) as a read-only property"
    )
    def test_read_only_iothub_interface_id(self):
        msg = Message("some message")
        with pytest.raises(AttributeError):
            msg.iothub_interface_id = "value"

    @pytest.mark.it(
        "Uses string representation of data/payload attribute as string representation of Message"
    )
    @pytest.mark.parametrize("data", [data_str, data_int, data_obj],
                             ids=["String", "Integer", "Message"])
    def test_str_rep(self, data):
        msg = Message(data)
        assert str(msg) == str(data)

    @pytest.mark.it("Can be set as a security message via API")
    def test_setting_message_as_security_message(self):
        s = "After all this time? Always"
        ctype = "application/json"
        encoding = "utf-16"
        msg = Message(s, None, encoding, ctype)
        assert msg.iothub_interface_id is None
        msg.set_as_security_message()
        assert msg.iothub_interface_id == constant.SECURITY_MESSAGE_INTERFACE_ID
Example #22
0
 def test_read_only_iothub_interface_id(self):
     msg = Message("some message")
     with pytest.raises(AttributeError):
         msg.iothub_interface_id = "value"
Example #23
0
 def test_default_security_msg_status(self):
     msg = Message("some message")
     assert msg.iothub_interface_id is None
Example #24
0
 def test_default_input_name(self):
     msg = Message("some message")
     assert msg.input_name is None
Example #25
0
 def test_default_user_id(self):
     msg = Message("some message")
     assert msg.user_id is None
Example #26
0
 def test_default_corr_id(self):
     msg = Message("some message")
     assert msg.correlation_id is None
Example #27
0
 def test_str_rep(self, data):
     msg = Message(data)
     assert str(msg) == str(data)
Example #28
0
 def test_default_custom_properties(self):
     msg = Message("some message")
     assert msg.custom_properties == {}
def message():
    return Message("Wingardium Leviosa")
Example #30
0
 def test_default_expiry_time(self):
     msg = Message("some message")
     assert msg.expiry_time_utc is None