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)
Ejemplo n.º 3
0
        async def run():

            # set the execption handler to None. This makes exception actually stop code execution instead of going unnoticed
            loop = asyncio.get_running_loop()
            loop.set_exception_handler(None)

            # connect to the NATS server
            self.nats_client = NatsHandler("default", host=self.nats_host, port=self.nats_port, user=self.nats_user,
                                           password=self.nats_password, api_host=self.api_host, api_port=self.api_port, loop=asyncio.get_running_loop())
            await self.nats_client.connect()

            # creating logger
            self._logger = NatsLoggerFactory.get_logger(
                self.nats_client, self.service_type)

            # retrieving initial shared_storage
            await self._load_config()

            # setting nats sender id
            self.nats_client.sender_id = self.sender_id

            # registering callbacks
            await self._register_callbacks()

            # execute startup callback
            if self._startup_callback:
                if len(signature(self._startup_callback).parameters) == 4:
                    # include kubernetes_client
                    await self._startup_callback(self.nats_client, self.shared_storage, self._logger, self.kubernetes_client)
                else:
                    await self._startup_callback(self.nats_client, self.shared_storage, self._logger)
Ejemplo n.º 4
0
 async def test_connect(self):
     """
     Testing whether connecting to the NATS server works.
     """
     loop = self._asyncioTestLoop
     nats = NatsHandler("test", "0.0.0.0", "4222", loop=loop, user="******", password="******")
     result = await nats.connect()
     self.assertTrue(result)
     await nats.disconnect()
Ejemplo n.º 5
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()
Ejemplo n.º 6
0
    async def test_subscribe(self):
        """
        Testing whether the subscription mechanism works properly and rejects invalid channel names
        """

        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")

        result = await nats.subscribe_callback("subscribe-test", callback)
        self.assertTrue(result)
        await nats.disconnect()
    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()
Ejemplo n.º 8
0
    async def test_retrieve_data_message(self):
        """
        Testing whether retrieving data from the internal table and creating a message works
        """
        loop = self._asyncioTestLoop
        nats = NatsHandler("test", "0.0.0.0", "4222", loop=loop, user="******", password="******")
        message = nats.create_message({
                        "testData": "This is a test"
                    }, MessageSchemas.TEST_MESSAGE)
        nats.data_table["someID"] = message
        self.assertEqual(len(nats.data_table), 1)
        new_message = await nats.retrieve_data_message("someID")
        self.assertEqual(message.data, new_message.data)
        self.assertEqual(len(nats.data_table), 0)

        with self.assertRaises(KeyError):
            new_message = await nats.retrieve_data_message("someID")
Ejemplo n.º 9
0
    async def test_unsubscribe(self):
        """
        Tests unsubscribing from a channel and whether invalid names get rejected
        """

        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")

        await nats.subscribe_callback("subscribe-test", callback)
        result = await nats.unsubscribe_callback("foo", callback)
        self.assertFalse(result)
        result = await nats.unsubscribe_callback("subscribe-test", callback)
        self.assertTrue(result)
        await nats.disconnect()
Ejemplo n.º 10
0
 async def test_create_message(self):
     """
     Testing whether message creation works.
     """
     loop = self._asyncioTestLoop
     nats = NatsHandler("test", "0.0.0.0", "4222", loop=loop, user="******", password="******")
     nats.time_sent = "2020-07-06"
     nats.sender_id = "1"
     message = nats.create_message({
                     "testData": "This is a test"
                 }, MessageSchemas.TEST_MESSAGE)
     self.assertEqual(message.sender_id, "1")
     self.assertEqual(message.time_sent, "2020-07-06")
     self.assertEqual(message.data, {
                     "testData": "This is a test"
                 })
     with self.assertRaises(ValidationError):
         message = nats.create_message({
                     "testData": "This is a test"
                 }, MessageSchemas.ORBIT_MESSAGE)
Ejemplo n.º 11
0
 async def test_check_status(self):
     loop = asyncio.get_running_loop()
     shared_storage = {
         "simulation": {
             "clock": True,
             "logging": False,
             "czml": False,
             "config": False
         },
         "cubesats": {
             "cubesat_1": {
                 "orbits": False,
                 "rl": False,
                 "rl_training": False,
                 "data": False,
                 "agriculture": False
             }
         },
         "groundstations": {
             "groundstation_1": {
                 "groundstation": False
             }
         },
         "iots": {
             "iot_1": {
                 "iot": False
             }
         },
         "config_path": "./simulation_config"
     }
     nats = NatsHandler("data1",
                        "0.0.0.0",
                        "4222",
                        loop=loop,
                        user="******",
                        password="******")
     await nats.connect()
     logger = FakeLogger()
     await check_status(nats, shared_storage, logger)
     self.assertTrue(shared_storage["simulation"]["clock"] == False)
