Esempio n. 1
0
    def test_empty_search_result(self):
        """Test that at the beginning, the search request returns an empty search result."""
        request_id = 1
        query = Query(constraints=[], model=None)

        # build and send the request
        search_services_request = OEFMessage(
            oef_type=OEFMessage.Type.SEARCH_SERVICES,
            id=request_id,
            query=query)
        msg_bytes = OEFSerializer().encode(search_services_request)
        envelope = Envelope(to=DEFAULT_OEF,
                            sender=self.public_key_1,
                            protocol_id=OEFMessage.protocol_id,
                            message=msg_bytes)
        self.mailbox1.send(envelope)

        # check the result
        response_envelope = self.mailbox1.inbox.get(block=True, timeout=2.0)
        assert response_envelope.protocol_id == OEFMessage.protocol_id
        assert response_envelope.to == self.public_key_1
        assert response_envelope.sender == DEFAULT_OEF
        search_result = OEFSerializer().decode(response_envelope.message)
        assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
        assert search_result.get("agents") == []
Esempio n. 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.
            """
            request_id = 2
            data_model = DataModel("foobar", [Attribute("foo", str, True)])
            search_query = Query(
                [Constraint("foo", ConstraintType("==", "bar"))],
                model=data_model)
            search_request = OEFMessage(
                oef_type=OEFMessage.Type.SEARCH_SERVICES,
                id=request_id,
                query=search_query)
            self.mailbox1.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.crypto1.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=OEFSerializer().encode(search_request))

            envelope = self.mailbox1.inbox.get(block=True, timeout=5.0)
            search_result = OEFSerializer().decode(envelope.message)
            assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
            assert search_result.get("id") == request_id
            assert search_result.get("agents") == []
Esempio n. 3
0
    def unregister_service(self) -> None:
        """
        Unregister service from OEF Service Directory.

        :return: None
        """
        if self.game_instance.goods_demanded_description is not None:
            msg = OEFMessage(
                oef_type=OEFMessage.Type.UNREGISTER_SERVICE,
                id=DEFAULT_MSG_ID,
                service_description=self.game_instance.goods_demanded_description,
                service_id="",
            )
            msg_bytes = OEFSerializer().encode(msg)
            self.mailbox.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.crypto.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=msg_bytes,
            )
        if self.game_instance.goods_supplied_description is not None:
            msg = OEFMessage(
                oef_type=OEFMessage.Type.UNREGISTER_SERVICE,
                id=DEFAULT_MSG_ID,
                service_description=self.game_instance.goods_supplied_description,
                service_id="",
            )
            msg_bytes = OEFSerializer().encode(msg)
            self.mailbox.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.crypto.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=msg_bytes,
            )
Esempio n. 4
0
    def _unregister_service(self) -> None:
        """
        Unregister service from OEF Service Directory.

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

        if registration.registered_goods_demanded_description is not None:
            oef_msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE,
                                 id=registration.get_next_id(),
                                 service_description=registration.
                                 registered_goods_demanded_description,
                                 service_id="")
            self.context.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.context.agent_public_key,
                protocol_id=OEFMessage.protocol_id,
                message=OEFSerializer().encode(oef_msg))
            registration.registered_goods_demanded_description = None

        if registration.registered_goods_supplied_description is not None:
            oef_msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE,
                                 id=registration.get_next_id(),
                                 service_description=registration.
                                 registered_goods_supplied_description,
                                 service_id="")
            self.context.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.context.agent_public_key,
                protocol_id=OEFMessage.protocol_id,
                message=OEFSerializer().encode(oef_msg))
            registration.registered_goods_supplied_description = None
