예제 #1
0
    def setup_method(self):
        self.dummy_service = DummyMessagingService(MESSAGING_APP_TOKEN,
                                                   WeaveConnection.local())
        message_server_started = Event()
        app_registry = ApplicationRegistry([
            ("Test", TEST_URL, TEST_APP_TOKEN),
            ("MessagingServer", MESSAGING_SERVER_URL, MESSAGING_APP_TOKEN),
        ])
        channel_registry = ChannelRegistry(app_registry)

        synonym_registry = SynonymRegistry()
        self.message_server = MessageServer(PORT, app_registry,
                                            channel_registry, synonym_registry,
                                            message_server_started.set)
        self.message_server_thread = Thread(target=self.message_server.run)
        rpc_hub = MessagingRPCHub(self.dummy_service, channel_registry,
                                  app_registry, synonym_registry)

        self.message_server_thread.start()
        message_server_started.wait()
        self.dummy_service.start()
        rpc_hub.start()

        self.weave_service = DummyMessagingService(TEST_APP_TOKEN,
                                                   WeaveConnection.local())
        self.weave_service.start()

        self.appmgr_rpc_info = find_rpc(self.weave_service,
                                        MESSAGING_SERVER_URL, "app_manager")
    def test_queue_closure(self, queue_type, cookie):
        event = Event()
        test_app = Plugin("test", "test", "test-token")
        apps = ApplicationRegistry()
        registry = ChannelRegistry(apps)
        registry.create_queue("/fifo-closure", test_app, {"type": "string"},
                              {}, queue_type)

        server = MessageServer(11023, ApplicationRegistry(), registry,
                               SynonymRegistry(), event.set)
        thread = Thread(target=server.run)
        thread.start()
        event.wait()

        conn = WeaveConnection()
        conn.connect()

        def patch_receive(receiver, event):
            original = receiver.receive

            def receive():
                event.set()
                original()

            receiver.receive = receive

        def wrap_run(receiver):
            def run():
                try:
                    receiver.run()
                except:
                    pass

            return run

        e1 = Event()
        r1 = Receiver(conn, "/fifo-closure", cookie=next(cookie))
        r1.start()
        patch_receive(r1, e1)
        t1 = Thread(target=wrap_run(r1))
        t1.start()

        e2 = Event()
        r2 = Receiver(conn, "/fifo-closure", cookie=next(cookie))
        r2.start()
        patch_receive(r2, e2)
        t2 = Thread(target=wrap_run(r2))
        t2.start()

        e1.wait()
        e2.wait()

        server.shutdown()
        thread.join()
        t1.join()
        t2.join()
예제 #3
0
    def setup_class(cls):
        cls.messaging_service = MessagingService()
        cls.messaging_service.service_start()
        cls.messaging_service.wait_for_start(15)

        cls.conn = WeaveConnection.local()
        cls.conn.connect()

        cls.env_service = DummyEnvService(cls.messaging_service.test_token,
                                          cls.conn)

        rpc_info = find_rpc(cls.env_service, MESSAGING_PLUGIN_URL,
                            "app_manager")
        appmgr_client = RPCClient(cls.env_service.get_connection(), rpc_info,
                                  cls.env_service.get_auth_token())
        appmgr_client.start()

        http_token = appmgr_client["register_plugin"]("http",
                                                      WEAVE_HTTP_URL,
                                                      _block=True)
        dummy_token = appmgr_client["register_plugin"]("x", "y", _block=True)

        cls.http = ThreadedWeaveHTTPService(auth_token=http_token,
                                            plugin_dir="x",
                                            venv_dir="y",
                                            conn=cls.conn,
                                            started_token="")
        cls.http.service_start()
        cls.http.wait_for_start(15)

        cls.dummy_service = DummyService(cls.conn, dummy_token)
        cls.dummy_service.service_start()
        cls.dummy_service.wait_for_start(15)
예제 #4
0
    def test_register_queue(self):
        conn = WeaveConnection.local()
        conn.connect()
        client = RPCClient(conn, self.appmgr_rpc_info, TEST_APP_TOKEN)
        client.start()

        res = client["register_queue"]("test_queue/",
                                       "fifo", {
                                           "type": "string"
                                       }, [MESSAGING_SERVER_URL], [TEST_URL],
                                       _block=True)
        assert res == "/channels/{}/test_queue".format(TEST_URL)

        sender_no_auth = Sender(conn, res, auth=TEST_APP_TOKEN)
        sender_no_auth.start()
        with pytest.raises(Unauthorized):
            sender_no_auth.send("test")

        sender_auth = Sender(conn, res, auth=MESSAGING_APP_TOKEN)
        sender_auth.send("test")

        receiver_no_auth = Receiver(conn, res, auth=MESSAGING_APP_TOKEN)
        with pytest.raises(Unauthorized):
            receiver_no_auth.receive()

        receiver_auth = Receiver(conn, res, auth=TEST_APP_TOKEN)
        assert "test" == receiver_auth.receive().task

        client.stop()
