]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Add support for multiple RPC workers under Metaplugin
authorItsuro Oda <oda@valinux.co.jp>
Wed, 2 Apr 2014 04:24:42 +0000 (13:24 +0900)
committerItsuro Oda <oda@valinux.co.jp>
Tue, 15 Apr 2014 04:29:27 +0000 (13:29 +0900)
Metaplugin needs a fix to support multiple RPC workers properly
because a plugin which supports multiple RPC workers cannot
initialize RPC connections at plugin initialization.

Closes-Bug: #1300570
Change-Id: I584f70abb8969054cd4edc8f914d00f6be930bab

neutron/neutron_plugin_base_v2.py
neutron/plugins/metaplugin/meta_neutron_plugin.py
neutron/service.py
neutron/tests/unit/metaplugin/fake_plugin.py
neutron/tests/unit/metaplugin/test_metaplugin.py

index 4f2ec3c69e6245deba054d8741851762cd97b433..67bd581c82f71a3add00e5d52976f89ce2737568 100644 (file)
@@ -335,3 +335,18 @@ class NeutronPluginBaseV2(object):
                   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)
index 04905132da2e507573aae988b8775751c8c0d381..1a2686f37193f0c10d76eac2cf522b25c0ee6e27 100644 (file)
@@ -95,7 +95,7 @@ class MetaPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
         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:
@@ -104,7 +104,7 @@ class MetaPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
             # 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
@@ -135,9 +135,9 @@ class MetaPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
             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 == '':
@@ -203,6 +203,15 @@ class MetaPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
         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)
index 754a68f905860220173eaddf745eb2a5fd8c886f..3258245d10f89a68e64c4b012e1bbd11c23875e3 100644 (file)
@@ -24,7 +24,6 @@ from oslo.config import cfg
 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
@@ -137,10 +136,9 @@ def serve_rpc():
 
     # 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 "
index 6653ea25b5f109a178f7c60e5a9b00096cd10979..0feaafc9ae6a2188327d64a62f02b81241749503 100644 (file)
@@ -70,3 +70,7 @@ class Fake2(Fake1):
 
     def fake_func2(self):
         return 'fake2'
+
+    def start_rpc_listener(self):
+        # return value is only used to confirm this method was called.
+        return 'OK'
index c413c65bc093b9988b02a82d6f43330980d6a29a..43fb761fc8dd6152a3c1399ad24e5f93ddc57ea1 100644 (file)
@@ -393,6 +393,8 @@ class MetaNeutronPluginV2TestRpcFlavor(base.BaseTestCase):
         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()
@@ -400,3 +402,13 @@ class MetaNeutronPluginV2TestRpcFlavor(base.BaseTestCase):
         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)