Esempio n. 5
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
        """
        if self.game_instance.strategy.is_registering_as_seller:
            logger.debug("[{}]: Updating service directory as seller with goods supplied.".format(self.agent_name))
            goods_supplied_description = self.game_instance.get_service_description(is_supply=True)
            self.game_instance.goods_supplied_description = goods_supplied_description
            msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=DEFAULT_MSG_ID, service_description=goods_supplied_description, service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            self.mailbox.outbox.put_message(to=DEFAULT_OEF, sender=self.crypto.public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        if self.game_instance.strategy.is_registering_as_buyer:
            logger.debug("[{}]: Updating service directory as buyer with goods demanded.".format(self.agent_name))
            goods_demanded_description = self.game_instance.get_service_description(is_supply=False)
            self.game_instance.goods_demanded_description = goods_demanded_description
            msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=DEFAULT_MSG_ID, service_description=goods_demanded_description, service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            self.mailbox.outbox.put_message(to=DEFAULT_OEF, sender=self.crypto.public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
Esempio n. 6
0
    def _unregister_service(self) -> None:
        """
        Unregister service from OEF Service Directory.

        :return: None
        """
        if self._registered_goods_demanded_description is not None:
            msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE,
                             id=DEFAULT_MSG_ID,
                             service_description=self.
                             _registered_goods_demanded_description,
                             service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            self.context.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.context.agent_public_key,
                protocol_id=OEFMessage.protocol_id,
                message=msg_bytes)
            self._registered_goods_demanded_description = None
        if self._registered_goods_supplied_description is not None:
            msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE,
                             id=DEFAULT_MSG_ID,
                             service_description=self.
                             _registered_goods_supplied_description,
                             service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            self.context.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.context.agent_public_key,
                protocol_id=OEFMessage.protocol_id,
                message=msg_bytes)
            self._registered_goods_supplied_description = None
Esempio n. 7
0
async def test_send_oef_message(network_node):
    """Test the send oef message."""
    private_key_pem_path = os.path.join(CUR_PATH, "data", "priv.pem")
    wallet = Wallet({'default': private_key_pem_path})
    public_key = wallet.public_keys['default']
    oef_connection = OEFConnection(public_key=public_key,
                                   oef_addr="127.0.0.1",
                                   oef_port=10000)
    oef_connection.loop = asyncio.get_event_loop()
    await oef_connection.connect()

    msg = OEFMessage(oef_type=OEFMessage.Type.OEF_ERROR,
                     id=0,
                     operation=OEFMessage.OEFErrorOperation.SEARCH_AGENTS)
    msg_bytes = OEFSerializer().encode(msg)
    envelope = Envelope(to=DEFAULT_OEF,
                        sender=public_key,
                        protocol_id=OEFMessage.protocol_id,
                        message=msg_bytes)
    with pytest.raises(ValueError):
        await oef_connection.send(envelope)

    data_model = DataModel("foobar", attributes=[])
    query = Query(constraints=[], model=data_model)

    msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_AGENTS, id=0, query=query)
    msg_bytes = OEFSerializer().encode(msg)
    envelope = Envelope(to="recipient",
                        sender=public_key,
                        protocol_id=OEFMessage.protocol_id,
                        message=msg_bytes)
    await oef_connection.send(envelope)
    await oef_connection.disconnect()
Esempio n. 8
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)
            msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE,
                             id=1,
                             service_description=desc,
                             service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            self.mailbox1.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.crypto1.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=msg_bytes)

            search_request = OEFMessage(
                oef_type=OEFMessage.Type.SEARCH_SERVICES,
                id=2,
                query=Query([Constraint("bar", ConstraintType("==", 1))],
                            model=foo_datamodel))
            self.mailbox1.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.crypto1.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=OEFSerializer().encode(search_request))
            envelope = self.mailbox1.inbox.get(block=True, timeout=5.0)
            search_result = OEFSerializer().decode(envelope.message)
            assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
            assert search_result.get("id") == 2
            assert search_result.get("agents") == [self.crypto1.public_key]
Esempio n. 9
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)
        search = cast(Search, self.context.search)

        if strategy.is_searching_for_sellers:
            query = strategy.get_own_services_query(
                is_searching_for_sellers=True)
            if query is None:
                logger.warning(
                    "[{}]: Not searching the OEF for sellers because the agent demands no goods."
                    .format(self.context.agent_name))
                return None
            else:
                search_id = search.get_next_id(is_searching_for_sellers=True)
                logger.info(
                    "[{}]: Searching for sellers which match the demand of the agent, search_id={}."
                    .format(self.context.agent_name, search_id))
                oef_msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_SERVICES,
                                     id=search_id,
                                     query=query)
                self.context.outbox.put_message(
                    to=DEFAULT_OEF,
                    sender=self.context.agent_public_key,
                    protocol_id=OEFMessage.protocol_id,
                    message=OEFSerializer().encode(oef_msg))

        if strategy.is_searching_for_buyers:
            query = strategy.get_own_services_query(
                is_searching_for_sellers=False)
            if query is None:
                logger.warning(
                    "[{}]: Not searching the OEF for buyers because the agent supplies no goods."
                    .format(self.context.agent_name))
                return None
            else:
                search_id = search.get_next_id(is_searching_for_sellers=False)
                logger.info(
                    "[{}]: Searching for buyers which match the supply of the agent, search_id={}."
                    .format(self.context.agent_name, search_id))
                oef_msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_SERVICES,
                                     id=search_id,
                                     query=query)
                self.context.outbox.put_message(
                    to=DEFAULT_OEF,
                    sender=self.context.agent_public_key,
                    protocol_id=OEFMessage.protocol_id,
                    message=OEFSerializer().encode(oef_msg))
Esempio n. 10
0
        def setup_class(cls):
            """
            Set the test up.

            Steps:
            - Register a service
            - Check that the registration worked.
            """
            cls.crypto1 = DefaultCrypto()
            cls.connection = OEFConnection(cls.crypto1.public_key,
                                           oef_addr="127.0.0.1",
                                           oef_port=10000)
            cls.multiplexer = Multiplexer([cls.connection])
            cls.multiplexer.connect()

            cls.request_id = 1
            cls.foo_datamodel = DataModel(
                "foo", [Attribute("bar", int, True, "A bar attribute.")])
            cls.desc = Description({"bar": 1}, data_model=cls.foo_datamodel)
            msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE,
                             id=cls.request_id,
                             service_description=cls.desc,
                             service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            cls.multiplexer.put(
                Envelope(to=DEFAULT_OEF,
                         sender=cls.crypto1.public_key,
                         protocol_id=OEFMessage.protocol_id,
                         message=msg_bytes))

            time.sleep(1.0)

            cls.request_id += 1
            search_request = OEFMessage(
                oef_type=OEFMessage.Type.SEARCH_SERVICES,
                id=cls.request_id,
                query=Query([Constraint("bar", ConstraintType("==", 1))],
                            model=cls.foo_datamodel))
            cls.multiplexer.put(
                Envelope(to=DEFAULT_OEF,
                         sender=cls.crypto1.public_key,
                         protocol_id=OEFMessage.protocol_id,
                         message=OEFSerializer().encode(search_request)))
            envelope = cls.multiplexer.get(block=True, timeout=5.0)
            search_result = OEFSerializer().decode(envelope.message)
            assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
            assert search_result.get("id") == cls.request_id
            if search_result.get("agents") != [cls.crypto1.public_key]:
                logger.warning(
                    'search_result.get("agents") != [self.crypto1.public_key] FAILED in test_oef/test_communication.py'
                )
Esempio n. 11
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)
        transactions = cast(Transactions, self.context.transactions)
        if strategy.is_registering_as_seller:
            logger.debug(
                "[{}]: Updating service directory as seller with goods supplied."
                .format(self.context.agent_name))
            ownership_state_after_locks = transactions.ownership_state_after_locks(
                self.context.ownership_state, is_seller=True)
            goods_supplied_description = strategy.get_own_service_description(
                ownership_state_after_locks, is_supply=True)
            self._registered_goods_supplied_description = goods_supplied_description
            msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE,
                             id=DEFAULT_MSG_ID,
                             service_description=goods_supplied_description,
                             service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            self.context.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.context.agent_public_key,
                protocol_id=OEFMessage.protocol_id,
                message=msg_bytes)
        if strategy.is_registering_as_buyer:
            logger.debug(
                "[{}]: Updating service directory as buyer with goods demanded."
                .format(self.context.agent_name))
            ownership_state_after_locks = transactions.ownership_state_after_locks(
                self.context.ownership_state, is_seller=False)
            goods_demanded_description = strategy.get_own_service_description(
                ownership_state_after_locks, is_supply=False)
            self._registered_goods_demanded_description = goods_demanded_description
            msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE,
                             id=DEFAULT_MSG_ID,
                             service_description=goods_demanded_description,
                             service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            self.context.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.context.agent_public_key,
                protocol_id=OEFMessage.protocol_id,
                message=msg_bytes)
Esempio n. 12
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:
            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)
            registration.registered_goods_supplied_description = goods_supplied_description
            oef_msg = OEFMessage(
                oef_type=OEFMessage.Type.REGISTER_SERVICE,
                id=registration.get_next_id(),
                service_description=goods_supplied_description,
                service_id="")
            self.context.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.context.agent_public_key,
                protocol_id=OEFMessage.protocol_id,
                message=OEFSerializer().encode(oef_msg))

        if strategy.is_registering_as_buyer:
            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)
            registration.registered_goods_demanded_description = goods_demanded_description
            oef_msg = OEFMessage(
                oef_type=OEFMessage.Type.REGISTER_SERVICE,
                id=registration.get_next_id(),
                service_description=goods_demanded_description,
                service_id="")
            self.context.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.context.agent_public_key,
                protocol_id=OEFMessage.protocol_id,
                message=OEFSerializer().encode(oef_msg))
Esempio n. 13
0
def test_oef_message_OEFError():
    """Tests the OEF_ERROR type of message."""
    msg = OEFMessage(oef_type=OEFMessage.Type.OEF_ERROR,
                     id=0,
                     operation=OEFMessage.OEFErrorOperation.SEARCH_AGENTS)

    assert OEFMessage(oef_type=OEFMessage.Type.OEF_ERROR, id=0,
                      operation=OEFMessage.OEFErrorOperation.SEARCH_AGENTS),\
        "Expects an oef message Error!"
    msg_bytes = OEFSerializer().encode(msg)
    assert len(msg_bytes) > 0,\
        "Expects the length of bytes not to be Empty"
    deserialized_msg = OEFSerializer().decode(msg_bytes)
    assert msg == deserialized_msg,\
        "Expected the deserialized_msg to me equals to msg"
Esempio n. 14
0
    def test_unregister_service_result(self):
        """Test that at the beginning, the search request returns an empty search result."""
        data_model = DataModel("foobar", attributes=[])
        service_description = Description({"foo": 1, "bar": "baz"}, data_model=data_model)
        msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=0, service_description=service_description,
                         service_id="Test_service")
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        self.multiplexer1.put(envelope)

        # check the result
        response_envelope = self.multiplexer1.get(block=True, timeout=5.0)
        assert response_envelope.protocol_id == OEFMessage.protocol_id
        assert response_envelope.sender == DEFAULT_OEF
        result = OEFSerializer().decode(response_envelope.message)
        assert result.get("type") == OEFMessage.Type.OEF_ERROR

        msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=0, service_description=service_description,
                         service_id="Test_Service")
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        self.multiplexer1.put(envelope)

        # Search for the register agent
        msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_AGENTS, id=0, query=Query([Constraint("foo", ConstraintType("==", 1))]))
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        self.multiplexer1.put(envelope)
        # check the result
        response_envelope = self.multiplexer1.get(block=True, timeout=5.0)
        assert response_envelope.protocol_id == OEFMessage.protocol_id
        assert response_envelope.sender == DEFAULT_OEF
        result = OEFSerializer().decode(response_envelope.message)
        assert result.get("type") == OEFMessage.Type.SEARCH_RESULT
        assert len(result.get("agents")) == 1

        # unregister the service
        data_model = DataModel("foobar", attributes=[])
        service_description = Description({"foo": 1, "bar": "baz"}, data_model=data_model)
        msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=0, service_description=service_description,
                         service_id="Test_service")
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        self.multiplexer1.put(envelope)

        # the same query returns empty
        # Search for the register agent
        msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_AGENTS, id=0, query=Query([Constraint("foo", ConstraintType("==", 1))]))
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        self.multiplexer1.put(envelope)
        # check the result
        response_envelope = self.multiplexer1.get(block=True, timeout=5.0)
        assert response_envelope.protocol_id == OEFMessage.protocol_id
        assert response_envelope.sender == DEFAULT_OEF
        result = OEFSerializer().decode(response_envelope.message)
        assert result.get("type") == OEFMessage.Type.SEARCH_RESULT
        assert len(result.get("agents")) == 0
Esempio n. 15
0
    async def _search_services(self, public_key: str, search_id: int,
                               query: Query) -> None:
        """
        Search the agents in the local Service Directory, and send back the result.

        This is actually a dummy search, it will return all the registered agents with the specified data model.
        If the data model is not specified, it will return all the agents.

        :param public_key: the source of the search request.
        :param search_id: the search identifier associated with the search request.
        :param query: the query that constitutes the search.
        :return: None
        """
        result = []  # type: List[str]
        if query.model is None:
            result = list(set(self.services.keys()))
        else:
            for agent_public_key, descriptions in self.services.items():
                for description in descriptions:
                    if description.data_model == query.model:
                        result.append(agent_public_key)

        msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_RESULT,
                         id=search_id,
                         agents=sorted(set(result)))
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=public_key,
                            sender=DEFAULT_OEF,
                            protocol_id=OEFMessage.protocol_id,
                            message=msg_bytes)
        await self._send(envelope)
Esempio n. 16
0
    async def _unregister_agent(self, public_key: str, msg_id: int,
                                agent_description: Description) -> None:
        """
        Unregister an agent.

        :param agent_description:
        :param public_key: the public key of the service agent to be unregistered.
        :param msg_id: the message id of the request.
        :return: None
        """
        async with self._lock:
            if public_key not in self.agents:
                msg = OEFMessage(
                    oef_type=OEFMessage.Type.OEF_ERROR,
                    id=msg_id,
                    operation=OEFMessage.OEFErrorOperation.UNREGISTER_AGENT)
                msg_bytes = OEFSerializer().encode(msg)
                envelope = Envelope(to=public_key,
                                    sender=DEFAULT_OEF,
                                    protocol_id=OEFMessage.protocol_id,
                                    message=msg_bytes)
                await self._send(envelope)
            else:
                self.agents[public_key].remove(agent_description)
                if len(self.agents[public_key]) == 0:
                    self.agents.pop(public_key)
Esempio n. 17
0
    async def _handle_oef_message(self, envelope: Envelope) -> None:
        """Handle oef messages.

        :param envelope: the envelope
        :return: None
        """
        oef_message = OEFSerializer().decode(envelope.message)
        sender = envelope.sender
        request_id = cast(int, oef_message.get("id"))
        oef_type = OEFMessage.Type(oef_message.get("type"))
        if oef_type == OEFMessage.Type.REGISTER_SERVICE:
            await self._register_service(
                sender,
                cast(Description, oef_message.get("service_description")))
        elif oef_type == OEFMessage.Type.REGISTER_AGENT:
            await self._register_agent(
                sender, cast(Description,
                             oef_message.get("agent_description")))
        elif oef_type == OEFMessage.Type.UNREGISTER_SERVICE:
            await self._unregister_service(
                sender, request_id,
                cast(Description, oef_message.get("service_description")))
        elif oef_type == OEFMessage.Type.UNREGISTER_AGENT:
            await self._unregister_agent(
                sender, request_id,
                cast(Description, oef_message.get("agent_description")))
        elif oef_type == OEFMessage.Type.SEARCH_AGENTS:
            await self._search_agents(sender, request_id,
                                      cast(Query, oef_message.get("query")))
        elif oef_type == OEFMessage.Type.SEARCH_SERVICES:
            await self._search_services(sender, request_id,
                                        cast(Query, oef_message.get("query")))
        else:
            # request not recognized
            pass
Esempio n. 18
0
    def handle_oef_message(self, envelope: Envelope) -> None:
        """
        Handle messages from the oef.

        The oef does not expect a response for any of these messages.

        :param envelope: the OEF message

        :return: None
        """
        logger.debug(
            "[{}]: Handling OEF message. type={}".format(
                self.agent_name, type(envelope)
            )
        )
        assert envelope.protocol_id == "oef"
        msg = OEFSerializer().decode(envelope.message)
        if msg.get("type") == OEFMessage.Type.OEF_ERROR:
            self.on_oef_error(envelope)
        elif msg.get("type") == OEFMessage.Type.DIALOGUE_ERROR:
            self.on_dialogue_error(envelope)
        else:
            logger.warning(
                "[{}]: OEF Message type not recognized.".format(self.agent_name)
            )
Esempio n. 19
0
    def setup_class(cls):
        """Set up the test."""
        cls.node = LocalNode()

        cls.public_key_1 = "mailbox1"
        cls.mailbox1 = MailBox(OEFLocalConnection(cls.public_key_1, cls.node))

        cls.mailbox1.connect()

        # register a service.
        request_id = 1
        service_id = ''
        cls.data_model = DataModel("foobar", attributes=[])
        service_description = Description({
            "foo": 1,
            "bar": "baz"
        },
                                          data_model=cls.data_model)
        register_service_request = OEFMessage(
            oef_type=OEFMessage.Type.REGISTER_SERVICE,
            id=request_id,
            service_description=service_description,
            service_id=service_id)
        msg_bytes = OEFSerializer().encode(register_service_request)
        envelope = Envelope(to=DEFAULT_OEF,
                            sender=cls.public_key_1,
                            protocol_id=OEFMessage.protocol_id,
                            message=msg_bytes)
        cls.mailbox1.send(envelope)
Esempio n. 20
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
        """
        query = Query(
            [Constraint("version", GtEq(self.game_instance.expected_version_id))]
        )
        search_id = self.game_instance.search.get_next_id()
        self.game_instance.search.ids_for_tac.add(search_id)

        msg = OEFMessage(
            oef_type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query
        )
        msg_bytes = OEFSerializer().encode(msg)
        self.mailbox.outbox.put_message(
            to=DEFAULT_OEF,
            sender=self.crypto.public_key,
            protocol_id=OEFMessage.protocol_id,
            message=msg_bytes,
        )
