Adds ability to inherit wsgi extensions
Needed for blueprint disable-server-extensions It is possible to create a wsgi resource that extends another resource by using the same controller, but any extensions that have been applied to the original resource will have no affect. This adds a new parameter to ResourceExtension that allows it to inherit extensions from another resource. This is necessary because we are moving key funcionality of the /servers resource into extensions, and some other resources (like create-server-ext) extend that functionality. This way we can keep the functionality of the other extensions. Change-Id: I21b4c2569c35d59c1f466642355564084a277aea
This commit is contained in:
@@ -132,7 +132,13 @@ class APIRouter(base_wsgi.Router):
|
|||||||
LOG.debug(_('Extended resource: %s'),
|
LOG.debug(_('Extended resource: %s'),
|
||||||
resource.collection)
|
resource.collection)
|
||||||
|
|
||||||
wsgi_resource = wsgi.Resource(resource.controller)
|
inherits = None
|
||||||
|
if resource.inherits:
|
||||||
|
inherits = self.resources.get(resource.inherits)
|
||||||
|
if not resource.controller:
|
||||||
|
resource.controller = inherits.controller
|
||||||
|
wsgi_resource = wsgi.Resource(resource.controller,
|
||||||
|
inherits=inherits)
|
||||||
self.resources[resource.collection] = wsgi_resource
|
self.resources[resource.collection] = wsgi_resource
|
||||||
kargs = dict(
|
kargs = dict(
|
||||||
controller=wsgi_resource,
|
controller=wsgi_resource,
|
||||||
|
|||||||
@@ -289,9 +289,9 @@ class ControllerExtension(object):
|
|||||||
class ResourceExtension(object):
|
class ResourceExtension(object):
|
||||||
"""Add top level resources to the OpenStack API in nova."""
|
"""Add top level resources to the OpenStack API in nova."""
|
||||||
|
|
||||||
def __init__(self, collection, controller, parent=None,
|
def __init__(self, collection, controller=None, parent=None,
|
||||||
collection_actions=None, member_actions=None,
|
collection_actions=None, member_actions=None,
|
||||||
custom_routes_fn=None):
|
custom_routes_fn=None, inherits=None):
|
||||||
if not collection_actions:
|
if not collection_actions:
|
||||||
collection_actions = {}
|
collection_actions = {}
|
||||||
if not member_actions:
|
if not member_actions:
|
||||||
@@ -302,6 +302,7 @@ class ResourceExtension(object):
|
|||||||
self.collection_actions = collection_actions
|
self.collection_actions = collection_actions
|
||||||
self.member_actions = member_actions
|
self.member_actions = member_actions
|
||||||
self.custom_routes_fn = custom_routes_fn
|
self.custom_routes_fn = custom_routes_fn
|
||||||
|
self.inherits = inherits
|
||||||
|
|
||||||
|
|
||||||
def wrap_errors(fn):
|
def wrap_errors(fn):
|
||||||
|
|||||||
@@ -660,11 +660,16 @@ class Resource(wsgi.Application):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, controller, action_peek=None, **deserializers):
|
def __init__(self, controller, action_peek=None, inherits=None,
|
||||||
|
**deserializers):
|
||||||
"""
|
"""
|
||||||
:param controller: object that implement methods created by routes lib
|
:param controller: object that implement methods created by routes lib
|
||||||
:param action_peek: dictionary of routines for peeking into an action
|
:param action_peek: dictionary of routines for peeking into an action
|
||||||
request body to determine the desired action
|
request body to determine the desired action
|
||||||
|
:param inherits: another resource object that this resource should
|
||||||
|
inherit extensions from. Any action extensions that
|
||||||
|
are applied to the parent resource will also apply
|
||||||
|
to this resource.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
@@ -689,6 +694,7 @@ class Resource(wsgi.Application):
|
|||||||
# Save a mapping of extensions
|
# Save a mapping of extensions
|
||||||
self.wsgi_extensions = {}
|
self.wsgi_extensions = {}
|
||||||
self.wsgi_action_extensions = {}
|
self.wsgi_action_extensions = {}
|
||||||
|
self.inherits = inherits
|
||||||
|
|
||||||
def register_actions(self, controller):
|
def register_actions(self, controller):
|
||||||
"""Registers controller actions with this resource."""
|
"""Registers controller actions with this resource."""
|
||||||
@@ -944,6 +950,19 @@ class Resource(wsgi.Application):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
def get_method(self, request, action, content_type, body):
|
def get_method(self, request, action, content_type, body):
|
||||||
|
meth, extensions = self._get_method(request,
|
||||||
|
action,
|
||||||
|
content_type,
|
||||||
|
body)
|
||||||
|
if self.inherits:
|
||||||
|
_meth, parent_ext = self.inherits.get_method(request,
|
||||||
|
action,
|
||||||
|
content_type,
|
||||||
|
body)
|
||||||
|
extensions.extend(parent_ext)
|
||||||
|
return meth, extensions
|
||||||
|
|
||||||
|
def _get_method(self, request, action, content_type, body):
|
||||||
"""Look up the action-specific method and its extensions."""
|
"""Look up the action-specific method and its extensions."""
|
||||||
|
|
||||||
# Look up the method
|
# Look up the method
|
||||||
|
|||||||
@@ -109,11 +109,14 @@ class StubExtensionManager(object):
|
|||||||
self.action_ext = action_ext
|
self.action_ext = action_ext
|
||||||
self.request_ext = request_ext
|
self.request_ext = request_ext
|
||||||
self.controller_ext = controller_ext
|
self.controller_ext = controller_ext
|
||||||
|
self.extra_resource_ext = None
|
||||||
|
|
||||||
def get_resources(self):
|
def get_resources(self):
|
||||||
resource_exts = []
|
resource_exts = []
|
||||||
if self.resource_ext:
|
if self.resource_ext:
|
||||||
resource_exts.append(self.resource_ext)
|
resource_exts.append(self.resource_ext)
|
||||||
|
if self.extra_resource_ext:
|
||||||
|
resource_exts.append(self.extra_resource_ext)
|
||||||
return resource_exts
|
return resource_exts
|
||||||
|
|
||||||
def get_actions(self):
|
def get_actions(self):
|
||||||
@@ -511,6 +514,27 @@ class ControllerExtensionTest(ExtensionTestCase):
|
|||||||
self.assertEqual(200, response.status_int)
|
self.assertEqual(200, response.status_int)
|
||||||
self.assertEqual(extension_body, response.body)
|
self.assertEqual(extension_body, response.body)
|
||||||
|
|
||||||
|
def test_controller_extension_late_inherited_resource(self):
|
||||||
|
# Need a dict for the body to convert to a ResponseObject
|
||||||
|
controller = StubController(dict(foo=response_body))
|
||||||
|
parent_ext = base_extensions.ResourceExtension('tweedles', controller)
|
||||||
|
|
||||||
|
ext_controller = StubLateExtensionController(extension_body)
|
||||||
|
extension = StubControllerExtension()
|
||||||
|
cont_ext = base_extensions.ControllerExtension(extension, 'tweedles',
|
||||||
|
ext_controller)
|
||||||
|
|
||||||
|
manager = StubExtensionManager(resource_ext=parent_ext,
|
||||||
|
controller_ext=cont_ext)
|
||||||
|
child_ext = base_extensions.ResourceExtension('beetles', controller,
|
||||||
|
inherits='tweedles')
|
||||||
|
manager.extra_resource_ext = child_ext
|
||||||
|
app = compute.APIRouter(manager)
|
||||||
|
request = webob.Request.blank("/fake/beetles")
|
||||||
|
response = request.get_response(app)
|
||||||
|
self.assertEqual(200, response.status_int)
|
||||||
|
self.assertEqual(extension_body, response.body)
|
||||||
|
|
||||||
def test_controller_action_extension_early(self):
|
def test_controller_action_extension_early(self):
|
||||||
controller = StubActionController(response_body)
|
controller = StubActionController(response_body)
|
||||||
actions = dict(action='POST')
|
actions = dict(action='POST')
|
||||||
|
|||||||
Reference in New Issue
Block a user