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( type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=query ) msg_bytes = OEFSerializer().encode(search_services_request) envelope = Envelope( to=DEFAULT_OEF, sender=self.address_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.address_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.address_1]
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( type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=query ) msg_bytes = OEFSerializer().encode(search_services_request) envelope = Envelope( to=DEFAULT_OEF, sender=self.address_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.address_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.address_2]
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: self.context.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) self.context.logger.info( "[{}]: Searching for sellers which match the demand of the agent, search_id={}." .format(self.context.agent_name, search_id)) oef_msg = OEFMessage(type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, 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: self.context.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) self.context.logger.info( "[{}]: Searching for buyers which match the supply of the agent, search_id={}." .format(self.context.agent_name, search_id)) oef_msg = OEFMessage(type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), )
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) registration.registered_goods_supplied_description = ( goods_supplied_description) oef_msg = OEFMessage( 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_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().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) registration.registered_goods_demanded_description = ( goods_demanded_description) oef_msg = OEFMessage( 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_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), )
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"
def test_on_dialogue_error(self): """Test the dialogue error.""" oef_connection = self.multiplexer1.connections[0] oef_connection = cast(OEFConnection, oef_connection) 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"
def send_oef_message(self, envelope: Envelope) -> None: """ Send oef message handler. :param envelope: the message. :return: None """ oef_message = OEFSerializer().decode(envelope.message) oef_message = cast(OEFMessage, oef_message) oef_type = oef_message.type oef_msg_id = oef_message.id if oef_type == OEFMessage.Type.REGISTER_SERVICE: service_description = oef_message.service_description service_id = oef_message.service_id oef_service_description = OEFObjectTranslator.to_oef_description( service_description ) self.register_service(oef_msg_id, oef_service_description, service_id) elif oef_type == OEFMessage.Type.UNREGISTER_SERVICE: service_description = oef_message.service_description service_id = oef_message.service_id oef_service_description = OEFObjectTranslator.to_oef_description( service_description ) self.unregister_service(oef_msg_id, oef_service_description, service_id) elif oef_type == OEFMessage.Type.SEARCH_AGENTS: query = oef_message.query oef_query = OEFObjectTranslator.to_oef_query(query) self.search_agents(oef_msg_id, oef_query) elif oef_type == OEFMessage.Type.SEARCH_SERVICES: query = oef_message.query oef_query = OEFObjectTranslator.to_oef_query(query) self.search_services(oef_msg_id, oef_query) else: raise ValueError("OEF request not recognized.")
def on_dialogue_error( self, answer_id: int, dialogue_id: int, origin: Address ) -> None: """ On dialogue error event handler. :param answer_id: the answer id. :param dialogue_id: the dialogue id. :param origin: the message sender. :return: None """ assert self.in_queue is not None assert self.loop is not None msg = OEFMessage( type=OEFMessage.Type.DIALOGUE_ERROR, id=answer_id, dialogue_id=dialogue_id, origin=origin, ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=self.address, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) asyncio.run_coroutine_threadsafe( self.in_queue.put(envelope), self.loop ).result()
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 = OEFMessage( type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), )
async def _search_services(self, address: Address, 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 address: 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_address, descriptions in self.services.items(): for description in descriptions: if description.data_model == query.model: result.append(agent_address) msg = OEFMessage(type=OEFMessage.Type.SEARCH_RESULT, id=search_id, agents=sorted(set(result))) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=address, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) await self._send(envelope)
async def _handle_agent_message(self, envelope: Envelope) -> None: """ Forward an envelope to the right agent. :param envelope: the envelope :return: None """ destination = envelope.to if destination not in self._out_queues.keys(): msg = OEFMessage( type=OEFMessage.Type.DIALOGUE_ERROR, id=STUB_DIALOGUE_ID, dialogue_id=STUB_DIALOGUE_ID, origin=destination, ) msg_bytes = OEFSerializer().encode(msg) error_envelope = Envelope( to=envelope.sender, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) await self._send(error_envelope) return else: await self._send(envelope)
async def _handle_oef_message(self, envelope: Envelope) -> None: """Handle oef messages. :param envelope: the envelope :return: None """ oef_message = OEFSerializer().decode(envelope.message) oef_message = cast(OEFMessage, oef_message) sender = envelope.sender request_id = oef_message.id oef_type = oef_message.type if oef_type == OEFMessage.Type.REGISTER_SERVICE: await self._register_service(sender, oef_message.service_description) elif oef_type == OEFMessage.Type.REGISTER_AGENT: await self._register_agent(sender, oef_message.agent_description) elif oef_type == OEFMessage.Type.UNREGISTER_SERVICE: await self._unregister_service(sender, request_id, oef_message.service_description) elif oef_type == OEFMessage.Type.UNREGISTER_AGENT: await self._unregister_agent(sender, request_id, oef_message.agent_description) elif oef_type == OEFMessage.Type.SEARCH_AGENTS: await self._search_agents(sender, request_id, oef_message.query) elif oef_type == OEFMessage.Type.SEARCH_SERVICES: await self._search_services(sender, request_id, oef_message.query) else: # request not recognized pass
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( type=OEFMessage.Type.OEF_ERROR, id=answer_id, operation=operation ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=self.address, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) asyncio.run_coroutine_threadsafe( self.in_queue.put(envelope), self.loop ).result()
async def _unregister_agent(self, address: Address, msg_id: int, agent_description: Description) -> None: """ Unregister an agent. :param agent_description: :param address: the address of the service agent to be unregistered. :param msg_id: the message id of the request. :return: None """ async with self._lock: if address not in self.agents: msg = OEFMessage( type=OEFMessage.Type.OEF_ERROR, id=msg_id, operation=OEFMessage.OEFErrorOperation.UNREGISTER_AGENT, ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=address, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) await self._send(envelope) else: self.agents[address].remove(agent_description) if len(self.agents[address]) == 0: self.agents.pop(address)
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 = OEFMessage( type=OEFMessage.Type.UNREGISTER_SERVICE, id=oef_msg_id, service_description=self._registered_service_description, service_id=SERVICE_ID, ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(msg), ) self.context.logger.info( "[{}]: unregistering generic seller services from OEF.".format( self.context.agent_name ) ) self._registered_service_description = None
def test_oef_message_oef_error(): """Tests the OEF_ERROR type of message.""" msg = OEFMessage( type=OEFMessage.Type.OEF_ERROR, id=0, operation=OEFMessage.OEFErrorOperation.SEARCH_AGENTS, ) assert OEFMessage( 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"
def _register_service(self) -> None: """ Register to the OEF Service Directory. :return: None """ strategy = cast(Strategy, self.context.strategy) if strategy.has_service_description(): desc = strategy.get_service_description() self._registered_service_description = desc self._oef_msf_id += 1 msg = OEFMessage( type=OEFMessage.Type.REGISTER_SERVICE, id=self._oef_msf_id, service_description=desc, service_id=SERVICE_ID, ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(msg), ) self.context.logger.info( "[{}]: updating car park detection services on OEF.".format( self.context.agent_name))
def _register_tac(self) -> None: """ Register on the OEF as a TAC controller agent. :return: None. """ self._oef_msg_id += 1 desc = Description( {"version": self.context.parameters.version_id}, data_model=CONTROLLER_DATAMODEL, ) self.context.logger.info("[{}]: Registering TAC data model".format( self.context.agent_name)) oef_msg = OEFMessage( type=OEFMessage.Type.REGISTER_SERVICE, id=self._oef_msg_id, service_description=desc, service_id="", ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), ) self._registered_desc = desc
async def test_send_oef_message(network_node): """Test the send oef message.""" address = FetchAICrypto().address oef_connection = OEFConnection( address=address, oef_addr="127.0.0.1", oef_port=10000, connection_id=PublicId("fetchai", "oef", "0.1.0"), ) oef_connection.loop = asyncio.get_event_loop() await oef_connection.connect() msg = OEFMessage( type=OEFMessage.Type.OEF_ERROR, id=0, operation=OEFMessage.OEFErrorOperation.SEARCH_AGENTS, ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=DEFAULT_OEF, sender=address, 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(type=OEFMessage.Type.SEARCH_AGENTS, id=0, query=query) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=DEFAULT_OEF, sender=address, protocol_id=OEFMessage.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_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( type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=search_query ) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=self.crypto1.address, 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") == request_id assert search_result.get("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 = OEFMessage( type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=search_query_empty_model, ) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=self.crypto1.address, 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") == []
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( 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_address, 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( 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_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), ) registration.registered_goods_supplied_description = None
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( type=OEFMessage.Type.REGISTER_SERVICE, id=1, service_description=desc, service_id="", ) msg_bytes = OEFSerializer().encode(msg) assert len(msg_bytes) > 0
async def test_messages(self): """Test that at the beginning, the search request returns an empty search result.""" msg = FIPAMessage((str(0), ""), 0, 0, FIPAMessage.Performative.CFP, query=None) msg_bytes = FIPASerializer().encode(msg) envelope = Envelope( to=DEFAULT_OEF, sender=self.address_1, protocol_id=FIPAMessage.protocol_id, message=msg_bytes, ) with pytest.raises(AEAConnectionError): await OEFLocalConnection( self.address_1, self.node, connection_id=PublicId("fetchai", "local", "0.1.0"), ).send(envelope) self.multiplexer1.connect() msg = FIPAMessage( (str(0), str(1)), 0, 0, FIPAMessage.Performative.CFP, query=None ) msg_bytes = FIPASerializer().encode(msg) envelope = Envelope( to="this_address_does_not_exist", sender=self.address_1, protocol_id=FIPAMessage.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.DIALOGUE_ERROR
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( type=OEFMessage.Type.UNREGISTER_SERVICE, id=self.request_id, service_description=self.desc, service_id="", ) msg_bytes = OEFSerializer().encode(msg) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=self.crypto1.address, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) ) time.sleep(1.0) self.request_id += 1 search_request = OEFMessage( type=OEFMessage.Type.SEARCH_SERVICES, id=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=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") == self.request_id assert search_result.get("agents") == []
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( type=OEFMessage.Type.REGISTER_SERVICE, id=1, service_description=desc, service_id="", ) msg_bytes = OEFSerializer().encode(msg) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=self.crypto1.address, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) ) time.sleep(0.5) search_request = OEFMessage( type=OEFMessage.Type.SEARCH_SERVICES, id=2, query=Query( [Constraint("bar", ConstraintType("==", 1))], model=foo_datamodel ), ) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=self.crypto1.address, 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") == 2 if search_result.get("agents") != [self.crypto1.address]: logger.warning( 'search_result.get("agents") != [self.crypto1.address] FAILED in test_oef/test_communication.py' )
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 = OEFMessage(type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), )
def setup_class(cls): """Set up the test.""" cls.node = LocalNode() cls.node.start() cls.address_1 = "address" cls.multiplexer = Multiplexer( [ OEFLocalConnection( cls.address_1, cls.node, connection_id=PublicId("fetchai", "local", "0.1.0"), ) ] ) cls.multiplexer.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( 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.address_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) cls.multiplexer.put(envelope)
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 = OEFMessage( type=OEFMessage.Type.UNREGISTER_SERVICE, id=self._oef_msg_id, service_description=self._registered_desc, service_id="", ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), ) self._registered_desc = None
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 msg = OEFMessage( type=OEFMessage.Type.SEARCH_RESULT, id=search_id, agents=agents ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=self.address, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) asyncio.run_coroutine_threadsafe( self.in_queue.put(envelope), self.loop ).result()