Пример #1
0
    def create_message(self, data, schema: dict = MessageSchemas.MESSAGE):
        """
        Create a new message instance pre populated with the sender_ID and time known  to the nats_handler. 
        Uses the data arg as value for the "data" field and validates on the provided schema. Raises an exception
        if the validation is unsuccessful.

        Args:
            data (dict): Data used to populate the "data" field of a message.
            schema (dict): Schema to validate the message

        Returns:
            Message: Message object populated with the data.
        """
        message_type = "unknown"
        time_sent = self.time_sent
        if not time_sent:
            time_sent = datetime.now().isoformat(timespec='milliseconds')
        if "name" in schema.keys():
            message_type = schema["name"]
        return Message.decode_json(
            {
                "sender_ID": self.sender_id,
                "origin_ID": self.sender_id,
                "message_type": message_type,
                "time_sent": time_sent,
                "data": data
            }, schema)
    async def test_publish(self):
        """
        Testing publishing to a channel
        """

        loop = self._asyncioTestLoop
        nats = NatsHandler("test",
                           "0.0.0.0",
                           "4222",
                           loop=loop,
                           user="******",
                           password="******")
        await nats.connect()

        message = Message.decode_json(
            {
                "sender_ID": "User",
                "time_sent": "2020-07-06",
                "data": {
                    "testData": "This is a test"
                }
            }, MessageSchemas.TEST_MESSAGE)

        result = await nats.send_message("subscribe-test", message)
        self.assertTrue(result)
        await nats.disconnect()
    async def test_send_data(self):
        """
        Testing whether sending data to a channel works.
        """

        loop = self._asyncioTestLoop
        nats = NatsHandler("test",
                           "0.0.0.0",
                           "4222",
                           loop=loop,
                           user="******",
                           password="******")
        await nats.connect()

        message = Message.decode_json(
            {
                "sender_ID": "User",
                "time_sent": "2020-07-06",
                "data": {
                    "testData": "This is a test"
                }
            }, MessageSchemas.TEST_MESSAGE)

        result = await nats.send_data("subscribe-test", message)
        self.assertTrue(result)
        await nats.disconnect()
        self.assertEqual(len(nats.data_table), 1)
Пример #4
0
    async def test_cubesat_X_attitude_provider(self):
        """
        Test for cubesat_X_attitude_provider() callback
        """
        # Creating variables that will be used as arguments for the callback
        loop = asyncio.get_running_loop()
        nats = utils.FakeNatsHandler("cubesat_2",
                                     "4222",
                                     loop=loop,
                                     user="******",
                                     password="******")
        await nats.connect()

        # Opening a file that contains a sample shared storage
        f = open("test_orbits_config.json")
        shared_storage = json.load(f)

        # Data that will be sent in the message
        data = {
            "sender_ID": "cubesat_2",
            "time_sent": "2020-07-05T09:51:49",
            "data": {
                "id": "cubesat_1",
                "attitude": "nadir_tracking",
                "time": "2022-12-02T03:00:00.000"
            }
        }

        message = Message.decode_json(data, MessageSchemas.ATTITUDE_MESSAGE)
        await orbit_service.cubesat_X_attitude_provider(
            message, nats, shared_storage, None)
        # Verifying that "cubesat_1"'s state was updated properly
        self.assertTrue(shared_storage["swarm"]["cubesat_1"]["orbit"]
                        ["attitude"] == message.data["attitude"])
Пример #5
0
                async def callback_wrapper(msg):

                    # try executing the callback and log if exception occurs
                    try:
                        # decode message and copy raw message to preserve the response channel name
                        raw_message = msg
                        msg = Message.decode_raw(msg.data, message_schema)

                        # temporarily copy shared storage, so callback cannot perform invalid changes
                        shared_storage = self.shared_storage.copy()

                        # execute callback
                        if len(signature(callback_function).parameters) == 5:
                            response = await callback_function(msg, self.nats_client, shared_storage, self._logger, self.kubernetes_client)
                        else:
                            response = await callback_function(msg, self.nats_client, shared_storage, self._logger)

                        # check whether the shared storage is still valid and set it if that is the case
                        if not validate_json(shared_storage, self._schema):
                            raise ValueError(
                                "Invalid change in shared storage")
                        self.shared_storage = shared_storage

                        # buffer the current shared storage in redis
                        self.redis_client.set_shared_storage(
                            self.shared_storage)

                        # send the response via NATS
                        await self.nats_client.send_message(raw_message.reply, response)
                    except Exception as e:
                        await self._logger.error(traceback.format_exc())
Пример #6
0
 def create_message(self, data, schema):
     """
     TODO
     """
     return Message.decode_json(
         {
             "sender_ID": self.sender_id,
             "time_sent": "sometime",
             "data": data
         }, schema)
