Beispiel #1
0
    def _search_for_tac(self) -> None:
        """
        Search for active TAC Controller.

        We assume that the controller is registered as a service with the 'tac' data model
        and with an attribute version = expected_version_id.

        :return: None
        """
        game = cast(Game, self.context.game)
        query = game.get_game_query()
        oef_search_dialogues = cast(OefSearchDialogues,
                                    self.context.oef_search_dialogues)
        oef_search_msg = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            dialogue_reference=oef_search_dialogues.
            new_self_initiated_dialogue_reference(),
            query=query,
        )
        oef_search_msg.counterparty = self.context.search_service_address
        oef_search_dialogues.update(oef_search_msg)
        self.context.outbox.put_message(message=oef_search_msg)
        self.context.logger.info(
            "[{}]: Searching for TAC, search_id={}".format(
                self.context.agent_name, oef_search_msg.dialogue_reference))
Beispiel #2
0
        def test_search_services_with_query_with_model(self):
            """Test that a search services request can be sent correctly.

            In this test, the query has a simple data model.
            """
            data_model = DataModel("foobar", [Attribute("foo", str, True)])
            search_query = Query(
                [Constraint("foo", ConstraintType("==", "bar"))], model=data_model
            )
            oef_search_request = OefSearchMessage(
                performative=OefSearchMessage.Performative.SEARCH_SERVICES,
                dialogue_reference=self.oef_search_dialogues.new_self_initiated_dialogue_reference(),
                query=search_query,
            )
            oef_search_request.counterparty = DEFAULT_OEF
            sending_dialogue = self.oef_search_dialogues.update(oef_search_request)
            self.multiplexer.put(
                Envelope(
                    to=DEFAULT_OEF,
                    sender=FETCHAI_ADDRESS_ONE,
                    protocol_id=OefSearchMessage.protocol_id,
                    message=oef_search_request,
                )
            )

            envelope = self.multiplexer.get(block=True, timeout=5.0)
            oef_search_response = envelope.message
            oef_search_dialogue = self.oef_search_dialogues.update(oef_search_response)
            assert (
                oef_search_response.performative
                == OefSearchMessage.Performative.SEARCH_RESULT
            )
            assert oef_search_dialogue is not None
            assert oef_search_dialogue == sending_dialogue
            assert oef_search_response.agents == ()
Beispiel #3
0
    def test_filtered_search_result(self):
        """Test that the search result contains only the entries matching the query."""
        query = Query(constraints=[], model=self.data_model_barfoo)

        # build and send the request
        search_services_request = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            dialogue_reference=self.dialogues1.new_self_initiated_dialogue_reference(),
            query=query,
        )
        search_services_request.counterparty = str(OEFLocalConnection.connection_id)
        sending_dialogue = cast(
            Optional[OefSearchDialogue], self.dialogues1.update(search_services_request)
        )
        assert sending_dialogue is not None
        envelope = Envelope(
            to=search_services_request.counterparty,
            sender=search_services_request.sender,
            protocol_id=search_services_request.protocol_id,
            message=search_services_request,
        )
        self.multiplexer1.put(envelope)

        # check the result
        response_envelope = InBox(self.multiplexer1).get(block=True, timeout=5.0)
        search_result_orig = cast(OefSearchMessage, response_envelope.message)
        search_result = copy.copy(search_result_orig)
        search_result.is_incoming = True
        search_result.counterparty = search_result_orig.sender
        response_dialogue = self.dialogues1.update(search_result)
        assert response_dialogue == sending_dialogue
        assert search_result.performative == OefSearchMessage.Performative.SEARCH_RESULT
        assert search_result.agents == (self.address_2,), self.node.services
Beispiel #4
0
    def test_empty_search_result(self):
        """Test that at the beginning, the search request returns an empty search result."""
        query = Query(constraints=[], model=None)

        # build and send the request
        search_services_request = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            dialogue_reference=self.dialogues.new_self_initiated_dialogue_reference(),
            query=query,
        )
        search_services_request.counterparty = str(OEFLocalConnection.connection_id)
        sending_dialogue = cast(
            Optional[OefSearchDialogue], self.dialogues.update(search_services_request)
        )
        assert sending_dialogue is not None
        envelope = Envelope(
            to=search_services_request.counterparty,
            sender=search_services_request.sender,
            protocol_id=search_services_request.protocol_id,
            message=search_services_request,
        )
        self.multiplexer.put(envelope)

        # check the result
        response_envelope = self.multiplexer.get(block=True, timeout=2.0)
        assert response_envelope.protocol_id == OefSearchMessage.protocol_id
        search_result_orig = cast(OefSearchMessage, response_envelope.message)
        search_result = copy.copy(search_result_orig)
        search_result.is_incoming = True
        search_result.counterparty = search_result_orig.sender
        response_dialogue = self.dialogues.update(search_result)
        assert response_dialogue == sending_dialogue
        assert search_result.performative == OefSearchMessage.Performative.SEARCH_RESULT
        assert search_result.agents == ()
