Merge "Add ability to send notifications for actors"

This commit is contained in:
Jenkins 2016-03-09 23:39:56 +00:00 committed by Gerrit Code Review
commit 782bd611ca
2 changed files with 43 additions and 4 deletions

View File

@ -109,7 +109,8 @@ class Audit(object):
"""
@classmethod
def _emit(cls, operation, resource_type, resource_id, initiator, public):
def _emit(cls, operation, resource_type, resource_id, initiator, public,
actor_dict=None):
"""Directly send an event notification.
:param operation: one of the values from ACTIONS
@ -120,6 +121,8 @@ class Audit(object):
:param public: If True (default), the event will be sent to the
notifier API. If False, the event will only be sent via
notify_event_callbacks to in process listeners
:param actor_dict: dictionary of actor information in the event of
assignment notification
"""
# NOTE(stevemar): the _send_notification function is
# overloaded, it's used to register callbacks and to actually
@ -130,6 +133,7 @@ class Audit(object):
operation,
resource_type,
resource_id,
actor_dict,
public=public)
if CONF.notification_format == 'cadf' and public:
@ -161,6 +165,24 @@ class Audit(object):
cls._emit(ACTIONS.deleted, resource_type, resource_id, initiator,
public)
@classmethod
def added_to(cls, target_type, target_id, actor_type, actor_id,
initiator=None, public=True):
actor_dict = {'id': actor_id,
'type': actor_type,
'actor_operation': 'added'}
cls._emit(ACTIONS.updated, target_type, target_id, initiator, public,
actor_dict=actor_dict)
@classmethod
def removed_from(cls, target_type, target_id, actor_type, actor_id,
initiator=None, public=True):
actor_dict = {'id': actor_id,
'type': actor_type,
'actor_operation': 'removed'}
cls._emit(ACTIONS.updated, target_type, target_id, initiator, public,
actor_dict=actor_dict)
class ManagerNotificationWrapper(object):
"""Send event notifications for ``Manager`` methods.
@ -430,7 +452,8 @@ def _create_cadf_payload(operation, resource_type, resource_id,
target, event_type, **audit_kwargs)
def _send_notification(operation, resource_type, resource_id, public=True):
def _send_notification(operation, resource_type, resource_id, actor_dict=None,
public=True):
"""Send notification to inform observers about the affected resource.
This method doesn't raise an exception when sending the notification fails.
@ -438,6 +461,7 @@ def _send_notification(operation, resource_type, resource_id, public=True):
: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 actor_dict: a dictionary containing the actor's ID and type
:param public: if True (default), the event will be sent
to the notifier API.
if False, the event will only be sent via
@ -445,6 +469,11 @@ def _send_notification(operation, resource_type, resource_id, public=True):
"""
payload = {'resource_info': resource_id}
if actor_dict:
payload['actor_id'] = actor_dict['id']
payload['actor_type'] = actor_dict['type']
payload['actor_operation'] = actor_dict['actor_operation']
notify_event_callbacks(SERVICE, resource_type, operation, payload)
# Only send this notification if the 'basic' format is used, otherwise

View File

@ -212,13 +212,17 @@ class BaseNotificationTest(test_v3.RestfulTestCase):
self._audits = []
def fake_notify(operation, resource_type, resource_id,
public=True):
actor_dict=None, public=True):
note = {
'resource_id': resource_id,
'operation': operation,
'resource_type': resource_type,
'send_notification_called': True,
'public': public}
if actor_dict:
note['actor_id'] = actor_dict.get('id')
note['actor_type'] = actor_dict.get('type')
note['actor_operation'] = actor_dict.get('actor_operation')
self._notifications.append(note)
self.useFixture(mockpatch.PatchObject(
@ -248,7 +252,9 @@ class BaseNotificationTest(test_v3.RestfulTestCase):
self.useFixture(mockpatch.PatchObject(
notifications, '_send_audit_notification', fake_audit))
def _assert_last_note(self, resource_id, operation, resource_type):
def _assert_last_note(self, resource_id, operation, resource_type,
actor_id=None, actor_type=None,
actor_operation=None):
# NOTE(stevemar): If 'basic' format is not used, then simply
# return since this assertion is not valid.
if CONF.notification_format != 'basic':
@ -259,6 +265,10 @@ class BaseNotificationTest(test_v3.RestfulTestCase):
self.assertEqual(resource_id, note['resource_id'])
self.assertEqual(resource_type, note['resource_type'])
self.assertTrue(note['send_notification_called'])
if actor_id:
self.assertEqual(actor_id, note['actor_id'])
self.assertEqual(actor_type, note['actor_type'])
self.assertEqual(actor_operation, note['actor_operation'])
def _assert_last_audit(self, resource_id, operation, resource_type,
target_uri):