Use registry.receives decorator in neutron.db.l3_db

Switch to registry.receives decorator in neutron.db.l3_db.

Partial-Bug: #1668262
Change-Id: Ia8ac4f510c003667cac95f76dea0e9ae55159878
This commit is contained in:
Cedric Brandily 2017-02-28 18:45:56 +01:00 committed by Kevin Benton
parent 5691f29e8f
commit 67f3977454
3 changed files with 70 additions and 97 deletions

View File

@ -66,6 +66,7 @@ API_TO_DB_COLUMN_MAP = {'port_id': 'fixed_port_id'}
CORE_ROUTER_ATTRS = ('id', 'name', 'tenant_id', 'admin_state_up', 'status')
@registry.has_registry_receivers
class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
neutron_worker.WorkerSupportServiceMixin,
st_attr.StandardAttrDescriptionMixin):
@ -80,22 +81,20 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
_dns_integration = None
# NOTE(armax): multiple l3 service plugins (potentially out of tree)
# inherit from l3_db and may need the callbacks to be processed. Having
# an implicit subscription (through the __new__ method) preserves the
# existing behavior, and at the same time it avoids fixing it manually
# in each and every l3 plugin out there.
def __new__(cls):
L3_NAT_dbonly_mixin._subscribe_callbacks()
inst = super(L3_NAT_dbonly_mixin, cls).__new__(cls)
inst._start_janitor()
return inst
@staticmethod
def _subscribe_callbacks():
registry.subscribe(
_prevent_l3_port_delete_callback, resources.PORT,
events.BEFORE_DELETE)
@registry.receives(resources.PORT, [events.BEFORE_DELETE])
def _prevent_l3_port_delete_callback(resource, event, trigger, **kwargs):
context = kwargs['context']
port_id = kwargs['port_id']
port_check = kwargs['port_check']
l3plugin = directory.get_plugin(constants.L3)
if l3plugin and port_check:
l3plugin.prevent_l3_port_deletion(context, port_id)
@property
def _is_dns_integration_supported(self):
@ -1732,29 +1731,63 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
return list(routers_dict.values())
@registry.has_registry_receivers
class L3RpcNotifierMixin(object):
"""Mixin class to add rpc notifier attribute to db_base_plugin_v2."""
# NOTE(armax): multiple l3 service plugins (potentially out of tree)
# inherit from l3_db and may need the callbacks to be processed. Having
# an implicit subscription (through the __new__ method) preserves the
# existing behavior, and at the same time it avoids fixing it manually
# in each and every l3 plugin out there.
def __new__(cls):
L3RpcNotifierMixin._subscribe_callbacks()
return super(L3RpcNotifierMixin, cls).__new__(cls)
@staticmethod
@registry.receives(resources.PORT, [events.AFTER_DELETE])
def _notify_routers_callback(resource, event, trigger, **kwargs):
context = kwargs['context']
router_ids = kwargs['router_ids']
l3plugin = directory.get_plugin(constants.L3)
if l3plugin:
l3plugin.notify_routers_updated(context, router_ids)
else:
LOG.debug('%s not configured', constants.L3)
@staticmethod
def _subscribe_callbacks():
registry.subscribe(
_notify_routers_callback, resources.PORT, events.AFTER_DELETE)
registry.subscribe(
_notify_subnet_gateway_ip_update, resources.SUBNET_GATEWAY,
events.AFTER_UPDATE)
registry.subscribe(
_notify_subnetpool_address_scope_update,
resources.SUBNETPOOL_ADDRESS_SCOPE,
events.AFTER_UPDATE)
@registry.receives(resources.SUBNET_GATEWAY, [events.AFTER_UPDATE])
def _notify_subnet_gateway_ip_update(resource, event, trigger, **kwargs):
l3plugin = directory.get_plugin(constants.L3)
if not l3plugin:
return
context = kwargs['context']
network_id = kwargs['network_id']
subnet_id = kwargs['subnet_id']
query = context.session.query(models_v2.Port).filter_by(
network_id=network_id,
device_owner=constants.DEVICE_OWNER_ROUTER_GW)
query = query.join(models_v2.Port.fixed_ips).filter(
models_v2.IPAllocation.subnet_id == subnet_id)
router_ids = set(port['device_id'] for port in query)
for router_id in router_ids:
l3plugin.notify_router_updated(context, router_id)
@staticmethod
@registry.receives(resources.SUBNETPOOL_ADDRESS_SCOPE,
[events.AFTER_UPDATE])
def _notify_subnetpool_address_scope_update(resource, event,
trigger, **kwargs):
context = kwargs['context']
subnetpool_id = kwargs['subnetpool_id']
query = context.session.query(l3_models.RouterPort.router_id)
query = query.join(models_v2.Port)
query = query.join(
models_v2.Subnet,
models_v2.Subnet.network_id == models_v2.Port.network_id)
query = query.filter(
models_v2.Subnet.subnetpool_id == subnetpool_id,
l3_models.RouterPort.port_type.in_(n_const.ROUTER_PORT_OWNERS))
query = query.distinct()
router_ids = [r[0] for r in query]
l3plugin = directory.get_plugin(constants.L3)
if l3plugin:
l3plugin.notify_routers_updated(context, router_ids)
else:
LOG.debug('%s not configured', constants.L3)
@property
def l3_rpc_notifier(self):
@ -1883,65 +1916,6 @@ class L3_NAT_db_mixin(L3_NAT_dbonly_mixin, L3RpcNotifierMixin):
rp.port.device_owner = new_owner
def _prevent_l3_port_delete_callback(resource, event, trigger, **kwargs):
context = kwargs['context']
port_id = kwargs['port_id']
port_check = kwargs['port_check']
l3plugin = directory.get_plugin(constants.L3)
if l3plugin and port_check:
l3plugin.prevent_l3_port_deletion(context, port_id)
def _notify_routers_callback(resource, event, trigger, **kwargs):
context = kwargs['context']
router_ids = kwargs['router_ids']
l3plugin = directory.get_plugin(constants.L3)
if l3plugin:
l3plugin.notify_routers_updated(context, router_ids)
else:
LOG.debug('%s not configured', constants.L3)
def _notify_subnet_gateway_ip_update(resource, event, trigger, **kwargs):
l3plugin = directory.get_plugin(constants.L3)
if not l3plugin:
return
context = kwargs['context']
network_id = kwargs['network_id']
subnet_id = kwargs['subnet_id']
query = context.session.query(models_v2.Port).filter_by(
network_id=network_id,
device_owner=constants.DEVICE_OWNER_ROUTER_GW)
query = query.join(models_v2.Port.fixed_ips).filter(
models_v2.IPAllocation.subnet_id == subnet_id)
router_ids = set(port['device_id'] for port in query)
for router_id in router_ids:
l3plugin.notify_router_updated(context, router_id)
def _notify_subnetpool_address_scope_update(resource, event,
trigger, **kwargs):
context = kwargs['context']
subnetpool_id = kwargs['subnetpool_id']
query = context.session.query(l3_models.RouterPort.router_id)
query = query.join(models_v2.Port)
query = query.join(
models_v2.Subnet,
models_v2.Subnet.network_id == models_v2.Port.network_id)
query = query.filter(
models_v2.Subnet.subnetpool_id == subnetpool_id,
l3_models.RouterPort.port_type.in_(n_const.ROUTER_PORT_OWNERS))
query = query.distinct()
router_ids = [r[0] for r in query]
l3plugin = directory.get_plugin(constants.L3)
if l3plugin:
l3plugin.notify_routers_updated(context, router_ids)
else:
LOG.debug('%s not configured', constants.L3)
@removals.remove(
message="This will be removed in the Pike release. "
"Subscriptions are now registered during object creation."

View File

@ -199,16 +199,14 @@ class TestL3_NAT_dbonly_mixin(base.BaseTestCase):
with testtools.ExpectedException(n_exc.ServicePortInUse):
self.db.prevent_l3_port_deletion(mock.Mock(), None)
@mock.patch.object(l3_db, '_notify_subnetpool_address_scope_update')
def test_subscribe_address_scope_of_subnetpool(self, notify):
l3_db.L3RpcNotifierMixin._subscribe_callbacks()
@mock.patch.object(directory, 'get_plugin')
def test_subscribe_address_scope_of_subnetpool(self, gp):
l3_db.L3RpcNotifierMixin()
registry.notify(resources.SUBNETPOOL_ADDRESS_SCOPE,
events.AFTER_UPDATE, mock.ANY, context=mock.ANY,
events.AFTER_UPDATE, mock.ANY,
context=mock.MagicMock(),
subnetpool_id='fake_id')
notify.assert_called_once_with(resources.SUBNETPOOL_ADDRESS_SCOPE,
events.AFTER_UPDATE, mock.ANY,
context=mock.ANY,
subnetpool_id='fake_id')
self.assertTrue(gp.return_value.notify_routers_updated.called)
def test__check_and_get_fip_assoc_with_extra_association_no_change(self):
fip = {'extra_key': 'value'}

View File

@ -3212,7 +3212,8 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
self.skipTest("Plugin does not support l3_rpc_notifier")
# make sure the callback is registered.
registry.subscribe(
l3_db._notify_subnet_gateway_ip_update, resources.SUBNET_GATEWAY,
l3_db.L3RpcNotifierMixin._notify_subnet_gateway_ip_update,
resources.SUBNET_GATEWAY,
events.AFTER_UPDATE)
with mock.patch.object(plugin.l3_rpc_notifier,
'routers_updated') as chk_method:
@ -3262,7 +3263,7 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
plugin.add_router_interface(
admin_ctx,
router['router']['id'], {'subnet_id': subnet['subnet']['id']})
l3_db._notify_subnetpool_address_scope_update(
l3_db.L3RpcNotifierMixin._notify_subnetpool_address_scope_update(
mock.ANY, mock.ANY, mock.ANY,
context=admin_ctx, subnetpool_id=subnetpool_id)
chk_method.assert_called_with(admin_ctx, [router['router']['id']])