Ejemplo n.º 1
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)
Ejemplo n.º 2
0
class DummyService(MessagingEnabled, BaseService):
    def __init__(self, conn, token):
        super(DummyService, self).__init__(auth_token=token, conn=conn)
        apis = [
            ServerAPI("api", "desc1", [
                ArgParameter("param", "d1", str),
            ], self.api),
            ServerAPI("number", "desc1", [
                ArgParameter("param", "d1", int),
            ], self.number),
            ServerAPI("exception", "desc1", [], self.exception),
        ]
        self.rpc_server = RPCServer("name", "desc", apis, self)
        dashboard_rpc_info = find_rpc(self, "b", "static_files")
        self.http_client = RPCClient(self.get_connection(), dashboard_rpc_info,
                                     self.get_auth_token())

    def number(self, param):
        return param + 1

    def api(self, param):
        return "API" + param

    def exception(self):
        raise ObjectNotFound("blah")

    def on_service_start(self):
        self.rpc_server.start()
        self.http_client.start()

    def on_service_stop(self):
        self.http_client.stop()
        self.rpc_server.stop()
Ejemplo n.º 3
0
class MessagingRegistrationHook(StateHook):
    def __init__(self, service: MessagingEnabled):
        self.service = service
        self.client: RPCClient = None

    def load(self, plugin_state: PluginState):
        rpc_info = find_rpc(self.service, MESSAGING_PLUGIN_URL, "app_manager")
        self.client = RPCClient(self.service.get_connection(), rpc_info,
                                self.service.get_auth_token())
        self.client.start()

        plugin_state.app_manager_client = self.client

        if plugin_state.enabled:
            self.on_activate(plugin_state)

    def stop(self):
        self.client.stop()

    def on_activate(self, state: PluginState):
        state.token = self.client["register_plugin"](state.name,
                                                     state.remote_url,
                                                     _block=True)

    def on_deactivate(self, plugin_state: PluginState):
        self.client["unregister_plugin"](plugin_state.remote_url, _block=True)
        plugin_state.token = None
Ejemplo n.º 4
0
 def start(self):
     rpc = self.service.rpc_client["rpc_info"]
     rpc_info = rpc("weaveserver.services.simpledb",
                    "object_store",
                    _block=True)
     self.db_rpc = RPCClient(self.conn, rpc_info, self.service.token)
     self.db_rpc.start()
Ejemplo n.º 5
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))
Ejemplo n.º 6
0
class AppDBConnection(object):
    def __init__(self, conn, service):
        self.conn = conn
        self.service = service
        self.db_rpc = None

    def start(self):
        rpc = self.service.rpc_client["rpc_info"]
        rpc_info = rpc("weaveserver.services.simpledb",
                       "object_store",
                       _block=True)
        self.db_rpc = RPCClient(self.conn, rpc_info, self.service.token)
        self.db_rpc.start()

    def stop(self):
        self.db_rpc.stop()

    def __getitem__(self, key):
        try:
            return self.db_rpc["query"](key, _block=True)
        except ObjectNotFound:
            raise KeyError(key)

    def __setitem__(self, key, value):
        self.db_rpc["insert"](key, value, _block=True)
Ejemplo n.º 7
0
    def load(self, plugin_state: PluginState):
        rpc_info = find_rpc(self.service, MESSAGING_PLUGIN_URL, "app_manager")
        self.client = RPCClient(self.service.get_connection(), rpc_info,
                                self.service.get_auth_token())
        self.client.start()

        plugin_state.app_manager_client = self.client

        if plugin_state.enabled:
            self.on_activate(plugin_state)
Ejemplo n.º 8
0
 def __init__(self, conn, token):
     super(DummyService, self).__init__(auth_token=token, conn=conn)
     apis = [
         ServerAPI("api", "desc1", [
             ArgParameter("param", "d1", str),
         ], self.api),
         ServerAPI("number", "desc1", [
             ArgParameter("param", "d1", int),
         ], self.number),
         ServerAPI("exception", "desc1", [], self.exception),
     ]
     self.rpc_server = RPCServer("name", "desc", apis, self)
     dashboard_rpc_info = find_rpc(self, "b", "static_files")
     self.http_client = RPCClient(self.get_connection(), dashboard_rpc_info,
                                  self.get_auth_token())