예제 #5
0
    def __init__(self, **kwargs):
        super(CoreService, self).__init__(**kwargs)

        messaging_token = "app-token-" + str(uuid4())
        weave_env_token = kwargs.pop('auth_token')

        self.dummy_service = DummyMessagingService(messaging_token,
                                                   WeaveConnection.local())
        self.message_server_started = Event()
        self.shutdown_event = Event()

        app_registry = ApplicationRegistry([
            ("WeaveEnv", "https://github.com/HomeWeave/WeaveEnv.git",
             weave_env_token),
            ("MessagingServer", "https://github.com/HomeWeave/WeaveServer.git",
             messaging_token),
        ])
        channel_registry = ChannelRegistry(app_registry)
        synonym_registry = SynonymRegistry()

        self.message_server = MessageServer(PORT, app_registry,
                                            channel_registry, synonym_registry,
                                            self.message_server_started.set)
        self.message_server_thread = Thread(target=self.message_server.run)
        self.discovery_server = DiscoveryServer(PORT)
        self.discovery_server_thread = Thread(target=self.discovery_server.run)
        self.rpc_hub = MessagingRPCHub(self.dummy_service, channel_registry,
                                       app_registry, synonym_registry)
예제 #6
0
def handle_weave_launch():
    params = json.loads(sys.stdin.readline().strip())

    plugin_dir = params["plugin_dir"]
    os.chdir(plugin_dir)
    sys.path.append(plugin_dir)

    if params.get("venv_dir"):
        venv = VirtualEnvManager(params["venv_dir"])
        venv.activate()

    plugin_info = load_plugin_json(plugin_dir)

    if issubclass(plugin_info["service_cls"], MessagingEnabled):
        conn = WeaveConnection.discover()
        conn.connect()
        params["conn"] = conn

    app = plugin_info["service_cls"](**params)

    signal.signal(signal.SIGTERM, lambda x, y: app.on_service_stop())
    signal.signal(signal.SIGINT, lambda x, y: app.on_service_stop())

    app.before_service_start()
    app.on_service_start()
예제 #7
0
def handle_rpc():
    class FakeService(MessagingEnabled):
        def __init__(self, auth_token, conn):
            super(FakeService, self).__init__(auth_token=auth_token, conn=conn)

        def start(self):
            self.get_connection().connect()

    app_url = sys.argv[1]
    rpc_name = sys.argv[2]
    api_name = sys.argv[3]
    json_args = sys.argv[4]

    plugins_db = PluginsDatabase(os.path.join(get_config_path(), "db"))
    plugins_db.start()

    conn = WeaveConnection.discover()
    conn.connect()

    instance_data = get_instance_data()
    token = instance_data.app_token

    rpc_info = find_rpc(FakeService(token, conn), app_url, rpc_name)
    client = RPCClient(conn, rpc_info, token)
    client.start()

    print(
        json.dumps(client[api_name](*json.loads(json_args), _block=True),
                   indent=2))
예제 #8
0
    def start(self):
        self.plugin_manager.start()

        # Check if the messaging plugin is installed on any machine.
        try:
            messaging_db_plugin = PluginData.get(
                PluginData.app_url == MESSAGING_PLUGIN_URL)
        except DoesNotExist:
            print("No messaging plugin installed.")
            sys.exit(1)

        auth_token = self.instance_data.app_token
        if (messaging_db_plugin.machine.machine_id !=
                self.instance_data.machine_id):
            conn = WeaveConnection.discover()
        else:
            self.plugin_manager.load_plugin(messaging_db_plugin)
            self.plugin_manager.activate(MESSAGING_PLUGIN_URL, auth_token)
            conn = WeaveConnection.local()

        conn.connect()

        service = MessagingEnabled(auth_token=auth_token, conn=conn)

        self.registration_helper = PluginRegistrationHelper(service)
        self.registration_helper.start()

        plugin_tokens = []
        for plugin in self.instance_data.plugins:
            # We should have either started this above, or shouldn't be starting
            # at all.
            if plugin.app_url == MESSAGING_PLUGIN_URL:
                continue

            token = None
            if plugin.enabled:
                # TODO: try-except for register_plugin. Support loading plugin
                # in error state.
                token = self.registration_helper.register_plugin(plugin)

            plugin_tokens.append((plugin, token))

        self.plugin_manager.start_plugins(plugin_tokens)
        self.rpc_wrapper = PluginManagerRPCWrapper(self.plugin_manager,
                                                   self.registration_helper,
                                                   service, self.instance_data)
        self.rpc_wrapper.start()