Esempio n. 21
0
    def handle_envelope(self, envelope: Envelope) -> None:
        """
        Implement the reaction to an envelope.

        :param envelope: the envelope
        :return: None
        """
        msg = OEFSerializer().decode(envelope.message)
        msg_type = OEFMessage.Type(msg.get("type"))

        if msg_type is OEFMessage.Type.SEARCH_RESULT:
            agents = cast(List[str], msg.get("agents"))
            logger.info("[{}]: found agents={}".format(self.context.agent_name,
                                                       agents))
            for agent in agents:
                msg = FIPAMessage(message_id=STARTING_MESSAGE_ID,
                                  dialogue_id=self.dialogue_id,
                                  performative=FIPAMessage.Performative.CFP,
                                  target=STARTING_TARGET_ID,
                                  query=None)
                self.dialogue_id += 1
                self.context.outbox.put_message(
                    to=agent,
                    sender=self.context.agent_public_key,
                    protocol_id=FIPAMessage.protocol_id,
                    message=FIPASerializer().encode(msg))
Esempio n. 22
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 = OEFMessage.OEFErrorOperation(operation)
        except ValueError:
            operation = OEFMessage.OEFErrorOperation.OTHER

        msg = OEFMessage(oef_type=OEFMessage.Type.OEF_ERROR,
                         id=answer_id,
                         operation=operation)
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=self.public_key,
                            sender=DEFAULT_OEF,
                            protocol_id=OEFMessage.protocol_id,
                            message=msg_bytes)
        asyncio.run_coroutine_threadsafe(self.in_queue.put(envelope),
                                         self.loop).result()
