Browse Source

Disable notifications

As part of the manila-telemetry integration work
we are now triggering notifications for several
events. We should provide a way to disable those.

In this patch-set we define a decorator that can be
used to change the behavior of those classes used
to emit notification.

Partially-Implements: bp ceilometer-integration

Change-Id: I806e0133e9fe3ad5cc35ad1e000e5ca61ff3b8ca
changes/36/482136/4
Victoria Martinez de la Cruz 4 years ago
parent
commit
e745fb7a8f
  1. 12
      manila/rpc.py
  2. 2
      manila/share/utils.py
  3. 11
      manila/test.py
  4. 2
      manila/tests/fake_notifier.py
  5. 41
      manila/tests/test_rpc.py
  6. 36
      manila/tests/test_utils.py
  7. 32
      manila/utils.py

12
manila/rpc.py

@ -32,6 +32,7 @@ from oslo_serialization import jsonutils
import manila.context
import manila.exception
from manila import utils
CONF = cfg.CONF
TRANSPORT = None
@ -53,9 +54,13 @@ def init(conf):
conf,
allowed_remote_exmods=exmods)
serializer = RequestContextSerializer(JsonPayloadSerializer())
NOTIFIER = messaging.Notifier(NOTIFICATION_TRANSPORT,
serializer=serializer)
if utils.notifications_enabled(conf):
json_serializer = messaging.JsonPayloadSerializer()
serializer = RequestContextSerializer(json_serializer)
NOTIFIER = messaging.Notifier(NOTIFICATION_TRANSPORT,
serializer=serializer)
else:
NOTIFIER = utils.DO_NOTHING
def initialized():
@ -141,6 +146,7 @@ def get_server(target, endpoints, serializer=None):
access_policy=access_policy)
@utils.if_notifications_enabled
def get_notifier(service=None, host=None, publisher_id=None):
assert NOTIFIER is not None
if not publisher_id:

2
manila/share/utils.py

@ -20,6 +20,7 @@ from oslo_config import cfg
from manila.common import constants
from manila import rpc
from manila import utils
DEFAULT_POOL_NAME = '_pool0'
CONF = cfg.CONF
@ -109,6 +110,7 @@ def cast_access_object_to_dict_in_readonly(rules):
return dict_rules
@utils.if_notifications_enabled
def notify_about_share_usage(context, share, share_instance,
event_suffix, extra_usage_info=None, host=None):

11
manila/test.py

@ -30,6 +30,7 @@ from oslo_concurrency import lockutils
from oslo_config import cfg
from oslo_config import fixture as config_fixture
import oslo_i18n
import oslo_messaging
from oslo_messaging import conffixture as messaging_conffixture
from oslo_utils import uuidutils
import oslotest.base as base_test
@ -140,6 +141,11 @@ class TestCase(base_test.BaseTestCase):
self.messaging_conf.transport_driver = 'fake'
self.messaging_conf.response_timeout = 15
self.useFixture(self.messaging_conf)
oslo_messaging.get_notification_transport(CONF)
self.override_config('driver', ['test'],
group='oslo_messaging_notifications')
rpc.init(CONF)
mock.patch('keystoneauth1.loading.load_auth_from_conf_options').start()
@ -373,3 +379,8 @@ class TestCase(base_test.BaseTestCase):
self.assertEqual(call[0], posargs[0])
self.assertEqual(call[1], posargs[2])
def override_config(self, name, override, group=None):
"""Cleanly override CONF variables."""
CONF.set_override(name, override, group)
self.addCleanup(CONF.clear_override, name, group)

2
manila/tests/fake_notifier.py

@ -35,7 +35,7 @@ FakeMessage = collections.namedtuple(
class FakeNotifier(object):
def __init__(self, transport, publisher_id, serializer=None):
def __init__(self, transport, publisher_id=None, serializer=None):
self.transport = transport
self.publisher_id = publisher_id
for priority in ['debug', 'info', 'warn', 'error', 'critical']:

41
manila/tests/test_rpc.py

@ -0,0 +1,41 @@
# Copyright 2017 Red Hat, Inc.
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import ddt
import mock
from manila import rpc
from manila import test
@ddt.ddt
class RPCTestCase(test.TestCase):
def setUp(self):
super(RPCTestCase, self).setUp()
@ddt.data([], ['noop'], ['noop', 'noop'])
@mock.patch('oslo_messaging.JsonPayloadSerializer', wraps=True)
def test_init_no_notifications(self, driver, serializer_mock):
self.override_config('driver', driver,
group='oslo_messaging_notifications')
rpc.init(test.CONF)
self.assertEqual(rpc.utils.DO_NOTHING, rpc.NOTIFIER)
serializer_mock.assert_not_called()
@mock.patch.object(rpc, 'messaging')
def test_init_notifications(self, messaging_mock):
rpc.init(test.CONF)
self.assertTrue(messaging_mock.JsonPayloadSerializer.called)
self.assertTrue(messaging_mock.Notifier.called)
self.assertEqual(rpc.NOTIFIER, messaging_mock.Notifier.return_value)

36
manila/tests/test_utils.py

@ -16,6 +16,7 @@
import datetime
import errno
import json
import socket
import time
@ -803,3 +804,38 @@ class ConvertStrTestCase(test.TestCase):
self.assertEqual(0, utils.encodeutils.safe_encode.call_count)
self.assertIsInstance(output_value, six.string_types)
self.assertEqual(six.text_type("binary_input"), output_value)
@ddt.ddt
class TestDisableNotifications(test.TestCase):
def test_do_nothing_getter(self):
"""Test any attribute will always return the same instance (self)."""
donothing = utils.DoNothing()
self.assertIs(donothing, donothing.anyname)
def test_do_nothing_caller(self):
"""Test calling the object will always return the same instance."""
donothing = utils.DoNothing()
self.assertIs(donothing, donothing())
def test_do_nothing_json_serializable(self):
"""Test calling the object will always return the same instance."""
donothing = utils.DoNothing()
self.assertEqual('""', json.dumps(donothing))
@utils.if_notifications_enabled
def _decorated_method(self):
return mock.sentinel.success
def test_if_notification_enabled_when_enabled(self):
"""Test method is called when notifications are enabled."""
result = self._decorated_method()
self.assertEqual(mock.sentinel.success, result)
@ddt.data([], ['noop'], ['noop', 'noop'])
def test_if_notification_enabled_when_disabled(self, driver):
"""Test method is not called when notifications are disabled."""
self.override_config('driver', driver,
group='oslo_messaging_notifications')
result = self._decorated_method()
self.assertEqual(utils.DO_NOTHING, result)

32
manila/utils.py

@ -641,3 +641,35 @@ def wait_for_access_update(context, db, share_instance,
raise exception.ShareMigrationFailed(reason=msg)
else:
time.sleep(tries ** 2)
class DoNothing(str):
"""Class that literrally does nothing.
We inherit from str in case it's called with json.dumps.
"""
def __call__(self, *args, **kwargs):
return self
def __getattr__(self, name):
return self
DO_NOTHING = DoNothing()
def notifications_enabled(conf):
"""Check if oslo notifications are enabled."""
notifications_driver = set(conf.oslo_messaging_notifications.driver)
return notifications_driver and notifications_driver != {'noop'}
def if_notifications_enabled(function):
"""Calls decorated method only if notifications are enabled."""
@functools.wraps(function)
def wrapped(*args, **kwargs):
if notifications_enabled(CONF):
return function(*args, **kwargs)
return DO_NOTHING
return wrapped

Loading…
Cancel
Save