diff --git a/ceilometer/notification.py b/ceilometer/notification.py index 56ea03af8e..33f24be954 100644 --- a/ceilometer/notification.py +++ b/ceilometer/notification.py @@ -94,7 +94,12 @@ class NotificationService(os_service.Service): {'name': ext.name, 'type': ', '.join(handler.event_types), 'error': ack_on_error}) - targets.extend(handler.get_targets(cfg.CONF)) + # NOTE(gordc): this could be a set check but oslo.messaging issue + # https://bugs.launchpad.net/oslo.messaging/+bug/1398511 + # This ensures we don't create multiple duplicate consumers. + for new_tar in handler.get_targets(cfg.CONF): + if new_tar not in targets: + targets.append(new_tar) endpoints.append(handler) urls = cfg.CONF.notification.messaging_urls or [None] diff --git a/ceilometer/tests/test_notification.py b/ceilometer/tests/test_notification.py index c105d9a0ce..a13e745ba3 100644 --- a/ceilometer/tests/test_notification.py +++ b/ceilometer/tests/test_notification.py @@ -163,6 +163,24 @@ class TestNotification(tests_base.BaseTestCase): event_endpoint = self.srv.listeners[0].dispatcher.endpoints[0] self.assertEqual(1, len(list(event_endpoint.dispatcher_manager))) + @mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock()) + @mock.patch.object(oslo.messaging.MessageHandlingServer, 'start', + mock.MagicMock()) + @mock.patch('ceilometer.event.endpoint.EventsNotificationEndpoint') + def test_unique_consumers(self, fake_event_endpoint_class): + + def fake_get_notifications_manager_dup_targets(pm): + plugin = instance.Instance(pm) + return extension.ExtensionManager.make_test_instance( + [extension.Extension('test', None, None, plugin), + extension.Extension('test', None, None, plugin)]) + + with mock.patch.object(self.srv, + '_get_notifications_manager') as get_nm: + get_nm.side_effect = fake_get_notifications_manager_dup_targets + self.srv.start() + self.assertEqual(1, len(self.srv.listeners[0].dispatcher.targets)) + class TestRealNotification(tests_base.BaseTestCase): def setUp(self):