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.
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,
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'),
# 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
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'])