Beispiel #5
0
    async def _send_error_response(
        self,
        oef_search_message: OefSearchMessage,
        oef_search_dialogue: OefSearchDialogue,
        oef_error_operation: OefErrorOperation = OefSearchMessage.
        OefErrorOperation.OTHER,
    ) -> None:
        """
        Send an error response back.

        :param oef_search_message: the oef search message
        :param oef_search_dialogue: the oef search dialogue
        :param oef_error_operation: the error code to send back
        :return: None
        """
        assert self.in_queue is not None, "Inqueue not set!"
        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.OEF_ERROR,
            oef_error_operation=oef_error_operation,
            dialogue_reference=oef_search_dialogue.dialogue_label.
            dialogue_reference,
            target=oef_search_message.message_id,
            message_id=oef_search_message.message_id + 1,
        )
        message.counterparty = oef_search_message.counterparty
        assert oef_search_dialogue.update(message)
        envelope = Envelope(
            to=message.counterparty,
            sender=SOEFConnection.connection_id.latest,
            protocol_id=message.protocol_id,
            message=message,
        )
        await self.in_queue.put(envelope)
Beispiel #6
0
    def test_on_oef_error(self):
        """Test the oef error."""
        oef_connection = self.multiplexer1.connections[0]
        oef_channel = oef_connection.channel

        oef_channel.oef_msg_id += 1
        dialogue_reference = ("1", "2")
        query = Query(
            constraints=[Constraint("foo", ConstraintType("==", "bar"))], model=None,
        )
        dialogue = OefSearchDialogue(
            BaseDialogueLabel(dialogue_reference, "agent", "agent"),
            "agent",
            OefSearchDialogue.Role.OEF_NODE,
        )
        oef_search_msg = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            dialogue_reference=dialogue_reference,
            query=query,
        )
        oef_search_msg.is_incoming = True
        oef_search_msg.counterparty = "agent"
        dialogue._incoming_messages = [oef_search_msg]
        oef_channel.oef_msg_id_to_dialogue[oef_channel.oef_msg_id] = dialogue
        oef_channel.on_oef_error(
            answer_id=oef_channel.oef_msg_id,
            operation=OEFErrorOperation.SEARCH_SERVICES,
        )
        envelope = self.multiplexer1.get(block=True, timeout=5.0)
        dec_msg = envelope.message
        assert dec_msg.dialogue_reference == dialogue_reference
        assert (
            dec_msg.performative is OefSearchMessage.Performative.OEF_ERROR
        ), "It should be an error message"
Beispiel #7
0
def test_oef_error_serialization():
    """Test the serialization for 'oef_error' speech-act works."""
    msg = OefSearchMessage(
        performative=OefSearchMessage.Performative.OEF_ERROR,
        oef_error_operation=OefSearchMessage.OefErrorOperation.OTHER,
    )
    msg.to = "receiver"
    envelope = Envelope(
        to=msg.to,
        sender="sender",
        protocol_id=OefSearchMessage.protocol_id,
        message=msg,
    )
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope.to == actual_envelope.to
    assert expected_envelope.sender == actual_envelope.sender
    assert expected_envelope.protocol_id == actual_envelope.protocol_id
    assert expected_envelope.message != actual_envelope.message

    actual_msg = OefSearchMessage.serializer.decode(actual_envelope.message)
    actual_msg.to = actual_envelope.to
    actual_msg.sender = actual_envelope.sender
    expected_msg = msg
    assert expected_msg == actual_msg
Beispiel #8
0
    async def test_wrong_dialogue(self):
        """Test that at the beginning, the search request returns an empty search result."""
        query = Query(constraints=[Constraint("foo", ConstraintType("==", 1))],
                      model=None)

        # build and send the request
        search_services_request = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            message_id=2,
            target=1,
            dialogue_reference=self.dialogues.
            new_self_initiated_dialogue_reference(),
            query=query,
        )
        search_services_request.to = str(OEFLocalConnection.connection_id)

        # the incorrect message cannot be sent into a dialogue, so this is omitted.

        search_services_request.sender = self.address_1
        envelope = Envelope(
            to=search_services_request.to,
            sender=search_services_request.sender,
            message=search_services_request,
        )
        with unittest.mock.patch.object(
                self.node,
                "_handle_oef_message",
                side_effect=self.node._handle_oef_message) as mock_handle:
            with unittest.mock.patch.object(self.node.logger,
                                            "warning") as mock_logger:
                self.multiplexer.put(envelope)
                wait_for_condition(lambda: mock_handle.called, timeout=1.0)
                mock_logger.assert_any_call(
                    AnyStringWith("Could not create dialogue for message="))
