示例#1
0
def test_fipa_propose_serialization():
    """Test that the serialization for the 'fipa' protocol works."""
    proposal = [
        Description({"foo1": 1, "bar1": 2}),
        Description({"foo2": 1, "bar2": 2}),
    ]
    msg = FIPAMessage(message_id=0,
                      dialogue_reference=(str(0), ''),
                      target=0,
                      performative=FIPAMessage.Performative.PROPOSE,
                      proposal=proposal)
    msg_bytes = FIPASerializer().encode(msg)
    envelope = Envelope(to="receiver",
                        sender="sender",
                        protocol_id=FIPAMessage.protocol_id,
                        message=msg_bytes)
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope == actual_envelope

    actual_msg = FIPASerializer().decode(actual_envelope.message)
    expected_msg = msg

    p1 = actual_msg.get("proposal")
    p2 = expected_msg.get("proposal")
    assert p1[0].values == p2[0].values
    assert p1[1].values == p2[1].values
    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
    def test_propose(self):
        """Test that a Propose can be sent correctly."""
        propose_empty = FIPAMessage(
            message_id=0,
            dialogue_id=0,
            target=0,
            performative=FIPAMessage.Performative.PROPOSE,
            proposal=[])
        self.mailbox1.outbox.put_message(
            to=self.crypto2.public_key,
            sender=self.crypto1.public_key,
            protocol_id=FIPAMessage.protocol_id,
            message=FIPASerializer().encode(propose_empty))
        envelope = self.mailbox2.inbox.get(block=True, timeout=2.0)
        expected_propose_empty = FIPASerializer().decode(envelope.message)
        assert expected_propose_empty == propose_empty

        propose_descriptions = FIPAMessage(
            message_id=0,
            dialogue_id=0,
            target=0,
            performative=FIPAMessage.Performative.PROPOSE,
            proposal=[
                Description({"foo": "bar"},
                            DataModel("foobar", [Attribute("foo", str, True)]))
            ])
        self.mailbox1.outbox.put_message(
            to=self.crypto2.public_key,
            sender=self.crypto1.public_key,
            protocol_id=FIPAMessage.protocol_id,
            message=FIPASerializer().encode(propose_descriptions))
        envelope = self.mailbox2.inbox.get(block=True, timeout=2.0)
        expected_propose_descriptions = FIPASerializer().decode(
            envelope.message)
        assert expected_propose_descriptions == propose_descriptions
        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]
示例#5
0
    def generate_proposal_and_data(
            self, query: Query
    ) -> Tuple[Description, Dict[str, List[Dict[str, Any]]]]:
        """
        Generate a proposal matching the query.

        :param query: the query
        :return: a tuple of proposal and the bytes of carpark data
        """
        assert (self.db.is_db_exits())

        data = self.db.get_latest_detection_data(1)
        assert (len(data) > 0)

        del data[0]['raw_image_path']
        del data[0]['processed_image_path']

        last_detection_time = data[0]["epoch"]
        max_spaces = data[0]["free_spaces"] + data[0]["total_count"]
        proposal = Description({
            "lat": data[0]["lat"],
            "lon": data[0]["lon"],
            "price": self.data_price_fet,
            "last_detection_time": last_detection_time,
            "max_spaces": max_spaces,
        })

        data[0]["price_fet"] = self.data_price_fet
        data[0]["message_type"] = "car_park_data"

        return proposal, data[0]
示例#6
0
    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)
示例#7
0
 def test_not_check(self):
     """Test the not().check function."""
     attribute_foo = Attribute("foo", int, True, "a foo attribute.")
     attribute_bar = Attribute("bar", str, True, "a bar attribute.")
     data_model_foobar = DataModel("foobar", [attribute_foo, attribute_bar], "A foobar data model.")
     description_foobar = Description({"foo": 1, "bar": "baz"}, data_model=data_model_foobar)
     no_constraint = Not(Constraint("foo", ConstraintType("==", 5)))
     assert no_constraint.check(description_foobar)
示例#8
0
    def get_service_description(self) -> Description:
        """
        Get the service description.

        :return: a description of the offered services
        """
        desc = Description(SCHEME, data_model=WEATHER_STATION_DATAMODEL())
        return desc
    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)
