From baf05561c4a43a3c361e6e0e9f68767150165244 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" Date: Fri, 16 Dec 2011 11:46:15 -0600 Subject: Pull resource extensions into APIRouter First step in refactoring extensions to do away with the extensions middleware, which is needed to get rid of the lazy serialization middleware. Converts ExtensionManager into a singleton to inhibit double-loading of extensions. Change-Id: Ia561d601df1a8c72c734c9426270268c1be13c3e --- nova/api/openstack/v2/__init__.py | 26 +++++++++++++++++ nova/api/openstack/v2/extensions.py | 40 ++++++++++---------------- nova/tests/api/openstack/v2/test_extensions.py | 11 +++---- nova/tests/integrated/test_extensions.py | 3 ++ 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/nova/api/openstack/v2/__init__.py b/nova/api/openstack/v2/__init__.py index 1ea2ba250..5575cd184 100644 --- a/nova/api/openstack/v2/__init__.py +++ b/nova/api/openstack/v2/__init__.py @@ -26,6 +26,7 @@ import webob.exc 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 @@ class APIRouter(base_wsgi.Router): 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 91db251f5..b3fbfc923 100644 --- a/nova/api/openstack/v2/extensions.py +++ b/nova/api/openstack/v2/extensions.py @@ -293,27 +293,6 @@ class ExtensionMiddleware(base_wsgi.Middleware): 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 91c86bdad..650770f50 100644 --- a/nova/tests/api/openstack/v2/test_extensions.py +++ b/nova/tests/api/openstack/v2/test_extensions.py @@ -89,6 +89,7 @@ class ExtensionTestCase(test.TestCase): 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 @@ class ResourceExtensionTest(ExtensionTestCase): 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 @@ class ResourceExtensionTest(ExtensionTestCase): 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 @@ class ResourceExtensionTest(ExtensionTestCase): 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 @@ class ResourceExtensionTest(ExtensionTestCase): 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 4318e30f2..b10da166a 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 @@ LOG = logging.getLogger('nova.tests.integrated') 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.' -- cgit