Beispiel #9
0
def test_success_serialization():
    """Test the serialization for 'success' speech-act works."""
    msg = OefSearchMessage(
        performative=OefSearchMessage.Performative.SUCCESS,
        agents_info=OefSearchMessage.AgentsInfo(
            {
                "key_1": {"key_1": b"value_1", "key_2": b"value_2"},
                "key_2": {"key_3": b"value_3", "key_4": b"value_4"},
            }
        ),
    )
    msg.to = "receiver"
    envelope = Envelope(to=msg.to, sender="sender", message=msg,)
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope.to == actual_envelope.to
    assert expected_envelope.sender == actual_envelope.sender
    assert (
        expected_envelope.protocol_specification_id
        == actual_envelope.protocol_specification_id
    )
    assert expected_envelope.message != actual_envelope.message

    actual_msg = OefSearchMessage.serializer.decode(actual_envelope.message)
    actual_msg.to = actual_envelope.to
    actual_msg.sender = actual_envelope.sender
    expected_msg = msg
    assert expected_msg == actual_msg
Beispiel #10
0
    def _search_services(self) -> None:
        """
        Search on OEF Service Directory.

        In particular, search
            - for sellers and their supply, or
            - for buyers and their demand, or
            - for both.

        :return: None
        """
        strategy = cast(Strategy, self.context.strategy)
        oef_search_dialogues = cast(OefSearchDialogues,
                                    self.context.oef_search_dialogues)
        query = strategy.get_location_and_service_query()
        for (is_seller_search, searching_for) in strategy.searching_for_types:
            oef_msg = OefSearchMessage(
                performative=OefSearchMessage.Performative.SEARCH_SERVICES,
                dialogue_reference=oef_search_dialogues.
                new_self_initiated_dialogue_reference(),
                query=query,
            )
            oef_msg.counterparty = self.context.search_service_address
            oef_search_dialogue = cast(Optional[OefSearchDialogue],
                                       oef_search_dialogues.update(oef_msg))
            assert oef_search_dialogue is not None, "OefSearchDialogue not created."
            oef_search_dialogue.is_seller_search = is_seller_search
            self.context.outbox.put_message(message=oef_msg)
            self.context.logger.info("searching for {}, search_id={}.".format(
                searching_for, oef_msg.dialogue_reference))
Beispiel #11
0
    async def test_bad_search_query(self, caplog):
        """Test fail on invalid query for search."""
        await self.test_register_service()
        closeness_query = Query([], model=models.AGENT_LOCATION_MODEL)
        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            dialogue_reference=self.oef_search_dialogues.new_self_initiated_dialogue_reference(),
            query=closeness_query,
        )
        message.counterparty = SOEFConnection.connection_id.latest
        sending_dialogue = self.oef_search_dialogues.update(message)
        assert sending_dialogue is not None
        envelope = Envelope(
            to=message.counterparty,
            sender=self.crypto.address,
            protocol_id=message.protocol_id,
            message=message,
        )

        with patch.object(
            self.connection.channel,
            "_request_text",
            make_async(self.search_empty_response),
        ):
            await self.connection.send(envelope)

        expected_envelope = await asyncio.wait_for(self.connection.receive(), timeout=1)
        assert expected_envelope
        message = expected_envelope.message
        assert message.performative == OefSearchMessage.Performative.OEF_ERROR
        message = copy.deepcopy(expected_envelope.message)
        message.is_incoming = True  # TODO: fix
        message.counterparty = SOEFConnection.connection_id.latest  # TODO; fix
        receiving_dialogue = self.oef_search_dialogues.update(message)
        assert sending_dialogue == receiving_dialogue
Beispiel #12
0
    async def _unregister_service(
        self, oef_search_msg: OefSearchMessage, dialogue: OefSearchDialogue,
    ) -> None:
        """
        Unregister a service agent.

        :param oef_search_msg: the incoming message.
        :param dialogue: the dialogue.
        :return: None
        """
        service_description = oef_search_msg.service_description
        address = oef_search_msg.sender
        async with self._lock:
            if address not in self.services:
                msg = OefSearchMessage(
                    performative=OefSearchMessage.Performative.OEF_ERROR,
                    target=oef_search_msg.message_id,
                    message_id=oef_search_msg.message_id + 1,
                    oef_error_operation=OefSearchMessage.OefErrorOperation.UNREGISTER_SERVICE,
                    dialogue_reference=dialogue.dialogue_label.dialogue_reference,
                )
                msg.counterparty = oef_search_msg.sender
                assert dialogue.update(msg)
                envelope = Envelope(
                    to=msg.counterparty,
                    sender=msg.sender,
                    protocol_id=msg.protocol_id,
                    message=msg,
                )
                await self._send(envelope)
            else:
                self.services[address].remove(service_description)
                if len(self.services[address]) == 0:
                    self.services.pop(address)
