def test_route_method_request_will_route_method_to_generic_method_request_inbox_until_named_method_inbox_is_created(
            self, manager):
        # Two MethodRequests for the SAME method name
        method_name = "some_method"
        method_request1 = MethodRequest(request_id="1",
                                        name=method_name,
                                        payload="{'key': 'value'}")
        method_request2 = MethodRequest(request_id="2",
                                        name=method_name,
                                        payload="{'key': 'value'}")

        # Do NOT get a specific named inbox - just the generic one
        generic_method_inbox = manager.get_method_request_inbox()
        assert generic_method_inbox.empty()

        # Route the first method request
        delivered_request1 = manager.route_method_request(method_request1)
        assert delivered_request1

        # Method Request 1 was delivered to the generic method inbox since the method name was unknown
        assert method_request1 in generic_method_inbox

        # Get an inbox for the specific method name
        named_method_inbox = manager.get_method_request_inbox(method_name)
        assert named_method_inbox.empty()

        # Route the second method request
        delivered_request2 = manager.route_method_request(method_request2)
        assert delivered_request2

        # Method Request 2 was delivered to its corresponding named inbox since the method name is known
        assert method_request2 in named_method_inbox
        assert method_request2 not in generic_method_inbox
    def test_payload_property_is_read_only(self):
        m_req = MethodRequest(request_id=dummy_rid,
                              name=dummy_name,
                              payload=dummy_payload)
        new_payload = {"NewPayload": "somenewpayload"}

        with pytest.raises(AttributeError):
            m_req.payload = new_payload
        assert m_req.payload != new_payload
        assert m_req.payload == dummy_payload
    def test_request_id_property_is_read_only(self):
        m_req = MethodRequest(request_id=dummy_rid,
                              name=dummy_name,
                              payload=dummy_payload)
        new_rid = 2

        with pytest.raises(AttributeError):
            m_req.request_id = new_rid
        assert m_req.request_id != new_rid
        assert m_req.request_id == dummy_rid
    def test_name_property_is_read_only(self):
        m_req = MethodRequest(request_id=dummy_rid,
                              name=dummy_name,
                              payload=dummy_payload)
        new_name = "new_name"

        with pytest.raises(AttributeError):
            m_req.name = new_name
        assert m_req.name != new_name
        assert m_req.name == dummy_name
    def test_clear_all_method_requests_clears_named_method_request_inboxes(self, manager):
        method_request_inbox1 = manager.get_method_request_inbox("some_method")
        method_request_inbox2 = manager.get_method_request_inbox("some_other_method")
        assert method_request_inbox1.empty()
        assert method_request_inbox2.empty()
        manager.route_method_request(MethodRequest("id1", "some_method", "payload"))
        manager.route_method_request(MethodRequest("id2", "some_other_method", "payload"))
        assert not method_request_inbox1.empty()
        assert not method_request_inbox2.empty()

        manager.clear_all_method_requests()
        assert method_request_inbox1.empty()
        assert method_request_inbox2.empty()
    def test_clears_generic_method_request_inbox(self, manager):
        generic_method_request_inbox = manager.get_method_request_inbox()
        assert generic_method_request_inbox.empty()
        manager.route_method_request(MethodRequest("id", "unrecognized_method_name", "payload"))
        assert not generic_method_request_inbox.empty()

        manager.clear_all_method_requests()
        assert generic_method_request_inbox.empty()
    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)
    def test_instantiates_without_payload(self):
        request = MethodRequest(request_id=dummy_rid,
                                name=dummy_name,
                                payload=dummy_payload)
        status = 200
        response = MethodResponse.create_from_method_request(request, status)

        assert isinstance(response, MethodResponse)
        assert response.request_id == request.request_id
        assert response.status == status
        assert response.payload is None
Exemple #9
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_instantiates_from_method_request(self):
        request = MethodRequest(request_id=dummy_rid,
                                name=dummy_name,
                                payload=dummy_payload)
        status = 200
        payload = {"ResponsePayload": "SomeResponse"}
        response = MethodResponse.create_from_method_request(
            method_request=request, status=status, payload=payload)

        assert isinstance(response, MethodResponse)
        assert response.request_id == request.request_id
        assert response.status == status
        assert response.payload == payload
    def test_receive_method_request_called_without_method_name_returns_method_request_from_generic_method_inbox(
            self, mocker, client):
        request = MethodRequest(request_id="1",
                                name="some_method",
                                payload={"key": "value"})
        inbox_mock = mocker.MagicMock(autospec=SyncClientInbox)
        inbox_mock.get.return_value = request
        manager_get_inbox_mock = mocker.patch.object(
            target=client._inbox_manager,
            attribute="get_method_request_inbox",
            return_value=inbox_mock,
        )

        received_request = client.receive_method_request()
        assert manager_get_inbox_mock.call_count == 1
        assert manager_get_inbox_mock.call_args == mocker.call(None)
        assert inbox_mock.get.call_count == 1
        assert received_request is received_request
Exemple #12
0
    async def test_receive_method_request_called_with_method_name_returns_method_request_from_named_method_inbox(
            self, mocker, client):
        method_name = "some_method"
        request = MethodRequest(request_id="1",
                                name=method_name,
                                payload={"key": "value"})
        inbox_mock = mocker.MagicMock(autospec=AsyncClientInbox)
        inbox_mock.get.return_value = await create_completed_future(request)
        manager_get_inbox_mock = mocker.patch.object(
            target=client._inbox_manager,
            attribute="get_method_request_inbox",
            return_value=inbox_mock,
        )

        received_request = await client.receive_method_request(method_name)
        assert manager_get_inbox_mock.call_count == 1
        assert manager_get_inbox_mock.call_args == mocker.call(method_name)
        assert inbox_mock.get.call_count == 1
        assert received_request is received_request
Exemple #13
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)
def method_request():
    return MethodRequest(request_id="1",
                         name="some_method",
                         payload={"key": "value"})
 def method_request(self):
     return MethodRequest(request_id="1",
                          name="some_method",
                          payload="{'key': 'value'}")