Ejemplo n.º 9
0
    def test_several_functions_invoke(self):
        info = self.service.rpc_server.info_message

        self.service.paused = True

        client = RPCClient(self.conn, info, self.test_token)
        client.start()
        api1 = client["api1"]
        api2 = client["api2"]

        res = []

        with ThreadPoolExecutor(max_workers=100) as exc:
            for i in range(20):
                future = exc.submit(api1,
                                    "iter",
                                    i,
                                    k3=i % 2 == 0,
                                    _block=True)
                expected = "iter{}{}".format(i, i % 2 == 0)
                res.append((future, expected))

                future = exc.submit(api2, _block=True)
                res.append((future, "API2"))

            time.sleep(5)
            self.service.paused = False

            for future, expected in res:
                assert future.result() == expected
            exc.shutdown()
        client.stop()
Ejemplo n.º 10
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()
Ejemplo n.º 11
0
def register_plugin(service, plugin):
    conn = service.get_connection()
    token = service.get_auth_token()

    # TODO: Find a find to get find_rpc(..) work for core system RPC too.
    rpc_info = find_rpc(service, None)
    client = RPCClient(conn, rpc_info, token)

    # TODO: Make InstalledPlugin, and RunnablePlugin have GitHub url in them.
    return client["register_plugin"](plugin.plugin_id(),
                                     plugin.name,
                                     plugin.src,
                                     _block=True)
Ejemplo n.º 12
0
    def handle_rpc(self, body):
        app_url = get_required_argument(body, 'app_url')
        rpc_name = get_required_argument(body, 'rpc_name')
        api_name = get_required_argument(body, 'api_name')
        args = get_required_argument(body, 'args')

        with self.clients_lock:
            client = self.clients.get((app_url, rpc_name), None)

        if not client:
            rpc_info = find_rpc(self.service, app_url, rpc_name)

        with self.clients_lock:
            client = self.clients.get((app_url, rpc_name), None)
            if not client:
                client = RPCClient(self.service.get_connection(), rpc_info,
                                   self.service.get_auth_token())
                client.start()
                self.clients[(app_url, rpc_name)] = client

        response = client[api_name](*args, _block=True)

        return response
Ejemplo n.º 13
0
    def test_server_function_invoke(self):
        info = self.service.rpc_server.info_message
        client = RPCClient(self.conn, info, self.test_token)
        client.start()

        res = client["api1"]("hello", 5, k3=False, _block=True)
        assert res == "hello5False"

        client.stop()
Ejemplo n.º 14
0
    def test_rpc_caller(self):
        info = self.service.rpc_server.info_message
        client = RPCClient(self.conn, info, self.test_token)
        client.start()

        res = client["api3"](_block=True)
        expected = {"app_name": "x", "app_url": "y", "app_type": "plugin"}
        assert res == expected

        client.stop()
Ejemplo n.º 15
0
    def test_api_with_exception(self):
        info = self.service.rpc_server.info_message
        client = RPCClient(self.conn, info, self.test_token)
        client.start()

        with pytest.raises(RemoteAPIError):
            client["exception"](_block=True)

        client["exception"]()  # Exception is not visible.

        client.stop()
Ejemplo n.º 16
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()
Ejemplo n.º 17
0
    def test_callback_rpc_invoke(self):
        info = self.service.rpc_server.info_message
        client = RPCClient(self.conn, info, self.test_token)
        client.start()

        event = Event()
        result = []

        def callback(res):
            result.append(extract_rpc_payload(res))
            event.set()

        client["api1"]("hello", 5, k3=False, _callback=callback)

        event.wait()

        assert result[0] == "hello5False"

        client.stop()