Beispiel #13
0
    def _register_service(self) -> None:
        """
        Register to the OEF Service Directory.

        In particular, register
            - as a seller, listing the goods supplied, or
            - as a buyer, listing the goods demanded, or
            - as both.

        :return: None
        """
        strategy = cast(Strategy, self.context.strategy)
        oef_search_dialogues = cast(OefSearchDialogues,
                                    self.context.oef_search_dialogues)
        self.context.logger.debug("updating service directory as {}.".format(
            strategy.registering_as))
        description = strategy.get_register_service_description()
        oef_msg = OefSearchMessage(
            performative=OefSearchMessage.Performative.REGISTER_SERVICE,
            dialogue_reference=oef_search_dialogues.
            new_self_initiated_dialogue_reference(),
            service_description=description,
        )
        oef_msg.counterparty = self.context.search_service_address
        oef_dialogue = oef_search_dialogues.update(oef_msg)
        assert oef_dialogue is not None, "OefSearchDialogue not created."
        self.context.outbox.put_message(message=oef_msg)
Beispiel #14
0
    async def test_register_service(self):
        """Test register service."""
        agent_location = Location(52.2057092, 2.1183431)
        service_instance = {"location": agent_location}
        service_description = Description(
            service_instance, data_model=models.AGENT_LOCATION_MODEL
        )
        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.REGISTER_SERVICE,
            dialogue_reference=self.oef_search_dialogues.new_self_initiated_dialogue_reference(),
            service_description=service_description,
        )
        message.counterparty = SOEFConnection.connection_id.latest
        sending_dialogue = self.oef_search_dialogues.update(message)
        assert sending_dialogue is not None
        envelope = Envelope(
            to=message.counterparty,
            sender=self.crypto.address,
            protocol_id=message.protocol_id,
            message=message,
        )

        with patch.object(
            self.connection.channel,
            "_request_text",
            make_async(self.generic_success_response),
        ):
            await self.connection.send(envelope)

        with pytest.raises(asyncio.TimeoutError):  # got no message back
            await asyncio.wait_for(self.connection.receive(), timeout=1)

        assert self.connection.channel.agent_location == agent_location
Beispiel #15
0
    async def test_unregister_service(self):
        """Test unregister service."""
        agent_location = Location(52.2057092, 2.1183431)
        service_instance = {"location": agent_location}
        service_description = Description(
            service_instance, data_model=models.AGENT_LOCATION_MODEL
        )
        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.UNREGISTER_SERVICE,
            dialogue_reference=self.oef_search_dialogues.new_self_initiated_dialogue_reference(),
            service_description=service_description,
        )
        message.counterparty = SOEFConnection.connection_id.latest
        sending_dialogue = self.oef_search_dialogues.update(message)
        assert sending_dialogue is not None
        envelope = Envelope(
            to=message.counterparty,
            sender=self.crypto.address,
            protocol_id=message.protocol_id,
            message=message,
        )
        with patch.object(
            self.connection.channel,
            "_request_text",
            make_async("<response><message>Goodbye!</message></response>"),
        ):
            await self.connection.send(envelope)

        assert self.connection.channel.unique_page_address is None
Beispiel #16
0
def test_unregister_service_serialization():
    """Test the serialization for 'unregister_service' speech-act works."""
    msg = OefSearchMessage(
        message_id=2,
        target=1,
        performative=OefSearchMessage.Performative.UNREGISTER_SERVICE,
        service_description=Description({
            "foo1": 1,
            "bar1": 2
        }),
    )
    msg.to = "receiver"
    envelope = Envelope(
        to=msg.to,
        sender="sender",
        protocol_id=OefSearchMessage.protocol_id,
        message=msg,
    )
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope.to == actual_envelope.to
    assert expected_envelope.sender == actual_envelope.sender
    assert expected_envelope.protocol_id == actual_envelope.protocol_id
    assert expected_envelope.message != actual_envelope.message

    actual_msg = OefSearchMessage.serializer.decode(actual_envelope.message)
    actual_msg.to = actual_envelope.to
    actual_msg.sender = actual_envelope.sender
    expected_msg = msg
    assert expected_msg == actual_msg
Beispiel #17
0
    def test_on_oef_error(self):
        """Test the oef error."""
        oef_connection = self.multiplexer1.connections[0]
        oef_channel = oef_connection.channel

        oef_channel.oef_msg_id += 1
        dialogue_reference = ("1", "")
        query = Query(
            constraints=[Constraint("foo", ConstraintType("==", "bar"))],
            model=None,
        )
        dialogues = oef_channel.oef_search_dialogues
        oef_search_msg = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            dialogue_reference=dialogue_reference,
            query=query,
        )
        oef_search_msg.to = str(oef_connection.connection_id)
        oef_search_msg.sender = "agent"
        dialogue = dialogues.update(oef_search_msg)
        assert dialogue is not None
        oef_channel.oef_msg_id_to_dialogue[oef_channel.oef_msg_id] = dialogue
        oef_channel.on_oef_error(
            answer_id=oef_channel.oef_msg_id,
            operation=OEFErrorOperation.SEARCH_SERVICES,
        )
        envelope = self.multiplexer1.get(block=True, timeout=5.0)
        dec_msg = envelope.message
        assert dec_msg.dialogue_reference[0] == dialogue_reference[0]
        assert (dec_msg.performative is OefSearchMessage.Performative.OEF_ERROR
                ), "It should be an error message"