Esempio n. 23
0
    def setup_class(cls):
        """Set up the test."""
        cls.node = LocalNode()
        cls.node.start()

        cls.public_key_1 = "multiplexer1"
        cls.public_key_2 = "multiplexer2"
        cls.multiplexer1 = Multiplexer([OEFLocalConnection(cls.public_key_1, cls.node)])
        cls.multiplexer2 = Multiplexer([OEFLocalConnection(cls.public_key_2, cls.node)])
        cls.multiplexer1.connect()
        cls.multiplexer2.connect()

        # register 'multiplexer1' as a service 'foobar'.
        request_id = 1
        service_id = ''
        cls.data_model_foobar = DataModel("foobar", attributes=[])
        service_description = Description({"foo": 1, "bar": "baz"}, data_model=cls.data_model_foobar)
        register_service_request = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=request_id,
                                              service_description=service_description, service_id=service_id)
        msg_bytes = OEFSerializer().encode(register_service_request)
        envelope = Envelope(to=DEFAULT_OEF, sender=cls.public_key_1, protocol_id=OEFMessage.protocol_id,
                            message=msg_bytes)
        cls.multiplexer1.put(envelope)

        time.sleep(1.0)

        # register 'multiplexer2' as a service 'barfoo'.
        cls.data_model_barfoo = DataModel("barfoo", attributes=[])
        service_description = Description({"foo": 1, "bar": "baz"}, data_model=cls.data_model_barfoo)
        register_service_request = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=request_id,
                                              service_description=service_description, service_id=service_id)
        msg_bytes = OEFSerializer().encode(register_service_request)
        envelope = Envelope(to=DEFAULT_OEF, sender=cls.public_key_2, protocol_id=OEFMessage.protocol_id,
                            message=msg_bytes)
        cls.multiplexer2.put(envelope)

        # unregister multiplexer1
        data_model = DataModel("foobar", attributes=[])
        service_description = Description({"foo": 1, "bar": "baz"}, data_model=data_model)
        msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=0, service_description=service_description,
                         service_id="Test_service")
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=DEFAULT_OEF, sender=cls.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        cls.multiplexer1.put(envelope)
Esempio n. 24
0
def test_oef_serialization():
    """Testing the serialization of the OEF."""
    foo_datamodel = DataModel(
        "foo", [Attribute("bar", int, True, "A bar attribute.")])
    desc = Description({"bar": 1}, data_model=foo_datamodel)
    msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE,
                     id=1,
                     service_description=desc,
                     service_id="")
    msg_bytes = OEFSerializer().encode(msg)
    assert len(msg_bytes) > 0
