diff --git a/nova/api/openstack/v2/__init__.py b/nova/api/openstack/v2/__init__.py index 1ea2ba250a9..5575cd1842d 100644 --- a/nova/api/openstack/v2/__init__.py +++ b/nova/api/openstack/v2/__init__.py @@ -26,6 +26,7 @@ from nova.api.openstack.v2 import accounts from nova.api.openstack.v2 import consoles +from nova.api.openstack.v2 import extensions from nova.api.openstack.v2 import flavors from nova.api.openstack.v2 import images from nova.api.openstack.v2 import image_metadata @@ -101,11 +102,36 @@ def factory(cls, global_config, **local_config): return cls() def __init__(self, ext_mgr=None): + if ext_mgr is None: + ext_mgr = extensions.ExtensionManager() + self.server_members = {} mapper = ProjectMapper() self._setup_routes(mapper) + self._setup_ext_routes(mapper, ext_mgr) super(APIRouter, self).__init__(mapper) + def _setup_ext_routes(self, mapper, ext_mgr): + serializer = wsgi.ResponseSerializer( + {'application/xml': wsgi.XMLDictSerializer()}) + for resource in ext_mgr.get_resources(): + LOG.debug(_('Extended resource: %s'), + resource.collection) + if resource.serializer is None: + resource.serializer = serializer + + kargs = dict( + controller=wsgi.Resource( + resource.controller, resource.deserializer, + resource.serializer), + collection=resource.collection_actions, + member=resource.member_actions) + + if resource.parent: + kargs['parent_resource'] = resource.parent + + mapper.resource(resource.collection, resource.collection, **kargs) + def _setup_routes(self, mapper): server_members = self.server_members server_members['action'] = 'POST' diff --git a/nova/api/openstack/v2/extensions.py b/nova/api/openstack/v2/extensions.py index 91db251f561..b3fbfc923b0 100644 --- a/nova/api/openstack/v2/extensions.py +++ b/nova/api/openstack/v2/extensions.py @@ -293,27 +293,6 @@ def __init__(self, application, ext_mgr=None): mapper = nova.api.openstack.v2.ProjectMapper() - serializer = wsgi.ResponseSerializer( - {'application/xml': wsgi.XMLDictSerializer()}) - # extended resources - for resource in ext_mgr.get_resources(): - LOG.debug(_('Extended resource: %s'), - resource.collection) - if resource.serializer is None: - resource.serializer = serializer - - kargs = dict( - controller=wsgi.Resource( - resource.controller, resource.deserializer, - resource.serializer), - collection=resource.collection_actions, - member=resource.member_actions) - - if resource.parent: - kargs['parent_resource'] = resource.parent - - mapper.resource(resource.collection, resource.collection, **kargs) - # extended actions action_resources = self._action_ext_resources(application, ext_mgr, mapper) @@ -368,11 +347,22 @@ class ExtensionManager(object): """ - def __init__(self): - LOG.audit(_('Initializing extension manager.')) + _ext_mgr = None + + @classmethod + def reset(cls): + cls._ext_mgr = None + + def __new__(cls): + if cls._ext_mgr is None: + LOG.audit(_('Initializing extension manager.')) + + cls._ext_mgr = super(ExtensionManager, cls).__new__(cls) + + cls._ext_mgr.extensions = {} + cls._ext_mgr._load_extensions() - self.extensions = {} - self._load_extensions() + return cls._ext_mgr def register(self, ext): # Do nothing if the extension doesn't check out diff --git a/nova/tests/api/openstack/v2/test_extensions.py b/nova/tests/api/openstack/v2/test_extensions.py index 91c86bdad1b..650770f5053 100644 --- a/nova/tests/api/openstack/v2/test_extensions.py +++ b/nova/tests/api/openstack/v2/test_extensions.py @@ -89,6 +89,7 @@ def setUp(self): ext_list.append('nova.tests.api.openstack.v2.extensions.' 'foxinsocks.Foxinsocks') self.flags(osapi_extension=ext_list) + extensions.ExtensionManager.reset() class ExtensionControllerTest(ExtensionTestCase): @@ -227,7 +228,7 @@ class ResourceExtensionTest(ExtensionTestCase): def test_no_extension_present(self): manager = StubExtensionManager(None) - app = v2.APIRouter() + app = v2.APIRouter(manager) ext_midware = extensions.ExtensionMiddleware(app, manager) ser_midware = wsgi.LazySerializationMiddleware(ext_midware) request = webob.Request.blank("/blah") @@ -238,7 +239,7 @@ def test_get_resources(self): res_ext = extensions.ResourceExtension('tweedles', StubController(response_body)) manager = StubExtensionManager(res_ext) - app = v2.APIRouter() + app = v2.APIRouter(manager) ext_midware = extensions.ExtensionMiddleware(app, manager) ser_midware = wsgi.LazySerializationMiddleware(ext_midware) request = webob.Request.blank("/123/tweedles") @@ -250,7 +251,7 @@ def test_get_resources_with_controller(self): res_ext = extensions.ResourceExtension('tweedles', StubController(response_body)) manager = StubExtensionManager(res_ext) - app = v2.APIRouter() + app = v2.APIRouter(manager) ext_midware = extensions.ExtensionMiddleware(app, manager) ser_midware = wsgi.LazySerializationMiddleware(ext_midware) request = webob.Request.blank("/123/tweedles") @@ -262,7 +263,7 @@ def test_bad_request(self): res_ext = extensions.ResourceExtension('tweedles', StubController(response_body)) manager = StubExtensionManager(res_ext) - app = v2.APIRouter() + app = v2.APIRouter(manager) ext_midware = extensions.ExtensionMiddleware(app, manager) ser_midware = wsgi.LazySerializationMiddleware(ext_midware) request = webob.Request.blank("/123/tweedles") @@ -283,7 +284,7 @@ def test_non_exist_resource(self): res_ext = extensions.ResourceExtension('tweedles', StubController(response_body)) manager = StubExtensionManager(res_ext) - app = v2.APIRouter() + app = v2.APIRouter(manager) ext_midware = extensions.ExtensionMiddleware(app, manager) ser_midware = wsgi.LazySerializationMiddleware(ext_midware) request = webob.Request.blank("/123/tweedles/1") diff --git a/nova/tests/integrated/test_extensions.py b/nova/tests/integrated/test_extensions.py index 4318e30f2da..b10da166a18 100644 --- a/nova/tests/integrated/test_extensions.py +++ b/nova/tests/integrated/test_extensions.py @@ -17,6 +17,7 @@ import os +from nova.api.openstack.v2 import extensions from nova import flags from nova.log import logging from nova.tests.integrated import integrated_helpers @@ -28,6 +29,8 @@ class ExtensionsTest(integrated_helpers._IntegratedTestBase): def _get_flags(self): + extensions.ExtensionManager.reset() + f = super(ExtensionsTest, self)._get_flags() f['osapi_extension'] = FLAGS.osapi_extension[:] f['osapi_extension'].append('nova.tests.api.openstack.v2.extensions.'