Merge "Transform aggregate.create notification"
This commit is contained in:
commit
281ee20acb
19
doc/notification_samples/aggregate-create-end.json
Normal file
19
doc/notification_samples/aggregate-create-end.json
Normal file
@ -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.create.end",
|
||||
"publisher_id": "nova-api:fake-mini"
|
||||
}
|
17
doc/notification_samples/aggregate-create-start.json
Normal file
17
doc/notification_samples/aggregate-create-start.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
"uuid": "788608ec-ebdc-45c5-bc7f-e5f24ab92c80"
|
||||
}
|
||||
},
|
||||
"event_type": "aggregate.create.start",
|
||||
"publisher_id": "nova-api:fake-mini"
|
||||
}
|
@ -32,6 +32,7 @@ from nova import exception
|
||||
from nova.i18n import _LW
|
||||
from nova.network import model as network_model
|
||||
from nova import notifications
|
||||
from nova.notifications.objects import aggregate as aggregate_notification
|
||||
from nova.notifications.objects import base as notification_base
|
||||
from nova.notifications.objects import exception as notification_exception
|
||||
from nova.notifications.objects import instance as instance_notification
|
||||
@ -451,6 +452,20 @@ def notify_about_aggregate_update(context, event_suffix, aggregate_payload):
|
||||
notifier.info(context, 'aggregate.%s' % event_suffix, aggregate_payload)
|
||||
|
||||
|
||||
def notify_about_aggregate_action(context, aggregate, action, phase):
|
||||
payload = aggregate_notification.AggregatePayload(aggregate)
|
||||
notification = aggregate_notification.AggregateNotification(
|
||||
priority=fields.NotificationPriority.INFO,
|
||||
publisher=notification_base.NotificationPublisher(
|
||||
context=context, host=CONF.host, binary='nova-api'),
|
||||
event_type=notification_base.EventType(
|
||||
object='aggregate',
|
||||
action=action,
|
||||
phase=phase),
|
||||
payload=payload)
|
||||
notification.emit(context)
|
||||
|
||||
|
||||
def notify_about_host_update(context, event_suffix, host_payload):
|
||||
"""Send a notification about host update.
|
||||
|
||||
|
51
nova/notifications/objects/aggregate.py
Normal file
51
nova/notifications/objects/aggregate.py
Normal file
@ -0,0 +1,51 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova.notifications.objects import base
|
||||
from nova.objects import base as nova_base
|
||||
from nova.objects import fields
|
||||
|
||||
|
||||
@nova_base.NovaObjectRegistry.register_notification
|
||||
class AggregatePayload(base.NotificationPayloadBase):
|
||||
SCHEMA = {
|
||||
'id': ('aggregate', 'id'),
|
||||
'uuid': ('aggregate', 'uuid'),
|
||||
'name': ('aggregate', 'name'),
|
||||
'hosts': ('aggregate', 'hosts'),
|
||||
'metadata': ('aggregate', 'metadata'),
|
||||
}
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
fields = {
|
||||
'id': fields.IntegerField(),
|
||||
'uuid': fields.UUIDField(nullable=False),
|
||||
'name': fields.StringField(),
|
||||
'hosts': fields.ListOfStringsField(nullable=True),
|
||||
'metadata': fields.DictOfStringsField(nullable=True),
|
||||
}
|
||||
|
||||
def __init__(self, aggregate, **kwargs):
|
||||
super(AggregatePayload, self).__init__(**kwargs)
|
||||
self.populate_schema(aggregate=aggregate)
|
||||
|
||||
|
||||
@base.notification_sample('aggregate-create-start.json')
|
||||
@base.notification_sample('aggregate-create-end.json')
|
||||
@nova_base.NovaObjectRegistry.register_notification
|
||||
class AggregateNotification(base.NotificationBase):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
fields = {
|
||||
'payload': fields.ObjectField('AggregatePayload')
|
||||
}
|
@ -360,11 +360,18 @@ class Aggregate(base.NovaPersistentObject, base.NovaObject):
|
||||
payload['meta_data'] = payload.pop('metadata')
|
||||
if 'uuid' not in updates:
|
||||
updates['uuid'] = uuidutils.generate_uuid()
|
||||
self.uuid = updates['uuid']
|
||||
LOG.debug('Generated uuid %(uuid)s for aggregate',
|
||||
dict(uuid=updates['uuid']))
|
||||
compute_utils.notify_about_aggregate_update(self._context,
|
||||
"create.start",
|
||||
payload)
|
||||
compute_utils.notify_about_aggregate_action(
|
||||
context=self._context,
|
||||
aggregate=self,
|
||||
action=fields.NotificationAction.CREATE,
|
||||
phase=fields.NotificationPhase.START)
|
||||
|
||||
metadata = updates.pop('metadata', None)
|
||||
db_aggregate = _aggregate_create_in_db(self._context, updates,
|
||||
metadata=metadata)
|
||||
@ -373,6 +380,11 @@ class Aggregate(base.NovaPersistentObject, base.NovaObject):
|
||||
compute_utils.notify_about_aggregate_update(self._context,
|
||||
"create.end",
|
||||
payload)
|
||||
compute_utils.notify_about_aggregate_action(
|
||||
context=self._context,
|
||||
aggregate=self,
|
||||
action=fields.NotificationAction.CREATE,
|
||||
phase=fields.NotificationPhase.END)
|
||||
|
||||
@base.remotable
|
||||
def save(self):
|
||||
|
@ -388,3 +388,6 @@ class TestOpenStackClient(object):
|
||||
def get_instance_actions(self, server_id):
|
||||
return self.api_get('/servers/%s/os-instance-actions' %
|
||||
(server_id)).body['instanceActions']
|
||||
|
||||
def post_aggregate(self, aggregate):
|
||||
return self.api_post('/os-aggregates', aggregate).body['aggregate']
|
||||
|
@ -0,0 +1,40 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from nova.tests.functional.notification_sample_tests \
|
||||
import notification_sample_base
|
||||
from nova.tests.unit import fake_notifier
|
||||
|
||||
|
||||
class TestAggregateNotificationSample(
|
||||
notification_sample_base.NotificationSampleTestBase):
|
||||
|
||||
def test_aggregate_create_delete(self):
|
||||
aggregate_req = {
|
||||
"aggregate": {
|
||||
"name": "my-aggregate",
|
||||
"availability_zone": "nova"}}
|
||||
aggregate = self.admin_api.post_aggregate(aggregate_req)
|
||||
|
||||
self.assertEqual(2, len(fake_notifier.VERSIONED_NOTIFICATIONS))
|
||||
# The uuid hasn't been exposed on the REST API yet so we have no way to
|
||||
# match it here, now.
|
||||
self._verify_notification(
|
||||
'aggregate-create-start',
|
||||
replacements={
|
||||
'uuid': self.ANY},
|
||||
actual=fake_notifier.VERSIONED_NOTIFICATIONS[0])
|
||||
self._verify_notification(
|
||||
'aggregate-create-end',
|
||||
replacements={
|
||||
'uuid': self.ANY,
|
||||
'id': aggregate['id']},
|
||||
actual=fake_notifier.VERSIONED_NOTIFICATIONS[1])
|
@ -33,5 +33,7 @@ class TestExceptionNotificationSample(
|
||||
self.assertRaises(api_client.OpenStackApiException,
|
||||
self.admin_api.api_post, 'os-aggregates', post)
|
||||
|
||||
self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS))
|
||||
self._verify_notification('compute-exception')
|
||||
self.assertEqual(4, len(fake_notifier.VERSIONED_NOTIFICATIONS))
|
||||
self._verify_notification(
|
||||
'compute-exception',
|
||||
actual=fake_notifier.VERSIONED_NOTIFICATIONS[3])
|
||||
|
@ -10573,10 +10573,18 @@ class ComputeAPIAggrTestCase(BaseTestCase):
|
||||
self.stub_out('oslo_messaging.rpc.client.call', fake_rpc_method)
|
||||
self.stub_out('oslo_messaging.rpc.client.cast', fake_rpc_method)
|
||||
|
||||
def test_aggregate_no_zone(self):
|
||||
@mock.patch('nova.compute.utils.notify_about_aggregate_action')
|
||||
def test_aggregate_no_zone(self, mock_notify):
|
||||
# Ensure we can create an aggregate without an availability zone
|
||||
aggr = self.api.create_aggregate(self.context, 'fake_aggregate',
|
||||
None)
|
||||
|
||||
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')])
|
||||
|
||||
self.api.delete_aggregate(self.context, aggr.id)
|
||||
self.assertRaises(exception.AggregateNotFound,
|
||||
self.api.delete_aggregate, self.context, aggr.id)
|
||||
|
@ -257,6 +257,8 @@ class TestNotificationBase(test.NoDBTestCase):
|
||||
|
||||
|
||||
notification_object_data = {
|
||||
'AggregateNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
|
||||
'AggregatePayload': '1.0-2550af604410af7b4ad5d46fb29ba45b',
|
||||
'AuditPeriodPayload': '1.0-2b429dd307b8374636703b843fa3f9cb',
|
||||
'BandwidthPayload': '1.0-ee2616a7690ab78406842a2b68e34130',
|
||||
'EventType': '1.4-da0f0fbcda143ca96c2ac1b93937c22c',
|
||||
|
Loading…
Reference in New Issue
Block a user