Decouple hook and func registration from CommonDbMixin

Move the model query hook registration and resource extend funcs
registration methods out of the CommonDbMixin class and make them
regular utility functions.

This is a step in refactoring the CommonDbMixin class.

Change-Id: Iec1bb7f7098c83640ae695fd7cf2f4736f414ad2
This commit is contained in:
Henry Gessau 2016-10-14 23:52:55 -04:00
parent fbe8f9eddb
commit e7cd868c20
32 changed files with 284 additions and 134 deletions

125
neutron/db/_model_query.py Normal file
View File

@ -0,0 +1,125 @@
# 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.
"""
NOTE: This module shall not be used by external projects. It will be moved
to neutron-lib in due course, and then it can be used from there.
"""
from neutron.common import utils
# Classes implementing extensions will register hooks into this dictionary
# for "augmenting" the "core way" of building a query for retrieving objects
# from a model class. Hooks are registered by invoking register_hook().
_model_query_hooks = {
# model1 : {
# hook1: {
# 'query': query_hook,
# 'filter': filter_hook,
# 'result_filters': result_filters
# },
# hook2: {
# 'query': query_hook,
# 'filter': filter_hook,
# 'result_filters': result_filters
# },
# ...
# },
# model2 : {
# hook1: {
# 'query': query_hook,
# 'filter': filter_hook,
# 'result_filters': result_filters
# },
# hook2: {
# 'query': query_hook,
# 'filter': filter_hook,
# 'result_filters': result_filters
# },
# ...
# },
# ...
}
def register_hook(model, name, query_hook, filter_hook,
result_filters=None):
"""Register a hook to be invoked when a query is executed.
:param model: The DB Model that the hook applies to.
:type model: sqlalchemy orm model
:param name: A name for the hook.
:type name: str
:param query_hook: The method to be called to augment the query.
:type query_hook: callable or None
:param filter_hook: A method to be called to augment the query filter.
:type filter_hook: callable or None
:param result_filters: A Method to be called to filter the query result.
:type result_filters: callable or None
Adds the hook components to the _model_query_hooks dict. Models are the
keys of this dict, whereas the value is another dict mapping hook names
to callables performing the hook.
Each hook has three components:
"query", used to build the query expression
"filter", used to build the filter expression
"result_filters", used for final filtering on the query result
Query hooks take as input the query being built and return a
transformed query expression.
def mymodel_query_hook(context, original_model, query):
augmented_query = ...
return augmented_query
Filter hooks take as input the filter expression being built and return
a transformed filter expression
def mymodel_filter_hook(context, original_model, filters):
refined_filters = ...
return refined_filters
Result filter hooks take as input the query expression and the filter
expression, and return a final transformed query expression.
def mymodel_result_filter_hook(query, filters):
final_filters = ...
return query.filter(final_filters)
"""
if callable(query_hook):
query_hook = utils.make_weak_ref(query_hook)
if callable(filter_hook):
filter_hook = utils.make_weak_ref(filter_hook)
if callable(result_filters):
result_filters = utils.make_weak_ref(result_filters)
_model_query_hooks.setdefault(model, {})[name] = {
'query': query_hook,
'filter': filter_hook,
'result_filters': result_filters
}
def get_hooks(model):
"""Retrieve the model query hooks for a model.
:param model: The DB Model to look up for query hooks.
:type model: sqlalchemy orm model
:return: list of hooks
:rtype: list of dict of callable
"""
return _model_query_hooks.get(model, {}).values()

View File

@ -0,0 +1,61 @@
# 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.
"""
NOTE: This module shall not be used by external projects. It will be moved
to neutron-lib in due course, and then it can be used from there.
"""
from neutron.common import utils
# This dictionary will store methods for extending API resources.
# Extensions can add their own methods by invoking register_funcs().
_resource_extend_functions = {
# <resource1> : [<func1>, <func2>, ...],
# <resource2> : [<func1>, <func2>, ...],
# ...
}
def register_funcs(resource, funcs):
"""Add functions to extend a resource.
:param resource: A resource collection name.
:type resource: str
:param funcs: A list of functions.
:type funcs: list of callable
These functions take a resource dict and a resource object and
update the resource dict with extension data (possibly retrieved
from the resource db object).
def _extend_foo_with_bar(foo_res, foo_db):
foo_res['bar'] = foo_db.bar_info # example
return foo_res
"""
funcs = [utils.make_weak_ref(f) if callable(f) else f
for f in funcs]
_resource_extend_functions.setdefault(resource, []).extend(funcs)
def get_funcs(resource):
"""Retrieve a list of functions extending a resource.
:param resource: A resource collection name.
:type resource: str
:return: A list (possibly empty) of functions extending resource.
:rtype: list of callable
"""
return _resource_extend_functions.get(resource, [])

