Merge "Enhance GET networks performance of metaplugin"
This commit is contained in:
commit
8c994e6610
@ -36,6 +36,19 @@ from neutron.plugins.metaplugin.meta_models_v2 import (NetworkFlavor,
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Hooks used to select records which belong a target plugin.
|
||||
def _meta_network_model_hook(context, original_model, query):
|
||||
return query.outerjoin(NetworkFlavor,
|
||||
NetworkFlavor.network_id == models_v2.Network.id)
|
||||
|
||||
|
||||
def _meta_flavor_filter_hook(query, filters):
|
||||
if FLAVOR_NETWORK in filters:
|
||||
return query.filter(NetworkFlavor.flavor ==
|
||||
filters[FLAVOR_NETWORK][0])
|
||||
return query
|
||||
|
||||
|
||||
# Metaplugin Exceptions
|
||||
class FlavorNotFound(exc.NotFound):
|
||||
message = _("Flavor %(flavor)s could not be found")
|
||||
@ -111,6 +124,20 @@ class MetaPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
for method_name, flavor in extension_list:
|
||||
self.extension_map[method_name] = flavor
|
||||
|
||||
# Register hooks.
|
||||
# The hooks are applied for each target plugin instance when
|
||||
# calling the base class to get networks so that only records
|
||||
# which belong to the plugin are selected.
|
||||
#NOTE: Doing registration here (within __init__()) is to avoid
|
||||
# registration when merely importing this file. This is only
|
||||
# for running whole unit tests.
|
||||
db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook(
|
||||
models_v2.Network,
|
||||
'metaplugin_net',
|
||||
_meta_network_model_hook,
|
||||
None,
|
||||
_meta_flavor_filter_hook)
|
||||
|
||||
def _load_plugin(self, plugin_provider):
|
||||
LOG.debug(_("Plugin location: %s"), plugin_provider)
|
||||
plugin_klass = importutils.import_class(plugin_provider)
|
||||
@ -190,28 +217,24 @@ class MetaPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
del net['id']
|
||||
return net
|
||||
|
||||
def get_networks_with_flavor(self, context, filters=None,
|
||||
fields=None):
|
||||
collection = self._model_query(context, models_v2.Network)
|
||||
model = NetworkFlavor
|
||||
collection = collection.join(model,
|
||||
models_v2.Network.id == model.network_id)
|
||||
if filters:
|
||||
for key, value in filters.iteritems():
|
||||
if key == FLAVOR_NETWORK:
|
||||
column = NetworkFlavor.flavor
|
||||
else:
|
||||
column = getattr(models_v2.Network, key, None)
|
||||
if column:
|
||||
collection = collection.filter(column.in_(value))
|
||||
return [self._make_network_dict(c, fields) for c in collection]
|
||||
|
||||
def get_networks(self, context, filters=None, fields=None):
|
||||
nets = self.get_networks_with_flavor(context, filters, None)
|
||||
if filters:
|
||||
nets = self._filter_nets_l3(context, nets, filters)
|
||||
nets = [self.get_network(context, net['id'], fields)
|
||||
for net in nets]
|
||||
nets = []
|
||||
for flavor, plugin in self.plugins.items():
|
||||
if (filters and FLAVOR_NETWORK in filters and
|
||||
not flavor in filters[FLAVOR_NETWORK]):
|
||||
continue
|
||||
if filters:
|
||||
#NOTE: copy each time since a target plugin may modify
|
||||
# plugin_filters.
|
||||
plugin_filters = filters.copy()
|
||||
else:
|
||||
plugin_filters = {}
|
||||
plugin_filters[FLAVOR_NETWORK] = [flavor]
|
||||
plugin_nets = plugin.get_networks(context, plugin_filters, fields)
|
||||
for net in plugin_nets:
|
||||
if not fields or FLAVOR_NETWORK in fields:
|
||||
net[FLAVOR_NETWORK] = flavor
|
||||
nets.append(net)
|
||||
return nets
|
||||
|
||||
def _get_flavor_by_network_id(self, context, network_id):
|
||||
|
@ -14,6 +14,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
from neutron.tests.unit.metaplugin.test_metaplugin import setup_metaplugin_conf
|
||||
from neutron.tests.unit.metaplugin.test_metaplugin import unregister_meta_hooks
|
||||
from neutron.tests.unit import test_db_plugin as test_plugin
|
||||
from neutron.tests.unit import test_l3_plugin
|
||||
|
||||
@ -31,6 +32,7 @@ class MetaPluginV2DBTestCase(test_plugin.NeutronDbPluginV2TestCase):
|
||||
# same signature.
|
||||
setup_metaplugin_conf()
|
||||
ext_mgr = ext_mgr or test_l3_plugin.L3TestExtensionManager()
|
||||
self.addCleanup(unregister_meta_hooks)
|
||||
super(MetaPluginV2DBTestCase, self).setUp(
|
||||
plugin=self._plugin_name, ext_mgr=ext_mgr,
|
||||
service_plugins=service_plugins)
|
||||
|
@ -23,6 +23,8 @@ import testtools
|
||||
|
||||
from neutron import context
|
||||
from neutron.db import api as db
|
||||
from neutron.db import db_base_plugin_v2
|
||||
from neutron.db import models_v2
|
||||
from neutron.extensions.flavor import (FLAVOR_NETWORK, FLAVOR_ROUTER)
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.plugins.metaplugin.meta_neutron_plugin import FlavorNotFound
|
||||
@ -68,6 +70,13 @@ def setup_metaplugin_conf(has_l3=True):
|
||||
'neutron.openstack.common.rpc.impl_fake')
|
||||
|
||||
|
||||
# Hooks registered by metaplugin must not exist for other plugins UT.
|
||||
# So hooks must be unregistered (overwrite to None in fact).
|
||||
def unregister_meta_hooks():
|
||||
db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook(
|
||||
models_v2.Network, 'metaplugin_net', None, None, None)
|
||||
|
||||
|
||||
class MetaNeutronPluginV2Test(base.BaseTestCase):
|
||||
"""Class conisting of MetaNeutronPluginV2 unit tests."""
|
||||
|
||||
@ -82,6 +91,7 @@ class MetaNeutronPluginV2Test(base.BaseTestCase):
|
||||
|
||||
db.configure_db()
|
||||
self.addCleanup(db.clear_db)
|
||||
self.addCleanup(unregister_meta_hooks)
|
||||
|
||||
setup_metaplugin_conf(self.has_l3)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user