Beispiel #18
0
def test_search_services_serialization():
    """Test the serialization for 'search_services' speech-act works."""
    msg = OefSearchMessage(
        performative=OefSearchMessage.Performative.SEARCH_SERVICES,
        query=Query([Constraint("something", ConstraintType(">", 1))]),
    )
    msg.to = "receiver"
    envelope = Envelope(
        to=msg.to,
        sender="sender",
        protocol_id=OefSearchMessage.protocol_id,
        message=msg,
    )
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope.to == actual_envelope.to
    assert expected_envelope.sender == actual_envelope.sender
    assert expected_envelope.protocol_id == actual_envelope.protocol_id
    assert expected_envelope.message != actual_envelope.message

    actual_msg = OefSearchMessage.serializer.decode(actual_envelope.message)
    actual_msg.to = actual_envelope.to
    actual_msg.sender = actual_envelope.sender
    expected_msg = msg
    assert expected_msg == actual_msg
Beispiel #19
0
    def on_oef_error(
        self, answer_id: int, operation: oef.messages.OEFErrorOperation
    ) -> None:
        """
        On oef error event handler.

        :param answer_id: the answer id.
        :param operation: the error operation.
        :return: None
        """
        assert self.in_queue is not None
        assert self.loop is not None
        try:
            operation = OefSearchMessage.OefErrorOperation(operation)
        except ValueError:
            operation = OefSearchMessage.OefErrorOperation.OTHER
        dialogue_reference = self.oef_msg_it_to_dialogue_reference[answer_id]
        msg = OefSearchMessage(
            performative=OefSearchMessage.Performative.OEF_ERROR,
            dialogue_reference=dialogue_reference,
            target=RESPONSE_TARGET,
            message_id=RESPONSE_MESSAGE_ID,
            oef_error_operation=operation,
        )
        msg_bytes = OefSearchSerializer().encode(msg)
        envelope = Envelope(
            to=self.address,
            sender=DEFAULT_OEF,
            protocol_id=OefSearchMessage.protocol_id,
            message=msg_bytes,
        )
        asyncio.run_coroutine_threadsafe(
            self.in_queue.put(envelope), self.loop
        ).result()
Beispiel #20
0
    async def test_ping_command(self):
        """Test set service key."""
        service_description = Description({}, data_model=models.PING_MODEL)
        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.REGISTER_SERVICE,
            dialogue_reference=self.oef_search_dialogues.new_self_initiated_dialogue_reference(),
            service_description=service_description,
        )
        message.counterparty = SOEFConnection.connection_id.latest
        sending_dialogue = self.oef_search_dialogues.update(message)
        assert sending_dialogue is not None
        envelope = Envelope(
            to=message.counterparty,
            sender=self.crypto.address,
            protocol_id=message.protocol_id,
            message=message,
        )

        with patch.object(
            self.connection.channel,
            "_request_text",
            make_async(self.generic_success_response),
        ):
            await self.connection.send(envelope)

        with pytest.raises(asyncio.TimeoutError):  # got no message back
            await asyncio.wait_for(self.connection.receive(), timeout=1)
    def decode(obj: bytes) -> Message:
        """
        Decode bytes into a 'OefSearch' message.

        :param obj: the bytes object.
        :return: the 'OefSearch' message.
        """
        message_pb = ProtobufMessage()
        oef_search_pb = oef_search_pb2.OefSearchMessage()
        message_pb.ParseFromString(obj)
        message_id = message_pb.dialogue_message.message_id
        dialogue_reference = (
            message_pb.dialogue_message.dialogue_starter_reference,
            message_pb.dialogue_message.dialogue_responder_reference,
        )
        target = message_pb.dialogue_message.target

        oef_search_pb.ParseFromString(message_pb.dialogue_message.content)
        performative = oef_search_pb.WhichOneof("performative")
        performative_id = OefSearchMessage.Performative(str(performative))
        performative_content = dict()  # type: Dict[str, Any]
        if performative_id == OefSearchMessage.Performative.REGISTER_SERVICE:
            pb2_service_description = oef_search_pb.register_service.service_description
            service_description = Description.decode(pb2_service_description)
            performative_content["service_description"] = service_description
        elif performative_id == OefSearchMessage.Performative.UNREGISTER_SERVICE:
            pb2_service_description = (
                oef_search_pb.unregister_service.service_description)
            service_description = Description.decode(pb2_service_description)
            performative_content["service_description"] = service_description
        elif performative_id == OefSearchMessage.Performative.SEARCH_SERVICES:
            pb2_query = oef_search_pb.search_services.query
            query = Query.decode(pb2_query)
            performative_content["query"] = query
        elif performative_id == OefSearchMessage.Performative.SEARCH_RESULT:
            agents = oef_search_pb.search_result.agents
            agents_tuple = tuple(agents)
            performative_content["agents"] = agents_tuple
            pb2_agents_info = oef_search_pb.search_result.agents_info
            agents_info = AgentsInfo.decode(pb2_agents_info)
            performative_content["agents_info"] = agents_info
        elif performative_id == OefSearchMessage.Performative.SUCCESS:
            pb2_agents_info = oef_search_pb.success.agents_info
            agents_info = AgentsInfo.decode(pb2_agents_info)
            performative_content["agents_info"] = agents_info
        elif performative_id == OefSearchMessage.Performative.OEF_ERROR:
            pb2_oef_error_operation = oef_search_pb.oef_error.oef_error_operation
            oef_error_operation = OefErrorOperation.decode(
                pb2_oef_error_operation)
            performative_content["oef_error_operation"] = oef_error_operation
        else:
            raise ValueError(
                "Performative not valid: {}.".format(performative_id))

        return OefSearchMessage(message_id=message_id,
                                dialogue_reference=dialogue_reference,
                                target=target,
                                performative=performative,
                                **performative_content)