View File

@ -17,9 +17,9 @@ from oslo_utils import uuidutils
from neutron._i18n import _
from neutron.api.v2 import attributes as attr
from neutron.db import _resource_extend as resource_extend
from neutron.db import _utils as db_utils
from neutron.db import api as db_api
from neutron.db import db_base_plugin_v2
from neutron.extensions import address_scope as ext_address_scope
from neutron.objects import address_scope as obj_addr_scope
from neutron.objects import base as base_obj
@ -133,5 +133,5 @@ class AddressScopeDbMixin(ext_address_scope.AddressScopePluginBase):
network_res[ext_address_scope.IPV6_ADDRESS_SCOPE] = as_id
return network_res
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attr.NETWORKS, ['_extend_network_dict_address_scope'])

View File

@ -16,8 +16,8 @@
from neutron_lib.api import validators
from neutron.api.v2 import attributes as attr
from neutron.db import _resource_extend as resource_extend
from neutron.db import _utils as db_utils
from neutron.db import db_base_plugin_v2
from neutron.common import utils
from neutron.extensions import allowedaddresspairs as addr_pair
@ -73,8 +73,7 @@ class AllowedAddressPairsMixin(object):
port_res[addr_pair.ADDRESS_PAIRS] = allowed_address_pairs
return port_res
# Register dict extend functions for ports
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attr.PORTS, ['_extend_port_dict_allowed_address_pairs'])
def _delete_allowed_address_pairs(self, context, id):

View File

@ -12,7 +12,7 @@
# under the License.
from neutron.api.v2 import attributes
from neutron.db import common_db_mixin
from neutron.db import _resource_extend as resource_extend
from neutron.extensions import availability_zone as az_ext
from neutron.extensions import network_availability_zone as net_az
@ -26,5 +26,5 @@ class NetworkAvailabilityZoneMixin(net_az.NetworkAvailabilityZonePluginBase):
net_res[az_ext.AVAILABILITY_ZONES] = (
self.get_network_availability_zones(net_db))
common_db_mixin.CommonDbMixin.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.NETWORKS, ['_extend_availability_zone'])

View File

