예제 #1
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)
예제 #2
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)
예제 #3
0
    async def _search_services(
        self, oef_search_msg: OefSearchMessage, dialogue: OefSearchDialogue,
    ) -> 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 oef_search_msg: the message.
        :param dialogue: the dialogue.
        :return: None
        """
        async with self._lock:
            query = oef_search_msg.query
            result = []  # type: List[str]
            if query.model is None:
                result = list(set(self.services.keys()))
            else:
                for agent_address, descriptions in self.services.items():
                    for description in descriptions:
                        if description.data_model == query.model:
                            result.append(agent_address)

            msg = OefSearchMessage(
                performative=OefSearchMessage.Performative.SEARCH_RESULT,
                target=oef_search_msg.message_id,
                dialogue_reference=dialogue.dialogue_label.dialogue_reference,
                message_id=oef_search_msg.message_id + 1,
                agents=tuple(sorted(set(result))),
            )
            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)
예제 #4
0
    async def _find_around_me(
        self,
        oef_message: OefSearchMessage,
        oef_search_dialogue: OefSearchDialogue,
        radius: float,
        params: Dict[str, List[str]],
    ) -> None:
        """
        Find agents around me.

        :param oef_message: OefSearchMessage
        :param oef_search_dialogue: OefSearchDialogue
        :param radius: the radius in which to search
        :param params: the parameters for the query
        :return: None
        """
        assert self.in_queue is not None, "Inqueue not set!"
        logger.debug("Searching in radius={} of myself".format(radius))

        response_text = await self._generic_oef_command(
            "find_around_me", {
                "range_in_km": [str(radius)],
                **params
            })
        root = ET.fromstring(response_text)
        agents = {key: {}
                  for key in self.SUPPORTED_CHAIN_IDENTIFIERS
                  }  # type: Dict[str, Dict[str, str]]
        agents_l = []  # type: List[str]
        for agent in root.findall(path=".//agent"):
            chain_identifier = ""
            for identities in agent.findall("identities"):
                for identity in identities.findall("identity"):
                    for (
                            chain_identifier_key,
                            chain_identifier_name,
                    ) in identity.items():
                        if chain_identifier_key == "chain_identifier":
                            chain_identifier = chain_identifier_name
                            agent_address = identity.text
            agent_distance = agent.find("range_in_km").text
            if chain_identifier in agents:
                agents[chain_identifier][agent_address] = agent_distance
                agents_l.append(agent_address)

        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_RESULT,
            dialogue_reference=oef_search_dialogue.dialogue_label.
            dialogue_reference,
            agents=tuple(agents_l),
            target=oef_message.message_id,
            message_id=oef_message.message_id + 1,
        )
        message.counterparty = oef_message.counterparty
        oef_search_dialogue.update(message)
        message = copy.deepcopy(
            message
        )  # TODO: fix; need to copy atm to avoid overwriting "is_incoming"
        envelope = Envelope(
            to=message.counterparty,
            sender=SOEFConnection.connection_id.latest,
            protocol_id=message.protocol_id,
            message=message,
        )
        await self.in_queue.put(envelope)