summaryrefslogtreecommitdiffstats
path: root/nova/openstack
diff options
context:
space:
mode:
authorAndrew Bogott <abogott@wikimedia.org>2012-08-03 20:15:54 -0500
committerAndrew Bogott <abogott@wikimedia.org>2012-08-03 20:37:51 -0500
commitee3cc503f26147087c961089ffbce30810697e80 (patch)
tree12f5988c5bfe1f8e85fd312209eddf0beb088d69 /nova/openstack
parent0e6ec643c26a7355e4f5e8db7c4fce2786a9f63b (diff)
downloadnova-ee3cc503f26147087c961089ffbce30810697e80.tar.gz
nova-ee3cc503f26147087c961089ffbce30810697e80.tar.xz
nova-ee3cc503f26147087c961089ffbce30810697e80.zip
Migrate a notifier patch from common:
commit c767e9beffe4b826eac869ce7e2eef2cc1499bbe Author: Andrew Bogott <abogott@wikimedia.org> Date: Thu Jul 19 03:34:31 2012 -0500 Add multiple-driver support to the notifier api. Move all of the functionality previously provided by the list_notifier into the basic notifier api. Move and restructure tests accordingly. Remove the list_notifier file and test file. For bug 1025820 Change-Id: Icadaafe8bc312942249272873d9a4a8f1aa49a94
Diffstat (limited to 'nova/openstack')
-rw-r--r--nova/openstack/common/log.py7
-rw-r--r--nova/openstack/common/notifier/api.py74
-rw-r--r--nova/openstack/common/notifier/list_notifier.py117
-rw-r--r--nova/openstack/common/plugin/plugin.py1
-rw-r--r--nova/openstack/common/plugin/pluginmanager.py21
5 files changed, 62 insertions, 158 deletions
diff --git a/nova/openstack/common/log.py b/nova/openstack/common/log.py
index 31238062b..e055e8148 100644
--- a/nova/openstack/common/log.py
+++ b/nova/openstack/common/log.py
@@ -247,10 +247,9 @@ class JSONFormatter(logging.Formatter):
class PublishErrorsHandler(logging.Handler):
def emit(self, record):
- if 'list_notifier_drivers' in CONF:
- if ('nova.openstack.common.notifier.log_notifier' in
- CONF.list_notifier_drivers):
- return
+ if ('nova.openstack.common.notifier.log_notifier' in
+ CONF.notification_driver):
+ return
notifier.api.notify(None, 'error.publisher',
'error_notification',
notifier.api.ERROR,
diff --git a/nova/openstack/common/notifier/api.py b/nova/openstack/common/notifier/api.py
index ba6c2dd9f..f90a4eba8 100644
--- a/nova/openstack/common/notifier/api.py
+++ b/nova/openstack/common/notifier/api.py
@@ -28,16 +28,17 @@ from nova.openstack.common import timeutils
LOG = logging.getLogger(__name__)
notifier_opts = [
- cfg.StrOpt('notification_driver',
- default='nova.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'),
cfg.StrOpt('default_publisher_id',
default='$host',
help='Default publisher_id for outgoing notifications'),
- ]
+]
CONF = cfg.CONF
CONF.register_opts(notifier_opts)
@@ -122,21 +123,60 @@ def notify(context, publisher_id, event_type, priority, payload):
"""
if priority not in log_levels:
raise BadPriorityException(
- _('%s not in valid priorities') % priority)
+ _('%s not in valid priorities') % priority)
# 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())
+ publisher_id=publisher_id,
+ event_type=event_type,
+ priority=priority,
+ payload=payload,
+ timestamp=str(timeutils.utcnow()))
+
+ 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
diff --git a/nova/openstack/common/notifier/list_notifier.py b/nova/openstack/common/notifier/list_notifier.py
deleted file mode 100644
index f59106d9a..000000000
--- a/nova/openstack/common/notifier/list_notifier.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# 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 nova.openstack.common import cfg
-from nova.openstack.common.gettextutils import _
-from nova.openstack.common import importutils
-from nova.openstack.common import log as logging
-
-
-list_notifier_drivers_opt = cfg.MultiStrOpt('list_notifier_drivers',
- default=['nova.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
diff --git a/nova/openstack/common/plugin/plugin.py b/nova/openstack/common/plugin/plugin.py
index 3db753d65..96be0af82 100644
--- a/nova/openstack/common/plugin/plugin.py
+++ b/nova/openstack/common/plugin/plugin.py
@@ -14,7 +14,6 @@
# under the License.
from nova.openstack.common import log as logging
-from nova.openstack.common.notifier import list_notifier
LOG = logging.getLogger(__name__)
diff --git a/nova/openstack/common/plugin/pluginmanager.py b/nova/openstack/common/plugin/pluginmanager.py
index 6b921656a..29656477d 100644
--- a/nova/openstack/common/plugin/pluginmanager.py
+++ b/nova/openstack/common/plugin/pluginmanager.py
@@ -19,7 +19,7 @@ import pkg_resources
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
-from nova.openstack.common.notifier import list_notifier
+from nova.openstack.common.notifier import api as notifier_api
CONF = cfg.CONF
@@ -53,17 +53,6 @@ class PluginManager(object):
self._service_name = service_name
self.plugins = []
- def _force_use_list_notifier(self):
- if (CONF.notification_driver !=
- 'nova.openstack.common.notifier.list_notifier'):
- if not hasattr(CONF, "list_notifier_drivers"):
- CONF.list_notifier_drivers = []
- old_notifier = CONF.notification_driver
- drvstring = 'nova.openstack.common.notifier.list_notifier'
- CONF.notification_driver = drvstring
- if old_notifier:
- list_notifier.add_driver(old_notifier)
-
def load_plugins(self):
self.plugins = []
@@ -77,16 +66,10 @@ class PluginManager(object):
LOG.error(_("Failed to load plugin %(plug)s: %(exc)s") %
{'plug': entrypoint, 'exc': exc})
- # See if we need to turn on the list notifier
- for plugin in self.plugins:
- if plugin.notifiers:
- self._force_use_list_notifier()
- break
-
# Register individual notifiers.
for plugin in self.plugins:
for notifier in plugin.notifiers:
- list_notifier.add_driver(notifier)
+ notifier_api.add_driver(notifier)
def plugin_extension_factory(self, ext_mgr):
for plugin in self.plugins: