From 5bc5e8440e7354b78caea37e077509695067bff5 Mon Sep 17 00:00:00 2001 From: Juan Antonio Osorio Robles Date: Mon, 13 Mar 2017 17:25:07 +0200 Subject: [PATCH] Make versioned notifications topics configurable Some services (such as telemetry) actually consume the notifications. So if one deploys a service that listens on the same queue as telemetry, there will be race-conditions with these services and one will not get the notifications that are expected at points. To address this, one sets a different topic and consumes from there. This is not possible with versioned notifications at the moment. And, as services move to using that, the same need will arise. So, this adds a configuration option to nova for enabling the configuration of topics for this notifier. Change-Id: I817ce4bae0dd37e0d06bd44f21ba81b3cb800548 --- nova/conf/notifications.py | 15 +++++++++++++++ nova/rpc.py | 14 ++++++++------ nova/tests/unit/test_notifier.py | 2 ++ nova/tests/unit/test_rpc.py | 19 ++++++++++++++++++- ...-topics-configurable-a4baad995a74a076.yaml | 4 ++++ 5 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 releasenotes/notes/Make-versioned-notifications-topics-configurable-a4baad995a74a076.yaml diff --git a/nova/conf/notifications.py b/nova/conf/notifications.py index fb7ee88abf65..78cca69d35ac 100644 --- a/nova/conf/notifications.py +++ b/nova/conf/notifications.py @@ -99,6 +99,21 @@ Possible values: * both: Both the legacy unversioned and the new versioned notifications are emitted. (Default) +The list of versioned notifications is visible in +http://docs.openstack.org/developer/nova/notifications.html +"""), + cfg.ListOpt( + 'versioned_notifications_topics', + default=['versioned_notifications'], + help=""" +Specifies the topics for the versioned notifications issued by nova. + +The default value is fine for most deployments and rarely needs to be changed. +However, if you have a third-party service that consumes versioned +notifications, it might be worth getting a topic for that service. +Nova will send a message containing a versioned notification payload to each +topic queue in this list. + The list of versioned notifications is visible in http://docs.openstack.org/developer/nova/notifications.html """), diff --git a/nova/rpc.py b/nova/rpc.py index f374a7f4e3f1..54eeb8e8725a 100644 --- a/nova/rpc.py +++ b/nova/rpc.py @@ -85,16 +85,18 @@ def init(conf): elif conf.notifications.notification_format == 'both': LEGACY_NOTIFIER = messaging.Notifier(NOTIFICATION_TRANSPORT, serializer=serializer) - NOTIFIER = messaging.Notifier(NOTIFICATION_TRANSPORT, - serializer=serializer, - topics=['versioned_notifications']) + NOTIFIER = messaging.Notifier( + NOTIFICATION_TRANSPORT, + serializer=serializer, + topics=conf.notifications.versioned_notifications_topics) else: LEGACY_NOTIFIER = messaging.Notifier(NOTIFICATION_TRANSPORT, serializer=serializer, driver='noop') - NOTIFIER = messaging.Notifier(NOTIFICATION_TRANSPORT, - serializer=serializer, - topics=['versioned_notifications']) + NOTIFIER = messaging.Notifier( + NOTIFICATION_TRANSPORT, + serializer=serializer, + topics=conf.notifications.versioned_notifications_topics) def cleanup(): diff --git a/nova/tests/unit/test_notifier.py b/nova/tests/unit/test_notifier.py index d77f69d30a62..743e05bb22a0 100644 --- a/nova/tests/unit/test_notifier.py +++ b/nova/tests/unit/test_notifier.py @@ -29,6 +29,8 @@ class TestNotifier(test.NoDBTestCase): mock_noti_trans, mock_transport): conf = mock.Mock() + conf.notifications.versioned_notifications_topics = [ + 'versioned_notifications'] cases = { 'unversioned': [ diff --git a/nova/tests/unit/test_rpc.py b/nova/tests/unit/test_rpc.py index 0c49762c9e1a..41eff64277d1 100644 --- a/nova/tests/unit/test_rpc.py +++ b/nova/tests/unit/test_rpc.py @@ -85,6 +85,20 @@ class TestRPC(testtools.TestCase): self._test_init(mock_notif, mock_noti_trans, mock_ser, mock_exmods, 'versioned', expected) + @mock.patch.object(rpc, 'get_allowed_exmods') + @mock.patch.object(rpc, 'RequestContextSerializer') + @mock.patch.object(messaging, 'get_notification_transport') + @mock.patch.object(messaging, 'Notifier') + def test_init_versioned_with_custom_topics(self, mock_notif, + mock_noti_trans, mock_ser, + mock_exmods): + expected = [{'driver': 'noop'}, + {'topics': ['custom_topic1', 'custom_topic2']}] + self._test_init( + mock_notif, mock_noti_trans, mock_ser, mock_exmods, 'versioned', + expected, versioned_notification_topics=['custom_topic1', + 'custom_topic2']) + def test_cleanup_transport_null(self): rpc.NOTIFICATION_TRANSPORT = mock.Mock() rpc.LEGACY_NOTIFIER = mock.Mock() @@ -304,7 +318,8 @@ class TestRPC(testtools.TestCase): aliases=rpc.TRANSPORT_ALIASES) def _test_init(self, mock_notif, mock_noti_trans, mock_ser, - mock_exmods, notif_format, expected_driver_topic_kwargs): + mock_exmods, notif_format, expected_driver_topic_kwargs, + versioned_notification_topics=['versioned_notifications']): legacy_notifier = mock.Mock() notifier = mock.Mock() notif_transport = mock.Mock() @@ -314,6 +329,8 @@ class TestRPC(testtools.TestCase): conf.transport_url = None conf.notifications.notification_format = notif_format + conf.notifications.versioned_notifications_topics = ( + versioned_notification_topics) mock_exmods.return_value = ['foo'] mock_noti_trans.return_value = notif_transport mock_ser.return_value = serializer diff --git a/releasenotes/notes/Make-versioned-notifications-topics-configurable-a4baad995a74a076.yaml b/releasenotes/notes/Make-versioned-notifications-topics-configurable-a4baad995a74a076.yaml new file mode 100644 index 000000000000..208a8fefcfda --- /dev/null +++ b/releasenotes/notes/Make-versioned-notifications-topics-configurable-a4baad995a74a076.yaml @@ -0,0 +1,4 @@ +--- +features: + - The versioned_notifications_topic configuration option; This enables one to + configure the topics used for versioned notifications.