Add router precommit events
This adds PRECOMMIT callback events to the basic router DB operations (create/update/delete). These are leveraged by the dependent patch for flavor and provider processing. This also adds a small context manager to the callback manager to make it simple to reraise the original first exception raised during the callback processing to avoid littering the exception unpacking logic around every 'notify' call. Partially-Implements: bp/multi-l3-backends Change-Id: I0479f0054f9c22f8021531c54b138179f9688de5
This commit is contained in:
parent
2862c261d3
commit
6bce4d5ea9
|
@ -216,14 +216,18 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
|||
# pre-generate id so it will be available when
|
||||
# configuring external gw port
|
||||
status = router.get('status', n_const.ROUTER_STATUS_ACTIVE)
|
||||
router_db = Router(id=(router.get('id') or
|
||||
uuidutils.generate_uuid()),
|
||||
tenant_id=tenant_id,
|
||||
router.setdefault('id', uuidutils.generate_uuid())
|
||||
router['tenant_id'] = tenant_id
|
||||
router_db = Router(id=router['id'],
|
||||
tenant_id=router['tenant_id'],
|
||||
name=router['name'],
|
||||
admin_state_up=router['admin_state_up'],
|
||||
status=status,
|
||||
description=router.get('description'))
|
||||
context.session.add(router_db)
|
||||
registry.notify(resources.ROUTER, events.PRECOMMIT_CREATE,
|
||||
self, context=context, router=router,
|
||||
router_id=router['id'], router_db=router_db)
|
||||
return router_db
|
||||
|
||||
def create_router(self, context, router):
|
||||
|
@ -245,8 +249,13 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
|||
"""Update the DB object."""
|
||||
with context.session.begin(subtransactions=True):
|
||||
router_db = self._get_router(context, router_id)
|
||||
old_router = self._make_router_dict(router_db)
|
||||
if data:
|
||||
router_db.update(data)
|
||||
registry.notify(resources.ROUTER, events.PRECOMMIT_UPDATE,
|
||||
self, context=context, router_id=router_id,
|
||||
router=data, router_db=router_db,
|
||||
old_router=old_router)
|
||||
return router_db
|
||||
|
||||
def update_router(self, context, id, router):
|
||||
|
@ -521,6 +530,8 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
|||
rp.port.id,
|
||||
l3_port_check=False)
|
||||
with context.session.begin(subtransactions=True):
|
||||
registry.notify(resources.ROUTER, events.PRECOMMIT_DELETE,
|
||||
self, context=context, router_id=id)
|
||||
context.session.delete(router)
|
||||
|
||||
def get_router(self, context, id, fields=None):
|
||||
|
|
|
@ -3030,6 +3030,66 @@ class L3AgentDbTestCaseBase(L3NatTestCaseMixin):
|
|||
def test_floatingips_op_agent(self):
|
||||
self._test_notify_op_agent(self._test_floatingips_op_agent)
|
||||
|
||||
def test_router_create_precommit_event(self):
|
||||
nset = lambda *a, **k: setattr(k['router_db'], 'name', 'hello')
|
||||
registry.subscribe(nset, resources.ROUTER, events.PRECOMMIT_CREATE)
|
||||
with self.router() as r:
|
||||
self.assertEqual('hello', r['router']['name'])
|
||||
|
||||
def test_router_create_event_exception_preserved(self):
|
||||
# this exception should be propagated out of the callback and
|
||||
# converted into its API equivalent of 404
|
||||
e404 = mock.Mock(side_effect=l3.RouterNotFound(router_id='1'))
|
||||
registry.subscribe(e404, resources.ROUTER, events.PRECOMMIT_CREATE)
|
||||
res = self._create_router(self.fmt, 'tenid')
|
||||
self.assertEqual(exc.HTTPNotFound.code, res.status_int)
|
||||
# make sure nothing committed
|
||||
body = self._list('routers')
|
||||
self.assertFalse(body['routers'])
|
||||
|
||||
def test_router_update_precommit_event(self):
|
||||
nset = lambda *a, **k: setattr(k['router_db'], 'name',
|
||||
k['old_router']['name'] + '_ha!')
|
||||
registry.subscribe(nset, resources.ROUTER, events.PRECOMMIT_UPDATE)
|
||||
with self.router(name='original') as r:
|
||||
update = self._update('routers', r['router']['id'],
|
||||
{'router': {'name': 'hi'}})
|
||||
# our rude callback should have changed the name to the original
|
||||
# plus some extra
|
||||
self.assertEqual('original_ha!', update['router']['name'])
|
||||
|
||||
def test_router_update_event_exception_preserved(self):
|
||||
# this exception should be propagated out of the callback and
|
||||
# converted into its API equivalent of 404
|
||||
e404 = mock.Mock(side_effect=l3.RouterNotFound(router_id='1'))
|
||||
registry.subscribe(e404, resources.ROUTER, events.PRECOMMIT_UPDATE)
|
||||
with self.router(name='a') as r:
|
||||
self._update('routers', r['router']['id'],
|
||||
{'router': {'name': 'hi'}},
|
||||
expected_code=exc.HTTPNotFound.code)
|
||||
# ensure it stopped the commit
|
||||
new = self._show('routers', r['router']['id'])
|
||||
self.assertEqual('a', new['router']['name'])
|
||||
|
||||
def test_router_delete_precommit_event(self):
|
||||
deleted = []
|
||||
auditor = lambda *a, **k: deleted.append(k['router_id'])
|
||||
registry.subscribe(auditor, resources.ROUTER, events.PRECOMMIT_DELETE)
|
||||
with self.router() as r:
|
||||
self._delete('routers', r['router']['id'])
|
||||
self.assertEqual([r['router']['id']], deleted)
|
||||
|
||||
def test_router_delete_event_exception_preserved(self):
|
||||
# this exception should be propagated out of the callback and
|
||||
# converted into its API equivalent of 409
|
||||
e409 = mock.Mock(side_effect=l3.RouterInUse(router_id='1'))
|
||||
registry.subscribe(e409, resources.ROUTER, events.PRECOMMIT_DELETE)
|
||||
with self.router() as r:
|
||||
self._delete('routers', r['router']['id'],
|
||||
expected_code=exc.HTTPConflict.code)
|
||||
# ensure it stopped the commit
|
||||
self.assertTrue(self._show('routers', r['router']['id']))
|
||||
|
||||
|
||||
class L3BaseForIntTests(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue