diff options
-rw-r--r-- | oslo/messaging/notify/notifier.py | 56 | ||||
-rw-r--r-- | tests/test_notifier.py | 22 |
2 files changed, 70 insertions, 8 deletions
diff --git a/oslo/messaging/notify/notifier.py b/oslo/messaging/notify/notifier.py index 66f23f3..e250053 100644 --- a/oslo/messaging/notify/notifier.py +++ b/oslo/messaging/notify/notifier.py @@ -60,7 +60,7 @@ class Notifier(object): The Notifier class is used for sending notification messages over a messaging transport or other means. - Notification messages follow the following format: + Notification messages follow the following format:: {'message_id': str(uuid.uuid4()), 'publisher_id': 'compute.host1', @@ -72,22 +72,29 @@ class Notifier(object): A Notifier object can be instantiated with a transport object and a publisher ID: - notifier = notifier.Notifier(get_transport(CONF), 'compute.host1') + notifier = notifier.Notifier(get_transport(CONF), 'compute') and notifications are sent via drivers chosen with the notification_driver config option and on the topics consen with the notification_topics config option. Alternatively, a Notifier object can be instantiated with a specific - driver or topic: + driver or topic:: notifier = notifier.Notifier(RPC_TRANSPORT, 'compute.host', driver='messaging', topic='notifications') + + Notifier objects are relatively expensive to instantiate (mostly the cost + of loading notification drivers), so it is possible to specialize a given + Notifier object with a different publisher id using the prepare() method:: + + notifier = notifier.prepare(publisher_id='compute') + notifier.info(ctxt, event_type, payload) """ - def __init__(self, transport, publisher_id, + def __init__(self, transport, publisher_id=None, driver=None, topic=None, serializer=None): """Construct a Notifier object. @@ -127,12 +134,26 @@ class Notifier(object): }, ) - def _notify(self, ctxt, event_type, payload, priority): + _marker = object() + + def prepare(self, publisher_id=_marker): + """Return a specialized Notifier instance. + + Returns a new Notifier instance with the supplied publisher_id. Allows + sending notifications from multiple publisher_ids without the overhead + of notification driver loading. + + :param publisher_id: field in notifications sent, e.g. 'compute.host1' + :type publisher_id: str + """ + return _SubNotifier._prepare(self, publisher_id) + + def _notify(self, ctxt, event_type, payload, priority, publisher_id=None): payload = self._serializer.serialize_entity(ctxt, payload) ctxt = self._serializer.serialize_context(ctxt) msg = dict(message_id=uuidutils.generate_uuid(), - publisher_id=self.publisher_id, + publisher_id=publisher_id or self.publisher_id, event_type=event_type, priority=priority, payload=payload, @@ -208,3 +229,26 @@ class Notifier(object): :type payload: dict """ self._notify(ctxt, event_type, payload, 'CRITICAL') + + +class _SubNotifier(Notifier): + + _marker = Notifier._marker + + def __init__(self, base, publisher_id): + self._base = base + self.conf = base.conf + self.transport = base.transport + self.publisher_id = publisher_id + + self._serializer = self._base._serializer + self._driver_mgr = self._base._driver_mgr + + def _notify(self, ctxt, event_type, payload, priority): + super(_SubNotifier, self)._notify(ctxt, event_type, payload, priority) + + @classmethod + def _prepare(cls, base, publisher_id=_marker): + if publisher_id is cls._marker: + publisher_id = base.publisher_id + return cls(base, publisher_id) diff --git a/tests/test_notifier.py b/tests/test_notifier.py index 6ee2842..2b32383 100644 --- a/tests/test_notifier.py +++ b/tests/test_notifier.py @@ -82,6 +82,16 @@ class TestMessagingNotifier(test_utils.BaseTestCase): ('not_v2', dict(v2=False)), ] + _publisher_id = [ + ('ctor_pub_id', dict(ctor_pub_id='test', + expected_pub_id='test')), + ('prep_pub_id', dict(prep_pub_id='test.localhost', + expected_pub_id='test.localhost')), + ('override', dict(ctor_pub_id='test', + prep_pub_id='test.localhost', + expected_pub_id='test.localhost')), + ] + _topics = [ ('no_topics', dict(topics=[])), ('single_topic', dict(topics=['notifications'])), @@ -108,6 +118,7 @@ class TestMessagingNotifier(test_utils.BaseTestCase): def generate_scenarios(cls): cls.scenarios = testscenarios.multiply_scenarios(cls._v1, cls._v2, + cls._publisher_id, cls._topics, cls._priority, cls._payload, @@ -136,7 +147,14 @@ class TestMessagingNotifier(test_utils.BaseTestCase): transport = _FakeTransport(self.conf) - notifier = messaging.Notifier(transport, 'test.localhost') + if hasattr(self, 'ctor_pub_id'): + notifier = messaging.Notifier(transport, + publisher_id=self.ctor_pub_id) + else: + notifier = messaging.Notifier(transport) + + if hasattr(self, 'prep_pub_id'): + notifier = notifier.prepare(publisher_id=self.prep_pub_id) self.mox.StubOutWithMock(transport, '_send_notification') @@ -148,7 +166,7 @@ class TestMessagingNotifier(test_utils.BaseTestCase): message = { 'message_id': str(message_id), - 'publisher_id': 'test.localhost', + 'publisher_id': self.expected_pub_id, 'event_type': 'test.notify', 'priority': self.priority.upper(), 'payload': self.payload, |