summaryrefslogtreecommitdiffstats
path: root/openstack
diff options
context:
space:
mode:
authorAndrew Bogott <abogott@wikimedia.org>2012-07-19 03:34:31 -0500
committerAndrew Bogott <abogott@wikimedia.org>2012-08-02 18:11:37 -0500
commitc767e9beffe4b826eac869ce7e2eef2cc1499bbe (patch)
tree71e7bb4e8495db8e924ab355483781df32a6190e /openstack
parentbcb424dd730a977aeaae9f6e33e9bb35cbc0c062 (diff)
downloadoslo-c767e9beffe4b826eac869ce7e2eef2cc1499bbe.tar.gz
oslo-c767e9beffe4b826eac869ce7e2eef2cc1499bbe.tar.xz
oslo-c767e9beffe4b826eac869ce7e2eef2cc1499bbe.zip
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: Idf7cb975dd78e9951188781622a4d10ca466b154
Diffstat (limited to 'openstack')
-rw-r--r--openstack/common/log.py7
-rw-r--r--openstack/common/notifier/api.py60
-rw-r--r--openstack/common/notifier/list_notifier.py118
-rw-r--r--openstack/common/plugin/plugin.py1
-rw-r--r--openstack/common/plugin/pluginmanager.py21
5 files changed, 55 insertions, 152 deletions
diff --git a/openstack/common/log.py b/openstack/common/log.py
index 76962c2..49e6107 100644
--- a/openstack/common/log.py
+++ b/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 ('openstack.common.notifier.log_notifier' in
- CONF.list_notifier_drivers):
- return
+ if ('openstack.common.notifier.log_notifier' in
+ CONF.notification_driver):
+ return
notifier.api.notify(None, 'error.publisher',
'error_notification',
notifier.api.ERROR,
diff --git a/openstack/common/notifier/api.py b/openstack/common/notifier/api.py
index e699620..f36469c 100644
--- a/openstack/common/notifier/api.py
+++ b/openstack/common/notifier/api.py
@@ -28,9 +28,10 @@ from openstack.common import timeutils
LOG = logging.getLogger(__name__)
notifier_opts = [
- cfg.StrOpt('notification_driver',
- default='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'),
@@ -127,16 +128,55 @@ def notify(context, publisher_id, event_type, priority, payload):
# 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
diff --git a/openstack/common/notifier/list_notifier.py b/openstack/common/notifier/list_notifier.py
deleted file mode 100644
index 15ae470..0000000
--- a/openstack/common/notifier/list_notifier.py
+++ /dev/null
@@ -1,118 +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 openstack.common import cfg
-from openstack.common.gettextutils import _
-from openstack.common import importutils
-from openstack.common import log as logging
-
-
-list_notifier_drivers_opt = cfg.MultiStrOpt(
- 'list_notifier_drivers',
- default=['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/openstack/common/plugin/plugin.py b/openstack/common/plugin/plugin.py
index 9f06342..dc41f3d 100644
--- a/openstack/common/plugin/plugin.py
+++ b/openstack/common/plugin/plugin.py
@@ -14,7 +14,6 @@
# under the License.
from openstack.common import log as logging
-from openstack.common.notifier import list_notifier
LOG = logging.getLogger(__name__)
diff --git a/openstack/common/plugin/pluginmanager.py b/openstack/common/plugin/pluginmanager.py
index d9b6bc3..b10ce46 100644
--- a/openstack/common/plugin/pluginmanager.py
+++ b/openstack/common/plugin/pluginmanager.py
@@ -19,7 +19,7 @@ import pkg_resources
from openstack.common import cfg
from openstack.common import log as logging
-from openstack.common.notifier import list_notifier
+from 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 !=
- 'openstack.common.notifier.list_notifier'):
- if not hasattr(CONF, "list_notifier_drivers"):
- CONF.list_notifier_drivers = []
- old_notifier = CONF.notification_driver
- drvstring = '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: