From 3d8950f234fb01695f18d6efcbd243ced24ffee4 Mon Sep 17 00:00:00 2001 From: Gary Kotton Date: Mon, 13 Aug 2012 08:33:37 -0400 Subject: [PATCH] Update latest openstack files Ensure that the common code is updated with the latest common code. Change-Id: I8a8a21fdcf77a2f444fd3c919cca9aa3912e21af --- quantum/openstack/common/cfg.py | 19 ++++++++ quantum/openstack/common/log.py | 7 ++- quantum/openstack/common/notifier/api.py | 60 ++++++++++++++++++++---- quantum/openstack/common/timeutils.py | 18 +++++++ 4 files changed, 90 insertions(+), 14 deletions(-) diff --git a/quantum/openstack/common/cfg.py b/quantum/openstack/common/cfg.py index fa3a350f09..abd191c168 100644 --- a/quantum/openstack/common/cfg.py +++ b/quantum/openstack/common/cfg.py @@ -1156,6 +1156,25 @@ class ConfigOpts(collections.Mapping): for opt in opts: self.unregister_opt(opt, group, clear_cache=False) + def import_opt(self, name, module_str, group=None): + """Import an option definition from a module. + + Import a module and check that a given option is registered. + + This is intended for use with global configuration objects + like cfg.CONF where modules commonly register options with + CONF at module load time. If one module requires an option + defined by another module it can use this method to explicitly + declare the dependency. + + :param name: the name/dest of the opt + :param module_str: the name of a module to import + :param group: an option OptGroup object or group name + :raises: NoSuchOptError, NoSuchGroupError + """ + __import__(module_str) + self._get_opt_info(name, group) + @__clear_cache def set_override(self, name, override, group=None): """Override an opt value. diff --git a/quantum/openstack/common/log.py b/quantum/openstack/common/log.py index f9af4a785d..00340384f5 100644 --- a/quantum/openstack/common/log.py +++ b/quantum/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 ('quantum.openstack.common.notifier.log_notifier' in - CONF.list_notifier_drivers): - return + if ('quantum.openstack.common.notifier.log_notifier' in + CONF.notification_driver): + return notifier.api.notify(None, 'error.publisher', 'error_notification', notifier.api.ERROR, diff --git a/quantum/openstack/common/notifier/api.py b/quantum/openstack/common/notifier/api.py index 2b31ecc28d..cd3ce1e1b0 100644 --- a/quantum/openstack/common/notifier/api.py +++ b/quantum/openstack/common/notifier/api.py @@ -28,9 +28,10 @@ from quantum.openstack.common import timeutils LOG = logging.getLogger(__name__) notifier_opts = [ - cfg.StrOpt('notification_driver', - default='quantum.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/quantum/openstack/common/timeutils.py b/quantum/openstack/common/timeutils.py index 4416a3b19e..ae300e456d 100644 --- a/quantum/openstack/common/timeutils.py +++ b/quantum/openstack/common/timeutils.py @@ -106,3 +106,21 @@ def advance_time_seconds(seconds): def clear_time_override(): """Remove the overridden time.""" utcnow.override_time = None + + +def marshall_now(now=None): + """Make an rpc-safe datetime with microseconds. + + Note: tzinfo is stripped, but not required for relative times.""" + if not now: + now = utcnow() + return dict(day=now.day, month=now.month, year=now.year, hour=now.hour, + minute=now.minute, second=now.second, + microsecond=now.microsecond) + + +def unmarshall_time(tyme): + """Unmarshall a datetime dict.""" + return datetime.datetime(day=tyme['day'], month=tyme['month'], + year=tyme['year'], hour=tyme['hour'], minute=tyme['minute'], + second=tyme['second'], microsecond=tyme['microsecond'])