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 = OEFMessage( oef_type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=query) msg_bytes = OEFSerializer().encode(search_services_request) envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes) self.mailbox1.send(envelope) # check the result response_envelope = self.mailbox1.inbox.get(block=True, timeout=2.0) assert response_envelope.protocol_id == OEFMessage.protocol_id assert response_envelope.to == self.public_key_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") == []
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( oef_type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=search_query) self.mailbox1.outbox.put_message( to=DEFAULT_OEF, sender=self.crypto1.public_key, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(search_request)) envelope = self.mailbox1.inbox.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 unregister_service(self) -> None: """ Unregister service from OEF Service Directory. :return: None """ if self.game_instance.goods_demanded_description is not None: msg = OEFMessage( oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=DEFAULT_MSG_ID, service_description=self.game_instance.goods_demanded_description, service_id="", ) msg_bytes = OEFSerializer().encode(msg) self.mailbox.outbox.put_message( to=DEFAULT_OEF, sender=self.crypto.public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) if self.game_instance.goods_supplied_description is not None: msg = OEFMessage( oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=DEFAULT_MSG_ID, service_description=self.game_instance.goods_supplied_description, service_id="", ) msg_bytes = OEFSerializer().encode(msg) self.mailbox.outbox.put_message( to=DEFAULT_OEF, sender=self.crypto.public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes, )
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(oef_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_public_key, 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(oef_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_public_key, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg)) registration.registered_goods_supplied_description = None
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 """ if self.game_instance.strategy.is_registering_as_seller: logger.debug("[{}]: Updating service directory as seller with goods supplied.".format(self.agent_name)) goods_supplied_description = self.game_instance.get_service_description(is_supply=True) self.game_instance.goods_supplied_description = goods_supplied_description msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=DEFAULT_MSG_ID, service_description=goods_supplied_description, service_id="") msg_bytes = OEFSerializer().encode(msg) self.mailbox.outbox.put_message(to=DEFAULT_OEF, sender=self.crypto.public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes) if self.game_instance.strategy.is_registering_as_buyer: logger.debug("[{}]: Updating service directory as buyer with goods demanded.".format(self.agent_name)) goods_demanded_description = self.game_instance.get_service_description(is_supply=False) self.game_instance.goods_demanded_description = goods_demanded_description msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=DEFAULT_MSG_ID, service_description=goods_demanded_description, service_id="") msg_bytes = OEFSerializer().encode(msg) self.mailbox.outbox.put_message(to=DEFAULT_OEF, sender=self.crypto.public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
def _unregister_service(self) -> None: """ Unregister service from OEF Service Directory. :return: None """ if self._registered_goods_demanded_description is not None: msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=DEFAULT_MSG_ID, service_description=self. _registered_goods_demanded_description, service_id="") msg_bytes = OEFSerializer().encode(msg) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes) self._registered_goods_demanded_description = None if self._registered_goods_supplied_description is not None: msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=DEFAULT_MSG_ID, service_description=self. _registered_goods_supplied_description, service_id="") msg_bytes = OEFSerializer().encode(msg) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes) self._registered_goods_supplied_description = None
async def test_send_oef_message(network_node): """Test the send oef message.""" private_key_pem_path = os.path.join(CUR_PATH, "data", "priv.pem") wallet = Wallet({'default': private_key_pem_path}) public_key = wallet.public_keys['default'] oef_connection = OEFConnection(public_key=public_key, oef_addr="127.0.0.1", oef_port=10000) oef_connection.loop = asyncio.get_event_loop() await oef_connection.connect() msg = OEFMessage(oef_type=OEFMessage.Type.OEF_ERROR, id=0, operation=OEFMessage.OEFErrorOperation.SEARCH_AGENTS) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope(to=DEFAULT_OEF, sender=public_key, 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(oef_type=OEFMessage.Type.SEARCH_AGENTS, id=0, query=query) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope(to="recipient", sender=public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes) await oef_connection.send(envelope) 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) msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=1, service_description=desc, service_id="") msg_bytes = OEFSerializer().encode(msg) self.mailbox1.outbox.put_message( to=DEFAULT_OEF, sender=self.crypto1.public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes) search_request = OEFMessage( oef_type=OEFMessage.Type.SEARCH_SERVICES, id=2, query=Query([Constraint("bar", ConstraintType("==", 1))], model=foo_datamodel)) self.mailbox1.outbox.put_message( to=DEFAULT_OEF, sender=self.crypto1.public_key, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(search_request)) envelope = self.mailbox1.inbox.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 assert search_result.get("agents") == [self.crypto1.public_key]
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: 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) logger.info( "[{}]: Searching for sellers which match the demand of the agent, search_id={}." .format(self.context.agent_name, search_id)) oef_msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_public_key, 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: 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) logger.info( "[{}]: Searching for buyers which match the supply of the agent, search_id={}." .format(self.context.agent_name, search_id)) oef_msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_public_key, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg))
def setup_class(cls): """ Set the test up. Steps: - Register a service - Check that the registration worked. """ cls.crypto1 = DefaultCrypto() cls.connection = OEFConnection(cls.crypto1.public_key, oef_addr="127.0.0.1", oef_port=10000) cls.multiplexer = Multiplexer([cls.connection]) cls.multiplexer.connect() cls.request_id = 1 cls.foo_datamodel = DataModel( "foo", [Attribute("bar", int, True, "A bar attribute.")]) cls.desc = Description({"bar": 1}, data_model=cls.foo_datamodel) msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=cls.request_id, service_description=cls.desc, service_id="") msg_bytes = OEFSerializer().encode(msg) cls.multiplexer.put( Envelope(to=DEFAULT_OEF, sender=cls.crypto1.public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes)) time.sleep(1.0) cls.request_id += 1 search_request = OEFMessage( oef_type=OEFMessage.Type.SEARCH_SERVICES, id=cls.request_id, query=Query([Constraint("bar", ConstraintType("==", 1))], model=cls.foo_datamodel)) cls.multiplexer.put( Envelope(to=DEFAULT_OEF, sender=cls.crypto1.public_key, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(search_request))) envelope = cls.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") == cls.request_id if search_result.get("agents") != [cls.crypto1.public_key]: logger.warning( 'search_result.get("agents") != [self.crypto1.public_key] FAILED in test_oef/test_communication.py' )
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 """ strategy = cast(Strategy, self.context.strategy) transactions = cast(Transactions, self.context.transactions) if strategy.is_registering_as_seller: logger.debug( "[{}]: Updating service directory as seller with goods supplied." .format(self.context.agent_name)) ownership_state_after_locks = transactions.ownership_state_after_locks( self.context.ownership_state, is_seller=True) goods_supplied_description = strategy.get_own_service_description( ownership_state_after_locks, is_supply=True) self._registered_goods_supplied_description = goods_supplied_description msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=DEFAULT_MSG_ID, service_description=goods_supplied_description, service_id="") msg_bytes = OEFSerializer().encode(msg) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes) if strategy.is_registering_as_buyer: logger.debug( "[{}]: Updating service directory as buyer with goods demanded." .format(self.context.agent_name)) ownership_state_after_locks = transactions.ownership_state_after_locks( self.context.ownership_state, is_seller=False) goods_demanded_description = strategy.get_own_service_description( ownership_state_after_locks, is_supply=False) self._registered_goods_demanded_description = goods_demanded_description msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=DEFAULT_MSG_ID, service_description=goods_demanded_description, service_id="") msg_bytes = OEFSerializer().encode(msg) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
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: 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( oef_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_public_key, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg)) if strategy.is_registering_as_buyer: 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( oef_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_public_key, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg))
def test_oef_message_OEFError(): """Tests the OEF_ERROR type of message.""" msg = OEFMessage(oef_type=OEFMessage.Type.OEF_ERROR, id=0, operation=OEFMessage.OEFErrorOperation.SEARCH_AGENTS) assert OEFMessage(oef_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 test_unregister_service_result(self): """Test that at the beginning, the search request returns an empty search result.""" data_model = DataModel("foobar", attributes=[]) service_description = Description({"foo": 1, "bar": "baz"}, data_model=data_model) msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=0, service_description=service_description, service_id="Test_service") msg_bytes = OEFSerializer().encode(msg) envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.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.OEF_ERROR msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=0, service_description=service_description, service_id="Test_Service") msg_bytes = OEFSerializer().encode(msg) envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes) self.multiplexer1.put(envelope) # Search for the register agent msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_AGENTS, id=0, query=Query([Constraint("foo", ConstraintType("==", 1))])) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.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.SEARCH_RESULT assert len(result.get("agents")) == 1 # unregister the service data_model = DataModel("foobar", attributes=[]) service_description = Description({"foo": 1, "bar": "baz"}, data_model=data_model) msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=0, service_description=service_description, service_id="Test_service") msg_bytes = OEFSerializer().encode(msg) envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes) self.multiplexer1.put(envelope) # the same query returns empty # Search for the register agent msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_AGENTS, id=0, query=Query([Constraint("foo", ConstraintType("==", 1))])) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.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.SEARCH_RESULT assert len(result.get("agents")) == 0
async def _search_services(self, public_key: str, 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 public_key: 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_public_key, descriptions in self.services.items(): for description in descriptions: if description.data_model == query.model: result.append(agent_public_key) msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_RESULT, id=search_id, agents=sorted(set(result))) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope(to=public_key, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes) await self._send(envelope)
async def _unregister_agent(self, public_key: str, msg_id: int, agent_description: Description) -> None: """ Unregister an agent. :param agent_description: :param public_key: the public key of the service agent to be unregistered. :param msg_id: the message id of the request. :return: None """ async with self._lock: if public_key not in self.agents: msg = OEFMessage( oef_type=OEFMessage.Type.OEF_ERROR, id=msg_id, operation=OEFMessage.OEFErrorOperation.UNREGISTER_AGENT) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope(to=public_key, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes) await self._send(envelope) else: self.agents[public_key].remove(agent_description) if len(self.agents[public_key]) == 0: self.agents.pop(public_key)
async def _handle_oef_message(self, envelope: Envelope) -> None: """Handle oef messages. :param envelope: the envelope :return: None """ oef_message = OEFSerializer().decode(envelope.message) sender = envelope.sender request_id = cast(int, oef_message.get("id")) oef_type = OEFMessage.Type(oef_message.get("type")) if oef_type == OEFMessage.Type.REGISTER_SERVICE: await self._register_service( sender, cast(Description, oef_message.get("service_description"))) elif oef_type == OEFMessage.Type.REGISTER_AGENT: await self._register_agent( sender, cast(Description, oef_message.get("agent_description"))) elif oef_type == OEFMessage.Type.UNREGISTER_SERVICE: await self._unregister_service( sender, request_id, cast(Description, oef_message.get("service_description"))) elif oef_type == OEFMessage.Type.UNREGISTER_AGENT: await self._unregister_agent( sender, request_id, cast(Description, oef_message.get("agent_description"))) elif oef_type == OEFMessage.Type.SEARCH_AGENTS: await self._search_agents(sender, request_id, cast(Query, oef_message.get("query"))) elif oef_type == OEFMessage.Type.SEARCH_SERVICES: await self._search_services(sender, request_id, cast(Query, oef_message.get("query"))) else: # request not recognized pass
def handle_oef_message(self, envelope: Envelope) -> None: """ Handle messages from the oef. The oef does not expect a response for any of these messages. :param envelope: the OEF message :return: None """ logger.debug( "[{}]: Handling OEF message. type={}".format( self.agent_name, type(envelope) ) ) assert envelope.protocol_id == "oef" msg = OEFSerializer().decode(envelope.message) if msg.get("type") == OEFMessage.Type.OEF_ERROR: self.on_oef_error(envelope) elif msg.get("type") == OEFMessage.Type.DIALOGUE_ERROR: self.on_dialogue_error(envelope) else: logger.warning( "[{}]: OEF Message type not recognized.".format(self.agent_name) )
def setup_class(cls): """Set up the test.""" cls.node = LocalNode() cls.public_key_1 = "mailbox1" cls.mailbox1 = MailBox(OEFLocalConnection(cls.public_key_1, cls.node)) cls.mailbox1.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( oef_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.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes) cls.mailbox1.send(envelope)
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 """ query = Query( [Constraint("version", GtEq(self.game_instance.expected_version_id))] ) search_id = self.game_instance.search.get_next_id() self.game_instance.search.ids_for_tac.add(search_id) msg = OEFMessage( oef_type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query ) msg_bytes = OEFSerializer().encode(msg) self.mailbox.outbox.put_message( to=DEFAULT_OEF, sender=self.crypto.public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes, )
def handle_envelope(self, envelope: Envelope) -> None: """ Implement the reaction to an envelope. :param envelope: the envelope :return: None """ msg = OEFSerializer().decode(envelope.message) msg_type = OEFMessage.Type(msg.get("type")) if msg_type is OEFMessage.Type.SEARCH_RESULT: agents = cast(List[str], msg.get("agents")) logger.info("[{}]: found agents={}".format(self.context.agent_name, agents)) for agent in agents: msg = FIPAMessage(message_id=STARTING_MESSAGE_ID, dialogue_id=self.dialogue_id, performative=FIPAMessage.Performative.CFP, target=STARTING_TARGET_ID, query=None) self.dialogue_id += 1 self.context.outbox.put_message( to=agent, sender=self.context.agent_public_key, protocol_id=FIPAMessage.protocol_id, message=FIPASerializer().encode(msg))
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(oef_type=OEFMessage.Type.OEF_ERROR, id=answer_id, operation=operation) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope(to=self.public_key, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes) asyncio.run_coroutine_threadsafe(self.in_queue.put(envelope), self.loop).result()
def setup_class(cls): """Set up the test.""" cls.node = LocalNode() cls.node.start() cls.public_key_1 = "multiplexer1" cls.public_key_2 = "multiplexer2" cls.multiplexer1 = Multiplexer([OEFLocalConnection(cls.public_key_1, cls.node)]) cls.multiplexer2 = Multiplexer([OEFLocalConnection(cls.public_key_2, cls.node)]) cls.multiplexer1.connect() cls.multiplexer2.connect() # register 'multiplexer1' as a service 'foobar'. request_id = 1 service_id = '' cls.data_model_foobar = DataModel("foobar", attributes=[]) service_description = Description({"foo": 1, "bar": "baz"}, data_model=cls.data_model_foobar) register_service_request = OEFMessage(oef_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.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes) cls.multiplexer1.put(envelope) time.sleep(1.0) # register 'multiplexer2' as a service 'barfoo'. cls.data_model_barfoo = DataModel("barfoo", attributes=[]) service_description = Description({"foo": 1, "bar": "baz"}, data_model=cls.data_model_barfoo) register_service_request = OEFMessage(oef_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.public_key_2, protocol_id=OEFMessage.protocol_id, message=msg_bytes) cls.multiplexer2.put(envelope) # unregister multiplexer1 data_model = DataModel("foobar", attributes=[]) service_description = Description({"foo": 1, "bar": "baz"}, data_model=data_model) msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=0, service_description=service_description, service_id="Test_service") msg_bytes = OEFSerializer().encode(msg) envelope = Envelope(to=DEFAULT_OEF, sender=cls.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes) cls.multiplexer1.put(envelope)
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(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=1, service_description=desc, service_id="") msg_bytes = OEFSerializer().encode(msg) assert len(msg_bytes) > 0
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(oef_type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=query) msg_bytes = OEFSerializer().encode(search_services_request) envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_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.public_key_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.public_key_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(oef_type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=query) msg_bytes = OEFSerializer().encode(search_services_request) envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_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.public_key_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.public_key_2]
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( oef_type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=search_query_empty_model) self.multiplexer.put( Envelope(to=DEFAULT_OEF, sender=self.crypto1.public_key, 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 test_on_dialogue_error(self): """Test the dialogue error.""" oef_connection = self.multiplexer1.connections[0] 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 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_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(oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=self.request_id, service_description=self.desc, service_id="") msg_bytes = OEFSerializer().encode(msg) self.mailbox1.outbox.put_message( to=DEFAULT_OEF, sender=self.crypto1.public_key, protocol_id=OEFMessage.protocol_id, message=msg_bytes) time.sleep(1.0) self.request_id += 1 search_request = OEFMessage( oef_type=OEFMessage.Type.SEARCH_SERVICES, id=self.request_id, query=Query([Constraint("bar", ConstraintType("==", 1))], model=self.foo_datamodel)) self.mailbox1.outbox.put_message( to=DEFAULT_OEF, sender=self.crypto1.public_key, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(search_request)) envelope = self.mailbox1.inbox.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") == []