示例#10
0
 def test_pickable_description(self):
     """Test that an istance of the Description class is pickable."""
     attribute_foo = Attribute("foo", int, True, "a foo attribute.")
     attribute_bar = Attribute("bar", str, True, "a bar attribute.")
     data_model_foobar = DataModel("foobar", [attribute_foo, attribute_bar], "A foobar data model.")
     description_foobar = Description({"foo": 1, "bar": "baz"}, data_model=data_model_foobar)
     try:
         pickle.dumps(description_foobar)
     except Exception:
         pytest.fail("Error during pickling.")
示例#11
0
 def test_and_check(self):
     """Test the and().check function."""
     attribute_foo = Attribute("foo", int, True, "a foo attribute.")
     attribute_bar = Attribute("bar", str, True, "a bar attribute.")
     data_model_foobar = DataModel("foobar", [attribute_foo, attribute_bar], "A foobar data model.")
     description_foobar = Description({"foo": 1, "bar": "baz"}, data_model=data_model_foobar)
     constraint = And([(Constraint("foo", ConstraintType("==", 1))),
                       (Constraint("bar", ConstraintType("==", "baz")))
                       ])
     assert constraint.check(description_foobar)
示例#12
0
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
示例#13
0
 def test_description(self):
     """Test that the translation for the Description class works."""
     attribute_foo = Attribute("foo", int, True, "a foo attribute.")
     attribute_bar = Attribute("bar", str, True, "a bar attribute.")
     data_model_foobar = DataModel("foobar", [attribute_foo, attribute_bar], "A foobar data model.")
     description_foobar = Description({"foo": 1, "bar": "baz"}, data_model=data_model_foobar)
     oef_description = OEFObjectTranslator.to_oef_description(description_foobar)
     expected_description = OEFObjectTranslator.from_oef_description(oef_description)
     actual_description = description_foobar
     assert expected_description == actual_description
     m_desc = iter(description_foobar.values)
     assert next(m_desc) == "foo"
     assert {"foo", "bar"} == set(iter(description_foobar))
示例#14
0
        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'
                )
示例#15
0
    def handle_cfp(self, msg: FIPAMessage, sender: str, message_id: int,
                   dialogue_id: int) -> None:
        """
        Handle the CFP calls.

        :param msg: the message
        :param sender: the sender
        :param message_id: the message id
        :param dialogue_id: the dialogue id
        :return: None
        """
        new_message_id = message_id + 1
        new_target = message_id
        fetched_data = self.db.get_data_for_specific_dates(DATE_ONE, DATE_TWO)

        if len(fetched_data) >= 1:
            self.fetched_data = fetched_data
            total_price = self.fet_price * len(fetched_data)
            proposal = [
                Description({
                    "Rows": len(fetched_data),
                    "Price": total_price
                })
            ]
            logger.info(
                "[{}]: sending sender={} a proposal at price={}".format(
                    self.context.agent_name, sender, total_price))
            proposal_msg = FIPAMessage(
                message_id=new_message_id,
                dialogue_id=dialogue_id,
                target=new_target,
                performative=FIPAMessage.Performative.PROPOSE,
                proposal=proposal)
            self.context.outbox.put_message(
                to=sender,
                sender=self.context.agent_public_key,
                protocol_id=FIPAMessage.protocol_id,
                message=FIPASerializer().encode(proposal_msg))
        else:
            logger.info("[{}]: declined the CFP from sender={}".format(
                self.context.agent_name, sender))
            decline_msg = FIPAMessage(
                message_id=new_message_id,
                dialogue_id=dialogue_id,
                target=new_target,
                performative=FIPAMessage.Performative.DECLINE)
            self.context.outbox.put_message(
                to=sender,
                sender=self.context.agent_public_key,
                protocol_id=FIPAMessage.protocol_id,
                message=FIPASerializer().encode(decline_msg))