Beispiel #22
0
    def _register_service(self) -> None:
        """
        Register to the OEF Service Directory.

        In particular, register
            - as a seller, listing the goods supplied, or
            - as a buyer, listing the goods demanded, or
            - as both.

        :return: None
        """
        registration = cast(Registration, self.context.registration)
        strategy = cast(Strategy, self.context.strategy)

        if strategy.is_registering_as_seller:
            self.context.logger.debug(
                "[{}]: Updating service directory as seller with goods supplied."
                .format(self.context.agent_name))
            goods_supplied_description = strategy.get_own_service_description(
                is_supply=True,
                is_search_description=False,
            )
            registration.registered_goods_supplied_description = (
                goods_supplied_description)
            oef_msg = OefSearchMessage(
                performative=OefSearchMessage.Performative.REGISTER_SERVICE,
                dialogue_reference=(str(registration.get_next_id()), ""),
                service_description=goods_supplied_description,
            )
            self.context.outbox.put_message(
                to=self.context.search_service_address,
                sender=self.context.agent_address,
                protocol_id=OefSearchMessage.protocol_id,
                message=OefSearchSerializer().encode(oef_msg),
            )

        if strategy.is_registering_as_buyer:
            self.context.logger.debug(
                "[{}]: Updating service directory as buyer with goods demanded."
                .format(self.context.agent_name))
            goods_demanded_description = strategy.get_own_service_description(
                is_supply=False,
                is_search_description=False,
            )
            registration.registered_goods_demanded_description = (
                goods_demanded_description)
            oef_msg = OefSearchMessage(
                performative=OefSearchMessage.Performative.REGISTER_SERVICE,
                dialogue_reference=(str(registration.get_next_id()), ""),
                service_description=goods_demanded_description,
            )
            self.context.outbox.put_message(
                to=self.context.search_service_address,
                sender=self.context.agent_address,
                protocol_id=OefSearchMessage.protocol_id,
                message=OefSearchSerializer().encode(oef_msg),
            )
Beispiel #23
0
    async def test_send_oef_message(self, pytestconfig, caplog):
        """Test the send oef message."""
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            oef_connection = _make_oef_connection(
                address=FETCHAI_ADDRESS_ONE,
                oef_addr="127.0.0.1",
                oef_port=10000,
            )
            await oef_connection.connect()
            oef_search_dialogues = OefSearchDialogues(FETCHAI_ADDRESS_ONE)
            msg = OefSearchMessage(
                performative=OefSearchMessage.Performative.OEF_ERROR,
                dialogue_reference=oef_search_dialogues.
                new_self_initiated_dialogue_reference(),
                oef_error_operation=OefSearchMessage.OefErrorOperation.
                SEARCH_SERVICES,
            )
            msg.to = str(oef_connection.connection_id)
            msg.sender = FETCHAI_ADDRESS_ONE
            envelope = Envelope(
                to=msg.to,
                sender=msg.sender,
                message=msg,
            )
            with caplog.at_level(logging.DEBUG,
                                 "aea.packages.fetchai.connections.oef"):
                await oef_connection.send(envelope)
                assert "Could not create dialogue for message=" in caplog.text

            data_model = DataModel("foobar",
                                   attributes=[Attribute("foo", str, True)])
            query = Query(
                constraints=[Constraint("foo", ConstraintType("==", "bar"))],
                model=data_model,
            )

            msg, sending_dialogue = oef_search_dialogues.create(
                counterparty=str(oef_connection.connection_id),
                performative=OefSearchMessage.Performative.SEARCH_SERVICES,
                query=query,
            )
            envelope = Envelope(
                to=msg.to,
                sender=msg.sender,
                message=msg,
            )
            await oef_connection.send(envelope)
            envelope = await oef_connection.receive()
            search_result = envelope.message
            response_dialogue = oef_search_dialogues.update(search_result)
            assert (search_result.performative ==
                    OefSearchMessage.Performative.SEARCH_RESULT)
            assert sending_dialogue == response_dialogue
            await asyncio.sleep(2.0)
            await oef_connection.disconnect()