Esempio n. 25
0
    def test_not_empty_search_result(self):
        """Test that the search result contains one entry after a successful registration."""
        request_id = 1
        query = Query(constraints=[], model=self.data_model)

        # build and send the request
        search_services_request = OEFMessage(oef_type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=query)
        msg_bytes = OEFSerializer().encode(search_services_request)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id,
                            message=msg_bytes)
        self.multiplexer.put(envelope)

        # check the result
        response_envelope = self.multiplexer.get(block=True, timeout=2.0)
        assert response_envelope.protocol_id == OEFMessage.protocol_id
        assert response_envelope.to == self.public_key_1
        assert response_envelope.sender == DEFAULT_OEF
        search_result = OEFSerializer().decode(response_envelope.message)
        assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
        assert search_result.get("agents") == [self.public_key_1]
Esempio n. 26
0
    def test_filtered_search_result(self):
        """Test that the search result contains only the entries matching the query."""
        request_id = 1
        query = Query(constraints=[], model=self.data_model_barfoo)

        # build and send the request
        search_services_request = OEFMessage(oef_type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=query)
        msg_bytes = OEFSerializer().encode(search_services_request)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id,
                            message=msg_bytes)
        self.multiplexer1.put(envelope)

        # check the result
        response_envelope = InBox(self.multiplexer1).get(block=True, timeout=5.0)
        assert response_envelope.protocol_id == OEFMessage.protocol_id
        assert response_envelope.to == self.public_key_1
        assert response_envelope.sender == DEFAULT_OEF
        search_result = OEFSerializer().decode(response_envelope.message)
        assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
        assert search_result.get("agents") == [self.public_key_2]