示例#16
0
    def test_search_agent(self):
        """Test the registered agents, we will not find any."""
        data_model = DataModel("foobar", attributes=[])
        agent_description = Description({"foo": 1, "bar": "baz"}, data_model=data_model)
        query = Query(constraints=[], model=data_model)

        # Register an agent
        msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_AGENT, id=0, agent_description=agent_description,
                         agent_id="Test_agent")
        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)

        time.sleep(0.1)

        # Search for the register agent
        msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_AGENTS, id=0, query=query)
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_2, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        self.multiplexer2.put(envelope)

        # check the result
        response_envelope = self.multiplexer2.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 len(result.get("agents")) == 1, "There are registered agents!"

        # Send unregister message.
        msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_AGENT, id=0, agent_description=agent_description,
                         agent_id="Test_agent")
        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)

        time.sleep(0.1)

        # Trigger error message.
        msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_AGENT, id=0, agent_description=agent_description,
                         agent_id="Unknown_Agent")
        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
示例#17
0
def build_goods_description(good_pbk_to_quantities: Dict[str, int],
                            is_supply: bool) -> Description:
    """
    Get the service description (good quantities supplied or demanded and their price).

    :param good_pbk_to_quantities: a dictionary mapping the public keys of the goods to the quantities.
    :param is_supply: True if the description is indicating supply, False if it's indicating demand.

    :return: the description to advertise on the Service Directory.
    """
    data_model = build_goods_datamodel(good_pbks=list(
        good_pbk_to_quantities.keys()),
                                       currency='FET',
                                       is_supply=is_supply)
    desc = Description(good_pbk_to_quantities, data_model=data_model)
    return desc
示例#18
0
 def test_query_check(self):
     """Test that the query.check() method works."""
     attribute_foo = Attribute("foo", int, True, "a foo attribute.")
     attribute_bar = Attribute("bar", str, True, "a bar attribute.")
     data_model_foobar = DataModel("foobar", [attribute_foo, attribute_bar], "A foobar data model.")
     description_foobar = Description({"foo": 1, "bar": "baz"}, data_model=data_model_foobar)
     query = Query([
         And([
             Or([
                 Not(Constraint("foo", ConstraintType("==", 1))),
                 Not(Constraint("bar", ConstraintType("==", "baz")))
             ]),
             Constraint("foo", ConstraintType("<", 2)),
         ])
     ],
         data_model_foobar)
     assert not query.check(description=description_foobar)
示例#19
0
def build_goods_description(good_pbk_to_quantities: Dict[str, int],
                            currency: str, is_supply: bool) -> Description:
    """
    Get the service description (good quantities supplied or demanded and their price).

    :param good_pbk_to_quantities: a dictionary mapping the public keys of the goods to the quantities.
    :param currency: the currency used for pricing and transacting.
    :param is_supply: True if the description is indicating supply, False if it's indicating demand.

    :return: the description to advertise on the Service Directory.
    """
    data_model = build_goods_datamodel(good_pbks=list(
        good_pbk_to_quantities.keys()),
                                       is_supply=is_supply)
    values = cast(Dict[str, Union[int, str]], good_pbk_to_quantities)
    values.update({'currency': currency})
    desc = Description(values, data_model=data_model)
    return desc
示例#20
0
    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)
        logger.info("[{}]: Registering TAC data model".format(self.context.agent_name))
        oef_msg = OEFMessage(oef_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_public_key,
                                        protocol_id=OEFMessage.protocol_id,
                                        message=OEFSerializer().encode(oef_msg))
        self._registered_desc = desc
示例#21
0
    def get_service_description(self) -> Description:
        """
        Get the service description.

        :return: a description of the offered services
        """
        assert (self.has_service_description())

        lat, lon = self.db.get_lat_lon()
        desc = Description(
            {
                "latitude": lat,
                "longitude": lon,
                "unique_id": self.context.agent_public_key
            },
            data_model=CarParkDataModel())

        return desc
示例#22
0
    def register_tac(self) -> None:
        """
        Register on the OEF as a TAC controller agent.

        :return: None.
        """
        desc = Description({"version": self.tac_version_id},
                           data_model=CONTROLLER_DATAMODEL)
        logger.debug("[{}]: Registering with {} data model".format(
            self.agent_name, desc.data_model.name))
        msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE,
                         id=1,
                         service_description=desc,
                         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)
