cfg.StrOpt('storage_availability_zone',
default='cinder',
help='availability zone of this node'),
- cfg.StrOpt('notification_driver',
- default='cinder.openstack.common.notifier.no_op_notifier',
- help='Default driver for sending notifications'),
+ cfg.ListOpt('memcached_servers',
+ default=None,
+ help='Memcached servers or None for in process cache.'),
cfg.StrOpt('instance_usage_audit_period',
default='month',
help='time period to generate instance usages for. '
class PublishErrorsHandler(logging.Handler):
def emit(self, record):
- if 'list_notifier_drivers' in CONF:
- if ('cinder.openstack.common.notifier.log_notifier' in
- CONF.list_notifier_drivers):
- return
+ if ('cinder.openstack.common.notifier.log_notifier' in
+ CONF.notification_driver):
+ return
notifier.api.notify(None, 'error.publisher',
'error_notification',
notifier.api.ERROR,
LOG = logging.getLogger(__name__)
notifier_opts = [
- cfg.StrOpt('notification_driver',
- default='cinder.openstack.common.notifier.no_op_notifier',
- help='Default driver for sending notifications'),
+ cfg.MultiStrOpt('notification_driver',
+ default=[],
+ deprecated_name='list_notifier_drivers',
+ help='Driver or drivers to handle sending notifications'),
cfg.StrOpt('default_notification_level',
default='INFO',
help='Default notification level for outgoing notifications'),
# Ensure everything is JSON serializable.
payload = jsonutils.to_primitive(payload, convert_instances=True)
- driver = importutils.import_module(CONF.notification_driver)
msg = dict(message_id=str(uuid.uuid4()),
publisher_id=publisher_id,
event_type=event_type,
priority=priority,
payload=payload,
timestamp=str(timeutils.utcnow()))
- try:
- driver.notify(context, msg)
- except Exception, e:
- LOG.exception(_("Problem '%(e)s' attempting to "
- "send to notification system. Payload=%(payload)s") %
- locals())
+
+ for driver in _get_drivers():
+ try:
+ driver.notify(context, msg)
+ except Exception, e:
+ LOG.exception(_("Problem '%(e)s' attempting to "
+ "send to notification system. Payload=%(payload)s") %
+ locals())
+
+
+_drivers = None
+
+
+def _get_drivers():
+ """Instantiate, cache, and return drivers based on the CONF."""
+ global _drivers
+ if _drivers is None:
+ _drivers = {}
+ for notification_driver in CONF.notification_driver:
+ add_driver(notification_driver)
+
+ return _drivers.values()
+
+
+def add_driver(notification_driver):
+ """Add a notification driver at runtime."""
+ # Make sure the driver list is initialized.
+ _get_drivers()
+ if isinstance(notification_driver, basestring):
+ # Load and add
+ try:
+ driver = importutils.import_module(notification_driver)
+ _drivers[notification_driver] = driver
+ except ImportError as e:
+ LOG.exception(_("Failed to load notifier %s. "
+ "These notifications will not be sent.") %
+ notification_driver)
+ else:
+ # Driver is already loaded; just add the object.
+ _drivers[notification_driver] = notification_driver
+
+
+def _reset_drivers():
+ """Used by unit tests to reset the drivers."""
+ global _drivers
+ _drivers = None
+++ /dev/null
-# Copyright 2011 OpenStack LLC.
-# All Rights Reserved.
-#
-# 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.
-
-from cinder.openstack.common import cfg
-from cinder.openstack.common.gettextutils import _
-from cinder.openstack.common import importutils
-from cinder.openstack.common import log as logging
-
-
-list_notifier_drivers_opt = cfg.MultiStrOpt(
- 'list_notifier_drivers',
- default=['cinder.openstack.common.notifier.no_op_notifier'],
- help='List of drivers to send notifications')
-
-CONF = cfg.CONF
-CONF.register_opt(list_notifier_drivers_opt)
-
-LOG = logging.getLogger(__name__)
-
-drivers = None
-
-
-class ImportFailureNotifier(object):
- """Noisily re-raises some exception over-and-over when notify is called."""
-
- def __init__(self, exception):
- self.exception = exception
-
- def notify(self, context, message):
- raise self.exception
-
-
-def _get_drivers():
- """Instantiates and returns drivers based on the flag values."""
- global drivers
- if drivers is None:
- drivers = []
- for notification_driver in CONF.list_notifier_drivers:
- try:
- drivers.append(importutils.import_module(notification_driver))
- except ImportError as e:
- drivers.append(ImportFailureNotifier(e))
- return drivers
-
-
-def add_driver(notification_driver):
- """Add a notification driver at runtime."""
- # Make sure the driver list is initialized.
- _get_drivers()
- if isinstance(notification_driver, basestring):
- # Load and add
- try:
- drivers.append(importutils.import_module(notification_driver))
- except ImportError as e:
- drivers.append(ImportFailureNotifier(e))
- else:
- # Driver is already loaded; just add the object.
- drivers.append(notification_driver)
-
-
-def _object_name(obj):
- name = []
- if hasattr(obj, '__module__'):
- name.append(obj.__module__)
- if hasattr(obj, '__name__'):
- name.append(obj.__name__)
- else:
- name.append(obj.__class__.__name__)
- return '.'.join(name)
-
-
-def remove_driver(notification_driver):
- """Remove a notification driver at runtime."""
- # Make sure the driver list is initialized.
- _get_drivers()
- removed = False
- if notification_driver in drivers:
- # We're removing an object. Easy.
- drivers.remove(notification_driver)
- removed = True
- else:
- # We're removing a driver by name. Search for it.
- for driver in drivers:
- if _object_name(driver) == notification_driver:
- drivers.remove(driver)
- removed = True
-
- if not removed:
- raise ValueError("Cannot remove; %s is not in list" %
- notification_driver)
-
-
-def notify(context, message):
- """Passes notification to multiple notifiers in a list."""
- for driver in _get_drivers():
- try:
- driver.notify(context, message)
- except Exception as e:
- LOG.exception(_("Problem '%(e)s' attempting to send to "
- "notification driver %(driver)s."), locals())
-
-
-def _reset_drivers():
- """Used by unit tests to reset the drivers."""
- global drivers
- drivers = None
from cinder import flags
from cinder.tests.image import fake as fake_image
from cinder.openstack.common import importutils
+from cinder.openstack.common.notifier import api as notifier_api
from cinder.openstack.common.notifier import test_notifier
from cinder.openstack.common import rpc
import cinder.policy
super(VolumeTestCase, self).setUp()
vol_tmpdir = tempfile.mkdtemp()
self.flags(connection_type='fake',
- volumes_dir=vol_tmpdir)
+ volumes_dir=vol_tmpdir,
+ notification_driver=[test_notifier.__name__])
self.volume = importutils.import_object(FLAGS.volume_manager)
self.context = context.get_admin_context()
- self.stubs.Set(cinder.flags.FLAGS, 'notification_driver',
- 'cinder.openstack.common.notifier.test_notifier')
self.stubs.Set(iscsi.TgtAdm, '_get_target', self.fake_get_target)
fake_image.stub_out_image_service(self.stubs)
test_notifier.NOTIFICATIONS = []
shutil.rmtree(FLAGS.volumes_dir)
except OSError:
pass
+ notifier_api._reset_drivers()
super(VolumeTestCase, self).tearDown()
def fake_get_target(obj, iqn):
from cinder.volume import utils as volume_utils
from cinder.openstack.common import importutils
from cinder.openstack.common import log as logging
+from cinder.openstack.common.notifier import api as notifier_api
from cinder.openstack.common.notifier import test_notifier
def setUp(self):
super(UsageInfoTestCase, self).setUp()
self.flags(connection_type='fake',
- host='fake',
- notification_driver='cinder.openstack.common.notifier.test_notifier')
- self.stubs.Set(flags.FLAGS, 'notification_driver',
- 'cinder.openstack.common.notifier.test_notifier')
+ host='fake',
+ notification_driver=[test_notifier.__name__])
self.volume = importutils.import_object(FLAGS.volume_manager)
self.user_id = 'fake'
self.project_id = 'fake'
self.context = context.RequestContext(self.user_id, self.project_id)
test_notifier.NOTIFICATIONS = []
+ def tearDown(self):
+ notifier_api._reset_drivers()
+ super(UsageInfoTestCase, self).tearDown()
+
def _create_volume(self, params={}):
"""Create a test volume"""
vol = {}