From 7b609714b24e5d4abc17218a78ded2d2a945eecd Mon Sep 17 00:00:00 2001 From: Morgan Fainberg Date: Wed, 27 Aug 2014 11:58:35 -0700 Subject: [PATCH] Notification cleanup: namespace actions Update the notification actions to be properly namespaced rather than simple constant strings. This is a followup to the general notification constant cleanup changeset. Change-Id: Ife7597eba4a797b6909acd76720e46ee20a91727 bp: non-persistent-tokens --- .../contrib/endpoint_filter/controllers.py | 4 +- keystone/contrib/example/core.py | 14 ++++--- keystone/contrib/revoke/core.py | 6 +-- keystone/notifications.py | 25 ++++++------ keystone/tests/test_notifications.py | 6 +-- keystone/token/provider.py | 38 ++++++++++++------- 6 files changed, 53 insertions(+), 40 deletions(-) diff --git a/keystone/contrib/endpoint_filter/controllers.py b/keystone/contrib/endpoint_filter/controllers.py index 82161a7216..4dc5df67f2 100644 --- a/keystone/contrib/endpoint_filter/controllers.py +++ b/keystone/contrib/endpoint_filter/controllers.py @@ -26,10 +26,10 @@ class EndpointFilterV3Controller(controller.V3Controller): def __init__(self): super(EndpointFilterV3Controller, self).__init__() notifications.register_event_callback( - notifications.DELETED, 'project', + notifications.ACTIONS.deleted, 'project', self._on_project_or_endpoint_delete) notifications.register_event_callback( - notifications.DELETED, 'endpoint', + notifications.ACTIONS.deleted, 'endpoint', self._on_project_or_endpoint_delete) def _on_project_or_endpoint_delete(self, service, resource_type, operation, diff --git a/keystone/contrib/example/core.py b/keystone/contrib/example/core.py index 7edb03329d..d7a83c5815 100644 --- a/keystone/contrib/example/core.py +++ b/keystone/contrib/example/core.py @@ -17,6 +17,7 @@ from keystone.common import dependency from keystone.common import manager from keystone import exception from keystone.i18n import _ +from keystone import notifications from keystone.openstack.common import log @@ -47,12 +48,13 @@ class ExampleManager(manager.Manager): # This information is used when the @dependency.provider decorator acts # on the class. self.event_callbacks = { - 'deleted': { - 'project': [ - self.project_deleted_callback]}, - 'created': { - 'project': [ - self.project_created_callback]}} + notifications.ACTIONS.deleted: { + 'project': [self.project_deleted_callback], + }, + notifications.ACTIONS.created: { + 'project': [self.project_created_callback], + }, + } super(ExampleManager, self).__init__( 'keystone.contrib.example.core.ExampleDriver') diff --git a/keystone/contrib/revoke/core.py b/keystone/contrib/revoke/core.py index 2dd217fc31..87ac81f741 100644 --- a/keystone/contrib/revoke/core.py +++ b/keystone/contrib/revoke/core.py @@ -119,7 +119,7 @@ class Manager(manager.Manager): def _register_listeners(self): callbacks = { - notifications.DELETED: [ + notifications.ACTIONS.deleted: [ ['OS-TRUST:trust', self._trust_callback], ['OS-OAUTH1:consumer', self._consumer_callback], ['OS-OAUTH1:access_token', self._access_token_callback], @@ -127,12 +127,12 @@ class Manager(manager.Manager): ['user', self._user_callback], ['project', self._project_callback], ], - notifications.DISABLED: [ + notifications.ACTIONS.disabled: [ ['user', self._user_callback], ['project', self._project_callback], ['domain', self._domain_callback] ], - notifications.INTERNAL: [ + notifications.ACTIONS.internal: [ [notifications.INVALIDATE_USER_TOKEN_PERSISTENCE, self._user_callback] ] diff --git a/keystone/notifications.py b/keystone/notifications.py index 86391c2ce3..c32f51812f 100644 --- a/keystone/notifications.py +++ b/keystone/notifications.py @@ -14,6 +14,7 @@ """Notifications module for OpenStack Identity Service resources""" +import collections import inspect import logging import socket @@ -38,13 +39,12 @@ notifier_opts = [ LOG = log.getLogger(__name__) # NOTE(gyee): actions that can be notified. One must update this list whenever # a new action is supported. -CREATED = 'created' -DELETED = 'deleted' -DISABLED = 'disabled' -UPDATED = 'updated' -INTERNAL = 'internal' +_ACTIONS = collections.namedtuple( + 'NotificationActions', + 'created, deleted, disabled, updated, internal') +ACTIONS = _ACTIONS(created='created', deleted='deleted', disabled='disabled', + updated='updated', internal='internal') -ACTIONS = frozenset([CREATED, DELETED, DISABLED, UPDATED, INTERNAL]) # resource types that can be notified _SUBSCRIBERS = {} _notifier = None @@ -127,28 +127,28 @@ class ManagerNotificationWrapper(object): def created(*args, **kwargs): """Decorator to send notifications for ``Manager.create_*`` methods.""" - return ManagerNotificationWrapper(CREATED, *args, **kwargs) + return ManagerNotificationWrapper(ACTIONS.created, *args, **kwargs) def updated(*args, **kwargs): """Decorator to send notifications for ``Manager.update_*`` methods.""" - return ManagerNotificationWrapper(UPDATED, *args, **kwargs) + return ManagerNotificationWrapper(ACTIONS.updated, *args, **kwargs) def disabled(*args, **kwargs): """Decorator to send notifications when an object is disabled.""" - return ManagerNotificationWrapper(DISABLED, *args, **kwargs) + return ManagerNotificationWrapper(ACTIONS.disabled, *args, **kwargs) def deleted(*args, **kwargs): """Decorator to send notifications for ``Manager.delete_*`` methods.""" - return ManagerNotificationWrapper(DELETED, *args, **kwargs) + return ManagerNotificationWrapper(ACTIONS.deleted, *args, **kwargs) def internal(*args, **kwargs): """Decorator to send notifications for internal notifications only.""" kwargs['public'] = False - return ManagerNotificationWrapper(INTERNAL, *args, **kwargs) + return ManagerNotificationWrapper(ACTIONS.internal, *args, **kwargs) def _get_callback_info(callback): @@ -164,7 +164,8 @@ def register_event_callback(event, resource_type, callbacks): if event not in ACTIONS: raise ValueError(_('%(event)s is not a valid notification event, must ' 'be one of: %(actions)s') % - {'event': event, 'actions': ', '.join(ACTIONS)}) + {'event': event, + 'actions': ', '.join(str(a) for a in ACTIONS)}) if not hasattr(callbacks, '__iter__'): callbacks = [callbacks] diff --git a/keystone/tests/test_notifications.py b/keystone/tests/test_notifications.py index 3b3026f9f1..d51b181f0b 100644 --- a/keystone/tests/test_notifications.py +++ b/keystone/tests/test_notifications.py @@ -31,9 +31,9 @@ from keystone.tests import test_v3 CONF = cfg.CONF EXP_RESOURCE_TYPE = uuid.uuid4().hex -CREATED_OPERATION = 'created' -UPDATED_OPERATION = 'updated' -DELETED_OPERATION = 'deleted' +CREATED_OPERATION = notifications.ACTIONS.created +UPDATED_OPERATION = notifications.ACTIONS.updated +DELETED_OPERATION = notifications.ACTIONS.deleted class ArbitraryException(Exception): diff --git a/keystone/token/provider.py b/keystone/token/provider.py index 905724e99e..0f5c4b754b 100644 --- a/keystone/token/provider.py +++ b/keystone/token/provider.py @@ -150,27 +150,37 @@ class Manager(manager.Manager): def __init__(self): super(Manager, self).__init__(self.get_token_provider()) + self._register_callback_listeners() + def _register_callback_listeners(self): # This is used by the @dependency.provider decorator to register the # provider (token_provider_api) manager to listen for trust deletions. - self.event_callbacks = { - notifications.DELETED: { - 'OS-TRUST:trust': [self._trust_deleted_event_callback], - 'user': [self._delete_user_tokens_callback], - 'domain': [self._delete_domain_tokens_callback]}, - notifications.DISABLED: { - 'user': [self._delete_user_tokens_callback], - 'domain': [self._delete_domain_tokens_callback], - 'project': [self._delete_project_tokens_callback]}, - notifications.INTERNAL: { - notifications.INVALIDATE_USER_TOKEN_PERSISTENCE: [ + callbacks = { + notifications.ACTIONS.deleted: [ + ['OS-TRUST:trust', self._trust_deleted_event_callback], + ['user', self._delete_user_tokens_callback], + ['domain', self._delete_domain_tokens_callback], + ], + notifications.ACTIONS.disabled: [ + ['user', self._delete_user_tokens_callback], + ['domain', self._delete_domain_tokens_callback], + ['project', self._delete_project_tokens_callback], + ], + notifications.ACTIONS.internal: [ + [notifications.INVALIDATE_USER_TOKEN_PERSISTENCE, self._delete_user_tokens_callback], - notifications.INVALIDATE_USER_PROJECT_TOKEN_PERSISTENCE: [ + [notifications.INVALIDATE_USER_PROJECT_TOKEN_PERSISTENCE, self._delete_user_project_tokens_callback], - notifications.INVALIDATE_USER_OAUTH_CONSUMER_TOKENS: [ - self._delete_user_oauth_consumer_tokens_callback]} + [notifications.INVALIDATE_USER_OAUTH_CONSUMER_TOKENS, + self._delete_user_oauth_consumer_tokens_callback], + ] } + for event, cb_info in six.iteritems(callbacks): + for resource_type, callback_fns in cb_info: + notifications.register_event_callback(event, resource_type, + callback_fns) + @property def _persistence(self): # NOTE(morganfainberg): This should not be handled via __init__ to