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"
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)
def __init__( self, dialogue_label: BaseDialogueLabel, self_address: Address, role: BaseDialogue.Role, message_class: Type[OefSearchMessage] = OefSearchMessage, ) -> None: """ Initialize a dialogue. :param dialogue_label: the identifier of the dialogue :param self_address: the address of the entity for whom this dialogue is maintained :param role: the role of the agent this dialogue is maintained for :return: None """ BaseOefSearchDialogue.__init__( self, dialogue_label=dialogue_label, self_address=self_address, role=role ) self._envelope_context = None # type: Optional[EnvelopeContext]
def __init__( self, dialogue_label: DialogueLabel, agent_address: Address, role: Dialogue.Role, ) -> None: """ Initialize a dialogue. :param dialogue_label: the identifier of the dialogue :param agent_address: the address of the agent for whom this dialogue is maintained :param role: the role of the agent this dialogue is maintained for :return: None """ BaseOefSearchDialogue.__init__(self, dialogue_label=dialogue_label, agent_address=agent_address, role=role) self._is_seller_search = None # type: Optional[bool]
def __init__( self, dialogue_label: DialogueLabel, self_address: Address, role: BaseDialogue.Role, message_class: Type[OefSearchMessage], ) -> None: """ Initialize a dialogue. :param dialogue_label: the identifier of the dialogue :param self_address: the address of the entity for whom this dialogue is maintained :param role: the role of the agent this dialogue is maintained for :return: None """ OefSearchDialogue.__init__( self, dialogue_label=dialogue_label, self_address=self_address, role=role, message_class=message_class, )
def create_dialogue( self, dialogue_label: BaseDialogueLabel, role: BaseDialogue.Role, ) -> OefSearchDialogue: """ Create an instance of fipa dialogue. :param dialogue_label: the identifier of the dialogue :param role: the role of the agent this dialogue is maintained for :return: the created dialogue """ dialogue = OefSearchDialogue( dialogue_label=dialogue_label, agent_address=self.agent_address, role=role ) return dialogue
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)