def decode(self, obj: bytes) -> Message: """ Decode the message. :param obj: the bytes object :return: the message """ json_msg = json.loads(obj.decode("utf-8")) oef_type = OEFMessage.Type(json_msg["type"]) new_body = copy.copy(json_msg) new_body["type"] = oef_type if oef_type in { OEFMessage.Type.REGISTER_SERVICE, OEFMessage.Type.UNREGISTER_SERVICE }: service_description_bytes = base64.b64decode( json_msg["service_description"]) service_description = pickle.loads(service_description_bytes) new_body["service_description"] = service_description elif oef_type in { OEFMessage.Type.SEARCH_SERVICES, OEFMessage.Type.SEARCH_AGENTS }: query_bytes = base64.b64decode(json_msg["query"]) query = pickle.loads(query_bytes) new_body["query"] = query elif oef_type in {OEFMessage.Type.SEARCH_RESULT}: new_body["agents"] = list(json_msg["agents"]) elif oef_type in {OEFMessage.Type.OEF_ERROR}: operation = json_msg["operation"] new_body["operation"] = OEFMessage.OEFErrorOperation( int(operation)) oef_message = OEFMessage(oef_type=oef_type, body=new_body) return oef_message
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))
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(self, message: Message, sender: str) -> None: """ Implement the reaction to a message. :param message: the message :param sender: the sender :return: None """ # convenience representations oef_msg = cast(OEFMessage, message) oef_msg_type = OEFMessage.Type(oef_msg.get("type")) if oef_msg_type is OEFMessage.Type.SEARCH_RESULT: agents = cast(List[str], oef_msg.get("agents")) search_id = cast(int, oef_msg.get("id")) search = cast(Search, self.context.search) if self.context.agent_public_key in agents: agents.remove(self.context.agent_public_key) if search_id in search.ids_for_sellers: self._handle_search(agents, search_id, is_searching_for_sellers=True) elif search_id in search.ids_for_buyers: self._handle_search(agents, search_id, is_searching_for_sellers=False)
def encode(self, msg: Message) -> bytes: """ Decode the message. :param msg: the message object :return: the bytes """ oef_type = OEFMessage.Type(msg.get("type")) new_body = copy.copy(msg.body) new_body["type"] = oef_type.value if oef_type in {OEFMessage.Type.REGISTER_SERVICE, OEFMessage.Type.UNREGISTER_SERVICE}: service_description = msg.body["service_description"] # type: Description service_description_bytes = base64.b64encode(pickle.dumps(service_description)).decode("utf-8") new_body["service_description"] = service_description_bytes elif oef_type in {OEFMessage.Type.REGISTER_AGENT, OEFMessage.Type.UNREGISTER_AGENT}: agent_description = msg.body["agent_description"] # type: Description agent_description_bytes = base64.b64encode(pickle.dumps(agent_description)).decode("utf-8") new_body["agent_description"] = agent_description_bytes elif oef_type in {OEFMessage.Type.SEARCH_SERVICES, OEFMessage.Type.SEARCH_AGENTS}: query = msg.body["query"] # type: Query query_bytes = base64.b64encode(pickle.dumps(query)).decode("utf-8") new_body["query"] = query_bytes elif oef_type in {OEFMessage.Type.SEARCH_RESULT}: # we need this cast because the "agents" field might contains # the Protobuf type "RepeatedScalarContainer", which is not JSON serializable. new_body["agents"] = list(msg.body["agents"]) elif oef_type in {OEFMessage.Type.OEF_ERROR}: operation = msg.body["operation"] new_body["operation"] = str(operation) oef_message_bytes = json.dumps(new_body).encode("utf-8") return oef_message_bytes
def handle(self, message: Message, sender: str) -> None: """ Implement the reaction to a message. :param message: the message :param sender: the sender :return: None """ # convenience representations oef_msg = cast(OEFMessage, message) oef_msg_type = OEFMessage.Type(oef_msg.get("type")) if oef_msg_type is OEFMessage.Type.SEARCH_RESULT: agents = cast(List[str], oef_msg.get("agents")) self._handle_search(agents)
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_type = OEFMessage.Type(oef_message.get("type")) oef_msg_id = cast(int, oef_message.get("id")) if oef_type == OEFMessage.Type.REGISTER_SERVICE: service_description = cast(Description, oef_message.get("service_description")) service_id = cast(int, oef_message.get("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 = cast(Description, oef_message.get("service_description")) service_id = cast(int, oef_message.get("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 = cast(Query, oef_message.get("query")) oef_query = OEFObjectTranslator.to_oef_query(query) self.search_agents(oef_msg_id, oef_query) elif oef_type == OEFMessage.Type.SEARCH_SERVICES: query = cast(Query, oef_message.get("query")) oef_query = OEFObjectTranslator.to_oef_query(query) self.mail_stats.search_start(oef_msg_id) self.search_services(oef_msg_id, oef_query) else: raise ValueError("OEF request not recognized.")