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)
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)
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)
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)