Remove deprecated method registry.notify
All Neutron code now is using payload style callback. After stadium projects code will be switch to payload style callback notify() can be removed Depends-On: https://review.opendev.org/c/openstack/neutron-dynamic-routing/+/808024 Depends-On: https://review.opendev.org/c/openstack/networking-odl/+/808028 Change-Id: I4dd0d65f0e7b2c5161f725e542b795e0ba4ba2fe
This commit is contained in:
parent
64e4dc29a4
commit
ecb63131ec
@ -128,6 +128,7 @@ class CallbacksManager(object):
|
||||
callback_id)
|
||||
del self._index[callback_id]
|
||||
|
||||
@db_utils.reraise_as_retryrequest
|
||||
def publish(self, resource, event, trigger, payload=None):
|
||||
"""Notify all subscribed callback(s) with a payload.
|
||||
|
||||
@ -146,30 +147,12 @@ class CallbacksManager(object):
|
||||
if not isinstance(payload, events.EventPayload):
|
||||
raise exceptions.Invalid(element='event payload',
|
||||
value=type(payload))
|
||||
return self.notify(resource, event, trigger, payload=payload)
|
||||
|
||||
# NOTE(boden): We plan to deprecate the usage of this method and **kwargs
|
||||
# as the payload in Queens, but no warning here to avoid log flooding
|
||||
@db_utils.reraise_as_retryrequest
|
||||
def notify(self, resource, event, trigger, **kwargs):
|
||||
"""Notify all subscribed callback(s).
|
||||
|
||||
Dispatch the resource's event to the subscribed callbacks.
|
||||
|
||||
:param resource: The resource for the event.
|
||||
:param event: The event.
|
||||
:param trigger: The trigger. A reference to the sender of the event.
|
||||
:param kwargs: (deprecated) Unstructured key/value pairs to invoke
|
||||
the callback with. Using event objects with publish() is preferred.
|
||||
:raises CallbackFailure: CallbackFailure is raised if the underlying
|
||||
callback has errors.
|
||||
"""
|
||||
errors = self._notify_loop(resource, event, trigger, **kwargs)
|
||||
errors = self._notify_loop(resource, event, trigger, payload)
|
||||
if errors:
|
||||
if event.startswith(events.BEFORE):
|
||||
abort_event = event.replace(
|
||||
events.BEFORE, events.ABORT)
|
||||
self._notify_loop(resource, abort_event, trigger, **kwargs)
|
||||
self._notify_loop(resource, abort_event, trigger, payload)
|
||||
|
||||
raise exceptions.CallbackFailure(errors=errors)
|
||||
|
||||
@ -181,7 +164,7 @@ class CallbacksManager(object):
|
||||
self._callbacks = collections.defaultdict(dict)
|
||||
self._index = collections.defaultdict(dict)
|
||||
|
||||
def _notify_loop(self, resource, event, trigger, **kwargs):
|
||||
def _notify_loop(self, resource, event, trigger, payload):
|
||||
"""The notification loop."""
|
||||
errors = []
|
||||
# NOTE(yamahata): Since callback may unsubscribe it,
|
||||
@ -189,12 +172,12 @@ class CallbacksManager(object):
|
||||
callbacks = list(itertools.chain(
|
||||
*[pri_callbacks.items() for (priority, pri_callbacks)
|
||||
in self._callbacks[resource].get(event, [])]))
|
||||
LOG.debug("Notify callbacks %s for %s, %s",
|
||||
LOG.debug("Publish callbacks %s for %s, %s",
|
||||
[c[0] for c in callbacks], resource, event)
|
||||
# TODO(armax): consider using a GreenPile
|
||||
for callback_id, callback in callbacks:
|
||||
try:
|
||||
callback(resource, event, trigger, **kwargs)
|
||||
callback(resource, event, trigger, payload=payload)
|
||||
except Exception as e:
|
||||
abortable_event = (
|
||||
event.startswith(events.BEFORE) or
|
||||
|
@ -50,12 +50,6 @@ def unsubscribe_all(callback):
|
||||
_get_callback_manager().unsubscribe_all(callback)
|
||||
|
||||
|
||||
# NOTE(boden): This method is deprecated in favor of publish() and will be
|
||||
# removed in Queens, but not deprecation message to reduce log flooding
|
||||
def notify(resource, event, trigger, **kwargs):
|
||||
_get_callback_manager().notify(resource, event, trigger, **kwargs)
|
||||
|
||||
|
||||
def publish(resource, event, trigger, payload=None):
|
||||
_get_callback_manager().publish(resource, event, trigger, payload=payload)
|
||||
|
||||
|
@ -73,6 +73,7 @@ class CallBacksManagerTestCase(base.BaseTestCase):
|
||||
def setUp(self):
|
||||
super(CallBacksManagerTestCase, self).setUp()
|
||||
self.manager = manager.CallbacksManager()
|
||||
self.event_payload = events.EventPayload(object())
|
||||
callback_1.counter = 0
|
||||
callback_2.counter = 0
|
||||
callback_3.counter = 0
|
||||
@ -124,7 +125,8 @@ class CallBacksManagerTestCase(base.BaseTestCase):
|
||||
|
||||
self.manager.subscribe(unsub, resources.PORT,
|
||||
events.BEFORE_CREATE)
|
||||
self.manager.notify(resources.PORT, events.BEFORE_CREATE, mock.ANY)
|
||||
self.manager.publish(resources.PORT, events.BEFORE_CREATE, mock.ANY,
|
||||
payload=self.event_payload)
|
||||
self.assertNotIn(unsub, self.manager._index)
|
||||
|
||||
def test_unsubscribe(self):
|
||||
@ -199,58 +201,70 @@ class CallBacksManagerTestCase(base.BaseTestCase):
|
||||
self.manager._callbacks[resources.PORT][events.BEFORE_CREATE])
|
||||
self.assertNotIn(callback_id_1, self.manager._index)
|
||||
|
||||
def test_notify_none(self):
|
||||
self.manager.notify(resources.PORT, events.BEFORE_CREATE, mock.ANY)
|
||||
def test_publish_none(self):
|
||||
self.manager.publish(resources.PORT, events.BEFORE_CREATE, mock.ANY,
|
||||
payload=self.event_payload)
|
||||
self.assertEqual(0, callback_1.counter)
|
||||
self.assertEqual(0, callback_2.counter)
|
||||
|
||||
def test_feebly_referenced_callback(self):
|
||||
self.manager.subscribe(lambda *x, **y: None, resources.PORT,
|
||||
events.BEFORE_CREATE)
|
||||
self.manager.notify(resources.PORT, events.BEFORE_CREATE, mock.ANY)
|
||||
self.manager.publish(resources.PORT, events.BEFORE_CREATE, mock.ANY,
|
||||
payload=self.event_payload)
|
||||
|
||||
def test_notify_with_exception(self):
|
||||
def test_publish_with_exception(self):
|
||||
with mock.patch.object(self.manager, '_notify_loop') as n:
|
||||
n.return_value = ['error']
|
||||
self.assertRaises(exceptions.CallbackFailure,
|
||||
self.manager.notify,
|
||||
mock.ANY, events.BEFORE_CREATE, mock.ANY)
|
||||
self.manager.publish,
|
||||
mock.ANY, events.BEFORE_CREATE, mock.ANY,
|
||||
payload=self.event_payload)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY, 'before_create', mock.ANY),
|
||||
mock.call(mock.ANY, 'abort_create', mock.ANY)
|
||||
mock.call(mock.ANY, 'before_create', mock.ANY,
|
||||
self.event_payload),
|
||||
mock.call(mock.ANY, 'abort_create', mock.ANY,
|
||||
self.event_payload)
|
||||
]
|
||||
n.assert_has_calls(expected_calls)
|
||||
|
||||
def test_notify_with_precommit_exception(self):
|
||||
def test_publish_with_precommit_exception(self):
|
||||
with mock.patch.object(self.manager, '_notify_loop') as n:
|
||||
n.return_value = ['error']
|
||||
self.assertRaises(exceptions.CallbackFailure,
|
||||
self.manager.notify,
|
||||
mock.ANY, events.PRECOMMIT_UPDATE, mock.ANY)
|
||||
self.manager.publish,
|
||||
mock.ANY, events.PRECOMMIT_UPDATE, mock.ANY,
|
||||
payload=self.event_payload)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY, 'precommit_update', mock.ANY),
|
||||
mock.call(mock.ANY, 'precommit_update', mock.ANY,
|
||||
self.event_payload),
|
||||
]
|
||||
n.assert_has_calls(expected_calls)
|
||||
|
||||
def test_notify_handle_exception(self):
|
||||
def test_publish_handle_exception(self):
|
||||
self.manager.subscribe(
|
||||
callback_raise, resources.PORT, events.BEFORE_CREATE)
|
||||
e = self.assertRaises(exceptions.CallbackFailure, self.manager.notify,
|
||||
resources.PORT, events.BEFORE_CREATE, self)
|
||||
e = self.assertRaises(exceptions.CallbackFailure, self.manager.publish,
|
||||
resources.PORT, events.BEFORE_CREATE, self,
|
||||
payload=self.event_payload)
|
||||
self.assertIsInstance(e.errors[0], exceptions.NotificationError)
|
||||
|
||||
def test_notify_handle_retriable_exception(self):
|
||||
def test_publish_handle_retriable_exception(self):
|
||||
self.manager.subscribe(
|
||||
callback_raise_retriable, resources.PORT, events.BEFORE_CREATE)
|
||||
self.assertRaises(db_exc.RetryRequest, self.manager.notify,
|
||||
resources.PORT, events.BEFORE_CREATE, self)
|
||||
self.assertRaises(db_exc.RetryRequest, self.manager.publish,
|
||||
resources.PORT, events.BEFORE_CREATE, self,
|
||||
payload=self.event_payload)
|
||||
|
||||
def test_notify_called_once_with_no_failures(self):
|
||||
def test_publish_called_once_with_no_failures(self):
|
||||
with mock.patch.object(self.manager, '_notify_loop') as n:
|
||||
n.return_value = False
|
||||
self.manager.notify(resources.PORT, events.BEFORE_CREATE, mock.ANY)
|
||||
self.manager.publish(resources.PORT, events.BEFORE_CREATE,
|
||||
mock.ANY,
|
||||
payload=self.event_payload)
|
||||
n.assert_called_once_with(
|
||||
resources.PORT, events.BEFORE_CREATE, mock.ANY)
|
||||
resources.PORT, events.BEFORE_CREATE, mock.ANY,
|
||||
self.event_payload)
|
||||
|
||||
def test__notify_loop_single_event(self):
|
||||
self.manager.subscribe(
|
||||
@ -258,7 +272,8 @@ class CallBacksManagerTestCase(base.BaseTestCase):
|
||||
self.manager.subscribe(
|
||||
callback_2, resources.PORT, events.BEFORE_CREATE)
|
||||
self.manager._notify_loop(
|
||||
resources.PORT, events.BEFORE_CREATE, mock.ANY)
|
||||
resources.PORT, events.BEFORE_CREATE, mock.ANY,
|
||||
payload=mock.ANY)
|
||||
self.assertEqual(1, callback_1.counter)
|
||||
self.assertEqual(1, callback_2.counter)
|
||||
|
||||
@ -270,9 +285,11 @@ class CallBacksManagerTestCase(base.BaseTestCase):
|
||||
self.manager.subscribe(
|
||||
callback_2, resources.PORT, events.BEFORE_CREATE)
|
||||
self.manager._notify_loop(
|
||||
resources.PORT, events.BEFORE_CREATE, mock.ANY)
|
||||
resources.PORT, events.BEFORE_CREATE, mock.ANY,
|
||||
payload=mock.ANY)
|
||||
self.manager._notify_loop(
|
||||
resources.ROUTER, events.BEFORE_DELETE, mock.ANY)
|
||||
resources.ROUTER, events.BEFORE_DELETE, mock.ANY,
|
||||
payload=mock.ANY)
|
||||
self.assertEqual(2, callback_1.counter)
|
||||
self.assertEqual(1, callback_2.counter)
|
||||
|
||||
@ -320,7 +337,8 @@ class CallBacksManagerTestCase(base.BaseTestCase):
|
||||
self.assertEqual(
|
||||
3, len(self.manager._callbacks['my-resource']['my-event']))
|
||||
self.manager.unsubscribe(callback_3, 'my-resource', 'my-event')
|
||||
self.manager.notify('my-resource', 'my-event', mock.ANY)
|
||||
self.manager.publish('my-resource', 'my-event', mock.ANY,
|
||||
payload=self.event_payload)
|
||||
# callback_3 should be deleted and not executed
|
||||
self.assertEqual(
|
||||
2, len(self.manager._callbacks['my-resource']['my-event']))
|
||||
@ -340,9 +358,10 @@ class CallBacksManagerTestCase(base.BaseTestCase):
|
||||
self.manager.subscribe(
|
||||
callback_raise, resources.PORT, events.PRECOMMIT_CREATE)
|
||||
self.manager._notify_loop(
|
||||
resources.PORT, events.BEFORE_CREATE, mock.ANY)
|
||||
resources.PORT, events.BEFORE_CREATE, mock.ANY, payload=mock.ANY)
|
||||
self.manager._notify_loop(
|
||||
resources.PORT, events.PRECOMMIT_CREATE, mock.ANY)
|
||||
resources.PORT, events.PRECOMMIT_CREATE, mock.ANY,
|
||||
payload=mock.ANY)
|
||||
self.assertFalse(_logger.exception.call_count)
|
||||
self.assertTrue(_logger.debug.call_count)
|
||||
|
||||
@ -357,7 +376,8 @@ class CallBacksManagerTestCase(base.BaseTestCase):
|
||||
# ensure idempotency remains for a single object
|
||||
self.manager.subscribe(
|
||||
o.callback, resources.PORT, events.BEFORE_CREATE)
|
||||
self.manager.notify(resources.PORT, events.BEFORE_CREATE, mock.ANY)
|
||||
self.manager.publish(resources.PORT, events.BEFORE_CREATE, mock.ANY,
|
||||
payload=events.EventPayload(object()))
|
||||
self.assertEqual(1, a.counter)
|
||||
self.assertEqual(1, b.counter)
|
||||
self.assertEqual(1, c.counter)
|
||||
@ -384,6 +404,5 @@ class CallBacksManagerTestCase(base.BaseTestCase):
|
||||
notify_payload.append(payload)
|
||||
|
||||
self.manager.subscribe(_memo, 'x', 'y')
|
||||
payload = events.EventPayload(object())
|
||||
self.manager.publish('x', 'y', self, payload=payload)
|
||||
self.assertEqual(payload, notify_payload[0])
|
||||
self.manager.publish('x', 'y', self, payload=self.event_payload)
|
||||
self.assertEqual(self.event_payload, notify_payload[0])
|
||||
|
@ -74,19 +74,26 @@ class CallBacksManagerTestCase(base.BaseTestCase):
|
||||
|
||||
def test_decorated_inst_method_receives(self):
|
||||
i1 = ObjectWithDecoratedCallback()
|
||||
registry.notify(resources.PORT, events.BEFORE_CREATE, self)
|
||||
event_payload = events.EventPayload(mock.ANY)
|
||||
registry.publish(resources.PORT, events.BEFORE_CREATE, self,
|
||||
payload=event_payload)
|
||||
self.assertEqual(0, i1.counter)
|
||||
registry.notify(resources.PORT, events.AFTER_CREATE, self)
|
||||
registry.publish(resources.PORT, events.AFTER_CREATE, self,
|
||||
payload=event_payload)
|
||||
self.assertEqual(1, i1.counter)
|
||||
registry.notify(resources.PORT, events.AFTER_UPDATE, self)
|
||||
registry.publish(resources.PORT, events.AFTER_UPDATE, self,
|
||||
payload=event_payload)
|
||||
self.assertEqual(2, i1.counter)
|
||||
registry.notify(resources.NETWORK, events.AFTER_UPDATE, self)
|
||||
registry.publish(resources.NETWORK, events.AFTER_UPDATE, self,
|
||||
payload=event_payload)
|
||||
self.assertEqual(2, i1.counter)
|
||||
registry.notify(resources.NETWORK, events.AFTER_DELETE, self)
|
||||
registry.publish(resources.NETWORK, events.AFTER_DELETE, self,
|
||||
payload=event_payload)
|
||||
self.assertEqual(3, i1.counter)
|
||||
i2 = ObjectWithDecoratedCallback()
|
||||
self.assertEqual(0, i2.counter)
|
||||
registry.notify(resources.NETWORK, events.AFTER_DELETE, self)
|
||||
registry.publish(resources.NETWORK, events.AFTER_DELETE, self,
|
||||
payload=event_payload)
|
||||
self.assertEqual(4, i1.counter)
|
||||
self.assertEqual(1, i2.counter)
|
||||
|
||||
@ -148,11 +155,6 @@ class TestCallbackRegistryDispatching(base.BaseTestCase):
|
||||
self.callback_manager.unsubscribe_all.assert_called_with(
|
||||
my_callback)
|
||||
|
||||
def test_notify(self):
|
||||
registry.notify('my-resource', 'my-event', mock.ANY)
|
||||
self.callback_manager.notify.assert_called_with(
|
||||
'my-resource', 'my-event', mock.ANY)
|
||||
|
||||
def test_clear(self):
|
||||
registry.clear()
|
||||
self.callback_manager.clear.assert_called_with()
|
||||
|
@ -50,8 +50,8 @@ class CallbackRegistryFixtureTestCase(base.BaseTestCase):
|
||||
callback_manager=self.manager))
|
||||
|
||||
def test_fixture(self):
|
||||
registry.notify('a', 'b', self)
|
||||
self.assertTrue(self.manager.notify.called)
|
||||
registry.publish('a', 'b', self, payload=mock.ANY)
|
||||
self.assertTrue(self.manager.publish.called)
|
||||
|
||||
|
||||
class SqlFixtureTestCase(base.BaseTestCase):
|
||||
|
@ -57,8 +57,9 @@ class TestBaseWorker(base.BaseTestCase):
|
||||
def test_start_callback_event(self):
|
||||
base_worker = _BaseWorker()
|
||||
base_worker.start()
|
||||
self._reg.notify.assert_called_once_with(
|
||||
resources.PROCESS, events.AFTER_INIT, base_worker.start)
|
||||
self._reg.publish.assert_called_once_with(
|
||||
resources.PROCESS, events.AFTER_INIT, base_worker.start,
|
||||
payload=mock.ANY)
|
||||
|
||||
# Forked workers, should call setproctitle
|
||||
|
||||
|
@ -108,4 +108,4 @@ class BaseWorker(service.ServiceBase):
|
||||
desc = desc or self.desc
|
||||
self.setproctitle(name, desc)
|
||||
if self.worker_process_count > 0:
|
||||
registry.notify(resources.PROCESS, events.AFTER_INIT, self.start)
|
||||
registry.publish(resources.PROCESS, events.AFTER_INIT, self.start)
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
other:
|
||||
- The deprecated method neutron_lib.callbacks.registry.notify()`` and
|
||||
``neutron_lib.callbacks.manager.CallbacksManager.notify()`` has been
|
||||
removed in favor of their ``publish()`` counterparts
|
Loading…
x
Reference in New Issue
Block a user