From ce17c3d83b4477a94cae765fbd70af7e535380e7 Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Mon, 7 Nov 2016 17:07:41 +0100 Subject: [PATCH] Transform aggregate.delete notification The aggregate.delete.start and aggregate.delete.end notifications has been transformed to the versioned notification framework. Implements: bp versioned-notification-transformation-ocata Change-Id: I911e7aef813380291e6cf166eac91b53215a3726 --- .../aggregate-delete-end.json | 19 ++++++++++++++ .../aggregate-delete-start.json | 19 ++++++++++++++ nova/compute/api.py | 12 +++++++++ nova/notifications/objects/aggregate.py | 2 ++ nova/tests/functional/api/client.py | 3 +++ .../test_aggregate.py | 16 ++++++++++++ nova/tests/unit/compute/test_compute.py | 25 ++++++++++++++++++- 7 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 doc/notification_samples/aggregate-delete-end.json create mode 100644 doc/notification_samples/aggregate-delete-start.json diff --git a/doc/notification_samples/aggregate-delete-end.json b/doc/notification_samples/aggregate-delete-end.json new file mode 100644 index 000000000000..61dbaa1f7a11 --- /dev/null +++ b/doc/notification_samples/aggregate-delete-end.json @@ -0,0 +1,19 @@ +{ + "priority": "INFO", + "payload": { + "nova_object.version": "1.0", + "nova_object.namespace": "nova", + "nova_object.name": "AggregatePayload", + "nova_object.data": { + "name": "my-aggregate", + "metadata": { + "availability_zone": "nova" + }, + "hosts": [], + "id": 1, + "uuid": "788608ec-ebdc-45c5-bc7f-e5f24ab92c80" + } + }, + "event_type": "aggregate.delete.end", + "publisher_id": "nova-api:fake-mini" +} diff --git a/doc/notification_samples/aggregate-delete-start.json b/doc/notification_samples/aggregate-delete-start.json new file mode 100644 index 000000000000..8bd25fe43bc8 --- /dev/null +++ b/doc/notification_samples/aggregate-delete-start.json @@ -0,0 +1,19 @@ +{ + "priority": "INFO", + "payload": { + "nova_object.version": "1.0", + "nova_object.namespace": "nova", + "nova_object.name": "AggregatePayload", + "nova_object.data": { + "name": "my-aggregate", + "metadata": { + "availability_zone": "nova" + }, + "hosts": [], + "id": 1, + "uuid": "788608ec-ebdc-45c5-bc7f-e5f24ab92c80" + } + }, + "event_type": "aggregate.delete.start", + "publisher_id": "nova-api:fake-mini" +} diff --git a/nova/compute/api.py b/nova/compute/api.py index 552d4c367b59..f76af12285e7 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -4275,6 +4275,13 @@ class AggregateAPI(base.Base): "delete.start", aggregate_payload) aggregate = objects.Aggregate.get_by_id(context, aggregate_id) + + compute_utils.notify_about_aggregate_action( + context=context, + aggregate=aggregate, + action=fields_obj.NotificationAction.DELETE, + phase=fields_obj.NotificationPhase.START) + if len(aggregate.hosts) > 0: msg = _("Host aggregate is not empty") raise exception.InvalidAggregateActionDelete( @@ -4284,6 +4291,11 @@ class AggregateAPI(base.Base): compute_utils.notify_about_aggregate_update(context, "delete.end", aggregate_payload) + compute_utils.notify_about_aggregate_action( + context=context, + aggregate=aggregate, + action=fields_obj.NotificationAction.DELETE, + phase=fields_obj.NotificationPhase.END) def is_safe_to_update_az(self, context, metadata, aggregate, hosts=None, diff --git a/nova/notifications/objects/aggregate.py b/nova/notifications/objects/aggregate.py index 5d1160acc3a1..67768982708a 100644 --- a/nova/notifications/objects/aggregate.py +++ b/nova/notifications/objects/aggregate.py @@ -41,6 +41,8 @@ class AggregatePayload(base.NotificationPayloadBase): @base.notification_sample('aggregate-create-start.json') @base.notification_sample('aggregate-create-end.json') +@base.notification_sample('aggregate-delete-start.json') +@base.notification_sample('aggregate-delete-end.json') @nova_base.NovaObjectRegistry.register_notification class AggregateNotification(base.NotificationBase): # Version 1.0: Initial version diff --git a/nova/tests/functional/api/client.py b/nova/tests/functional/api/client.py index 436b45643bc2..cae02e307759 100644 --- a/nova/tests/functional/api/client.py +++ b/nova/tests/functional/api/client.py @@ -391,3 +391,6 @@ class TestOpenStackClient(object): def post_aggregate(self, aggregate): return self.api_post('/os-aggregates', aggregate).body['aggregate'] + + def delete_aggregate(self, aggregate_id): + self.api_delete('/os-aggregates/%s' % aggregate_id) diff --git a/nova/tests/functional/notification_sample_tests/test_aggregate.py b/nova/tests/functional/notification_sample_tests/test_aggregate.py index 6fc4fdbda780..d5c0ccfae846 100644 --- a/nova/tests/functional/notification_sample_tests/test_aggregate.py +++ b/nova/tests/functional/notification_sample_tests/test_aggregate.py @@ -38,3 +38,19 @@ class TestAggregateNotificationSample( 'uuid': self.ANY, 'id': aggregate['id']}, actual=fake_notifier.VERSIONED_NOTIFICATIONS[1]) + + self.admin_api.delete_aggregate(aggregate['id']) + + self.assertEqual(4, len(fake_notifier.VERSIONED_NOTIFICATIONS)) + self._verify_notification( + 'aggregate-delete-start', + replacements={ + 'uuid': self.ANY, + 'id': aggregate['id']}, + actual=fake_notifier.VERSIONED_NOTIFICATIONS[2]) + self._verify_notification( + 'aggregate-delete-end', + replacements={ + 'uuid': self.ANY, + 'id': aggregate['id']}, + actual=fake_notifier.VERSIONED_NOTIFICATIONS[3]) diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py index 9ba39ac49a3f..a71a9e38f57d 100644 --- a/nova/tests/unit/compute/test_compute.py +++ b/nova/tests/unit/compute/test_compute.py @@ -10847,7 +10847,8 @@ class ComputeAPIAggrTestCase(BaseTestCase): self.api.update_aggregate_metadata, self.context, aggr4.id, metadata) - def test_delete_aggregate(self): + @mock.patch('nova.compute.utils.notify_about_aggregate_action') + def test_delete_aggregate(self, mock_notify): # Ensure we can delete an aggregate. fake_notifier.NOTIFICATIONS = [] aggr = self.api.create_aggregate(self.context, 'fake_aggregate', @@ -10859,6 +10860,13 @@ class ComputeAPIAggrTestCase(BaseTestCase): msg = fake_notifier.NOTIFICATIONS[1] self.assertEqual(msg.event_type, 'aggregate.create.end') + mock_notify.assert_has_calls([ + mock.call(context=self.context, aggregate=aggr, + action='create', phase='start'), + mock.call(context=self.context, aggregate=aggr, + action='create', phase='end')]) + + mock_notify.reset_mock() fake_notifier.NOTIFICATIONS = [] self.api.delete_aggregate(self.context, aggr.id) self.assertEqual(len(fake_notifier.NOTIFICATIONS), 2) @@ -10871,6 +10879,21 @@ class ComputeAPIAggrTestCase(BaseTestCase): self.assertRaises(exception.AggregateNotFound, self.api.delete_aggregate, self.context, aggr.id) + class AggregateIdMatcher(object): + def __init__(self, aggr): + self.aggr = aggr + + def __eq__(self, other_aggr): + if type(self.aggr) != type(other_aggr): + return False + return self.aggr.id == other_aggr.id + + mock_notify.assert_has_calls([ + mock.call(context=self.context, aggregate=AggregateIdMatcher(aggr), + action='delete', phase='start'), + mock.call(context=self.context, aggregate=AggregateIdMatcher(aggr), + action='delete', phase='end')]) + def test_delete_non_empty_aggregate(self): # Ensure InvalidAggregateAction is raised when non empty aggregate. _create_service_entries(self.context,