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'),
 | 
			
		||||
                      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
 | 
			
		||||
            kargs = dict(
 | 
			
		||||
                controller=wsgi_resource,
 | 
			
		||||
 
 | 
			
		||||
@@ -289,9 +289,9 @@ class ControllerExtension(object):
 | 
			
		||||
class ResourceExtension(object):
 | 
			
		||||
    """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,
 | 
			
		||||
                 custom_routes_fn=None):
 | 
			
		||||
                 custom_routes_fn=None, inherits=None):
 | 
			
		||||
        if not collection_actions:
 | 
			
		||||
            collection_actions = {}
 | 
			
		||||
        if not member_actions:
 | 
			
		||||
@@ -302,6 +302,7 @@ class ResourceExtension(object):
 | 
			
		||||
        self.collection_actions = collection_actions
 | 
			
		||||
        self.member_actions = member_actions
 | 
			
		||||
        self.custom_routes_fn = custom_routes_fn
 | 
			
		||||
        self.inherits = inherits
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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 action_peek: dictionary of routines for peeking into an 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
 | 
			
		||||
@@ -689,6 +694,7 @@ class Resource(wsgi.Application):
 | 
			
		||||
        # Save a mapping of extensions
 | 
			
		||||
        self.wsgi_extensions = {}
 | 
			
		||||
        self.wsgi_action_extensions = {}
 | 
			
		||||
        self.inherits = inherits
 | 
			
		||||
 | 
			
		||||
    def register_actions(self, controller):
 | 
			
		||||
        """Registers controller actions with this resource."""
 | 
			
		||||
@@ -944,6 +950,19 @@ class Resource(wsgi.Application):
 | 
			
		||||
        return response
 | 
			
		||||
 | 
			
		||||
    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 method
 | 
			
		||||
 
 | 
			
		||||
@@ -109,11 +109,14 @@ class StubExtensionManager(object):
 | 
			
		||||
        self.action_ext = action_ext
 | 
			
		||||
        self.request_ext = request_ext
 | 
			
		||||
        self.controller_ext = controller_ext
 | 
			
		||||
        self.extra_resource_ext = None
 | 
			
		||||
 | 
			
		||||
    def get_resources(self):
 | 
			
		||||
        resource_exts = []
 | 
			
		||||
        if self.resource_ext:
 | 
			
		||||
            resource_exts.append(self.resource_ext)
 | 
			
		||||
        if self.extra_resource_ext:
 | 
			
		||||
            resource_exts.append(self.extra_resource_ext)
 | 
			
		||||
        return resource_exts
 | 
			
		||||
 | 
			
		||||
    def get_actions(self):
 | 
			
		||||
@@ -511,6 +514,27 @@ class ControllerExtensionTest(ExtensionTestCase):
 | 
			
		||||
        self.assertEqual(200, response.status_int)
 | 
			
		||||
        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):
 | 
			
		||||
        controller = StubActionController(response_body)
 | 
			
		||||
        actions = dict(action='POST')
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user