示例#23
0
    def act(self) -> None:
        """
        Implement the act.

        :return: None
        """
        if not self.registered:
            desc = Description(self.scheme, data_model=self.data_model)
            msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE,
                             id=REGISTER_ID,
                             service_description=desc,
                             service_id=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)
            logger.info("[{}]: registered! My public key is : {}".format(self.context.agent_name, self.context.agent_public_key))
            self.registered = True
示例#24
0
def get_goods_quantities_description(
    good_pbks: List[str], good_quantities: List[int], is_supply: bool
) -> Description:
    """
    Get the TAC description for supply or demand.

    That is, a description with the following structure:
    >>> description = {
    ...     "tac_good_0": 1,
    ...     "tac_good_1": 0,
    ...     #...
    ...
    ... }
    >>>

     where the keys indicate the good_pbk and the values the quantity.

     >>> desc = get_goods_quantities_description(['tac_good_0', 'tac_good_1', 'tac_good_2', 'tac_good_3'], [0, 0, 1, 2], True)
     >>> desc.data_model.name == TAC_SUPPLY_DATAMODEL_NAME
     True
     >>> desc.values == {
     ...    "tac_good_0": 0,
     ...    "tac_good_1": 0,
     ...    "tac_good_2": 1,
     ...    "tac_good_3": 2}
     ...
     True

    :param good_pbks: the public keys of the goods.
    :param good_quantities: the quantities per good.
    :param is_supply: True if the description is indicating supply, False if it's indicating demand.

    :return: the description to advertise on the Service Directory.
    """
    data_model = build_datamodel(good_pbks, is_supply=is_supply)
    desc = Description(
        {good_pbk: quantity for good_pbk, quantity in zip(good_pbks, good_quantities)},
        data_model=data_model,
    )
    return desc
示例#25
0
    def generate_proposal_and_data(
            self, query: Query
    ) -> Tuple[Description, Dict[str, List[Dict[str, Any]]]]:
        """
        Generate a proposal matching the query.

        :param query: the query
        :return: a tuple of proposal and the weather data
        """
        fetched_data = self.db.get_data_for_specific_dates(
            self._date_one, self._date_two)  # TODO: fetch real data
        weather_data, rows = self._build_data_payload(fetched_data)
        total_price = self._price_per_row * rows
        assert total_price - self._seller_tx_fee > 0, "This sale would generate a loss, change the configs!"
        proposal = Description({
            "rows": rows,
            "price": total_price,
            "seller_tx_fee": self._seller_tx_fee,
            "currency_pbk": self._currency_pbk,
            "ledger_id": self._ledger_id
        })
        return (proposal, weather_data)
示例#26
0
def test_oef_message_consistency():
    """Tests the consistency of an OEFMessage."""
    foo_datamodel = DataModel(
        "foo", [Attribute("bar", int, True, "A bar attribute.")])
    msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_AGENTS,
                     id=2,
                     query=Query([Constraint("bar", ConstraintType("==", 1))],
                                 model=foo_datamodel))
    assert msg.check_consistency(), "We expect the consistency to return TRUE"
    with mock.patch("aea.protocols.oef.message.OEFMessage.Type")\
            as mock_type_enum:
        mock_type_enum.SEARCH_AGENTS.value = "unknown"
        assert not msg.check_consistency(),\
            "Expect the consistency to return False"

    attribute_foo = Attribute("foo", int, True, "a foo attribute.")
    attribute_bar = Attribute("bar", str, True, "a bar attribute.")
    data_model_foobar = DataModel("foobar", [attribute_foo, attribute_bar],
                                  "A foobar data model.")
    description_foobar = Description({
        "foo": 1,
        "bar": "baz"
    },
                                     data_model=data_model_foobar)
    msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_AGENT,
                     id=0,
                     agent_description=description_foobar,
                     agent_id="public_key")
    assert msg.check_consistency()

    msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_AGENT,
                     id=0,
                     agent_description=description_foobar,
                     agent_id="public_key")

    assert msg.check_consistency()
示例#27
0
 def from_oef_description(cls, oef_desc: OEFDescription) -> Description:
     """From an OEF description to our description."""
     data_model = cls.from_oef_data_model(
         oef_desc.data_model) if oef_desc.data_model is not None else None
     return Description(oef_desc.values, data_model=data_model)