Merge "Do not register notification objects"

This commit is contained in:
Jenkins 2016-06-10 10:49:07 +00:00 committed by Gerrit Code Review
commit c867b3b85d
6 changed files with 56 additions and 22 deletions

View File

@ -41,6 +41,7 @@ class VersionedNotificationDirective(Directive):
return self._build_markup(notifications)
def _collect_notifications(self):
base.NovaObjectRegistry.register_notification_objects()
notifications = []
ovos = base.NovaObjectRegistry.obj_classes()
for name, cls in ovos.items():

View File

@ -106,20 +106,25 @@ How to add a new versioned notification
To support the above contract from the Nova code every versioned notification
is modeled with oslo versionedobjects. Every versioned notification class
shall inherit from the `nova.objects.notification.NotificationBase` which
shall inherit from the `nova.notifications.objects.base.NotificationBase` which
already defines three mandatory fields of the notification `event_type`,
`publisher_id` and `priority`. The new notification class shall add a new field
`payload` with an appropriate payload type. The payload object of the
notifications shall inherit from the
`nova.objects.notification.NotificationPayloadBase` class and shall define the
fields of the payload as versionedobject fields. The base classes are described
in [3]_.
`nova.objects.notifications.base.NotificationPayloadBase` class and shall
define the fields of the payload as versionedobject fields. The base classes
are described in [3]_.
Please note that the notification objects shall not be registered to the
NovaObjectRegistry to avoid mixing nova internal objects with the notification
objects. Instead of that use the register_notification decorator on every
concrete notification object.
The following code example defines the necessary model classes for a new
notification `myobject.update`::
@notification.notification_sample('myobject-update.json')
@base.NovaObjectRegistry.register
@object_base.NovaObjectRegistry.register.register_notification
class MyObjectNotification(notification.NotificationBase):
# Version 1.0: Initial version
VERSION = '1.0'
@ -129,7 +134,7 @@ notification `myobject.update`::
}
@base.NovaObjectRegistry.register
@object_base.NovaObjectRegistry.register.register_notification
class MyObjectUpdatePayload(notification.NotificationPayloadBase):
# Version 1.0: Initial version
VERSION = '1.0'
@ -177,7 +182,7 @@ object. For example the service.status notification reuses the existing
`nova.objects.service.Service` object when defines the notification's payload::
@notification.notification_sample('service-update.json')
@base.NovaObjectRegistry.register
@object_base.NovaObjectRegistry.register.register_notification
class ServiceStatusNotification(notification.NotificationBase):
# Version 1.0: Initial version
VERSION = '1.0'
@ -186,7 +191,7 @@ object. For example the service.status notification reuses the existing
'payload': fields.ObjectField('ServiceStatusPayload')
}
@base.NovaObjectRegistry.register
@object_base.NovaObjectRegistry.register.register_notification
class ServiceStatusPayload(notification.NotificationPayloadBase):
SCHEMA = {
'host': ('service', 'host'),

View File

@ -12,14 +12,20 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova.objects import base
from nova.objects import fields
from nova import rpc
@base.NovaObjectRegistry.register
class EventType(base.NovaObject):
@base.NovaObjectRegistry.register_if(False)
class NotificationObject(base.NovaObject):
"""Base class for every notification related versioned object."""
# Version 1.0: Initial version
VERSION = '1.0'
@base.NovaObjectRegistry.register_notification
class EventType(NotificationObject):
# Version 1.0: Initial version
VERSION = '1.0'
@ -37,10 +43,8 @@ class EventType(base.NovaObject):
return s
# Note(gibi): It is explicitly not registered as this class shall not be used
# directly, it is just a base class for notification payloads.
@base.NovaObjectRegistry.register_if(False)
class NotificationPayloadBase(base.NovaObject):
class NotificationPayloadBase(NotificationObject):
"""Base class for the payload of versioned notifications."""
# SCHEMA defines how to populate the payload fields. It is a dictionary
# where every key value pair has the following format:
@ -81,8 +85,8 @@ class NotificationPayloadBase(base.NovaObject):
self.populated = True
@base.NovaObjectRegistry.register
class NotificationPublisher(base.NovaObject):
@base.NovaObjectRegistry.register_notification
class NotificationPublisher(NotificationObject):
# Version 1.0: Initial version
VERSION = '1.0'
@ -96,10 +100,8 @@ class NotificationPublisher(base.NovaObject):
return cls(host=service.host, binary=service.binary)
# Note(gibi): It is explicitly not registered as this class shall not be used
# directly, it is just a base class for notification.
@base.NovaObjectRegistry.register_if(False)
class NotificationBase(base.NovaObject):
class NotificationBase(NotificationObject):
"""Base class for versioned notifications.
Every subclass shall define a 'payload' field.

View File

@ -14,12 +14,12 @@
# under the License.
from nova.notifications.objects import base
from nova.objects import base as object_base
from nova.objects import base as nova_base
from nova.objects import fields
@base.notification_sample('service-update.json')
@object_base.NovaObjectRegistry.register
@nova_base.NovaObjectRegistry.register_notification
class ServiceStatusNotification(base.NotificationBase):
# Version 1.0: Initial version
VERSION = '1.0'
@ -29,7 +29,7 @@ class ServiceStatusNotification(base.NotificationBase):
}
@object_base.NovaObjectRegistry.register
@nova_base.NovaObjectRegistry.register_notification
class ServiceStatusPayload(base.NotificationPayloadBase):
SCHEMA = {
'host': ('service', 'host'),

View File

@ -40,6 +40,8 @@ def get_attrname(name):
class NovaObjectRegistry(ovoo_base.VersionedObjectRegistry):
notification_classes = []
def registration_hook(self, cls, index):
# NOTE(danms): This is called when an object is registered,
# and is responsible for maintaining nova.objects.$OBJECT
@ -53,6 +55,25 @@ class NovaObjectRegistry(ovoo_base.VersionedObjectRegistry):
if version >= cur_version:
setattr(objects, cls.obj_name(), cls)
@classmethod
def register_notification(cls, notification_cls):
"""Register a class as notification.
Use only to register concrete notification or payload classes,
do not register base classes intended for inheritance only.
"""
cls.register_if(False)(notification_cls)
cls.notification_classes.append(notification_cls)
return notification_cls
@classmethod
def register_notification_objects(cls):
"""Register previously decorated notification as normal ovos.
This is not intended for production use but only for testing and
document generation purposes.
"""
for notification_cls in cls.notification_classes:
cls.register(notification_cls)
remotable_classmethod = ovoo_base.remotable_classmethod
remotable = ovoo_base.remotable

View File

@ -1209,6 +1209,11 @@ object_data = {
class TestObjectVersions(test.NoDBTestCase):
def setUp(self):
super(test.NoDBTestCase, self).setUp()
base.NovaObjectRegistry.register_notification_objects()
def test_versions(self):
checker = fixture.ObjectVersionChecker(
base.NovaObjectRegistry.obj_classes())