Use payloads for ROUTER callbacks

This patch switches over to callback payloads for ROUTER
BEFORE_CREATE, PRECOMMIT_CREATE, BEFORE_UPDATE and
PRECOMMIT_DELETE events.

Change-Id: I4a52c773d3f753c918df0986f1d261083156651c
This commit is contained in:
Nurmatov Mamatisa 2021-07-30 15:56:10 +03:00
parent 19372a3cd8
commit 40c8f60ee3
13 changed files with 124 additions and 51 deletions

View File

@ -482,8 +482,11 @@ class L3NATAgent(ha.AgentMixin,
def _router_added(self, router_id, router): def _router_added(self, router_id, router):
ri = self._create_router(router_id, router) ri = self._create_router(router_id, router)
registry.notify(resources.ROUTER, events.BEFORE_CREATE, registry.publish(resources.ROUTER, events.BEFORE_CREATE, self,
self, router=ri) payload=events.DBEventPayload(
self.context,
resource_id=router_id,
states=(ri,)))
self.router_info[router_id] = ri self.router_info[router_id] = ri
@ -688,8 +691,12 @@ class L3NATAgent(ha.AgentMixin,
self.check_ha_state_for_router( self.check_ha_state_for_router(
router['id'], router.get(lib_const.HA_ROUTER_STATE_KEY)) router['id'], router.get(lib_const.HA_ROUTER_STATE_KEY))
ri.router = router ri.router = router
registry.notify(resources.ROUTER, events.BEFORE_UPDATE, registry.publish(resources.ROUTER, events.BEFORE_UPDATE, self,
self, router=ri) payload=events.DBEventPayload(
self.context,
resource_id=router['id'],
states=(ri,)))
ri.process() ri.process()
registry.notify( registry.notify(
resources.ROUTER, events.AFTER_UPDATE, self, router=ri) resources.ROUTER, events.AFTER_UPDATE, self, router=ri)

View File

@ -369,8 +369,8 @@ def get_router_entry(ns_name, primary):
@runtime.synchronized("l3-agent-pd") @runtime.synchronized("l3-agent-pd")
def add_router(resource, event, l3_agent, **kwargs): def add_router(resource, event, l3_agent, payload):
added_router = kwargs['router'] added_router = payload.latest_state
router = l3_agent.pd.routers.get(added_router.router_id) router = l3_agent.pd.routers.get(added_router.router_id)
gw_ns_name = added_router.get_gw_ns_name() gw_ns_name = added_router.get_gw_ns_name()
primary = added_router.is_router_primary() primary = added_router.is_router_primary()

View File

@ -40,8 +40,10 @@ class RouterAvailabilityZoneMixin(l3_attrs_db.ExtraAttributesMixin):
l3_plugin.get_router_availability_zones(router_db)) l3_plugin.get_router_availability_zones(router_db))
@registry.receives(resources.ROUTER, [events.PRECOMMIT_CREATE]) @registry.receives(resources.ROUTER, [events.PRECOMMIT_CREATE])
def _process_az_request(self, resource, event, trigger, context, def _process_az_request(self, resource, event, trigger, payload):
router, router_db, **kwargs): context = payload.context
router = payload.latest_state
router_db = payload.metadata['router_db']
if az_def.AZ_HINTS in router: if az_def.AZ_HINTS in router:
self.validate_availability_zones(context, 'router', self.validate_availability_zones(context, 'router',
router[az_def.AZ_HINTS]) router[az_def.AZ_HINTS])

View File