Пример #7
0
    async def test_request_response(self):
        """
        Testing whether request response works and whether the callback is called.
        """

        loop = self._asyncioTestLoop
        loop.set_exception_handler(None)
        nats = NatsHandler("test", "0.0.0.0", "4222", loop=loop, user="******", password="******")
        await nats.connect()

        async def callback(msg):
            print("Got message")
            loop = self._asyncioTestLoop
            raw_message = msg
            msg = Message.decode_raw(msg.data, MessageSchemas.TEST_MESSAGE)
            print(msg)
            self.assertEqual(msg.encode_json(), {
                    "sender_ID": "User",
                    "origin_ID": "User",
                    "message_type": "test_message",
                    "time_sent": "2020-07-06",
                    "data": {
                        "testData": "This is a test"
                    }
                })
            await nats.send_message(raw_message.reply, msg)

        await nats.subscribe_callback("response-test", callback)

        message = Message.decode_json({
            "sender_ID": "User",
            "time_sent": "2020-07-06",
            "data": {
                "testData": "This is a test"
            }
        }, MessageSchemas.TEST_MESSAGE)

        response = await nats.request_message("response-test", message, MessageSchemas.TEST_MESSAGE, timeout=1)
        self.assertEqual(response.encode_json(), {
                    "sender_ID": "test",
                    "origin_ID": "User",
                    "message_type": "test_message",
                    "time_sent": "2020-07-06",
                    "data": {
                        "testData": "This is a test"
                    }
                })
        result = await nats.unsubscribe_callback("response-test", callback)
        self.assertTrue(result)
        await nats.disconnect()
Пример #8
0
 async def callback(msg):
     print("Got message")
     print(msg)
     self.assertEquals(Message.decode_raw(msg.data, MessageSchemas.TEST_MESSAGE).encode_json(), 
         {
             "sender_ID": "User",
             "time_sent": "2020-07-06",
             "data": {
                 "testData": "This is a test"
             }
         }
     )
     print("Is equal")
     raise ValueError("TEST")
    async def test_receive(self):
        """
        TODO: LOOK at first comment inside test--see if resolved yet
        
        Testing whether receiving actually works and whether the callback is called. Could not figure out yet
        how to assert within the callback. USE WITH CAUTION!! Must check the print output to see if the messages
        were actually received
        """
        # TODO: Figure out how to assert within the callback and check that it is called in the first place

        print("Starting")
        loop = self._asyncioTestLoop
        nats = NatsHandler("test",
                           "0.0.0.0",
                           "4222",
                           loop=loop,
                           user="******",
                           password="******")
        await nats.connect()

        async def callback(msg):
            print("Got message")
            print(msg)
            self.assertEquals(
                Message.decode_raw(msg.data,
                                   MessageSchemas.TEST_MESSAGE).encode_json(),
                {
                    "sender_ID": "User",
                    "time_sent": "2020-07-06",
                    "data": {
                        "testData": "This is a test"
                    }
                })
            print("Is equal")
            raise ValueError("TEST")

        await nats.subscribe_callback("subscribe-test", callback)

        message = Message.decode_json(
            {
                "sender_ID": "User",
                "time_sent": "2020-07-06",
                "data": {
                    "testData": "This is a test"
                }
            }, MessageSchemas.TEST_MESSAGE)
        await nats.send_message("subscribe-test", message)
        await nats.disconnect()
Пример #10
0
 async def callback(msg):
     print("Got message")
     loop = self._asyncioTestLoop
     raw_message = msg
     msg = Message.decode_raw(msg.data, MessageSchemas.TEST_MESSAGE)
     print(msg)
     self.assertEqual(msg.encode_json(), {
             "sender_ID": "User",
             "origin_ID": "User",
             "message_type": "test_message",
             "time_sent": "2020-07-06",
             "data": {
                 "testData": "This is a test"
             }
         })
     await nats.send_message(raw_message.reply, msg)
Пример #11
0
    async def request_message(self, topic, message, schema, timeout=1):
        """
        Sends a request to a channel and returns the response.

        Args:
            topic (string): channel name to publish to
            message (object): message to send
            schema (dict): Schema of the expected response
            timeout (int, optional): Timeout that limits how long to wait for a response. Defaults to 1.

        Returns:
            object: returns the response.
        """
        message = message.encode_raw()
        result = await self.nc.request(topic, message, timeout)
        return Message.decode_raw(result.data, schema)
Пример #12
0
            async def handle_api_message(message, nats, shared_storage, logger):

                # if a validator function was given, call it to determine whether the message should be processed
                if not validator or validator(message, nats, shared_storage, logger):
                    async with aiohttp.ClientSession() as session:

                        # construct the URL to access the data using the info from the API message
                        url = f"http://{message.data['host']}:{message.data['port']}{message.data['route']}/{message.data['data_id']}"
                        async with session.get(url) as response:

                            # check whether GET was successful
                            if response.status == 200:

                                # decode the message and execute the callback
                                msg = Message.decode_json(await response.json(), message_schema)
                                await callback_function(msg, self.nats_client, self.shared_storage, self._logger)
                                return
                            await self._logger.error(json.dumps(await response.json()))