Esempio n. 27
0
        def test_search_count_increases(self):
            """Test that the search count increases."""
            request_id = 1
            search_query_empty_model = Query(
                [Constraint("foo", ConstraintType("==", "bar"))], model=None)
            search_request = OEFMessage(
                oef_type=OEFMessage.Type.SEARCH_SERVICES,
                id=request_id,
                query=search_query_empty_model)
            self.multiplexer.put(
                Envelope(to=DEFAULT_OEF,
                         sender=self.crypto1.public_key,
                         protocol_id=OEFMessage.protocol_id,
                         message=OEFSerializer().encode(search_request)))

            envelope = self.multiplexer.get(block=True, timeout=5.0)
            search_result = OEFSerializer().decode(envelope.message)
            assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
            assert search_result.get("id")
            assert request_id and search_result.get("agents") == []
Esempio n. 28
0
    def test_on_dialogue_error(self):
        """Test the dialogue error."""
        oef_connection = self.multiplexer1.connections[0]
        oef_channel = oef_connection.channel

        oef_channel.on_dialogue_error(answer_id=0, dialogue_id=0, origin="me")
        envelope = self.multiplexer1.get(block=True, timeout=5.0)
        dec_msg = OEFSerializer().decode(envelope.message)
        assert dec_msg.get(
            "type"
        ) is OEFMessage.Type.DIALOGUE_ERROR, "It should be a dialogue error"