예제 #9
0
    def start(self):
        # Insert basic data into the DB such as command-line access Data and
        # current machine data.
        # Check if the messaging plugin is installed any machine.
        try:
            messaging_db_plugin = get_plugin_by_url(MESSAGING_PLUGIN_URL)
        except ObjectNotFound:
            print("No messaging plugin installed.")
            sys.exit(1)

        auth_token = self.instance_data.app_token
        if (messaging_db_plugin.machine.machine_id !=
                self.instance_data.machine_id):
            conn = WeaveConnection.discover()
        else:
            messaging_plugin = load_plugin(messaging_db_plugin,
                                           self.plugin_manager,
                                           auth_token,
                                           ignore_hierarchy=True)
            self.plugin_manager.activate(messaging_plugin)
            conn = WeaveConnection.local()

        conn.connect()

        service = MessagingEnabled(auth_token=auth_token, conn=conn)
        self.rpc_server = RPCServer("WeaveEnv", "WeaveInstance Manager", [
            ServerAPI("list_plugins", "List plugins.", [], self.list_plugins),
            ServerAPI("activate_plugin", "Activate a plugin", [
                ArgParameter("plugin_id", "PluginID to activate", str),
            ], self.activate),
            ServerAPI("deactivate_plugin", "Deactivate a plugin", [
                ArgParameter("plugin_id", "PluginID to deactivate", str),
            ], self.deactivate),
            ServerAPI("install_plugin", "Install a plugin", [
                ArgParameter("plugin_url", "URL ending with .git.", str),
            ], self.install),
            ServerAPI("uninstall_plugin", "Uninstall a plugin", [
                ArgParameter("plugin_id", "PluginID to uninstall", str),
            ], self.uninstall),
        ], service)

        installed_plugins = load_installed_plugins(self.instance_data.plugins,
                                                   service,
                                                   self.plugin_manager)
        self.plugin_manager.start(installed_plugins)
        self.rpc_server.start()
예제 #10
0
    def setup_class(cls):
        cls.messaging_service = MessagingService()
        cls.messaging_service.service_start()
        cls.messaging_service.wait_for_start(15)

        cls.conn = WeaveConnection.local()
        cls.conn.connect()

        cls.fake_service = DummyEnvService(cls.messaging_service.test_token,
                                           cls.conn)
예제 #11
0
    def test_register_unregister_plugin(self):
        conn = WeaveConnection.local()
        conn.connect()
        client = RPCClient(conn, self.appmgr_rpc_info, TEST_APP_TOKEN)
        client.start()
        token = client["register_plugin"]("name", "url1", _block=True)
        assert token

        assert client["unregister_plugin"]("url1", _block=True)

        client.stop()
        conn.close()
예제 #12
0
    def test_queue_waits_removed_after_client_disconnects(self, queue_name):
        conn1 = WeaveConnection.local()
        conn2 = WeaveConnection.local()
        conn3 = WeaveConnection.local()
        conn1.connect()
        conn2.connect()
        conn3.connect()

        msgs1 = []
        sem1 = Semaphore(0)
        receiver1 = Receiver(conn1, queue_name, cookie="a")
        receiver1.on_message = make_receiver(1, msgs1, sem1, receiver1)
        receiver1.start()
        Thread(target=receiver1.run).start()

        msgs2 = []
        sem2 = Semaphore(0)
        receiver2 = Receiver(conn2, queue_name, cookie="b")
        receiver2.on_message = make_receiver(1, msgs2, sem2, receiver2)
        receiver2.start()
        Thread(target=receiver2.run).start()

        conn1.close()

        import time
        time.sleep(1)

        sender1 = Sender(conn3, queue_name)
        sender1.start()

        sender1.send("test", headers={"COOKIE": "b"})

        assert sem2.acquire(timeout=5)
        assert msgs2[-1] == "test"

        conn2.close()
        conn3.close()
예제 #13
0
    def test_register_as_non_system_app(self):
        conn = WeaveConnection.local()
        conn.connect()
        client = RPCClient(conn, self.appmgr_rpc_info, TEST_APP_TOKEN)
        client.start()
        token = client["register_plugin"]("name", "url1", _block=True)
        plugin_client = RPCClient(conn, self.appmgr_rpc_info, token)
        plugin_client.start()

        with pytest.raises(AuthenticationFailed):
            plugin_client["register_plugin"]("a", "b", _block=True)

        plugin_client.stop()
        client.stop()
        conn.close()
