diff --git a/doc/notification_samples/aggregate-update_metadata-end.json b/doc/notification_samples/aggregate-update_metadata-end.json new file mode 100644 index 000000000..1bcb0a8e9 --- /dev/null +++ b/doc/notification_samples/aggregate-update_metadata-end.json @@ -0,0 +1,13 @@ +{ + "priority": "INFO", + "payload": { + "$ref": "common_payloads/AggregatePayload.json#", + "nova_object.data": { + "metadata": { + "availability_zone": "AZ-1" + } + } + }, + "event_type": "aggregate.update_metadata.end", + "publisher_id": "nova-api:fake-mini" +} diff --git a/doc/notification_samples/aggregate-update_metadata-start.json b/doc/notification_samples/aggregate-update_metadata-start.json new file mode 100644 index 000000000..68bd9e507 --- /dev/null +++ b/doc/notification_samples/aggregate-update_metadata-start.json @@ -0,0 +1,8 @@ +{ + "priority": "INFO", + "payload": { + "$ref": "common_payloads/AggregatePayload.json#" + }, + "event_type": "aggregate.update_metadata.start", + "publisher_id": "nova-api:fake-mini" +} diff --git a/nova/notifications/objects/aggregate.py b/nova/notifications/objects/aggregate.py index 3efa292ec..8698ee890 100644 --- a/nova/notifications/objects/aggregate.py +++ b/nova/notifications/objects/aggregate.py @@ -50,6 +50,8 @@ class AggregatePayload(base.NotificationPayloadBase): @base.notification_sample('aggregate-add_host-end.json') @base.notification_sample('aggregate-remove_host-start.json') @base.notification_sample('aggregate-remove_host-end.json') +@base.notification_sample('aggregate-update_metadata-start.json') +@base.notification_sample('aggregate-update_metadata-end.json') @nova_base.NovaObjectRegistry.register_notification class AggregateNotification(base.NotificationBase): # Version 1.0: Initial version diff --git a/nova/objects/aggregate.py b/nova/objects/aggregate.py index dfe3f890e..0f6ca130a 100644 --- a/nova/objects/aggregate.py +++ b/nova/objects/aggregate.py @@ -347,6 +347,11 @@ class Aggregate(base.NovaPersistentObject, base.NovaObject): compute_utils.notify_about_aggregate_update(self._context, "updatemetadata.start", payload) + compute_utils.notify_about_aggregate_action( + context=self._context, + aggregate=self, + action=fields.NotificationAction.UPDATE_METADATA, + phase=fields.NotificationPhase.START) to_add = {} for key, value in updates.items(): if value is None: @@ -365,6 +370,11 @@ class Aggregate(base.NovaPersistentObject, base.NovaObject): compute_utils.notify_about_aggregate_update(self._context, "updatemetadata.end", payload) + compute_utils.notify_about_aggregate_action( + context=self._context, + aggregate=self, + action=fields.NotificationAction.UPDATE_METADATA, + phase=fields.NotificationPhase.END) self.obj_reset_changes(fields=['metadata']) @base.remotable diff --git a/nova/tests/functional/notification_sample_tests/test_aggregate.py b/nova/tests/functional/notification_sample_tests/test_aggregate.py index 61a4a2056..95cb8775c 100644 --- a/nova/tests/functional/notification_sample_tests/test_aggregate.py +++ b/nova/tests/functional/notification_sample_tests/test_aggregate.py @@ -105,3 +105,34 @@ class TestAggregateNotificationSample( actual=fake_notifier.VERSIONED_NOTIFICATIONS[3]) self.admin_api.delete_aggregate(aggregate['id']) + + def test_aggregate_update_metadata(self): + aggregate_req = { + "aggregate": { + "name": "my-aggregate", + "availability_zone": "nova"}} + aggregate = self.admin_api.post_aggregate(aggregate_req) + + set_metadata_req = { + "set_metadata": { + "metadata": { + "availability_zone": "AZ-1" + } + } + } + fake_notifier.reset() + self.admin_api.post_aggregate_action(aggregate['id'], set_metadata_req) + + self.assertEqual(2, len(fake_notifier.VERSIONED_NOTIFICATIONS)) + self._verify_notification( + 'aggregate-update_metadata-start', + replacements={ + 'uuid': aggregate['uuid'], + 'id': aggregate['id']}, + actual=fake_notifier.VERSIONED_NOTIFICATIONS[0]) + self._verify_notification( + 'aggregate-update_metadata-end', + replacements={ + 'uuid': aggregate['uuid'], + 'id': aggregate['id']}, + actual=fake_notifier.VERSIONED_NOTIFICATIONS[1]) diff --git a/nova/tests/unit/objects/test_aggregate.py b/nova/tests/unit/objects/test_aggregate.py index cf78d22b7..3544f8bd5 100644 --- a/nova/tests/unit/objects/test_aggregate.py +++ b/nova/tests/unit/objects/test_aggregate.py @@ -122,7 +122,13 @@ class _TestAggregateObject(object): @mock.patch('nova.objects.aggregate._metadata_delete_from_db') @mock.patch('nova.objects.aggregate._metadata_add_to_db') - def test_update_metadata_api(self, mock_api_metadata_add, + @mock.patch('nova.compute.utils.notify_about_aggregate_action') + @mock.patch('oslo_versionedobjects.base.VersionedObject.' + 'obj_from_primitive') + def test_update_metadata_api(self, + mock_obj_from_primitive, + mock_notify, + mock_api_metadata_add, mock_api_metadata_delete): fake_notifier.NOTIFICATIONS = [] agg = aggregate.Aggregate() @@ -130,6 +136,8 @@ class _TestAggregateObject(object): agg.id = 123 agg.metadata = {'foo': 'bar'} agg.obj_reset_changes() + mock_obj_from_primitive.return_value = agg + agg.update_metadata({'todelete': None, 'toadd': 'myval'}) self.assertEqual(2, len(fake_notifier.NOTIFICATIONS)) msg = fake_notifier.NOTIFICATIONS[0] @@ -138,6 +146,11 @@ class _TestAggregateObject(object): msg.payload['meta_data']) msg = fake_notifier.NOTIFICATIONS[1] self.assertEqual('aggregate.updatemetadata.end', msg.event_type) + mock_notify.assert_has_calls([ + mock.call(context=self.context, aggregate=agg, + action='update_metadata', phase='start'), + mock.call(context=self.context, aggregate=agg, + action='update_metadata', phase='end')]) self.assertEqual({'todelete': None, 'toadd': 'myval'}, msg.payload['meta_data']) self.assertEqual({'foo': 'bar', 'toadd': 'myval'}, agg.metadata)