@ -229,8 +229,13 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
"""Create the DB object.""" """Create the DB object."""
router.setdefault('id', uuidutils.generate_uuid()) router.setdefault('id', uuidutils.generate_uuid())
router['tenant_id'] = tenant_id router['tenant_id'] = tenant_id
registry.notify(resources.ROUTER, events.BEFORE_CREATE,
self, context=context, router=router) registry.publish(resources.ROUTER, events.BEFORE_CREATE, self,
payload=events.DBEventPayload(
context,
resource_id=router['id'],
states=(router,)))
with db_api.CONTEXT_WRITER.using(context): with db_api.CONTEXT_WRITER.using(context):
# pre-generate id so it will be available when # pre-generate id so it will be available when
# configuring external gw port # configuring external gw port
@ -242,9 +247,13 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
status=constants.ACTIVE, status=constants.ACTIVE,
description=router.get('description')) description=router.get('description'))
context.session.add(router_db) context.session.add(router_db)
registry.notify(resources.ROUTER, events.PRECOMMIT_CREATE,
self, context=context, router=router, registry.publish(resources.ROUTER, events.PRECOMMIT_CREATE, self,
router_id=router['id'], router_db=router_db) payload=events.DBEventPayload(
context,
resource_id=router['id'],
metadata={'router_db': router_db},
states=(router,)))
return router_db return router_db
def _update_gw_for_create_router(self, context, gw_info, router_id): def _update_gw_for_create_router(self, context, gw_info, router_id):
@ -562,9 +571,11 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
l3_port_check=False) l3_port_check=False)
router = self._get_router(context, id) router = self._get_router(context, id)
registry.notify(resources.ROUTER, events.PRECOMMIT_DELETE, registry.publish(resources.ROUTER, events.PRECOMMIT_DELETE, self,
self, context=context, router_db=router, payload=events.DBEventPayload(
router_id=id) context,
resource_id=id,
states=(router,)))
# we bump the revision even though we are about to delete to throw # we bump the revision even though we are about to delete to throw
# staledataerror if something stuck in with a new interface # staledataerror if something stuck in with a new interface
router.bump_revision() router.bump_revision()

View File

