From bff14b95e3c15fde321e0e2da9e5c3250a4d3fca Mon Sep 17 00:00:00 2001 From: Jenny Shieh Date: Thu, 9 May 2013 09:01:37 -0700 Subject: [PATCH] Adds notifiers to both volumeTypes and volumeTypeExtraSpecs 1. add notifier to create and delete volumeTypes 2. add notifier to create, update and delete volumeTypeExtraSpecs Implements: notifiers for volumetypes and extra specs Fixes: bug #1176259 Change-Id: I30fe6cb764e5fda7c876a8b7256d9b0c0f4a7fdd --- cinder/api/contrib/types_extra_specs.py | 14 +++++++- cinder/api/contrib/types_manage.py | 35 +++++++++++++++++-- .../api/contrib/test_types_extra_specs.py | 18 ++++++++++ cinder/tests/api/contrib/test_types_manage.py | 19 ++++++++++ 4 files changed, 83 insertions(+), 3 deletions(-) diff --git a/cinder/api/contrib/types_extra_specs.py b/cinder/api/contrib/types_extra_specs.py index 9721c150e7..7377f5245d 100644 --- a/cinder/api/contrib/types_extra_specs.py +++ b/cinder/api/contrib/types_extra_specs.py @@ -24,9 +24,9 @@ from cinder.api import xmlutil from cinder import db from cinder import exception +from cinder.openstack.common.notifier import api as notifier_api from cinder.volume import volume_types - authorize = extensions.extension_authorizer('volume', 'types_extra_specs') @@ -88,6 +88,10 @@ def create(self, req, type_id, body=None): db.volume_type_extra_specs_update_or_create(context, type_id, specs) + notifier_info = dict(type_id=type_id, specs=specs) + notifier_api.notify(context, 'volumeTypeExtraSpecs', + 'volume_type_extra_specs.create', + notifier_api.INFO, notifier_info) return body @wsgi.serializers(xml=VolumeTypeExtraSpecTemplate) @@ -107,6 +111,10 @@ def update(self, req, type_id, id, body=None): db.volume_type_extra_specs_update_or_create(context, type_id, body) + notifier_info = dict(type_id=type_id, id=id) + notifier_api.notify(context, 'volumeTypeExtraSpecs', + 'volume_type_extra_specs.update', + notifier_api.INFO, notifier_info) return body @wsgi.serializers(xml=VolumeTypeExtraSpecTemplate) @@ -127,6 +135,10 @@ def delete(self, req, type_id, id): self._check_type(context, type_id) authorize(context) db.volume_type_extra_specs_delete(context, type_id, id) + notifier_info = dict(type_id=type_id, id=id) + notifier_api.notify(context, 'volumeTypeExtraSpecs', + 'volume_type_extra_specs.delete', + notifier_api.INFO, notifier_info) return webob.Response(status_int=202) diff --git a/cinder/api/contrib/types_manage.py b/cinder/api/contrib/types_manage.py index ae1257e1db..eb17e730be 100644 --- a/cinder/api/contrib/types_manage.py +++ b/cinder/api/contrib/types_manage.py @@ -24,6 +24,7 @@ from cinder.api.v1 import types from cinder.api.views import types as views_types from cinder import exception +from cinder.openstack.common.notifier import api as notifier_api from cinder.volume import volume_types @@ -35,6 +36,13 @@ class VolumeTypesManageController(wsgi.Controller): _view_builder_class = views_types.ViewBuilder + def _notify_voloume_type_error(self, context, method, payload): + notifier_api.notify(context, + 'volumeType', + method, + notifier_api.ERROR, + payload) + @wsgi.action("create") @wsgi.serializers(xml=types.VolumeTypeTemplate) def _create(self, req, body): @@ -55,9 +63,23 @@ def _create(self, req, body): try: volume_types.create(context, name, specs) vol_type = volume_types.get_volume_type_by_name(context, name) + notifier_info = dict(volume_types=vol_type) + notifier_api.notify(context, 'volumeType', + 'volume_type.create', + notifier_api.INFO, notifier_info) + except exception.VolumeTypeExists as err: + notifier_err = dict(volume_types=vol_type, error_message=str(err)) + self._notify_voloume_type_error(context, + 'volume_type.create', + notifier_err) + raise webob.exc.HTTPConflict(explanation=str(err)) - except exception.NotFound: + except exception.NotFound as err: + notifier_err = dict(volume_types=vol_type, error_message=str(err)) + self._notify_voloume_type_error(context, + 'volume_type.create', + notifier_err) raise webob.exc.HTTPNotFound() return self._view_builder.show(req, vol_type) @@ -71,7 +93,16 @@ def _delete(self, req, id): try: vol_type = volume_types.get_volume_type(context, id) volume_types.destroy(context, vol_type['id']) - except exception.NotFound: + notifier_info = dict(volume_types=vol_type) + notifier_api.notify(context, 'volumeType', + 'volume_type.delete', + notifier_api.INFO, notifier_info) + except exception.NotFound as err: + notifier_err = dict(id=id, error_message=str(err)) + self._notify_voloume_type_error(context, + 'volume_type.delete', + notifier_err) + raise webob.exc.HTTPNotFound() return webob.Response(status_int=202) diff --git a/cinder/tests/api/contrib/test_types_extra_specs.py b/cinder/tests/api/contrib/test_types_extra_specs.py index a879390379..7b5b46931e 100644 --- a/cinder/tests/api/contrib/test_types_extra_specs.py +++ b/cinder/tests/api/contrib/test_types_extra_specs.py @@ -21,6 +21,8 @@ import webob from cinder.api.contrib import types_extra_specs +from cinder.openstack.common.notifier import api as notifier_api +from cinder.openstack.common.notifier import test_notifier from cinder import test from cinder.tests.api import fakes import cinder.wsgi @@ -61,9 +63,19 @@ class VolumeTypesExtraSpecsTest(test.TestCase): def setUp(self): super(VolumeTypesExtraSpecsTest, self).setUp() + self.flags(connection_type='fake', + host='fake', + notification_driver=[test_notifier.__name__]) self.stubs.Set(cinder.db, 'volume_type_get', volume_type_get) self.api_path = '/v2/fake/os-volume-types/1/extra_specs' self.controller = types_extra_specs.VolumeTypeExtraSpecsController() + """to reset notifier drivers left over from other api/contrib tests""" + notifier_api._reset_drivers() + test_notifier.NOTIFICATIONS = [] + + def tearDown(self): + notifier_api._reset_drivers() + super(VolumeTypesExtraSpecsTest, self).tearDown() def test_index(self): self.stubs.Set(cinder.db, 'volume_type_extra_specs_get', @@ -104,8 +116,10 @@ def test_delete(self): self.stubs.Set(cinder.db, 'volume_type_extra_specs_delete', delete_volume_type_extra_specs) + self.assertEquals(len(test_notifier.NOTIFICATIONS), 0) req = fakes.HTTPRequest.blank(self.api_path + '/key5') self.controller.delete(req, 1, 'key5') + self.assertEquals(len(test_notifier.NOTIFICATIONS), 1) def test_create(self): self.stubs.Set(cinder.db, @@ -113,8 +127,10 @@ def test_create(self): return_create_volume_type_extra_specs) body = {"extra_specs": {"key1": "value1"}} + self.assertEquals(len(test_notifier.NOTIFICATIONS), 0) req = fakes.HTTPRequest.blank(self.api_path) res_dict = self.controller.create(req, 1, body) + self.assertEquals(len(test_notifier.NOTIFICATIONS), 1) self.assertEqual('value1', res_dict['extra_specs']['key1']) @@ -124,8 +140,10 @@ def test_update_item(self): return_create_volume_type_extra_specs) body = {"key1": "value1"} + self.assertEquals(len(test_notifier.NOTIFICATIONS), 0) req = fakes.HTTPRequest.blank(self.api_path + '/key1') res_dict = self.controller.update(req, 1, 'key1', body) + self.assertEquals(len(test_notifier.NOTIFICATIONS), 1) self.assertEqual('value1', res_dict['key1']) diff --git a/cinder/tests/api/contrib/test_types_manage.py b/cinder/tests/api/contrib/test_types_manage.py index a94916f3a5..c007236ec4 100644 --- a/cinder/tests/api/contrib/test_types_manage.py +++ b/cinder/tests/api/contrib/test_types_manage.py @@ -17,6 +17,8 @@ from cinder.api.contrib import types_manage from cinder import exception +from cinder.openstack.common.notifier import api as notifier_api +from cinder.openstack.common.notifier import test_notifier from cinder import test from cinder.tests.api import fakes from cinder.volume import volume_types @@ -57,7 +59,17 @@ def return_volume_types_get_by_name(context, name): class VolumeTypesManageApiTest(test.TestCase): def setUp(self): super(VolumeTypesManageApiTest, self).setUp() + self.flags(connection_type='fake', + host='fake', + notification_driver=[test_notifier.__name__]) self.controller = types_manage.VolumeTypesManageController() + """to reset notifier drivers left over from other api/contrib tests""" + notifier_api._reset_drivers() + test_notifier.NOTIFICATIONS = [] + + def tearDown(self): + notifier_api._reset_drivers() + super(VolumeTypesManageApiTest, self).tearDown() def test_volume_types_delete(self): self.stubs.Set(volume_types, 'get_volume_type', @@ -66,7 +78,9 @@ def test_volume_types_delete(self): return_volume_types_destroy) req = fakes.HTTPRequest.blank('/v2/fake/types/1') + self.assertEquals(len(test_notifier.NOTIFICATIONS), 0) self.controller._delete(req, 1) + self.assertEquals(len(test_notifier.NOTIFICATIONS), 1) def test_volume_types_delete_not_found(self): self.stubs.Set(volume_types, 'get_volume_type', @@ -74,9 +88,11 @@ def test_volume_types_delete_not_found(self): self.stubs.Set(volume_types, 'destroy', return_volume_types_destroy) + self.assertEquals(len(test_notifier.NOTIFICATIONS), 0) req = fakes.HTTPRequest.blank('/v2/fake/types/777') self.assertRaises(webob.exc.HTTPNotFound, self.controller._delete, req, '777') + self.assertEquals(len(test_notifier.NOTIFICATIONS), 1) def test_create(self): self.stubs.Set(volume_types, 'create', @@ -87,8 +103,11 @@ def test_create(self): body = {"volume_type": {"name": "vol_type_1", "extra_specs": {"key1": "value1"}}} req = fakes.HTTPRequest.blank('/v2/fake/types') + + self.assertEquals(len(test_notifier.NOTIFICATIONS), 0) res_dict = self.controller._create(req, body) + self.assertEquals(len(test_notifier.NOTIFICATIONS), 1) self.assertEqual(1, len(res_dict)) self.assertEqual('vol_type_1', res_dict['volume_type']['name'])