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 = 1 data_model = DataModel("foobar", [Attribute("foo", str, True)]) search_query = Query( [Constraint("foo", ConstraintType("==", "bar"))], model=data_model ) search_request = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, dialogue_reference=(str(request_id), ""), query=search_query, ) 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) assert search_result.agents == ()
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 = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, dialogue_reference=(str(request_id), ""), query=search_query_empty_model, ) 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) assert request_id and search_result.agents == ()
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 = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, dialogue_reference=(str(request_id), ""), query=query, ) msg_bytes = OefSearchSerializer().encode(search_services_request) envelope = Envelope( to=DEFAULT_OEF, sender=self.address_1, protocol_id=OefSearchMessage.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 == OefSearchMessage.protocol_id assert response_envelope.to == self.address_1 assert response_envelope.sender == DEFAULT_OEF search_result = OefSearchSerializer().decode(response_envelope.message) assert search_result.performative == OefSearchMessage.Performative.SEARCH_RESULT assert search_result.agents == (self.address_2,)
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 = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, dialogue_reference=(str(request_id), ""), query=query, ) msg_bytes = OefSearchSerializer().encode(search_services_request) envelope = Envelope( to=DEFAULT_OEF, sender=self.address_1, protocol_id=OefSearchMessage.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 == OefSearchMessage.protocol_id assert response_envelope.to == self.address_1 assert response_envelope.sender == DEFAULT_OEF search_result = OefSearchSerializer().decode(response_envelope.message) assert search_result.performative == OefSearchMessage.Performative.SEARCH_RESULT assert search_result.agents == ()
def test_search_services_with_query_without_model(self): """Test that a search services request can be sent correctly. In this test, the query has no data model. """ request_id = 1 search_query_empty_model = Query( [Constraint("foo", ConstraintType("==", "bar"))], model=None) search_request = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, dialogue_reference=(str(request_id), ""), query=search_query_empty_model, ) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=FETCHAI_ADDRESS_ONE, 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) assert request_id and search_result.agents == ()
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), )
def test_oef_serialization_query(): """Testing the serialization of the OEF.""" query = Query([Constraint("foo", ConstraintType("==", "bar"))], model=None) msg = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, dialogue_reference=(str(1), ""), query=query, ) msg_bytes = OefSearchSerializer().encode(msg) assert len(msg_bytes) > 0 recovered_msg = OefSearchSerializer().decode(msg_bytes) assert recovered_msg == msg
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 == ()
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()
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" )
def test_oef_serialization_description(): """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 = OefSearchMessage( performative=OefSearchMessage.Performative.REGISTER_SERVICE, dialogue_reference=(str(1), ""), service_description=desc, ) msg_bytes = OefSearchSerializer().encode(msg) assert len(msg_bytes) > 0 recovered_msg = OefSearchSerializer().decode(msg_bytes) assert recovered_msg == msg
def setup_class(cls): """Set up the test.""" cls.node = LocalNode() cls.node.start() cls.address_1 = "address" cls.multiplexer = Multiplexer( [_make_local_connection(cls.address_1, cls.node,)] ) cls.multiplexer.connect() # register a service. request_id = 1 cls.data_model = DataModel("foobar", attributes=[]) service_description = Description( {"foo": 1, "bar": "baz"}, data_model=cls.data_model ) register_service_request = OefSearchMessage( performative=OefSearchMessage.Performative.REGISTER_SERVICE, dialogue_reference=(str(request_id), ""), service_description=service_description, ) msg_bytes = OefSearchSerializer().encode(register_service_request) envelope = Envelope( to=DEFAULT_OEF, sender=cls.address_1, protocol_id=OefSearchMessage.protocol_id, message=msg_bytes, ) cls.multiplexer.put(envelope)
def send_oef_message(self, envelope: Envelope) -> None: """ Send oef message handler. :param envelope: the message. :return: None """ oef_message = OefSearchSerializer().decode(envelope.message) oef_message = cast(OefSearchMessage, oef_message) self.oef_msg_id += 1 self.oef_msg_it_to_dialogue_reference[self.oef_msg_id] = ( oef_message.dialogue_reference[0], str(self.oef_msg_id), ) if oef_message.performative == OefSearchMessage.Performative.REGISTER_SERVICE: service_description = oef_message.service_description oef_service_description = OEFObjectTranslator.to_oef_description( service_description ) self.register_service(self.oef_msg_id, oef_service_description) elif ( oef_message.performative == OefSearchMessage.Performative.UNREGISTER_SERVICE ): service_description = oef_message.service_description oef_service_description = OEFObjectTranslator.to_oef_description( service_description ) self.unregister_service(self.oef_msg_id, oef_service_description) elif oef_message.performative == OefSearchMessage.Performative.SEARCH_SERVICES: query = oef_message.query oef_query = OEFObjectTranslator.to_oef_query(query) self.search_services(self.oef_msg_id, oef_query) else: raise ValueError("OEF request not recognized.")
async def _unregister_service( self, address: Address, dialogue_reference: Tuple[str, str], service_description: Description, ) -> None: """ Unregister a service agent. :param address: the address of the service agent to be unregistered. :param dialogue_reference: the dialogue_reference. :param service_description: the description of the service agent to be unregistered. :return: None """ async with self._lock: if address not in self.services: msg = OefSearchMessage( performative=OefSearchMessage.Performative.OEF_ERROR, dialogue_reference=(dialogue_reference[0], dialogue_reference[0]), target=RESPONSE_TARGET, message_id=RESPONSE_MESSAGE_ID, oef_error_operation=OefSearchMessage.OefErrorOperation.UNREGISTER_SERVICE, ) msg_bytes = OefSearchSerializer().encode(msg) envelope = Envelope( to=address, sender=DEFAULT_OEF, protocol_id=OefSearchMessage.protocol_id, message=msg_bytes, ) await self._send(envelope) else: self.services[address].remove(service_description) if len(self.services[address]) == 0: self.services.pop(address)
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) search = cast(Search, self.context.search) query = game.get_game_query() search_id = search.get_next_id() search.ids_for_tac.add(search_id) self.context.logger.info( "[{}]: Searching for TAC, search_id={}".format( self.context.agent_name, search_id)) oef_msg = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, dialogue_reference=(str(search_id), ""), query=query, ) 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), )
def _unregister_service(self) -> None: """ Unregister service from OEF Service Directory. :return: None """ strategy = cast(Strategy, self.context.strategy) oef_msg_id = strategy.get_next_oef_msg_id() msg = OefSearchMessage( performative=OefSearchMessage.Performative.UNREGISTER_SERVICE, dialogue_reference=(str(oef_msg_id), ""), service_description=self._registered_service_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(msg), ) self.context.logger.info( "[{}]: unregistering ml data provider service from OEF service directory.".format( self.context.agent_name ) ) self._registered_service_description = None
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()
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 ) )
def test_oef_message_oef_error(): """Tests the OEF_ERROR type of message.""" msg = OefSearchMessage( performative=OefSearchMessage.Performative.OEF_ERROR, message_id=1, oef_error_operation=OefSearchMessage.OefErrorOperation.SEARCH_SERVICES, ) assert OefSearchMessage( performative=OefSearchMessage.Performative.OEF_ERROR, message_id=1, oef_error_operation=OefSearchMessage.OefErrorOperation.SEARCH_SERVICES, ), "Expects an oef message Error!" msg_bytes = OefSearchSerializer().encode(msg) assert len(msg_bytes) > 0, "Expects the length of bytes not to be Empty" deserialized_msg = OefSearchSerializer().decode(msg_bytes) assert msg == deserialized_msg, "Expected the deserialized_msg to me equals to msg"
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()
def _register_service(self) -> None: """ Register to the OEF Service Directory. :return: None """ strategy = cast(Strategy, self.context.strategy) desc = strategy.get_service_description() self._registered_service_description = desc oef_msg_id = strategy.get_next_oef_msg_id() msg = OefSearchMessage( performative=OefSearchMessage.Performative.REGISTER_SERVICE, dialogue_reference=(str(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(msg), ) self.context.logger.info( "[{}]: updating weather station services on OEF service directory.".format( self.context.agent_name ) )
def _search_range(self, unique_page_address: str, radius: float, service_name: str) -> None: """ Search services on the SOEF. """ assert self.in_queue is not None, "Inqueue not set!" try: logger.debug("Searching in radius={} of service={}".format( radius, service_name)) url = self.base_url + "/" + unique_page_address params = { "range_in_km": str(radius), "command": "find_around_me", } response = requests.get(url=url, params=params) root = ET.fromstring(response.text) agents = { "fetchai": {}, "cosmos": {}, "ethereum": {}, } # 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) if root.tag == "response": logger.debug("Search SUCCESS") message = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_RESULT, agents=tuple(agents_l), ) envelope = Envelope( to=self.address, sender="simple_oef", protocol_id=OefSearchMessage.protocol_id, message=OefSearchSerializer().encode(message), ) self.in_queue.put_nowait(envelope) else: raise ValueError("Location registration error.") except Exception as e: logger.error("Exception when interacting with SOEF: {}".format(e))
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 = OefSearchMessage( performative=OefSearchMessage.Performative.UNREGISTER_SERVICE, dialogue_reference=(str(registration.get_next_id()), ""), service_description=registration. registered_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), ) registration.registered_goods_demanded_description = None if registration.registered_goods_supplied_description is not None: oef_msg = OefSearchMessage( performative=OefSearchMessage.Performative.UNREGISTER_SERVICE, dialogue_reference=(str(registration.get_next_id()), ""), service_description=registration. registered_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), ) registration.registered_goods_supplied_description = None
def test_search_services_with_distance_query(self): """Test that a search services request can be sent correctly. In this test, the query has a simple data model. """ tour_eiffel = Location(48.8581064, 2.29447) request_id = 1 attribute = Attribute("latlon", Location, True) data_model = DataModel("geolocation", [attribute]) search_query = Query( [ Constraint(attribute.name, ConstraintType("distance", (tour_eiffel, 1.0))) ], model=data_model, ) search_request = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, dialogue_reference=(str(request_id), ""), query=search_query, ) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=FETCHAI_ADDRESS_ONE, 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) print("HERE:" + str(search_result)) assert (search_result.performative == OefSearchMessage.Performative.SEARCH_RESULT) assert search_result.dialogue_reference[0] == str(request_id) assert search_result.agents == ()
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", str(oef_channel.oef_msg_id)) oef_channel.oef_msg_it_to_dialogue_reference[ oef_channel.oef_msg_id] = dialogue_reference 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 = OefSearchSerializer().decode(envelope.message) assert dec_msg.dialogue_reference == ("1", str(oef_channel.oef_msg_id)) assert (dec_msg.performative is OefSearchMessage.Performative.OEF_ERROR ), "It should be an error message"
def _unregister_tac(self) -> None: """ Unregister from the OEF as a TAC controller agent. :return: None. """ self._oef_msg_id += 1 self.context.logger.info("[{}]: Unregistering TAC data model".format( self.context.agent_name)) oef_msg = OefSearchMessage( performative=OefSearchMessage.Performative.UNREGISTER_SERVICE, dialogue_reference=(str(self._oef_msg_id), ""), service_description=self._registered_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 = None
def act(self) -> None: """ Implement the act. :return: None """ strategy = cast(Strategy, self.context.strategy) if strategy.is_searching: query = strategy.get_service_query() search_id = strategy.get_next_search_id() oef_msg = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, dialogue_reference=(str(search_id), ""), query=query, ) 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), )
async def _search_services( self, address: Address, dialogue_reference: Tuple[str, str], 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 address: the source of the search request. :param dialogue_reference: the dialogue_reference. :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_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, dialogue_reference=(dialogue_reference[0], dialogue_reference[0]), target=RESPONSE_TARGET, message_id=RESPONSE_MESSAGE_ID, agents=tuple(sorted(set(result))), ) msg_bytes = OefSearchSerializer().encode(msg) envelope = Envelope( to=address, sender=DEFAULT_OEF, protocol_id=OefSearchMessage.protocol_id, message=msg_bytes, ) await self._send(envelope)
def _unregister_service(self) -> None: """ Unregister service from OEF Service Directory. :return: None """ if self._registered_service_description is not None: self._oef_msf_id += 1 msg = OefSearchMessage( performative=OefSearchMessage.Performative.UNREGISTER_SERVICE, dialogue_reference=(str(self._oef_msf_id), ""), service_description=self._registered_service_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(msg), ) self.context.logger.info( "[{}]: unregistering car park detection services from OEF.". format(self.context.agent_name)) self._registered_service_description = None
async def _handle_oef_message(self, envelope: Envelope) -> None: """Handle oef messages. :param envelope: the envelope :return: None """ oef_message = OefSearchSerializer().decode(envelope.message) oef_message = cast(OefSearchMessage, oef_message) sender = envelope.sender if oef_message.performative == OefSearchMessage.Performative.REGISTER_SERVICE: await self._register_service(sender, oef_message.service_description) elif ( oef_message.performative == OefSearchMessage.Performative.UNREGISTER_SERVICE ): await self._unregister_service( sender, oef_message.dialogue_reference, oef_message.service_description ) elif oef_message.performative == OefSearchMessage.Performative.SEARCH_SERVICES: await self._search_services( sender, oef_message.dialogue_reference, oef_message.query ) else: # request not recognized pass