# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2013 IBM Corp. # # 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. """Notifications module for OpenStack Identity Service resources""" from keystone.openstack.common import log from keystone.openstack.common.notifier import api as notifier_api LOG = log.getLogger(__name__) class ManagerNotificationWrapper(object): """Send event notifications for ``Manager`` methods. Sends a notification if the wrapped Manager method does not raise an ``Exception`` (such as ``keystone.exception.NotFound``). :param resource_type: type of resource being affected :param host: host of the resource (optional) """ def __init__(self, operation, resource_type, host=None): self.operation = operation self.resource_type = resource_type self.host = host def __call__(self, f): def wrapper(*args, **kwargs): """Send a notification if the wrapped callable is successful.""" try: result = f(*args, **kwargs) except Exception: raise else: _send_notification( self.operation, self.resource_type, args[1], # f(self, resource_id, ...) self.host) return result return wrapper def created(*args, **kwargs): """Decorator to send notifications for ``Manager.create_*`` methods.""" return ManagerNotificationWrapper('created', *args, **kwargs) def updated(*args, **kwargs): """Decorator to send notifications for ``Manager.update_*`` methods.""" return ManagerNotificationWrapper('updated', *args, **kwargs) def deleted(*args, **kwargs): """Decorator to send notifications for ``Manager.delete_*`` methods.""" return ManagerNotificationWrapper('deleted', *args, **kwargs) def _send_notification(operation, resource_type, resource_id, host=None): """Send notification to inform observers about the affected resource. This method doesn't raise an exception when sending the notification fails. :param operation: operation being performed (created, updated, or deleted) :param resource_type: type of resource being operated on :param resource_id: ID of resource being operated on :param host: resource host """ context = {} payload = {'resource_info': resource_id} service = 'identity' publisher_id = notifier_api.publisher_id(service, host=host) event_type = '%(service)s.%(resource_type)s.%(operation)s' % { 'service': service, 'resource_type': resource_type, 'operation': operation} try: notifier_api.notify( context, publisher_id, event_type, notifier_api.INFO, payload) except Exception: msg = (_('Failed to send %(res_id)s %(event_type)s notification') % {'res_id': resource_id, 'event_type': event_type}) LOG.exception(msg)