Beispiel #24
0
        def test_unregister_service(self):
            """Test that an unregister service request works correctly.

            Steps:
            2. unregister the service
            3. search for that service
            4. assert that no result is found.
            """
            self.request_id += 1
            msg = OefSearchMessage(
                performative=OefSearchMessage.Performative.UNREGISTER_SERVICE,
                dialogue_reference=(str(self.request_id), ""),
                service_description=self.desc,
            )
            msg_bytes = OefSearchSerializer().encode(msg)
            self.multiplexer.put(
                Envelope(
                    to=DEFAULT_OEF,
                    sender=self.crypto1.address,
                    protocol_id=OefSearchMessage.protocol_id,
                    message=msg_bytes,
                )
            )

            time.sleep(1.0)

            self.request_id += 1
            search_request = OefSearchMessage(
                performative=OefSearchMessage.Performative.SEARCH_SERVICES,
                dialogue_reference=(str(self.request_id), ""),
                query=Query(
                    [Constraint("bar", ConstraintType("==", 1))],
                    model=self.foo_datamodel,
                ),
            )
            self.multiplexer.put(
                Envelope(
                    to=DEFAULT_OEF,
                    sender=self.crypto1.address,
                    protocol_id=OefSearchMessage.protocol_id,
                    message=OefSearchSerializer().encode(search_request),
                )
            )

            envelope = self.multiplexer.get(block=True, timeout=5.0)
            search_result = OefSearchSerializer().decode(envelope.message)
            assert (
                search_result.performative
                == OefSearchMessage.Performative.SEARCH_RESULT
            )
            assert search_result.dialogue_reference[0] == str(self.request_id)
            assert search_result.agents == ()
Beispiel #25
0
    async def test_send_oef_message(self, pytestconfig):
        """Test the send oef message."""
        oef_connection = _make_oef_connection(
            address=FETCHAI_ADDRESS_ONE,
            oef_addr="127.0.0.1",
            oef_port=10000,
        )
        request_id = 1
        oef_connection.loop = asyncio.get_event_loop()
        await oef_connection.connect()
        msg = OefSearchMessage(
            performative=OefSearchMessage.Performative.OEF_ERROR,
            dialogue_reference=(str(request_id), ""),
            oef_error_operation=OefSearchMessage.OefErrorOperation.
            SEARCH_SERVICES,
        )
        msg_bytes = OefSearchSerializer().encode(msg)
        envelope = Envelope(
            to=DEFAULT_OEF,
            sender=FETCHAI_ADDRESS_ONE,
            protocol_id=OefSearchMessage.protocol_id,
            message=msg_bytes,
        )
        with pytest.raises(ValueError):
            await oef_connection.send(envelope)

        data_model = DataModel("foobar",
                               attributes=[Attribute("foo", str, True)])
        query = Query(
            constraints=[Constraint("foo", ConstraintType("==", "bar"))],
            model=data_model,
        )

        request_id += 1
        msg = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            dialogue_reference=(str(request_id), ""),
            query=query,
        )
        msg_bytes = OefSearchSerializer().encode(msg)
        envelope = Envelope(
            to=DEFAULT_OEF,
            sender=FETCHAI_ADDRESS_ONE,
            protocol_id=OefSearchMessage.protocol_id,
            message=msg_bytes,
        )
        await oef_connection.send(envelope)
        search_result = await oef_connection.receive()
        assert isinstance(search_result, Envelope)
        await asyncio.sleep(2.0)
        await oef_connection.disconnect()
Beispiel #26
0
    async def test_search(self):
        """Test search."""
        agent_location = Location(52.2057092, 2.1183431)
        radius = 0.1
        close_to_my_service = Constraint(
            "location", ConstraintType("distance", (agent_location, radius))
        )
        personality_filters = [
            Constraint("genus", ConstraintType("==", "vehicle")),
            Constraint(
                "classification", ConstraintType("==", "mobility.railway.train")
            ),
        ]
        service_key_filters = [
            Constraint("custom_key", ConstraintType("==", "custom_value")),
        ]
        closeness_query = Query(
            [close_to_my_service] + personality_filters + service_key_filters
        )
        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            dialogue_reference=self.oef_search_dialogues.new_self_initiated_dialogue_reference(),
            query=closeness_query,
        )
        message.counterparty = SOEFConnection.connection_id.latest
        sending_dialogue = self.oef_search_dialogues.update(message)
        assert sending_dialogue is not None
        envelope = Envelope(
            to=message.counterparty,
            sender=self.crypto.address,
            protocol_id=message.protocol_id,
            message=message,
        )

        with patch.object(
            self.connection.channel,
            "_request_text",
            make_async(self.search_success_response),
        ):
            await self.connection.send(envelope)

        expected_envelope = await asyncio.wait_for(self.connection.receive(), timeout=1)
        assert expected_envelope
        message = expected_envelope.message
        assert len(message.agents) >= 1
        message = copy.deepcopy(expected_envelope.message)
        message.is_incoming = True  # TODO: fix
        message.counterparty = SOEFConnection.connection_id.latest  # TODO; fix
        receiving_dialogue = self.oef_search_dialogues.update(message)
        assert sending_dialogue == receiving_dialogue