Esempio n. 29
0
    def test_on_oef_error(self):
        """Test the oef error."""
        oef_connection = self.multiplexer1.connections[0]
        oef_channel = oef_connection.channel

        oef_channel.on_oef_error(answer_id=0,
                                 operation=OEFErrorOperation.SEARCH_AGENTS)
        envelope = self.multiplexer1.get(block=True, timeout=5.0)
        dec_msg = OEFSerializer().decode(envelope.message)
        assert dec_msg.get(
            "type"
        ) is OEFMessage.Type.OEF_ERROR, "It should be an error message"
Esempio n. 30
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 = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE,
                             id=self.request_id,
                             service_description=self.desc,
                             service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            self.mailbox1.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.crypto1.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=msg_bytes)

            time.sleep(1.0)

            self.request_id += 1
            search_request = OEFMessage(
                oef_type=OEFMessage.Type.SEARCH_SERVICES,
                id=self.request_id,
                query=Query([Constraint("bar", ConstraintType("==", 1))],
                            model=self.foo_datamodel))
            self.mailbox1.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.crypto1.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=OEFSerializer().encode(search_request))

            envelope = self.mailbox1.inbox.get(block=True, timeout=5.0)
            search_result = OEFSerializer().decode(envelope.message)
            assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
            assert search_result.get("id") == self.request_id
            assert search_result.get("agents") == []