defined plugin API.
"""
raise NotImplementedError
+
+ def rpc_workers_supported(self):
+ """Return whether the plugin supports multiple RPC workers.
+
+ A plugin that supports multiple RPC workers should override the
+ start_rpc_listener method to ensure that this method returns True and
+ that start_rpc_listener is called at the appropriate time.
+ Alternately, a plugin can override this method to customize detection
+ of support for multiple rpc workers
+
+ .. note:: this method is optional, as it was not part of the originally
+ defined plugin API.
+ """
+ return (self.__class__.start_rpc_listener !=
+ NeutronPluginBaseV2.start_rpc_listener)
plugin_list = [plugin_set.split(':')
for plugin_set
in cfg.CONF.META.plugin_list.split(',')]
- rpc_flavor = cfg.CONF.META.rpc_flavor
+ self.rpc_flavor = cfg.CONF.META.rpc_flavor
topic_save = topics.PLUGIN
topic_fake = topic_save + '-metaplugin'
for flavor, plugin_provider in plugin_list:
# This enforces the plugin specified by rpc_flavor is only
# consumer of 'q-plugin'. It is a bit tricky but there is no
# bad effect.
- if rpc_flavor and rpc_flavor != flavor:
+ if self.rpc_flavor and self.rpc_flavor != flavor:
topics.PLUGIN = topic_fake
self.plugins[flavor] = self._load_plugin(plugin_provider)
topics.PLUGIN = topic_save
self.supported_extension_aliases += ['router', 'ext-gw-mode',
'extraroute']
- if rpc_flavor and rpc_flavor not in self.plugins:
+ if self.rpc_flavor and self.rpc_flavor not in self.plugins:
raise exc.Invalid(_('rpc_flavor %s is not plugin list') %
- rpc_flavor)
+ self.rpc_flavor)
self.extension_map = {}
if not cfg.CONF.META.extension_map == '':
flavor = self._get_flavor_by_network_id(context, network['id'])
network[ext_flavor.FLAVOR_NETWORK] = flavor
+ def start_rpc_listener(self):
+ return self.plugins[self.rpc_flavor].start_rpc_listener()
+
+ def rpc_workers_supported(self):
+ #NOTE: If a plugin which supports multiple RPC workers is desired
+ # to handle RPC, rpc_flavor must be specified.
+ return (self.rpc_flavor and
+ self.plugins[self.rpc_flavor].rpc_workers_supported())
+
def create_network(self, context, network):
n = network['network']
flavor = n.get(ext_flavor.FLAVOR_NETWORK)
from neutron.common import config
from neutron import context
from neutron import manager
-from neutron import neutron_plugin_base_v2
from neutron.openstack.common.db.sqlalchemy import session
from neutron.openstack.common import excutils
from neutron.openstack.common import importutils
# If 0 < rpc_workers then start_rpc_listener would be called in a
# subprocess and we cannot simply catch the NotImplementedError. It is
- # simpler to check this up front by testing whether the plugin overrides
- # start_rpc_listener.
- base = neutron_plugin_base_v2.NeutronPluginBaseV2
- if plugin.__class__.start_rpc_listener == base.start_rpc_listener:
+ # simpler to check this up front by testing whether the plugin supports
+ # multiple RPC workers.
+ if not plugin.rpc_workers_supported():
LOG.debug(_("Active plugin doesn't implement start_rpc_listener"))
if 0 < cfg.CONF.rpc_workers:
msg = _("'rpc_workers = %d' ignored because start_rpc_listener "
def fake_func2(self):
return 'fake2'
+
+ def start_rpc_listener(self):
+ # return value is only used to confirm this method was called.
+ return 'OK'
cfg.CONF.set_override('rpc_flavor', 'fake1', 'META')
self.plugin = MetaPluginV2()
self.assertEqual(topics.PLUGIN, 'q-plugin')
+ ret = self.plugin.rpc_workers_supported()
+ self.assertFalse(ret)
def test_invalid_rpc_flavor(self):
setup_metaplugin_conf()
self.assertRaises(exc.Invalid,
MetaPluginV2)
self.assertEqual(topics.PLUGIN, 'q-plugin')
+
+ def test_rpc_flavor_multiple_rpc_workers(self):
+ setup_metaplugin_conf()
+ cfg.CONF.set_override('rpc_flavor', 'fake2', 'META')
+ self.plugin = MetaPluginV2()
+ self.assertEqual(topics.PLUGIN, 'q-plugin')
+ ret = self.plugin.rpc_workers_supported()
+ self.assertTrue(ret)
+ ret = self.plugin.start_rpc_listener()
+ self.assertEqual('OK', ret)