@ -24,7 +24,8 @@ from sqlalchemy import or_
from sqlalchemy import sql
from neutron.api.v2 import attributes
from neutron.common import utils
from neutron.db import _model_query
from neutron.db import _resource_extend
from neutron.db import _utils as ndb_utils
@ -37,52 +38,20 @@ resource_fields = ndb_utils.resource_fields
class CommonDbMixin(object):
"""Common methods used in core and service plugins."""
# Plugins, mixin classes implementing extension will register
# hooks into the dict below for "augmenting" the "core way" of
# building a query for retrieving objects from a model class.
# To this aim, the register_model_query_hook and unregister_query_hook
# from this class should be invoked
_model_query_hooks = {}
# This dictionary will store methods for extending attributes of
# api resources. Mixins can use this dict for adding their own methods
# TODO(salvatore-orlando): Avoid using class-level variables
_dict_extend_functions = {}
@classmethod
def register_model_query_hook(cls, model, name, query_hook, filter_hook,
@staticmethod
def register_model_query_hook(model, name, query_hook, filter_hook,
result_filters=None):
"""Register a hook to be invoked when a query is executed.
_model_query.register_hook(
model, name, query_hook, filter_hook,
result_filters=result_filters)
Add the hooks to the _model_query_hooks dict. Models are the keys
of this dict, whereas the value is another dict mapping hook names to
callables performing the hook.
Each hook has a "query" component, used to build the query expression
and a "filter" component, which is used to build the filter expression.
Query hooks take as input the query being built and return a
transformed query expression.
Filter hooks take as input the filter expression being built and return
a transformed filter expression
"""
if callable(query_hook):
query_hook = utils.make_weak_ref(query_hook)
if callable(filter_hook):
filter_hook = utils.make_weak_ref(filter_hook)
if callable(result_filters):
result_filters = utils.make_weak_ref(result_filters)
cls._model_query_hooks.setdefault(model, {})[name] = {
'query': query_hook, 'filter': filter_hook,
'result_filters': result_filters}
@classmethod
def register_dict_extend_funcs(cls, resource, funcs):
funcs = [utils.make_weak_ref(f) if callable(f) else f
for f in funcs]
cls._dict_extend_functions.setdefault(resource, []).extend(funcs)
@staticmethod
def register_dict_extend_funcs(resource, funcs):
_resource_extend.register_funcs(resource, funcs)
@property
# TODO(HenryG): Remove; used only by vmware-nsx.
def safe_reference(self):
"""Return a weakref to the instance.
@ -115,13 +84,12 @@ class CommonDbMixin(object):
else:
query_filter = (model.tenant_id == context.tenant_id)
# Execute query hooks registered from mixins and plugins
for _name, hooks in six.iteritems(self._model_query_hooks.get(model,
{})):
query_hook = self._resolve_ref(hooks.get('query'))
for hook in _model_query.get_hooks(model):
query_hook = self._resolve_ref(hook.get('query'))
if query_hook:
query = query_hook(context, model, query)
filter_hook = self._resolve_ref(hooks.get('filter'))
filter_hook = self._resolve_ref(hook.get('filter'))
if filter_hook:
query_filter = filter_hook(context, model, query_filter)
@ -195,10 +163,10 @@ class CommonDbMixin(object):
# scoped query
query = query.outerjoin(model.rbac_entries)
query = query.filter(is_shared)
for _nam, hooks in six.iteritems(self._model_query_hooks.get(model,
{})):
for hook in _model_query.get_hooks(model):
result_filter = self._resolve_ref(
hooks.get('result_filters', None))
hook.get('result_filters', None))
if result_filter:
query = result_filter(query, filters)
return query
@ -213,8 +181,7 @@ class CommonDbMixin(object):
def _apply_dict_extend_functions(self, resource_type,
response, db_object):
for func in self._dict_extend_functions.get(
resource_type, []):
for func in _resource_extend.get_funcs(resource_type):
args = (response, db_object)
if not isinstance(func, six.string_types):
# must call unbound method - use self as 1st argument

View File

@ -41,6 +41,7 @@ from neutron.common import constants as n_const
from neutron.common import exceptions as n_exc
from neutron.common import ipv6_utils
from neutron.common import utils
from neutron.db import _model_query as model_query
from neutron.db import _utils as ndb_utils
from neutron.db import api as db_api
from neutron.db import db_base_plugin_common
@ -1388,7 +1389,7 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon,
if tenant_id != router['tenant_id']:
raise n_exc.DeviceIDNotOwnedByTenant(device_id=device_id)
db_base_plugin_common.DbBasePluginCommon.register_model_query_hook(
model_query.register_hook(
models_v2.Port,
"port",
None,

View File

@ -20,7 +20,7 @@ from oslo_log import log as logging
from neutron._i18n import _, _LE
from neutron.common import utils
from neutron.db import db_base_plugin_v2
from neutron.db import _resource_extend as resource_extend
from neutron.extensions import dns
from neutron.extensions import l3
from neutron.objects import floatingip as fip_obj
@ -71,8 +71,7 @@ class DNSDbMixin(object):
floatingip_res['dns_name'] = floatingip_db.dns['dns_name']
return floatingip_res
# Register dict extend functions for floating ips
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
l3.FLOATINGIPS, ['_extend_floatingip_dict_dns'])
def _process_dns_floatingip_create_precommit(self, context,

View File

@ -25,8 +25,9 @@ from neutron.callbacks import events
from neutron.callbacks import exceptions as c_exc
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.db import _model_query as model_query
from neutron.db import _resource_extend as resource_extend
from neutron.db import _utils as db_utils
from neutron.db import db_base_plugin_v2
from neutron.db.models import l3 as l3_models
from neutron.db import models_v2
from neutron.db import rbac_db_models as rbac_db
@ -67,10 +68,7 @@ class External_net_db_mixin(object):
return query.filter(models_v2.Network.external.has())
return query.filter(~models_v2.Network.external.has())
# TODO(salvatore-orlando): Perform this operation without explicitly
# referring to db_base_plugin_v2, as plugins that do not extend from it
# might exist in the future
db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook(
model_query.register_hook(
models_v2.Network,
"external_net",
None,
@ -86,8 +84,7 @@ class External_net_db_mixin(object):
network_res[external_net.EXTERNAL] = network_db.external is not None
return network_res
# Register dict extend functions for networks
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.NETWORKS, ['_extend_network_dict_l3'])
def _process_l3_create(self, context, net_data, req_data):

View File

@ -14,7 +14,7 @@
# under the License.
from neutron.api.v2 import attributes
from neutron.db import db_base_plugin_v2
from neutron.db import _resource_extend as resource_extend
from neutron.extensions import extra_dhcp_opt as edo_ext
from neutron.objects.port.extensions import extra_dhcp_opt as obj_extra_dhcp
@ -120,5 +120,5 @@ class ExtraDhcpOptMixin(object):
for dho in port.dhcp_opts]
return res
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.PORTS, ['_extend_port_dict_extra_dhcp_opt'])

View File

@ -20,7 +20,7 @@ from oslo_log import log as logging
from neutron._i18n import _
from neutron.common import utils
from neutron.db import db_base_plugin_v2
from neutron.db import _resource_extend as resource_extend
from neutron.db import l3_db
from neutron.db import models_v2
from neutron.extensions import extraroute
@ -48,7 +48,7 @@ class ExtraRoute_dbonly_mixin(l3_db.L3_NAT_dbonly_mixin):
router_db['route_list']
))
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
l3.ROUTERS, ['_extend_router_dict_extraroute'])
def update_router(self, context, id, router):

View File

@ -15,7 +15,7 @@
from oslo_config import cfg
from neutron._i18n import _
from neutron.db import db_base_plugin_v2
from neutron.db import _resource_extend as resource_extend
from neutron.db.models import l3_attrs
from neutron.extensions import availability_zone as az
from neutron.extensions import l3
@ -62,5 +62,5 @@ class ExtraAttributesMixin(object):
raise RuntimeError(_("Tried to set a key '%s' that doesn't exist "
"in the extra attributes table.") % key)
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
l3.ROUTERS, ['_extend_extra_router_dict'])

View File

@ -18,7 +18,7 @@ import sqlalchemy as sa
from sqlalchemy import sql
from neutron._i18n import _
from neutron.db import db_base_plugin_v2
from neutron.db import _resource_extend as resource_extend
from neutron.db import l3_db
from neutron.db.models import l3 as l3_models
from neutron.extensions import l3
@ -41,8 +41,7 @@ setattr(l3_models.Router, 'enable_snat',
class L3_NAT_dbonly_mixin(l3_db.L3_NAT_dbonly_mixin):
"""Mixin class to add configurable gateway modes."""
# Register dict extend functions for ports and networks
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
l3.ROUTERS, ['_extend_router_dict_gw_mode'])
def _extend_router_dict_gw_mode(self, router_res, router_db):

View File

@ -16,7 +16,7 @@
from oslo_config import cfg
from neutron.api.v2 import attributes
from neutron.db import db_base_plugin_v2
from neutron.db import _resource_extend as resource_extend
from neutron.extensions import netmtu
from neutron.plugins.common import utils
@ -36,5 +36,5 @@ class Netmtu_db_mixin(object):
network_res[netmtu.MTU] = utils.get_deployment_physnet_mtu()
return network_res
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.NETWORKS, ['_extend_network_dict_mtu'])

View File

@ -14,7 +14,7 @@
# under the License.
from neutron.api.v2 import attributes
from neutron.db import db_base_plugin_v2
from neutron.db import _resource_extend as resource_extend
class PortBindingBaseMixin(object):
@ -36,5 +36,5 @@ def _extend_port_dict_binding(plugin, port_res, port_db):
def register_port_dict_function():
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.PORTS, [_extend_port_dict_binding])

View File

@ -16,7 +16,8 @@
from neutron_lib.api import validators
from neutron.api.v2 import attributes
from neutron.db import db_base_plugin_v2
from neutron.db import _model_query as model_query
from neutron.db import _resource_extend as resource_extend
from neutron.db.models import portbinding as pmodels
from neutron.db import models_v2
from neutron.db import portbindings_base
@ -39,7 +40,7 @@ class PortBindingMixin(portbindings_base.PortBindingBaseMixin):
query = query.filter(pmodels.PortBindingPort.host.in_(values))
return query
db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook(
model_query.register_hook(
models_v2.Port,
"portbindings_port",
'_port_model_hook',
@ -102,6 +103,4 @@ def _extend_port_dict_binding(plugin, port_res, port_db):
plugin.extend_port_dict_binding(port_res, port_db)
# Register dict extend functions for ports
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attributes.PORTS, [_extend_port_dict_binding])
resource_extend.register_funcs(attributes.PORTS, [_extend_port_dict_binding])

View File

@ -16,16 +16,15 @@ from neutron_lib.api import validators
from neutron.api.v2 import attributes as attrs
from neutron.common import utils
from neutron.db import db_base_plugin_v2
from neutron.db import _resource_extend as resource_extend
from neutron.db import portsecurity_db_common
from neutron.extensions import portsecurity as psec
class PortSecurityDbMixin(portsecurity_db_common.PortSecurityDbCommon):
# Register dict extend functions for ports and networks
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attrs.NETWORKS, ['_extend_port_security_dict'])
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attrs.PORTS, ['_extend_port_security_dict'])
def _extend_port_security_dict(self, response_data, db_data):

View File

@ -28,9 +28,9 @@ from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.common import constants as n_const
from neutron.common import utils
from neutron.db import _resource_extend as resource_extend
from neutron.db import _utils as db_utils
from neutron.db import api as db_api
from neutron.db import db_base_plugin_v2
from neutron.db.models import securitygroup as sg_models
from neutron.extensions import securitygroup as ext_sg
@ -662,8 +662,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
port_res[ext_sg.SECURITYGROUPS] = security_group_ids
return port_res
# Register dict extend functions for ports
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.PORTS, ['_extend_port_dict_security_group'])
def _process_port_create_security_group(self, context, port,

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from neutron.db import common_db_mixin
from neutron.db import _resource_extend as resource_extend
from neutron.db import standard_attr
@ -26,7 +26,7 @@ class StandardAttrDescriptionMixin(object):
def __new__(cls, *args, **kwargs):
for resource in standard_attr.get_standard_attr_resource_model_map():
common_db_mixin.CommonDbMixin.register_dict_extend_funcs(
resource_extend.register_funcs(
resource, ['_extend_standard_attr_description'])
return super(StandardAttrDescriptionMixin, cls).__new__(cls, *args,
**kwargs)

View File

@ -17,7 +17,7 @@
# any models at all
from neutron.api.v2 import attributes
from neutron.db import common_db_mixin
from neutron.db import _resource_extend as resource_extend
class SubnetServiceTypeMixin(object):
@ -28,5 +28,5 @@ class SubnetServiceTypeMixin(object):
service_type in
subnet_db.service_types]
common_db_mixin.CommonDbMixin.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.SUBNETS, [_extend_subnet_service_types])

View File

@ -13,7 +13,7 @@
# under the License.
from neutron.api.v2 import attributes
from neutron.db import db_base_plugin_v2
from neutron.db import _resource_extend as resource_extend
from neutron.extensions import vlantransparent
@ -25,5 +25,5 @@ class Vlantransparent_db_mixin(object):
network_db.vlan_transparent)
return network_res
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.NETWORKS, ['_extend_network_dict_vlan_transparent'])

View File

@ -46,6 +46,8 @@ from neutron.common import constants as n_const
from neutron.common import rpc as n_rpc
from neutron.common import topics
from neutron.common import utils
from neutron.db import _model_query as model_query
from neutron.db import _resource_extend as resource_extend
from neutron.db import _utils as db_utils
from neutron.db import address_scope_db
from neutron.db import agents_db
@ -579,17 +581,16 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
if port_db.port_binding:
self._update_port_dict_binding(port_res, port_db.port_binding)
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.PORTS, ['_ml2_extend_port_dict_binding'])
# Register extend dict methods for network and port resources.
# Each mechanism driver that supports extend attribute for the resources
# can add those attribute to the result.
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
# ML2's resource extend functions allow extension drivers that extend
# attributes for the resources to add those attributes to the result.
resource_extend.register_funcs(
attributes.NETWORKS, ['_ml2_md_extend_network_dict'])
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.PORTS, ['_ml2_md_extend_port_dict'])
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.SUBNETS, ['_ml2_md_extend_subnet_dict'])
def _ml2_md_extend_network_dict(self, result, netdb):
@ -616,7 +617,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
bind_criteria = models.PortBinding.host.in_(values)
return query.filter(models_v2.Port.port_binding.has(bind_criteria))
db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook(
model_query.register_hook(
models_v2.Port,
"ml2_port_bindings",
None,

View File

@ -25,10 +25,10 @@ from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.common import exceptions as c_exc
from neutron.db import _resource_extend as resource_extend
from neutron.db import _utils as db_utils
from neutron.db import api as db_api
from neutron.db import common_db_mixin
from neutron.db import db_base_plugin_v2
from neutron.extensions import l3
from neutron.objects import auto_allocate as auto_allocate_obj
from neutron.objects import base as base_obj
@ -75,7 +75,7 @@ def _ensure_external_network_default_value_callback(
class AutoAllocatedTopologyMixin(common_db_mixin.CommonDbMixin):
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.NETWORKS, [_extend_external_network_default])
def __new__(cls, *args, **kwargs):

View File

@ -22,6 +22,7 @@ from neutron.api.rpc.agentnotifiers import l3_rpc_agent_api
from neutron.api.rpc.handlers import l3_rpc
from neutron.common import rpc as n_rpc
from neutron.common import topics
from neutron.db import _resource_extend as resource_extend
from neutron.db import common_db_mixin
from neutron.db import dns_db
from neutron.db import extraroute_db
@ -125,5 +126,5 @@ def add_flavor_id(plugin, router_res, router_db):
router_res['flavor_id'] = router_db['flavor_id']
common_db_mixin.CommonDbMixin.register_dict_extend_funcs(
resource_extend.register_funcs(
l3.ROUTERS, [add_flavor_id])

View File

@ -17,8 +17,8 @@ from sqlalchemy.orm import exc
from sqlalchemy.orm import session as se
from neutron._i18n import _, _LW
from neutron.db import _resource_extend as resource_extend
from neutron.db import api as db_api
from neutron.db import db_base_plugin_v2
from neutron.db import standard_attr
from neutron.services import service_base
@ -33,7 +33,7 @@ class RevisionPlugin(service_base.ServicePluginBase):
def __init__(self):
super(RevisionPlugin, self).__init__()
for resource in standard_attr.get_standard_attr_resource_model_map():
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
resource, [self.extend_resource_dict_revision])
db_api.sqla_listen(se.Session, 'before_flush', self.bump_revisions)

View File

@ -29,7 +29,7 @@ from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.common import exceptions as n_exc
from neutron.db import common_db_mixin
from neutron.db import _resource_extend as resource_extend
from neutron.db.models import segment as segment_model
from neutron.db import models_v2
from neutron.extensions import ip_allocation
@ -79,11 +79,11 @@ class Plugin(db.SegmentDbMixin, segment.SegmentPluginBase):
supported_extension_aliases = ["segment", "ip_allocation", "l2_adjacency"]
def __init__(self):
common_db_mixin.CommonDbMixin.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.NETWORKS, [_extend_network_dict_binding])
common_db_mixin.CommonDbMixin.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.SUBNETS, [_extend_subnet_dict_binding])
common_db_mixin.CommonDbMixin.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.PORTS, [_extend_port_dict_binding])
self.nova_updater = NovaSegmentNotifier()

View File

@ -21,6 +21,8 @@ from oslo_log import helpers as log_helpers
from sqlalchemy.orm import exc
from neutron.api.v2 import attributes
from neutron.db import _model_query as model_query
from neutron.db import _resource_extend as resource_extend
from neutron.db import api as db_api
from neutron.db import common_db_mixin
from neutron.db.models import l3 as l3_model
@ -31,6 +33,7 @@ from neutron.extensions import l3 as l3_ext
from neutron.extensions import tag as tag_ext
# Taggable resources
resource_model_map = {
# When we'll add other resources, we must add new extension for them
# if we don't have better discovery mechanism instead of it.
@ -131,13 +134,11 @@ class TagPlugin(common_db_mixin.CommonDbMixin, tag_ext.TagPluginBase):
def __new__(cls, *args, **kwargs):
inst = super(TagPlugin, cls).__new__(cls, *args, **kwargs)
inst._filter_methods = [] # prevent GC of our partial functions
# support only _apply_dict_extend_functions supported resources
# at the moment.
for resource, model in resource_model_map.items():
common_db_mixin.CommonDbMixin.register_dict_extend_funcs(
resource_extend.register_funcs(
resource, [_extend_tags_dict])
method = functools.partial(tag_methods.apply_tag_filters, model)
inst._filter_methods.append(method)
common_db_mixin.CommonDbMixin.register_model_query_hook(
model_query.register_hook(
model, "tag", None, None, method)
return inst

View File

@ -12,7 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from neutron.db import db_base_plugin_v2
from neutron.db import _model_query as model_query
from neutron.db import _resource_extend as resource_extend
from neutron.db import models_v2
from neutron.db import standard_attr
from neutron.objects import base as base_obj
@ -31,9 +32,9 @@ class TimeStampPlugin(service_base.ServicePluginBase,
self.register_db_events()
rs_model_maps = standard_attr.get_standard_attr_resource_model_map()
for rsmap, model in rs_model_maps.items():
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
rsmap, [self.extend_resource_dict_timestamp])
db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook(
model_query.register_hook(
model, "change_since_query", None, None,
self._change_since_result_filter_hook)
# TODO(jlibosva): Move this to register_model_query_hook

View File

@ -22,10 +22,10 @@ from neutron.api.v2 import attributes
from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.db import _resource_extend as resource_extend
from neutron.db import api as db_api
from neutron.db import common_db_mixin
from neutron.db import db_base_plugin_common
from neutron.db import db_base_plugin_v2
from neutron.extensions import portbindings
from neutron.objects import base as objects_base
from neutron.objects import trunk as trunk_objects
@ -69,7 +69,7 @@ class TrunkPlugin(service_base.ServicePluginBase,
__native_sorting_support = True
def __init__(self):
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
attributes.PORTS, [_extend_port_trunk_details])
self._rpc_backend = None
self._drivers = []

View File

@ -35,7 +35,7 @@ import unittest2
from neutron.api.v2 import attributes
from neutron.common import constants as n_const
from neutron.db import common_db_mixin
from neutron.db import _model_query as model_query
from neutron.plugins.common import constants as p_const
@ -125,13 +125,13 @@ class SafeCleanupFixture(fixtures.Fixture):
class CommonDbMixinHooksFixture(fixtures.Fixture):
def _setUp(self):
self.original_hooks = common_db_mixin.CommonDbMixin._model_query_hooks
self.original_hooks = model_query._model_query_hooks
self.addCleanup(self.restore_hooks)
common_db_mixin.CommonDbMixin._model_query_hooks = copy.copy(
common_db_mixin.CommonDbMixin._model_query_hooks)
model_query._model_query_hooks = copy.copy(
model_query._model_query_hooks)
def restore_hooks(self):
common_db_mixin.CommonDbMixin._model_query_hooks = self.original_hooks
model_query._model_query_hooks = self.original_hooks
def setup_mock_calls(mocked_call, expected_calls_and_values):

View File

@ -37,6 +37,7 @@ from neutron.callbacks import events
from neutron.callbacks import exceptions
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.db import _resource_extend as resource_extend
from neutron.db import common_db_mixin
from neutron.db import db_base_plugin_v2
from neutron.db import dns_db
@ -616,7 +617,7 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
def _extend_router_dict_test_attr(*args, **kwargs):
self.extension_called = True
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
resource_extend.register_funcs(
l3.ROUTERS, [_extend_router_dict_test_attr])
self.assertFalse(self.extension_called)
with self.router():

View File

@ -31,7 +31,7 @@ import testtools
from neutron.common import constants
from neutron.common import utils
from neutron.db import db_base_plugin_v2
from neutron.db import _model_query as model_query
from neutron.db.models import l3 as l3_model
from neutron.db import standard_attr
from neutron import objects
@ -1507,7 +1507,7 @@ class BaseDbObjectTestCase(_BaseObjectTestCase,
return query
self.obj_registry.register(self._test_class)
db_base_plugin_v2.NeutronDbPluginV2.register_model_query_hook(
model_query.register_hook(
self._test_class.db_model,
'foo_filter',
None,