예제 #14
0
    def setup_class(cls):
        event = Event()

        schema = {
            "type": "object",
            "properties": {
                "foo": {
                    "type": "string"
                }
            },
            "required": ["foo"]
        }

        test_app = Plugin("test", "test", "test-token")
        apps = ApplicationRegistry()
        registry = ChannelRegistry(apps)
        registry.create_queue("/a.b.c", test_app, schema, {}, 'fifo')
        registry.create_queue("/test.sessionized", test_app,
                              {"type": "string"}, {}, 'sessionized')
        registry.create_queue("/test.sessionized2", test_app,
                              {"type": "string"}, {}, 'sessionized')
        registry.create_queue("/test.sessionized/several", test_app,
                              {"type": "string"}, {}, 'sessionized')
        registry.create_queue("/test.fifo/simple", test_app,
                              {"type": "string"}, {}, 'fifo')
        registry.create_queue("/test.fifo/test-disconnect", test_app,
                              {"type": "string"}, {}, 'fifo')
        registry.create_queue("/test.sessionized/test-disconnect", test_app,
                              {"type": "string"}, {}, 'sessionized')
        registry.create_queue('/multicast/1', test_app, {"type": "string"}, {},
                              'multicast')
        registry.create_queue('/multicast/2', test_app, {"type": "string"}, {},
                              'multicast')

        synonym_registry = SynonymRegistry()
        synonym_registry.register("/multi", "/multicast/2")

        cls.server = MessageServer(11023, apps, registry, synonym_registry,
                                   event.set)
        cls.server_thread = Thread(target=cls.server.run)
        cls.server_thread.start()
        event.wait()
        cls.conn = WeaveConnection.local()
        cls.conn.connect()
예제 #15
0
    def setup_class(cls):
        cls.messaging_service = MessagingService()
        cls.messaging_service.service_start()
        cls.messaging_service.wait_for_start(15)

        cls.conn = WeaveConnection.local()
        cls.conn.connect()

        cls.env_service = DummyEnvService(cls.messaging_service.test_token,
                                          cls.conn)

        rpc_info = find_rpc(cls.env_service, MESSAGING_PLUGIN_URL,
                            "app_manager")
        appmgr_client = RPCClient(cls.env_service.get_connection(), rpc_info,
                                  cls.env_service.get_auth_token())
        appmgr_client.start()

        # Register the DummyService used in the test cases.
        cls.test_token = appmgr_client["register_plugin"]("x",
                                                          "y",
                                                          _block=True)

        appmgr_client.stop()
예제 #16
0
    def test_register_rpc_with_whitelists(self):
        conn = WeaveConnection.local()
        conn.connect()
        client = RPCClient(conn, self.appmgr_rpc_info, TEST_APP_TOKEN)
        client.start()

        data = {
            "1": {
                "name": "name1",
                "url": "url1",
                "rpc_name": "rpc1",
                "allowed_requestors": []
            },
            "2": {
                "name": "name2",
                "url": "url2",
                "rpc_name": "rpc2",
                "allowed_requestors": ["url1"]
            },
            "3": {
                "name": "name3",
                "url": "url3",
                "rpc_name": "rpc3",
                "allowed_requestors": ["diff-url"]
            },
        }

        for info in data.values():
            info["token"] = client["register_plugin"](info["name"],
                                                      info["url"],
                                                      _block=True)

            service = DummyMessagingService(info["token"], conn)
            info["server"] = RPCServer(info["rpc_name"], "desc", [
                ServerAPI("name", "desc", [
                    ArgParameter("param", "desc", str),
                ], lambda x: x),
            ], service, info["allowed_requestors"])
            info["server"].start()

            info["rpc_info"] = find_rpc(service, info["url"], info["rpc_name"])

        allowed_requestors = [
            ("1", "2"),
            ("1", "1"),
            ("2", "1"),
            ("3", "1"),
        ]

        disallowed_requestors = [("1", "3"), ("2", "2"), ("2", "3"),
                                 ("3", "2"), ("3", "3")]

        for source, target in allowed_requestors:
            plugin_client = RPCClient(conn, data[target]["rpc_info"],
                                      data[source]["token"])
            plugin_client.start()
            assert plugin_client["name"]("x", _block=True) == "x"
            plugin_client.stop()

        for source, target in disallowed_requestors:
            plugin_client = RPCClient(conn, data[target]["rpc_info"],
                                      data[source]["token"])
            plugin_client.start()
            with pytest.raises(Unauthorized):
                plugin_client["name"]("x", _block=True)
            plugin_client.stop()

        for info in data.values():
            info["server"].stop()

        client.stop()
        conn.close()
예제 #17
0
def handle_discover():
    conn = WeaveConnection.discover()
    print(conn.default_host, conn.default_port)