Ejemplo n.º 12
0
        async def run():

            # set the execption handler to None. This makes exception actually stop code execution instead of going unnoticed
            loop = asyncio.get_running_loop()
            loop.set_exception_handler(None)

            # connect to the NATS server
            self.nats_client = NatsHandler("default",
                                           host=self.nats_host,
                                           port=self.nats_port,
                                           user=self.nats_user,
                                           password=self.nats_password,
                                           api_host=self.api_host,
                                           api_port=self.api_port,
                                           loop=asyncio.get_running_loop())
            await self.nats_client.connect()

            # creating logger
            self._logger = NatsLoggerFactory.get_logger(
                self.nats_client, self.service_type)

            # retrieving initial shared_storage
            if self.config_path is not None:

                # if a path to a config file is given, initializes from there
                with open(self.config_path, "r") as f:
                    config = json.load(f)

                # get own sender_id from config
                self.sender_id = config["sender_id"]

                # validate the shared_storage section of the config
                validate_json(config["shared_storage"], self._schema)
                self.shared_storage = config["shared_storage"]

                # write the shared storage and sender ID to Redis
                self.redis_client.set_shared_storage(self.shared_storage)
                self.redis_client.set_sender_id(self.sender_id)
                print(
                    f"Successfully initialized {self.sender_id} {self.service_type} from file"
                )
            else:
                try:
                    # requesting a config from the config service
                    message = self.nats_client.create_message(
                        self.service_type, MessageSchemas.SERVICE_TYPE_MESSAGE)
                    print(
                        f"Requesting config from config service for node {self.service_type}"
                    )
                    config_response = await self.nats_client.request_message(
                        "initialize.service",
                        message,
                        MessageSchemas.CONFIG_MESSAGE,
                        timeout=3)
                    print(f"Got config from config service: {config_response}")
                    print(f"Validating ...")

                    # validate the shared storage section of the config
                    validate_json(config_response.data["shared_storage"],
                                  self._schema)
                    self.sender_id = config_response.data["sender_id"]
                    self.shared_storage = config_response.data[
                        "shared_storage"]

                    # write the shared storage and sender ID to Redis
                    self.redis_client.set_sender_id(self.sender_id)
                    self.redis_client.set_shared_storage(self.shared_storage)
                    print(
                        f"Successfully initialized {self.sender_id} {self.service_type} from config service"
                    )
                except:
                    try:
                        # try initializing from redis
                        self.sender_id = self.redis_client.get_sender_id()
                        if not self.sender_id:
                            raise ValueError(
                                "Could not get sender id from redis")
                        self.shared_storage = self.redis_client.get_shared_storage(
                        )
                        print(
                            f"Successfully initialized {self.sender_id} {self.service_type} from redis"
                        )
                    except Exception as e:
                        raise ValueError(
                            f"Failed to initialize from redis. Aborting. Error: {e}"
                        )

            # setting nats sender id
            self.nats_client.sender_id = self.sender_id

            # registering callbacks
            await self._register_callbacks()

            # execute startup callback
            if self._startup_callback:
                await self._startup_callback(self.nats_client,
                                             self.shared_storage, self._logger)
Ejemplo n.º 13
0
    def run(self,
            nats_host="nats",
            nats_port="4222",
            nats_user=None,
            nats_password=None,
            api_host="127.0.0.1",
            api_port=8000,
            redis_host="redis",
            redis_port=6379,
            redis_password=None):
        """
        Runs the app with the REST API and NATS client running to train RL Model to create weights for unique simulation. Create a model and agent,
        and runs them in a loop. Interfaces with the OpenAI Gym environment when it is running, the environment then interfaces with the rest of the
        simulation through rl service. Saves the trained weights and models to be used in predict mode.

        Args:
            nats_host (str, optional): NATS server host. Defaults to "0.0.0.0".
            nats_port (str, optional): NATS server port. Defaults to "4222".
            nats_user (str, optional): NATS user. Defaults to "a".
            nats_password (str, optional): NATS password. Defaults to "b".
            api_host (str, optional): Host to run the REST API on. Defaults to "127.0.0.1".
            api_port (int, optional): Port to run the REST API on. Defaults to 8000.
            redis_host (str, optional): Host where Redis runs. Defaults to "redis".
            redis_port (int, optional): Port where Redis runs. Defaults to 6379.
            redis_password (str, optional): Password to acess Redis. Defaults to None.
        """
        # creating NATS client
        nats = NatsHandler("default",
                           host=nats_host,
                           user=nats_user,
                           password=nats_password)
        nats.loop.set_exception_handler(None)
        nats.loop.run_until_complete(nats.connect())

        # getting config from config service
        message = nats.create_message(self.service_type,
                                      MessageSchemas.SERVICE_TYPE_MESSAGE)
        config_response = nats.loop.run_until_complete(
            nats.request_message("initialize.service",
                                 message,
                                 MessageSchemas.CONFIG_MESSAGE,
                                 timeout=3))

        validate_json(config_response.data["shared_storage"], self.schema)
        sender_id = config_response.data["sender_id"]
        shared_storage = config_response.data["shared_storage"]

        nats.sender_id = sender_id

        ENV_NAME = 'SwarmEnv-v0'
        # Get the environment and extract the number of actions.
        env = gym.make(ENV_NAME, nats=nats)
        #np.random.seed(123)
        #env.seed(123)
        nb_actions = env.action_space.n

        # Next, we build a very simple model.
        model = Sequential()
        model.add(Flatten(input_shape=(1, env.observation_space.n)))
        model.add(Dense(8))
        model.add(Activation('relu'))
        model.add(Dense(8))
        model.add(Activation('relu'))
        model.add(Dense(8))
        model.add(Activation('relu'))
        model.add(Dense(nb_actions))
        model.add(Activation('linear'))
        print(model.summary())
        # Finally, we configure and compile our agent. You can use every built-in tensorflow.keras optimizer and
        # even the metrics!
        memory = SequentialMemory(limit=1000, window_length=1)
        policy = EpsGreedyQPolicy()
        dqn = DQNAgent(model=model,
                       nb_actions=nb_actions,
                       memory=memory,
                       nb_steps_warmup=5,
                       target_model_update=1e-2,
                       policy=policy)
        dqn.compile(Adam(lr=1e-3), metrics=['mae'])

        dqn.fit(env, nb_steps=500, visualize=True, verbose=2)

        #Save the weights and model
        dqn.save_weights(
            f"{shared_storage['weights_location']}/dqn_{ENV_NAME}_weights.h5f",
            overwrite=True)
        model.save(f"{shared_storage['model_location']}/dqn_{ENV_NAME}_model")
        dqn.test(env, nb_episodes=0, visualize=True)