Skip to content

Commit

Permalink
Pull resource extensions into APIRouter
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Kevin L. Mitchell committed Dec 16, 2011
1 parent 3f7353d commit baf0556
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 30 deletions.
26 changes: 26 additions & 0 deletions nova/api/openstack/v2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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'
Expand Down
40 changes: 15 additions & 25 deletions nova/api/openstack/v2/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
11 changes: 6 additions & 5 deletions nova/tests/api/openstack/v2/test_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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")
Expand All @@ -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")
Expand All @@ -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")
Expand All @@ -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")
Expand All @@ -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")
Expand Down
3 changes: 3 additions & 0 deletions nova/tests/integrated/test_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.'
Expand Down

0 comments on commit baf0556

Please sign in to comment.