Ejemplo n.º 18
0
    def test_api_with_exception_callback(self):
        info = self.service.rpc_server.info_message
        client = RPCClient(self.conn, info, self.test_token)
        client.start()

        event = Event()
        result = []

        def callback(res):
            result.append(res)
            event.set()

        client["exception"](_callback=callback)

        event.wait()

        with pytest.raises(RemoteAPIError):
            extract_rpc_payload(result[0])

        client.stop()
Ejemplo n.º 19
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()
Ejemplo n.º 20
0
class HTTPResourceRegistrationHelper(object):
    def __init__(self, service):
        self.service = service
        self.rpc_client = None
        self.watchers = []

    def start(self):
        rpc_info = find_rpc(self.service, WEAVE_HTTP_URL, "static_files")
        self.rpc_client = RPCClient(self.service.get_connection(), rpc_info,
                                    self.service.get_auth_token())
        self.rpc_client.start()

    def stop(self):
        self.rpc_client.stop()

        for watcher in self.watchers:
            watcher.stop()

        for watcher in self.watchers:
            watcher.join()

    def register_content(self,
                         content,
                         rel_http_url,
                         block=True,
                         callback=None):
        param = b64encode(content).decode('ascii')
        return self.rpc_client["register"](rel_http_url,
                                           param,
                                           _block=block,
                                           _callback=callback)

    def register_file(self,
                      local_path,
                      relative_http_url,
                      block=True,
                      callback=None):
        with open(local_path, "rb") as inp:
            content = inp.read()
        return self.register_content(content,
                                     relative_http_url,
                                     block=block,
                                     callback=callback)

    def register_directory(self, local_path, relative_http_url):
        files_tuple = []
        for cur_folder, _, files in os.walk(local_path):
            for filename in files:
                cur_file = os.path.join(cur_folder, filename)
                files_tuple.append(
                    (cur_file, os.path.relpath(cur_file, local_path)))

        events = {}
        responses = {}
        response_lock = Lock()

        def make_callback(rel_path, event):
            def callback(response):
                with response_lock:
                    responses[rel_path] = response
                event.set()

            return callback

        for abs_path, rel_path in files_tuple:
            cur_rel_http_url = os.path.join(relative_http_url, rel_path)
            event = Event()
            events[rel_path] = event
            callback = make_callback(rel_path, event)
            self.register_file(abs_path,
                               cur_rel_http_url,
                               block=False,
                               callback=callback)

        base_rel_url = None
        for rel_path, event in events.items():
            event.wait()
            with response_lock:
                rel_url = extract_rpc_payload(responses[rel_path])

            if base_rel_url is None and rel_url.endswith(rel_path):
                base_rel_url = rel_url[:-len(rel_path)]

        return base_rel_url

    def unregister_url(self, url, block=True, callback=None):
        return self.rpc_client["unregister"](url,
                                             _block=block,
                                             _callback=callback)
Ejemplo n.º 21
0
    def test_api_with_dynamic_schema(self):
        info = self.service.rpc_server.info_message
        client = RPCClient(self.conn, info, self.test_token)
        client.start()

        assert client["callback"]("1", _block=True)
        client["change_param"]("hi,there", _block=True)

        client.stop()

        info = self.service.rpc_server.info_message
        client = RPCClient(self.conn, info, self.test_token)
        client.start()
        with pytest.raises(BadArguments):
            client["callback"]("1", _block=True)
        client.stop()

        client = RPCClient(self.conn, info, self.test_token)
        client.start()
        assert client["callback"]("hi", _block=True)
        assert client["callback"]("there", _block=True)
        client.stop()
Ejemplo n.º 22
0
 def start(self):
     rpc_info = find_rpc(self.service, WEAVE_HTTP_URL, "static_files")
     self.rpc_client = RPCClient(self.service.get_connection(), rpc_info,
                                 self.service.get_auth_token())
     self.rpc_client.start()
Ejemplo n.º 23
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()
Ejemplo n.º 24
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()