@ -101,9 +101,11 @@ class DVRResourceOperationHandler(object):
@registry.receives(resources.ROUTER, [events.PRECOMMIT_CREATE], @registry.receives(resources.ROUTER, [events.PRECOMMIT_CREATE],
priority_group.PRIORITY_ROUTER_EXTENDED_ATTRIBUTE) priority_group.PRIORITY_ROUTER_EXTENDED_ATTRIBUTE)
def _set_distributed_flag(self, resource, event, trigger, context, def _set_distributed_flag(self, resource, event, trigger, payload):
router, router_db, **kwargs):
"""Event handler to set distributed flag on creation.""" """Event handler to set distributed flag on creation."""
context = payload.context
router = payload.latest_state
router_db = payload.metadata['router_db']
dist = is_distributed_router(router) dist = is_distributed_router(router)
router['distributed'] = dist router['distributed'] = dist
self.l3plugin.set_extra_attr_value(context, router_db, 'distributed', self.l3plugin.set_extra_attr_value(context, router_db, 'distributed',
@ -148,9 +150,12 @@ class DVRResourceOperationHandler(object):
# Notify advanced services of the imminent state transition # Notify advanced services of the imminent state transition
# for the router. # for the router.
try: try:
kwargs = {'context': context, 'router': router_db} registry.publish(
registry.notify( resources.ROUTER, events.BEFORE_UPDATE, self,
resources.ROUTER, events.BEFORE_UPDATE, self, **kwargs) payload=events.DBEventPayload(
context,
resource_id=router_db['id'],
states=(old_router, router_db,)))
except exceptions.CallbackFailure as e: except exceptions.CallbackFailure as e:
# NOTE(armax): preserve old check's behavior # NOTE(armax): preserve old check's behavior
if len(e.errors) == 1: if len(e.errors) == 1:

View File

@ -353,9 +353,13 @@ class L3_HA_NAT_db_mixin(l3_dvr_db.L3_NAT_with_dvr_db_mixin,
@registry.receives(resources.ROUTER, [events.BEFORE_CREATE], @registry.receives(resources.ROUTER, [events.BEFORE_CREATE],
priority_group.PRIORITY_ROUTER_EXTENDED_ATTRIBUTE) priority_group.PRIORITY_ROUTER_EXTENDED_ATTRIBUTE)
def _before_router_create_handler(self, resource, event, trigger,
payload):
return self._before_router_create(event, payload.context,
payload.latest_state)
@db_api.retry_if_session_inactive() @db_api.retry_if_session_inactive()
def _before_router_create(self, resource, event, trigger, def _before_router_create(self, event, context, router):
context, router, **kwargs):
"""Event handler to create HA resources before router creation.""" """Event handler to create HA resources before router creation."""
if not self._is_ha(router): if not self._is_ha(router):
return return
@ -367,9 +371,11 @@ class L3_HA_NAT_db_mixin(l3_dvr_db.L3_NAT_with_dvr_db_mixin,
@registry.receives(resources.ROUTER, [events.PRECOMMIT_CREATE], @registry.receives(resources.ROUTER, [events.PRECOMMIT_CREATE],
priority_group.PRIORITY_ROUTER_EXTENDED_ATTRIBUTE) priority_group.PRIORITY_ROUTER_EXTENDED_ATTRIBUTE)
def _precommit_router_create(self, resource, event, trigger, context, def _precommit_router_create(self, resource, event, trigger, payload):
router, router_db, **kwargs):
"""Event handler to set ha flag and status on creation.""" """Event handler to set ha flag and status on creation."""
context = payload.context
router = payload.latest_state
router_db = payload.metadata['router_db']
is_ha = self._is_ha(router) is_ha = self._is_ha(router)
router['ha'] = is_ha router['ha'] = is_ha
self.set_extra_attr_value(context, router_db, 'ha', is_ha) self.set_extra_attr_value(context, router_db, 'ha', is_ha)
@ -510,9 +516,10 @@ class L3_HA_NAT_db_mixin(l3_dvr_db.L3_NAT_with_dvr_db_mixin,
@registry.receives(resources.ROUTER, [events.PRECOMMIT_DELETE], @registry.receives(resources.ROUTER, [events.PRECOMMIT_DELETE],
priority_group.PRIORITY_ROUTER_EXTENDED_ATTRIBUTE) priority_group.PRIORITY_ROUTER_EXTENDED_ATTRIBUTE)
def _release_router_vr_id(self, resource, event, trigger, context, def _release_router_vr_id(self, resource, event, trigger, payload):
router_db, **kwargs):
"""Event handler for removal of VRID during router delete.""" """Event handler for removal of VRID during router delete."""
context = payload.context
router_db = payload.latest_state
if router_db.extra_attributes.ha: if router_db.extra_attributes.ha:
ha_network = self.get_ha_network(context, ha_network = self.get_ha_network(context,
router_db.tenant_id) router_db.tenant_id)

View File

@ -67,27 +67,31 @@ class DriverController(object):
@registry.receives(resources.ROUTER, [events.BEFORE_CREATE], @registry.receives(resources.ROUTER, [events.BEFORE_CREATE],
priority_group.PRIORITY_ROUTER_CONTROLLER) priority_group.PRIORITY_ROUTER_CONTROLLER)
def _check_router_request(self, resource, event, trigger, context, def _check_router_request(self, resource, event, trigger, payload):
router, **kwargs):
"""Validates that API request is sane (flags compat with flavor).""" """Validates that API request is sane (flags compat with flavor)."""
context = payload.context
router = payload.latest_state
drv = self._get_provider_for_create(context, router) drv = self._get_provider_for_create(context, router)
_ensure_driver_supports_request(drv, router) _ensure_driver_supports_request(drv, router)
@registry.receives(resources.ROUTER, [events.PRECOMMIT_CREATE], @registry.receives(resources.ROUTER, [events.PRECOMMIT_CREATE],
priority_group.PRIORITY_ROUTER_CONTROLLER) priority_group.PRIORITY_ROUTER_CONTROLLER)
def _set_router_provider(self, resource, event, trigger, context, router, def _set_router_provider(self, resource, event, trigger, payload):
router_db, **kwargs):
"""Associates a router with a service provider. """Associates a router with a service provider.
Association is done by flavor_id if it's specified, otherwise it will Association is done by flavor_id if it's specified, otherwise it will
fallback to determining which loaded driver supports the ha/distributed fallback to determining which loaded driver supports the ha/distributed
attributes associated with the router. attributes associated with the router.
""" """
context = payload.context
router = payload.latest_state
router_db = payload.metadata['router_db']
router_id = payload.resource_id
if _flavor_specified(router): if _flavor_specified(router):
router_db.flavor_id = router['flavor_id'] router_db.flavor_id = router['flavor_id']
drv = self._get_provider_for_create(context, router) drv = self._get_provider_for_create(context, router)
self._stm.add_resource_association(context, plugin_constants.L3, self._stm.add_resource_association(context, plugin_constants.L3,
drv.name, router['id']) drv.name, router_id)
registry.publish( registry.publish(
resources.ROUTER_CONTROLLER, events.PRECOMMIT_ADD_ASSOCIATION, resources.ROUTER_CONTROLLER, events.PRECOMMIT_ADD_ASSOCIATION,
trigger, payload=events.DBEventPayload( trigger, payload=events.DBEventPayload(
@ -97,9 +101,10 @@ class DriverController(object):
@registry.receives(resources.ROUTER, [events.PRECOMMIT_DELETE], @registry.receives(resources.ROUTER, [events.PRECOMMIT_DELETE],
priority_group.PRIORITY_ROUTER_CONTROLLER) priority_group.PRIORITY_ROUTER_CONTROLLER)
def _clear_router_provider(self, resource, event, trigger, context, def _clear_router_provider(self, resource, event, trigger, payload):
router_id, **kwargs):
"""Remove the association between a router and a service provider.""" """Remove the association between a router and a service provider."""
context = payload.context
router_id = payload.resource_id
drv = self.get_provider_for_router(context, router_id) drv = self.get_provider_for_router(context, router_id)
registry.publish( registry.publish(
resources.ROUTER_CONTROLLER, events.PRECOMMIT_DELETE_ASSOCIATIONS, resources.ROUTER_CONTROLLER, events.PRECOMMIT_DELETE_ASSOCIATIONS,

View File

@ -151,8 +151,11 @@ class OVNL3RouterPlugin(service_base.ServicePluginBase,
return ("L3 Router Service Plugin for basic L3 forwarding" return ("L3 Router Service Plugin for basic L3 forwarding"
" using OVN") " using OVN")
def create_router_precommit(self, resource, event, trigger, context, def create_router_precommit(self, resource, event, trigger, payload):
router, router_id, router_db): context = payload.context
router_id = payload.resource_id
router_db = payload.metadata['router_db']
db_rev.create_initial_revision( db_rev.create_initial_revision(
context, router_id, ovn_const.TYPE_ROUTERS, context, router_id, ovn_const.TYPE_ROUTERS,
std_attr_id=router_db.standard_attr.id) std_attr_id=router_db.standard_attr.id)

View File

@ -65,9 +65,9 @@ class L3AgentTestCase(framework.L3AgentTestFramework):
check.assert_called_once_with(router.router_id, None) check.assert_called_once_with(router.router_id, None)
expected_calls = [ expected_calls = [
mock.call('router', 'before_create', self.agent, router=router), mock.call('router', 'before_create', self.agent, payload=mock.ANY),
mock.call('router', 'after_create', self.agent, router=router), mock.call('router', 'after_create', self.agent, router=router),
mock.call('router', 'before_update', self.agent, router=router), mock.call('router', 'before_update', self.agent, payload=mock.ANY),
mock.call('router', 'after_update', self.agent, router=router), mock.call('router', 'after_update', self.agent, router=router),
mock.call('router', 'before_delete', self.agent, payload=mock.ANY), mock.call('router', 'before_delete', self.agent, payload=mock.ANY),
mock.call('router', 'after_delete', self.agent, router=router)] mock.call('router', 'after_delete', self.agent, router=router)]

View File

@ -12,6 +12,8 @@
from unittest import mock from unittest import mock
from neutron_lib.callbacks import events
from neutron.agent.l3 import dvr_edge_router from neutron.agent.l3 import dvr_edge_router
from neutron.agent.l3 import dvr_local_router from neutron.agent.l3 import dvr_local_router
from neutron.agent.l3 import legacy_router from neutron.agent.l3 import legacy_router
@ -36,7 +38,9 @@ class TestPrefixDelegation(tests_base.DietTestCase):
def _test_add_update_pd(self, l3_agent, router, ns_name): def _test_add_update_pd(self, l3_agent, router, ns_name):
# add entry # add entry
pd.add_router(None, None, l3_agent, router=router) pd.add_router(None, None, l3_agent,
payload=events.DBEventPayload(
mock.ANY, states=(router,)))
pd_router = l3_agent.pd.routers.get(router.router_id) pd_router = l3_agent.pd.routers.get(router.router_id)
self.assertEqual(ns_name, pd_router.get('ns_name')) self.assertEqual(ns_name, pd_router.get('ns_name'))

View File

@ -1235,12 +1235,16 @@ class L3DvrTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
def _test__validate_router_migration_notify_advanced_services(self): def _test__validate_router_migration_notify_advanced_services(self):
router = {'name': 'foo_router', 'admin_state_up': False} router = {'name': 'foo_router', 'admin_state_up': False}
router_db = self._create_router(router) router_db = self._create_router(router)
with mock.patch.object(l3_dvr_db.registry, 'notify') as mock_notify: with mock.patch.object(l3_dvr_db.registry, 'publish') as mock_publish:
self.mixin._validate_router_migration( self.mixin._validate_router_migration(
self.ctx, router_db, {'distributed': True}) self.ctx, router_db, {'distributed': True})
kwargs = {'context': self.ctx, 'router': router_db} mock_publish.assert_called_once_with(
mock_notify.assert_called_once_with( 'router', 'before_update', self.mixin,
'router', 'before_update', self.mixin, **kwargs) payload=mock.ANY)
payload = mock_publish.call_args_list[0][1]['payload']
self.assertEqual(self.ctx, payload.context)
self.assertEqual(router_db, payload.latest_state)
def _assert_mock_called_with_router(self, mock_fn, router_id): def _assert_mock_called_with_router(self, mock_fn, router_id):
router = mock_fn.call_args[1].get('router_db') router = mock_fn.call_args[1].get('router_db')

View File

@ -4044,7 +4044,8 @@ class L3AgentDbTestCaseBase(L3NatTestCaseMixin):
events.AFTER_DELETE) events.AFTER_DELETE)
def test_router_create_precommit_event(self): def test_router_create_precommit_event(self):
nset = lambda *a, **k: setattr(k['router_db'], 'name', 'hello') nset = lambda r, e, t, payload: \
setattr(payload.metadata['router_db'], 'name', 'hello')
registry.subscribe(nset, resources.ROUTER, events.PRECOMMIT_CREATE) registry.subscribe(nset, resources.ROUTER, events.PRECOMMIT_CREATE)
with self.router() as r: with self.router() as r:
self.assertEqual('hello', r['router']['name']) self.assertEqual('hello', r['router']['name'])
@ -4089,7 +4090,8 @@ class L3AgentDbTestCaseBase(L3NatTestCaseMixin):
def test_router_delete_precommit_event(self): def test_router_delete_precommit_event(self):
deleted = [] deleted = []
auditor = lambda *a, **k: deleted.append(k['router_id']) auditor = lambda r, e, t, payload: \
deleted.append(payload.resource_id)
registry.subscribe(auditor, resources.ROUTER, events.PRECOMMIT_DELETE) registry.subscribe(auditor, resources.ROUTER, events.PRECOMMIT_DELETE)
with self.router() as r: with self.router() as r:
self._delete('routers', r['router']['id']) self._delete('routers', r['router']['id'])

View File

@ -59,7 +59,11 @@ class TestDriverController(testlib_api.SqlTestCase):
router_id = uuidutils.generate_uuid() router_id = uuidutils.generate_uuid()
router = dict(id=router_id, flavor_id=flavor_id) router = dict(id=router_id, flavor_id=flavor_id)
self.dc._set_router_provider('router', 'PRECOMMIT_CREATE', self, self.dc._set_router_provider('router', 'PRECOMMIT_CREATE', self,
self.ctx, router, router_db) payload=events.DBEventPayload(
self.ctx,
resource_id=router_id,
metadata={'router_db': router_db},
states=(router,)))
self.assertTrue(self.dc.uses_scheduler(self.ctx, router_id)) self.assertTrue(self.dc.uses_scheduler(self.ctx, router_id))
self.dc.drivers['dvrha'].use_integrated_agent_scheduler = False self.dc.drivers['dvrha'].use_integrated_agent_scheduler = False
self.assertFalse(self.dc.uses_scheduler(self.ctx, router_id)) self.assertFalse(self.dc.uses_scheduler(self.ctx, router_id))
@ -72,7 +76,11 @@ class TestDriverController(testlib_api.SqlTestCase):
r2 = uuidutils.generate_uuid() r2 = uuidutils.generate_uuid()
router = dict(id=r1, flavor_id=flavor_id) router = dict(id=r1, flavor_id=flavor_id)
self.dc._set_router_provider('router', 'PRECOMMIT_CREATE', self, self.dc._set_router_provider('router', 'PRECOMMIT_CREATE', self,
self.ctx, router, router_db) payload=events.DBEventPayload(
self.ctx,
resource_id=r1,
metadata={'router_db': router_db},
states=(router,)))
self.assertTrue(self.dc.drivers['dvrha'].owns_router(self.ctx, r1)) self.assertTrue(self.dc.drivers['dvrha'].owns_router(self.ctx, r1))
self.assertFalse(self.dc.drivers['dvr'].owns_router(self.ctx, r1)) self.assertFalse(self.dc.drivers['dvr'].owns_router(self.ctx, r1))
self.assertFalse(self.dc.drivers['dvr'].owns_router(self.ctx, r2)) self.assertFalse(self.dc.drivers['dvr'].owns_router(self.ctx, r2))
@ -86,7 +94,11 @@ class TestDriverController(testlib_api.SqlTestCase):
router_id = uuidutils.generate_uuid() router_id = uuidutils.generate_uuid()
router = dict(id=router_id, flavor_id=flavor_id) router = dict(id=router_id, flavor_id=flavor_id)
self.dc._set_router_provider('router', 'PRECOMMIT_CREATE', self, self.dc._set_router_provider('router', 'PRECOMMIT_CREATE', self,
self.ctx, router, router_db) payload=events.DBEventPayload(
self.ctx,
resource_id=router_id,
metadata={'router_db': router_db},
states=(router,)))
mock_cb.assert_called_with(resources.ROUTER_CONTROLLER, mock_cb.assert_called_with(resources.ROUTER_CONTROLLER,
events.PRECOMMIT_ADD_ASSOCIATION, mock.ANY, events.PRECOMMIT_ADD_ASSOCIATION, mock.ANY,
payload=mock.ANY) payload=mock.ANY)
@ -190,7 +202,12 @@ class TestDriverController(testlib_api.SqlTestCase):
] ]
for driver, body in cases: for driver, body in cases:
self.dc._set_router_provider('router', 'PRECOMMIT_CREATE', self, self.dc._set_router_provider('router', 'PRECOMMIT_CREATE', self,
self.ctx, body, mock.Mock()) payload=events.DBEventPayload(
self.ctx,
resource_id=body['id'],
metadata={
'router_db': mock.Mock()},
states=(body,)))
mock_cb.assert_called_with( mock_cb.assert_called_with(
resources.ROUTER_CONTROLLER, resources.ROUTER_CONTROLLER,
events.PRECOMMIT_ADD_ASSOCIATION, mock.ANY, events.PRECOMMIT_ADD_ASSOCIATION, mock.ANY,
@ -206,7 +223,11 @@ class TestDriverController(testlib_api.SqlTestCase):
router_id1 = uuidutils.generate_uuid() router_id1 = uuidutils.generate_uuid()
body = dict(id=router_id1, distributed=True, ha=True) body = dict(id=router_id1, distributed=True, ha=True)
self.dc._set_router_provider('router', 'PRECOMMIT_CREATE', self, self.dc._set_router_provider('router', 'PRECOMMIT_CREATE', self,
self.ctx, body, mock.Mock()) payload=events.DBEventPayload(
self.ctx,
resource_id=router_id1,
metadata={'router_db': mock.Mock()},
states=(body,)))
mock_cb.assert_called_with(resources.ROUTER_CONTROLLER, mock_cb.assert_called_with(resources.ROUTER_CONTROLLER,
events.PRECOMMIT_ADD_ASSOCIATION, mock.ANY, events.PRECOMMIT_ADD_ASSOCIATION, mock.ANY,
payload=mock.ANY) payload=mock.ANY)
@ -219,7 +240,9 @@ class TestDriverController(testlib_api.SqlTestCase):
self.dc.get_provider_for_router(self.ctx, self.dc.get_provider_for_router(self.ctx,
body['id'])) body['id']))
self.dc._clear_router_provider('router', 'PRECOMMIT_DELETE', self, self.dc._clear_router_provider('router', 'PRECOMMIT_DELETE', self,
self.ctx, body['id']) payload=events.DBEventPayload(
self.ctx,
resource_id=body['id']))
mock_cb.assert_called_with(resources.ROUTER_CONTROLLER, mock_cb.assert_called_with(resources.ROUTER_CONTROLLER,
events.PRECOMMIT_DELETE_ASSOCIATIONS, mock.ANY, events.PRECOMMIT_DELETE_ASSOCIATIONS, mock.ANY,
payload=mock.ANY) payload=mock.ANY)