diff options
author | Russell Bryant <rbryant@redhat.com> | 2013-04-23 13:34:24 -0400 |
---|---|---|
committer | Russell Bryant <rbryant@redhat.com> | 2013-04-23 14:02:39 -0400 |
commit | 1a546c67ee94eef2260cd64e7fcb3fb0ed44b4f6 (patch) | |
tree | 0a4bfb8fc49e19f9efd43c66924d2d858d27b9a8 | |
parent | 98efba2dff8f67220595447728f69330089a3ebd (diff) | |
download | nova-1a546c67ee94eef2260cd64e7fcb3fb0ed44b4f6.tar.gz nova-1a546c67ee94eef2260cd64e7fcb3fb0ed44b4f6.tar.xz nova-1a546c67ee94eef2260cd64e7fcb3fb0ed44b4f6.zip |
Add an rpc API common to all services.
This patch adds an rpc API that is exposed by all services. The methods
in this API exist in their own namespace and are versioned independently
of the main API for the service.
The first method for this API is a simple ping() method. This method
exists in the conductor rpc API already, and could be more generally
useful. Other methods will be added in later patches.
The base rpc API will be exposed from all services automatically unless
they override the create_rpc_dispatcher method in the base manager
class. All services need to pass a service_name into the base manager
constructor. Some services already did this, but now it's needed for
all of them.
Implements blueprint base-rpc-api.
Change-Id: I02ab1970578bc53ba26461b533d06d1055c2d88e
-rw-r--r-- | nova/baserpc.py | 68 | ||||
-rw-r--r-- | nova/cells/manager.py | 3 | ||||
-rw-r--r-- | nova/cert/manager.py | 4 | ||||
-rw-r--r-- | nova/conductor/manager.py | 3 | ||||
-rw-r--r-- | nova/console/manager.py | 3 | ||||
-rw-r--r-- | nova/consoleauth/manager.py | 3 | ||||
-rw-r--r-- | nova/manager.py | 10 | ||||
-rw-r--r-- | nova/network/manager.py | 3 | ||||
-rw-r--r-- | nova/scheduler/manager.py | 3 | ||||
-rw-r--r-- | nova/tests/test_baserpc.py | 45 |
10 files changed, 136 insertions, 9 deletions
diff --git a/nova/baserpc.py b/nova/baserpc.py new file mode 100644 index 000000000..803a1b614 --- /dev/null +++ b/nova/baserpc.py @@ -0,0 +1,68 @@ +# +# Copyright 2013 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +""" +Base RPC client and server common to all services. +""" + +from nova.openstack.common import jsonutils +import nova.openstack.common.rpc.proxy as rpc_proxy + + +_NAMESPACE = 'baseapi' + + +class BaseAPI(rpc_proxy.RpcProxy): + """Client side of the base rpc API. + + API version history: + + 1.0 - Initial version. + """ + + # + # NOTE(russellb): This is the default minimum version that the server + # (manager) side must implement unless otherwise specified using a version + # argument to self.call()/cast()/etc. here. It should be left as X.0 where + # X is the current major API version (1.0, 2.0, ...). For more information + # about rpc API versioning, see the docs in + # openstack/common/rpc/dispatcher.py. + # + BASE_RPC_API_VERSION = '1.0' + + def __init__(self, topic): + super(BaseAPI, self).__init__(topic=topic, + default_version=self.BASE_RPC_API_VERSION) + self.namespace = _NAMESPACE + + def ping(self, context, arg, timeout=None): + arg_p = jsonutils.to_primitive(arg) + msg = self.make_namespaced_msg('ping', self.namespace, arg=arg_p) + return self.call(context, msg, timeout=timeout) + + +class BaseRPCAPI(object): + """Server side of the base RPC API.""" + + RPC_API_NAMESPACE = _NAMESPACE + RPC_API_VERSION = '1.0' + + def __init__(self, service_name): + self.service_name = service_name + + def ping(self, context, arg): + resp = {'service': self.service_name, 'arg': arg} + return jsonutils.to_primitive(resp) diff --git a/nova/cells/manager.py b/nova/cells/manager.py index 51d2f7cac..96e8ca8d8 100644 --- a/nova/cells/manager.py +++ b/nova/cells/manager.py @@ -68,7 +68,8 @@ class CellsManager(manager.Manager): def __init__(self, *args, **kwargs): # Mostly for tests. cell_state_manager = kwargs.pop('cell_state_manager', None) - super(CellsManager, self).__init__(*args, **kwargs) + super(CellsManager, self).__init__(service_name='cells', + *args, **kwargs) if cell_state_manager is None: cell_state_manager = cells_state.CellStateManager self.state_manager = cell_state_manager() diff --git a/nova/cert/manager.py b/nova/cert/manager.py index 3bbca0b53..a5f14fb69 100644 --- a/nova/cert/manager.py +++ b/nova/cert/manager.py @@ -33,6 +33,10 @@ from nova import manager class CertManager(manager.Manager): RPC_API_VERSION = '1.1' + def __init__(self, *args, **kwargs): + super(CertManager, self).__init__(service_name='cert', + *args, **kwargs) + def init_host(self): crypto.ensure_ca_filesystem() diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index e6ccba5d1..3713b1de9 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -52,7 +52,8 @@ class ConductorManager(manager.Manager): RPC_API_VERSION = '1.49' def __init__(self, *args, **kwargs): - super(ConductorManager, self).__init__(*args, **kwargs) + super(ConductorManager, self).__init__(service_name='conductor', + *args, **kwargs) self.security_group_api = ( openstack_driver.get_openstack_security_group_driver()) self._network_api = None diff --git a/nova/console/manager.py b/nova/console/manager.py index bd606a6ff..777f051bb 100644 --- a/nova/console/manager.py +++ b/nova/console/manager.py @@ -59,7 +59,8 @@ class ConsoleProxyManager(manager.Manager): if not console_driver: console_driver = CONF.console_driver self.driver = importutils.import_object(console_driver) - super(ConsoleProxyManager, self).__init__(*args, **kwargs) + super(ConsoleProxyManager, self).__init__(service_name='console', + *args, **kwargs) self.driver.host = self.host self.compute_rpcapi = compute_rpcapi.ComputeAPI() diff --git a/nova/consoleauth/manager.py b/nova/consoleauth/manager.py index 80a6d447f..18d75e68c 100644 --- a/nova/consoleauth/manager.py +++ b/nova/consoleauth/manager.py @@ -53,7 +53,8 @@ class ConsoleAuthManager(manager.Manager): RPC_API_VERSION = '1.2' def __init__(self, scheduler_driver=None, *args, **kwargs): - super(ConsoleAuthManager, self).__init__(*args, **kwargs) + super(ConsoleAuthManager, self).__init__(service_name='consoleauth', + *args, **kwargs) self.mc = memorycache.get_client() self.conductor_api = conductor_api.API() self.compute_rpcapi = compute_rpcapi.ComputeAPI() diff --git a/nova/manager.py b/nova/manager.py index d6a62c509..f2a0636d1 100644 --- a/nova/manager.py +++ b/nova/manager.py @@ -57,6 +57,7 @@ import datetime import eventlet from oslo.config import cfg +from nova import baserpc from nova.db import base from nova import exception from nova.openstack.common import log as logging @@ -195,12 +196,13 @@ class Manager(base.Base): # Set RPC API version to 1.0 by default. RPC_API_VERSION = '1.0' - def __init__(self, host=None, db_driver=None): + def __init__(self, host=None, db_driver=None, service_name='undefined'): if not host: host = CONF.host self.host = host self.load_plugins() self.backdoor_port = None + self.service_name = service_name super(Manager, self).__init__(db_driver) def load_plugins(self): @@ -213,7 +215,8 @@ class Manager(base.Base): If a manager would like to set an rpc API version, or support more than one class as the target of rpc messages, override this method. ''' - return rpc_dispatcher.RpcDispatcher([self]) + base_rpc = baserpc.BaseRPCAPI(self.service_name) + return rpc_dispatcher.RpcDispatcher([self, base_rpc]) def periodic_tasks(self, context, raise_on_error=False): """Tasks to be run at a periodic interval.""" @@ -292,7 +295,8 @@ class SchedulerDependentManager(Manager): self.last_capabilities = None self.service_name = service_name self.scheduler_rpcapi = scheduler_rpcapi.SchedulerAPI() - super(SchedulerDependentManager, self).__init__(host, db_driver) + super(SchedulerDependentManager, self).__init__(host, db_driver, + service_name) def load_plugins(self): pluginmgr = pluginmanager.PluginManager('nova', self.service_name) diff --git a/nova/network/manager.py b/nova/network/manager.py index 572aeda38..c910956d0 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -306,7 +306,8 @@ class NetworkManager(manager.Manager): l3_lib = kwargs.get("l3_lib", CONF.l3_lib) self.l3driver = importutils.import_object(l3_lib) - super(NetworkManager, self).__init__(*args, **kwargs) + super(NetworkManager, self).__init__(service_name='cells', + *args, **kwargs) def _import_ipam_lib(self, ipam_lib): self.ipam = importutils.import_module(ipam_lib).get_ipam_lib(self) diff --git a/nova/scheduler/manager.py b/nova/scheduler/manager.py index c6e1ed390..94438a2cd 100644 --- a/nova/scheduler/manager.py +++ b/nova/scheduler/manager.py @@ -63,7 +63,8 @@ class SchedulerManager(manager.Manager): if not scheduler_driver: scheduler_driver = CONF.scheduler_driver self.driver = importutils.import_object(scheduler_driver) - super(SchedulerManager, self).__init__(*args, **kwargs) + super(SchedulerManager, self).__init__(service_name='scheduler', + *args, **kwargs) def post_start_hook(self): """After we start up and can receive messages via RPC, tell all diff --git a/nova/tests/test_baserpc.py b/nova/tests/test_baserpc.py new file mode 100644 index 000000000..1e33fba67 --- /dev/null +++ b/nova/tests/test_baserpc.py @@ -0,0 +1,45 @@ +# +# Copyright 2013 - Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +""" +Test the base rpc API. +""" + +from oslo.config import cfg + +from nova import baserpc +from nova import context +from nova import test + +CONF = cfg.CONF + + +class BaseAPITestCase(test.TestCase): + + def setUp(self): + super(BaseAPITestCase, self).setUp() + self.user_id = 'fake' + self.project_id = 'fake' + self.context = context.RequestContext(self.user_id, + self.project_id) + self.conductor = self.start_service( + 'conductor', manager=CONF.conductor.manager) + self.compute = self.start_service('compute') + self.base_rpcapi = baserpc.BaseAPI(CONF.compute_topic) + + def test_ping(self): + res = self.base_rpcapi.ping(self.context, 'foo') + self.assertEqual(res, {'service': 'compute', 'arg': 'foo'}) |