Пример #13
0
    async def test_cubesat_state(self):
        """
        Test for cubesat_state() callback
        """
        # Creating variables that will be used as arguments for the callback
        loop = asyncio.get_running_loop()
        nats = FakeNatsHandler("cubesat_1",
                               "4222",
                               loop=loop,
                               user="******",
                               password="******")
        await nats.connect()

        # Opening a file that contains a sample shared storage
        f = open("test_orbits_config.json")
        shared_storage = json.load(f)

        # Updated state that will be sent
        state = {
            "cubesat_1": {
                "orbit": CONSTS.ORBIT_3,
                "last_update_time": "2022-12-02T03:00:00.000"
            }
        }

        # Data that will be sent in the message
        data = {
            "sender_ID": "cubesat_2",
            "time_sent": "2020-07-05T09:51:49",
            "data": {
                "id": "cubesat_1",
                "state": state
            }
        }

        message = Message.decode_json(data, MessageSchemas.STATE_MESSAGE)
        await orbit_service.cubesat_state(message, nats, shared_storage, None)
        # Verifying that cubesat_state() worked properly
        self.assertTrue(
            shared_storage["swarm"]["cubesat_1"] == state["cubesat_1"])
Пример #14
0
    async def test_simulation_timepulse_propagate(self):
        """
        Test the simulation_timepulse_propagate() callback
        """
        # Creating variables that will be used as arguments for the callback
        logger = FakeLogger()
        loop = asyncio.get_running_loop()
        nats = FakeNatsHandler("cubesat_1",
                               "4222",
                               loop=loop,
                               user="******",
                               password="******")
        await nats.connect()

        # opening a file that contains a sample shared storage
        f = open("test_orbits_config.json")
        shared_storage = json.load(f)

        # Testing the callback across mulitple timesteps
        for i in range(10, 59):
            # creating sample data
            data = {
                "sender_ID": "cubesat_2",
                "time_sent": "2021-12-05T00:" + str(i) + ":00.000",
                "data": {
                    "time": "2021-12-05T00:" + str(i) + ":00.000"
                }
            }

            orbit_1 = shared_storage["swarm"]["cubesat_1"]["orbit"]
            orbit_2 = shared_storage["swarm"]["cubesat_2"]["orbit"]

            attitude_provider_1 = {
                "type":
                "moving_body_tracking",
                "parameters":
                shared_storage["swarm"][shared_storage["swarm"]["cubesat_1"]
                                        ["orbit"]["attitude"]]["orbit"]
            }
            attitude_provider_2 = {
                "type":
                "moving_body_tracking",
                "parameters":
                shared_storage["swarm"][shared_storage["swarm"]["cubesat_2"]
                                        ["orbit"]["attitude"]]["orbit"]
            }

            message = Message.decode_json(data,
                                          MessageSchemas.TIMESTEP_MESSAGE)
            await orbit_service.simulation_timepulse_propagate(
                message, nats, shared_storage, logger)

            time = absolute_time_converter_utc_string(data["data"]["time"])

            # Creating propagators and attitude provider from orbit configuration of satellites
            propagator_1 = orekit_utils.analytical_propagator(orbit_1)
            propagator_2 = orekit_utils.analytical_propagator(orbit_2)
            attitude_provider_1 = orekit_utils.attitude_provider_constructor(
                attitude_provider_1["type"], attitude_provider_1["parameters"])
            attitude_provider_2 = orekit_utils.attitude_provider_constructor(
                attitude_provider_2["type"], attitude_provider_2["parameters"])

            # Setting attitude and propagating the orbit
            propagator_1.setAttitudeProvider(attitude_provider_1)
            propagator_2.setAttitudeProvider(attitude_provider_2)
            state_1 = propagator_1.propagate(time)
            state_2 = propagator_2.propagate(time)

            # Updating param
            cubesat_1_param = orekit_utils.get_keplerian_parameters(state_1)
            cubesat_1_param.update({"attitude": "cubesat_2"})
            cubesat_1_param.update({"frame": "EME"})
            cubesat_2_param = orekit_utils.get_keplerian_parameters(state_2)
            cubesat_2_param.update({"attitude": "cubesat_1"})
            cubesat_2_param.update({"frame": "EME"})

            # Checking to see if simulation_timestep_propagate updated params correctly
            self.assertTrue(shared_storage["swarm"]["cubesat_1"]["orbit"] ==
                            cubesat_1_param)
            self.assertTrue(shared_storage["swarm"]["cubesat_2"]["orbit"] ==
                            cubesat_2_param)
            self.assertTrue(shared_storage["swarm"]["cubesat_1"]["orbit"]
                            ["attitude"] == "cubesat_2")
            self.assertTrue(shared_storage["swarm"]["cubesat_2"]["orbit"]
                            ["attitude"] == "cubesat_1")
            print(shared_storage["swarm"]["cubesat_1"]["target_in_view"])
            print(shared_storage["swarm"]["cubesat_2"]["target_in_view"])
            # Making sure that phonebook gets updated properly
            if i <= 48:
                self.assertTrue(shared_storage["sat_phonebook"]["cubesat_2"])
                self.assertTrue(
                    shared_storage["swarm"]["cubesat_2"]["target_in_view"])
            else:
                self.assertFalse(shared_storage["sat_phonebook"]["cubesat_2"])
                self.assertFalse(
                    shared_storage["swarm"]["cubesat_2"]["target_in_view"])