Beispiel #27
0
        def test_register_service(self):
            """Test that a register service request works correctly."""
            foo_datamodel = DataModel(
                "foo", [Attribute("bar", int, True, "A bar attribute.")]
            )
            desc = Description({"bar": 1}, data_model=foo_datamodel)
            request_id = 1
            msg = OefSearchMessage(
                performative=OefSearchMessage.Performative.REGISTER_SERVICE,
                dialogue_reference=(str(request_id), ""),
                service_description=desc,
            )
            msg_bytes = OefSearchSerializer().encode(msg)
            self.multiplexer.put(
                Envelope(
                    to=DEFAULT_OEF,
                    sender=self.crypto1.address,
                    protocol_id=OefSearchMessage.protocol_id,
                    message=msg_bytes,
                )
            )
            time.sleep(0.5)

            request_id += 1
            search_request = OefSearchMessage(
                performative=OefSearchMessage.Performative.SEARCH_SERVICES,
                dialogue_reference=(str(request_id), ""),
                query=Query(
                    [Constraint("bar", ConstraintType("==", 1))], model=foo_datamodel
                ),
            )
            self.multiplexer.put(
                Envelope(
                    to=DEFAULT_OEF,
                    sender=self.crypto1.address,
                    protocol_id=OefSearchMessage.protocol_id,
                    message=OefSearchSerializer().encode(search_request),
                )
            )
            envelope = self.multiplexer.get(block=True, timeout=5.0)
            search_result = OefSearchSerializer().decode(envelope.message)
            assert (
                search_result.performative
                == OefSearchMessage.Performative.SEARCH_RESULT
            )
            assert search_result.dialogue_reference[0] == str(request_id)
            if search_result.agents != [self.crypto1.address]:
                logger.warning(
                    "search_result.agents != [self.crypto1.address] FAILED in test_oef/test_communication.py"
                )
Beispiel #28
0
def test_agent_info():
    """Test the agent_info custom type."""
    agents_info = OefSearchMessage.AgentsInfo(
        {
            "agent_address_1": {"key_1": b"value_1", "key_2": b"value_2"},
            "agent_address_2": {"key_3": b"value_3", "key_4": b"value_4"},
        }
    )
    assert agents_info.get_info_for_agent("agent_address_1") == {
        "key_1": b"value_1",
        "key_2": b"value_2",
    }

    with pytest.raises(ValueError, match="body must not be None"):
        OefSearchMessage.AgentsInfo(None)
Beispiel #29
0
    def _register_tac(self, parameters) -> None:
        """
        Register on the OEF as a TAC controller agent.

        :return: None.
        """
        self._oef_msg_id += 1
        desc = Description(
            {"version": parameters.version_id}, data_model=CONTROLLER_DATAMODEL,
        )
        self.context.logger.info(
            "[{}]: Registering TAC data model".format(self.context.agent_name)
        )
        oef_msg = OefSearchMessage(
            performative=OefSearchMessage.Performative.REGISTER_SERVICE,
            dialogue_reference=(str(self._oef_msg_id), ""),
            service_description=desc,
        )
        self.context.outbox.put_message(
            to=self.context.search_service_address,
            sender=self.context.agent_address,
            protocol_id=OefSearchMessage.protocol_id,
            message=OefSearchSerializer().encode(oef_msg),
        )
        self._registered_desc = desc
        self.context.logger.info(
            "[{}]: TAC open for registration until: {}".format(
                self.context.agent_name, parameters.registration_end_time
            )
        )
Beispiel #30
0
    def on_search_result(self, search_id: int, agents: List[Address]) -> None:
        """
        On accept event handler.

        :param search_id: the search id.
        :param agents: the list of agents.
        :return: None
        """
        assert self.in_queue is not None
        assert self.loop is not None
        dialogue_reference = self.oef_msg_it_to_dialogue_reference[search_id]
        msg = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_RESULT,
            dialogue_reference=dialogue_reference,
            target=RESPONSE_TARGET,
            message_id=RESPONSE_MESSAGE_ID,
            agents=tuple(agents),
        )
        msg_bytes = OefSearchSerializer().encode(msg)
        envelope = Envelope(
            to=self.address,
            sender=DEFAULT_OEF,
            protocol_id=OefSearchMessage.protocol_id,
            message=msg_bytes,
        )
        asyncio.run_coroutine_threadsafe(
            self.in_queue.put(envelope), self.loop
        ).result()