Replace "phase" with "status" in notification base
The notification spec is being updated to rename "phase" to "status" and make it a required field. This updates the notification base code and docs to reflect this modification. Version for the notification EventType base class is also bumped. Change-Id: I11b6ea44a01d2a830b592784ccc63a1de9bf2ec1 Depends-On: Ib25bd5a3a600c13f7b265d86ad253af3dfa5552f
This commit is contained in:
parent
047fc52a99
commit
77c7a710fc
@ -147,14 +147,24 @@ in the ironic notification base classes) and emit it::
|
||||
|
||||
notify = ExampleNotification(
|
||||
event_type=notification.EventType(object='example_obj',
|
||||
action='do_something', phase='start'),
|
||||
action='do_something', status='start'),
|
||||
publisher=notification.NotificationPublisher(service='conductor',
|
||||
host='cond-hostname01'),
|
||||
level=fields.NotificationLevel.DEBUG,
|
||||
payload=my_notify_payload)
|
||||
notify.emit(context)
|
||||
|
||||
This will send the following notification over the message bus::
|
||||
When specifying the event_type, ``object`` will specify the object being acted
|
||||
on, ``action`` will be a string describing what action is being performed on
|
||||
that object, and ``status`` will be one of "start", "end", "fail", or
|
||||
"success". "start" and "end" are used to indicate when actions that are not
|
||||
immediate begin and succeed. "success" is used to indicate when actions that
|
||||
are immediate succeed. "fail" is used to indicate when any type of action
|
||||
fails, regardless of whether it's immediate or not. As a result of specifying
|
||||
these parameters, event_type will be formatted as
|
||||
``baremetal.<object>.<action>.<status>`` on the message bus.
|
||||
|
||||
This example will send the following notification over the message bus::
|
||||
|
||||
{
|
||||
"priority": "debug",
|
||||
@ -171,6 +181,12 @@ This will send the following notification over the message bus::
|
||||
"publisher_id":"conductor.cond-hostname01"
|
||||
}
|
||||
|
||||
Existing notifications
|
||||
----------------------
|
||||
|
||||
Descriptions of notifications emitted by ironic will be documented here when
|
||||
they are added.
|
||||
|
||||
.. [1] http://docs.openstack.org/developer/oslo.messaging/notifier.html
|
||||
.. [2] http://docs.openstack.org/developer/oslo.versionedobjects
|
||||
.. [3] https://wiki.openstack.org/wiki/LoggingStandards#Log_level_definitions
|
||||
|
@ -611,6 +611,11 @@ class IncompleteLookup(Invalid):
|
||||
"is required")
|
||||
|
||||
|
||||
class NotificationEventTypeError(IronicException):
|
||||
_msg_fmt = _('Expected "status" to be one of "start", "end", '
|
||||
'"error", or "success", but got "%(status)s"')
|
||||
|
||||
|
||||
class NotificationSchemaObjectError(IronicException):
|
||||
_msg_fmt = _("Expected object %(obj)s when populating notification payload"
|
||||
" but got object %(source)s")
|
||||
|
@ -102,6 +102,10 @@ class FlexibleDictField(object_fields.AutoTypedField):
|
||||
super(FlexibleDictField, self)._null(obj, attr)
|
||||
|
||||
|
||||
class EnumField(object_fields.EnumField):
|
||||
pass
|
||||
|
||||
|
||||
class NotificationLevel(object_fields.Enum):
|
||||
DEBUG = 'debug'
|
||||
INFO = 'info'
|
||||
|
@ -35,22 +35,25 @@ class EventType(base.IronicObject):
|
||||
"""Defines the event_type to be sent on the wire.
|
||||
|
||||
An EventType must specify the object being acted on, a string describing
|
||||
the action being taken on the notification, and the phase of the action,
|
||||
if applicable.
|
||||
the action being taken on the notification, and the status of the action.
|
||||
"""
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
# Version 1.1: "phase" field was renamed to "status" and only accepts
|
||||
# "start", "end", "error", or "success" as valid
|
||||
VERSION = '1.1'
|
||||
|
||||
fields = {
|
||||
'object': fields.StringField(nullable=False),
|
||||
'action': fields.StringField(nullable=False),
|
||||
'phase': fields.StringField(nullable=True)
|
||||
'status': fields.EnumField(valid_values=['start', 'end', 'error',
|
||||
'success'],
|
||||
nullable=False)
|
||||
}
|
||||
|
||||
def to_event_type_field(self):
|
||||
parts = ['baremetal', self.object, self.action]
|
||||
if self.obj_attr_is_set('phase') and self.phase is not None:
|
||||
parts.append(self.phase)
|
||||
if self.status not in ['start', 'end', 'error', 'success']:
|
||||
raise exception.NotificationEventTypeError(status=self.status)
|
||||
parts = ['baremetal', self.object, self.action, self.status]
|
||||
return '.'.join(parts)
|
||||
|
||||
|
||||
|
@ -95,7 +95,7 @@ class TestNotificationBase(test_base.TestCase):
|
||||
payload.populate_schema(test_obj=self.fake_obj)
|
||||
notif = self.TestNotification(
|
||||
event_type=notification.EventType(
|
||||
object='test_object', action='test', phase='start'),
|
||||
object='test_object', action='test', status='start'),
|
||||
level=fields.NotificationLevel.DEBUG,
|
||||
publisher=notification.NotificationPublisher(
|
||||
service='ironic-conductor',
|
||||
@ -132,7 +132,7 @@ class TestNotificationBase(test_base.TestCase):
|
||||
payload.populate_schema(test_obj=self.fake_obj)
|
||||
notif = self.TestNotification(
|
||||
event_type=notification.EventType(
|
||||
object='test_object', action='test', phase='start'),
|
||||
object='test_object', action='test', status='start'),
|
||||
level=fields.NotificationLevel.DEBUG,
|
||||
publisher=notification.NotificationPublisher(
|
||||
service='ironic-conductor',
|
||||
@ -153,7 +153,7 @@ class TestNotificationBase(test_base.TestCase):
|
||||
payload.populate_schema(test_obj=self.fake_obj)
|
||||
notif = self.TestNotification(
|
||||
event_type=notification.EventType(
|
||||
object='test_object', action='test', phase='start'),
|
||||
object='test_object', action='test', status='start'),
|
||||
level=fields.NotificationLevel.DEBUG,
|
||||
publisher=notification.NotificationPublisher(
|
||||
service='ironic-conductor',
|
||||
@ -172,7 +172,7 @@ class TestNotificationBase(test_base.TestCase):
|
||||
an_optional_field=1)
|
||||
notif = self.TestNotification(
|
||||
event_type=notification.EventType(
|
||||
object='test_object', action='test', phase='start'),
|
||||
object='test_object', action='test', status='start'),
|
||||
level=fields.NotificationLevel.DEBUG,
|
||||
publisher=notification.NotificationPublisher(
|
||||
service='ironic-conductor',
|
||||
@ -190,7 +190,7 @@ class TestNotificationBase(test_base.TestCase):
|
||||
payload = self.TestNotificationPayloadEmptySchema(fake_field='123')
|
||||
notif = self.TestNotificationEmptySchema(
|
||||
event_type=notification.EventType(
|
||||
object='test_object', action='test', phase='fail'),
|
||||
object='test_object', action='test', status='error'),
|
||||
level=fields.NotificationLevel.ERROR,
|
||||
publisher=notification.NotificationPublisher(
|
||||
service='ironic-conductor',
|
||||
@ -203,7 +203,7 @@ class TestNotificationBase(test_base.TestCase):
|
||||
self._verify_notification(
|
||||
mock_notifier,
|
||||
mock_context,
|
||||
expected_event_type='baremetal.test_object.test.fail',
|
||||
expected_event_type='baremetal.test_object.test.error',
|
||||
expected_payload={
|
||||
'ironic_object.name': 'TestNotificationPayloadEmptySchema',
|
||||
'ironic_object.data': {
|
||||
@ -230,14 +230,19 @@ class TestNotificationBase(test_base.TestCase):
|
||||
payload.populate_schema,
|
||||
test_obj=test_obj)
|
||||
|
||||
def test_event_type_with_phase(self):
|
||||
def test_event_type_with_status(self):
|
||||
event_type = notification.EventType(
|
||||
object="some_obj", action="some_action", phase="some_phase")
|
||||
self.assertEqual("baremetal.some_obj.some_action.some_phase",
|
||||
object="some_obj", action="some_action", status="success")
|
||||
self.assertEqual("baremetal.some_obj.some_action.success",
|
||||
event_type.to_event_type_field())
|
||||
|
||||
def test_event_type_without_phase(self):
|
||||
def test_event_type_without_status_fails(self):
|
||||
event_type = notification.EventType(
|
||||
object="some_obj", action="some_action")
|
||||
self.assertEqual("baremetal.some_obj.some_action",
|
||||
event_type.to_event_type_field())
|
||||
self.assertRaises(NotImplementedError,
|
||||
event_type.to_event_type_field)
|
||||
|
||||
def test_event_type_invalid_status_fails(self):
|
||||
self.assertRaises(ValueError,
|
||||
notification.EventType, object="some_obj",
|
||||
action="some_action", status="invalid")
|
||||
|
@ -410,7 +410,7 @@ expected_object_fingerprints = {
|
||||
'Port': '1.6-609504503d68982a10f495659990084b',
|
||||
'Portgroup': '1.2-37b374b19bfd25db7e86aebc364e611e',
|
||||
'Conductor': '1.1-5091f249719d4a465062a1b3dc7f860d',
|
||||
'EventType': '1.0-3daeec50c6deb956990255f92b863333',
|
||||
'EventType': '1.1-5d44b591d93189b2ea91a1af9b082df6',
|
||||
'NotificationPublisher': '1.0-51a09397d6c0687771fb5be9a999605d',
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user