summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin L. Mitchell <kevin.mitchell@rackspace.com>2012-01-19 16:20:04 -0600
committerKevin L. Mitchell <kevin.mitchell@rackspace.com>2012-01-19 16:20:04 -0600
commited1e6d792c5b37576640acd3e174c8a733c96b61 (patch)
treee79b7b0b317e796ae6c8188c567e1452f59f0a38
parent4f204a6d75f2d48608aeeafae20ab3bf8cbadf73 (diff)
downloadnova-ed1e6d792c5b37576640acd3e174c8a733c96b61.tar.gz
nova-ed1e6d792c5b37576640acd3e174c8a733c96b61.tar.xz
nova-ed1e6d792c5b37576640acd3e174c8a733c96b61.zip
Remove deprecated extension code.
The recent extensions refactoring (blueprint extension-refactor) deprecated ActionExtension and RequestExtension, replacing them with ControllerExtension. This patch completes the deprecation by removing those classes and all related support infrastructure, including ExtensionMiddleware and LazySerializationMiddleware. (The classes remain, as deprecated do-nothing stubs, for compatibility with existing api-paste.ini files.) Change-Id: I8272ac3cf432813d749db67b2e1ad1a72abbb784
-rw-r--r--etc/nova/api-paste.ini15
-rw-r--r--nova/api/openstack/common.py26
-rw-r--r--nova/api/openstack/compute/contrib/floating_ip_pools.py37
-rw-r--r--nova/api/openstack/compute/contrib/keypairs.py8
-rw-r--r--nova/api/openstack/compute/contrib/zones.py14
-rw-r--r--nova/api/openstack/compute/extensions.py25
-rw-r--r--nova/api/openstack/extensions.py274
-rw-r--r--nova/api/openstack/volume/__init__.py2
-rw-r--r--nova/api/openstack/volume/extensions.py24
-rw-r--r--nova/api/openstack/volume/snapshots.py74
-rw-r--r--nova/api/openstack/volume/types.py51
-rw-r--r--nova/api/openstack/volume/volumes.py133
-rw-r--r--nova/api/openstack/wsgi.py217
-rw-r--r--nova/api/openstack/xmlutil.py42
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_admin_actions.py4
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_disk_config.py5
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_floating_ip_pools.py4
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_server_action_list.py4
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py4
-rw-r--r--nova/tests/api/openstack/compute/extensions/foxinsocks.py91
-rw-r--r--nova/tests/api/openstack/compute/test_extensions.py94
-rw-r--r--nova/tests/api/openstack/compute/test_limits.py3
-rw-r--r--nova/tests/api/openstack/fakes.py19
-rw-r--r--nova/tests/api/openstack/test_common.py37
-rw-r--r--nova/tests/api/openstack/test_wsgi.py243
-rw-r--r--nova/tests/api/openstack/test_xmlutil.py72
-rw-r--r--nova/tests/api/openstack/volume/test_snapshots.py8
-rw-r--r--nova/tests/api/openstack/volume/test_types.py12
-rw-r--r--nova/tests/api/openstack/volume/test_volumes.py47
-rw-r--r--nova/tests/integrated/test_extensions.py2
30 files changed, 274 insertions, 1317 deletions
diff --git a/etc/nova/api-paste.ini b/etc/nova/api-paste.ini
index c2de4b484..199fcf6f9 100644
--- a/etc/nova/api-paste.ini
+++ b/etc/nova/api-paste.ini
@@ -90,12 +90,12 @@ use = call:nova.api.openstack.urlmap:urlmap_factory
/v1: openstack_volume_api_v1
[pipeline:openstack_compute_api_v2]
-pipeline = faultwrap noauth ratelimit serialize compute_extensions osapi_compute_app_v2
+pipeline = faultwrap noauth ratelimit osapi_compute_app_v2
# NOTE(vish): use the following pipeline for deprecated auth
-# pipeline = faultwrap auth ratelimit serialize extensions osapi_compute_app_v2
+# pipeline = faultwrap auth ratelimit osapi_compute_app_v2
[pipeline:openstack_volume_api_v1]
-pipeline = faultwrap noauth ratelimit serialize volume_extensions osapi_volume_app_v1
+pipeline = faultwrap noauth ratelimit osapi_volume_app_v1
[filter:faultwrap]
paste.filter_factory = nova.api.openstack:FaultWrapper.factory
@@ -109,15 +109,6 @@ paste.filter_factory = nova.api.openstack.auth:NoAuthMiddleware.factory
[filter:ratelimit]
paste.filter_factory = nova.api.openstack.compute.limits:RateLimitingMiddleware.factory
-[filter:serialize]
-paste.filter_factory = nova.api.openstack.wsgi:LazySerializationMiddleware.factory
-
-[filter:compute_extensions]
-paste.filter_factory = nova.api.openstack.compute.extensions:ExtensionMiddleware.factory
-
-[filter:volume_extensions]
-paste.filter_factory = nova.api.openstack.volume.extensions:ExtensionMiddleware.factory
-
[app:osapi_compute_app_v2]
paste.app_factory = nova.api.openstack.compute:APIRouter.factory
diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py
index 0ac46d96e..2cc18661b 100644
--- a/nova/api/openstack/common.py
+++ b/nova/api/openstack/common.py
@@ -426,12 +426,6 @@ class MetadataXMLDeserializer(wsgi.XMLDeserializer):
return {'body': {'meta': metadata_item}}
-class MetadataHeadersSerializer(wsgi.ResponseHeadersSerializer):
-
- def delete(self, response, data):
- response.status_int = 204
-
-
metadata_nsmap = {None: xmlutil.XMLNS_V11}
@@ -459,26 +453,6 @@ class MetadataTemplate(xmlutil.TemplateBuilder):
return xmlutil.MasterTemplate(root, 1, nsmap=metadata_nsmap)
-class MetadataXMLSerializer(xmlutil.XMLTemplateSerializer):
- def index(self):
- return MetadataTemplate()
-
- def create(self):
- return MetadataTemplate()
-
- def update_all(self):
- return MetadataTemplate()
-
- def show(self):
- return MetaItemTemplate()
-
- def update(self):
- return MetaItemTemplate()
-
- def default(self):
- return xmlutil.MasterTemplate(None, 1)
-
-
def check_snapshots_enabled(f):
@functools.wraps(f)
def inner(*args, **kwargs):
diff --git a/nova/api/openstack/compute/contrib/floating_ip_pools.py b/nova/api/openstack/compute/contrib/floating_ip_pools.py
index 01b9a3645..0bf2362af 100644
--- a/nova/api/openstack/compute/contrib/floating_ip_pools.py
+++ b/nova/api/openstack/compute/contrib/floating_ip_pools.py
@@ -37,20 +37,6 @@ def _translate_floating_ip_pools_view(pools):
}
-class FloatingIPPoolsController(object):
- """The Floating IP Pool API controller for the OpenStack API."""
-
- def __init__(self):
- self.network_api = network.API()
- super(FloatingIPPoolsController, self).__init__()
-
- def index(self, req):
- """Return a list of pools."""
- context = req.environ['nova.context']
- pools = self.network_api.get_floating_ip_pools(context)
- return _translate_floating_ip_pools_view(pools)
-
-
def make_float_ip(elem):
elem.set('name')
@@ -72,9 +58,19 @@ class FloatingIPPoolsTemplate(xmlutil.TemplateBuilder):
return xmlutil.MasterTemplate(root, 1)
-class FloatingIPPoolsSerializer(xmlutil.XMLTemplateSerializer):
- def index(self):
- return FloatingIPPoolsTemplate()
+class FloatingIPPoolsController(object):
+ """The Floating IP Pool API controller for the OpenStack API."""
+
+ def __init__(self):
+ self.network_api = network.API()
+ super(FloatingIPPoolsController, self).__init__()
+
+ @wsgi.serializers(xml=FloatingIPPoolsTemplate)
+ def index(self, req):
+ """Return a list of pools."""
+ context = req.environ['nova.context']
+ pools = self.network_api.get_floating_ip_pools(context)
+ return _translate_floating_ip_pools_view(pools)
class Floating_ip_pools(extensions.ExtensionDescriptor):
@@ -89,15 +85,8 @@ class Floating_ip_pools(extensions.ExtensionDescriptor):
def get_resources(self):
resources = []
- body_serializers = {
- 'application/xml': FloatingIPPoolsSerializer(),
- }
-
- serializer = wsgi.ResponseSerializer(body_serializers)
-
res = extensions.ResourceExtension('os-floating-ip-pools',
FloatingIPPoolsController(),
- serializer=serializer,
member_actions={})
resources.append(res)
diff --git a/nova/api/openstack/compute/contrib/keypairs.py b/nova/api/openstack/compute/contrib/keypairs.py
index c09ca555f..504539d55 100644
--- a/nova/api/openstack/compute/contrib/keypairs.py
+++ b/nova/api/openstack/compute/contrib/keypairs.py
@@ -130,14 +130,6 @@ class KeypairController(object):
return {'keypairs': rval}
-class KeypairsSerializer(xmlutil.XMLTemplateSerializer):
- def index(self):
- return KeypairsTemplate()
-
- def default(self):
- return KeypairTemplate()
-
-
class Keypairs(extensions.ExtensionDescriptor):
"""Keypair Support"""
diff --git a/nova/api/openstack/compute/contrib/zones.py b/nova/api/openstack/compute/contrib/zones.py
index b68f3f4f5..539833ee2 100644
--- a/nova/api/openstack/compute/contrib/zones.py
+++ b/nova/api/openstack/compute/contrib/zones.py
@@ -195,20 +195,6 @@ class Controller(object):
return cooked
-class ZonesXMLSerializer(xmlutil.XMLTemplateSerializer):
- def index(self):
- return ZonesTemplate()
-
- def detail(self):
- return ZonesTemplate()
-
- def select(self):
- return WeightsTemplate()
-
- def default(self):
- return ZoneTemplate()
-
-
class Zones(extensions.ExtensionDescriptor):
"""Enables zones-related functionality such as adding child zones,
listing child zones, getting the capabilities of the local zone,
diff --git a/nova/api/openstack/compute/extensions.py b/nova/api/openstack/compute/extensions.py
index 39849e802..f5ebdfee9 100644
--- a/nova/api/openstack/compute/extensions.py
+++ b/nova/api/openstack/compute/extensions.py
@@ -25,21 +25,20 @@ FLAGS = flags.FLAGS
class ExtensionManager(base_extensions.ExtensionManager):
- def __new__(cls):
- if cls._ext_mgr is None:
- LOG.audit(_('Initializing extension manager.'))
+ def __init__(self):
+ LOG.audit(_('Initializing extension manager.'))
- cls._ext_mgr = super(ExtensionManager, cls).__new__(cls)
+ self.cls_list = FLAGS.osapi_compute_extension
+ self.extensions = {}
+ self._load_extensions()
- cls.cls_list = FLAGS.osapi_compute_extension
- cls._ext_mgr.extensions = {}
- cls._ext_mgr._load_extensions()
- return cls._ext_mgr
+class ExtensionMiddleware(base_extensions.ExtensionMiddleware):
+ """Extensions middleware for WSGI.
+ Provided only for backwards compatibility with existing
+ api-paste.ini files. This middleware will be removed in future
+ versions of nova.
+ """
-class ExtensionMiddleware(base_extensions.ExtensionMiddleware):
- def __init__(self, application, ext_mgr=None):
- if not ext_mgr:
- ext_mgr = ExtensionManager()
- super(ExtensionMiddleware, self).__init__(application, ext_mgr)
+ pass
diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py
index ce37e0a34..9a47a69d4 100644
--- a/nova/api/openstack/extensions.py
+++ b/nova/api/openstack/extensions.py
@@ -79,24 +79,6 @@ class ExtensionDescriptor(object):
resources = []
return resources
- def get_actions(self):
- """List of extensions.ActionExtension extension objects.
-
- Actions are verbs callable from the API.
-
- """
- actions = []
- return actions
-
- def get_request_extensions(self):
- """List of extensions.RequestExtension extension objects.
-
- Request extensions are used to handle custom request data.
-
- """
- request_exts = []
- return request_exts
-
def get_controller_extensions(self):
"""List of extensions.ControllerExtension extension objects.
@@ -124,92 +106,6 @@ class ExtensionDescriptor(object):
return '{%s}%s' % (cls.namespace, name)
-class ActionExtensionController(object):
- def __init__(self, application):
- self.application = application
- self.action_handlers = {}
-
- def add_action(self, action_name, handler):
- self.action_handlers[action_name] = handler
-
- def action(self, req, id, body):
- for action_name, handler in self.action_handlers.iteritems():
- if action_name in body:
- return handler(body, req, id)
- # no action handler found (bump to downstream application)
- res = self.application
- return res
-
-
-class ActionExtensionResource(wsgi.Resource):
-
- def __init__(self, application):
- controller = ActionExtensionController(application)
- wsgi.Resource.__init__(self, controller,
- serializer=wsgi.ResponseSerializer(),
- deserializer=wsgi.RequestDeserializer())
-
- def add_action(self, action_name, handler):
- self.controller.add_action(action_name, handler)
-
-
-class RequestExtensionController(object):
-
- def __init__(self, application):
- self.application = application
- self.handlers = []
- self.pre_handlers = []
-
- def add_handler(self, handler):
- self.handlers.append(handler)
-
- def add_pre_handler(self, pre_handler):
- self.pre_handlers.append(pre_handler)
-
- def process(self, req, *args, **kwargs):
- for pre_handler in self.pre_handlers:
- pre_handler(req)
-
- res = req.get_response(self.application)
- res.environ = req.environ
-
- # Don't call extensions if the main application returned an
- # unsuccessful status
- successful = 200 <= res.status_int < 400
- if not successful:
- return res
-
- # Deserialize the response body, if any
- body = None
- if res.body:
- body = utils.loads(res.body)
-
- # currently request handlers are un-ordered
- for handler in self.handlers:
- res = handler(req, res, body)
-
- # Reserialize the response body
- if body is not None:
- res.body = utils.dumps(body)
-
- return res
-
-
-class RequestExtensionResource(wsgi.Resource):
-
- def __init__(self, application):
- controller = RequestExtensionController(application)
- wsgi.Resource.__init__(self, controller,
- serializer=wsgi.ResponseSerializer(),
- deserializer=wsgi.RequestDeserializer())
-
- def add_handler(self, handler):
- self.controller.add_handler(handler)
-
- def add_pre_handler(self, pre_handler):
- self.controller.add_pre_handler(pre_handler)
-
-
def make_ext(elem):
elem.set('name')
elem.set('namespace')
@@ -281,106 +177,16 @@ class ExtensionsResource(wsgi.Resource):
raise webob.exc.HTTPNotFound()
+@utils.deprecated("The extension middleware is no longer necessary.")
class ExtensionMiddleware(base_wsgi.Middleware):
- """Extensions middleware for WSGI."""
- @classmethod
- def factory(cls, global_config, **local_config):
- """Paste factory."""
- def _factory(app):
- return cls(app, **local_config)
- return _factory
-
- def _action_ext_resources(self, application, ext_mgr, mapper):
- """Return a dict of ActionExtensionResource-s by collection."""
- action_resources = {}
- for action in ext_mgr.get_actions():
- if not action.collection in action_resources.keys():
- resource = ActionExtensionResource(application)
- mapper.connect("/:(project_id)/%s/:(id)/action.:(format)" %
- action.collection,
- action='action',
- controller=resource,
- conditions=dict(method=['POST']))
- mapper.connect("/:(project_id)/%s/:(id)/action" %
- action.collection,
- action='action',
- controller=resource,
- conditions=dict(method=['POST']))
- action_resources[action.collection] = resource
-
- return action_resources
-
- def _request_ext_resources(self, application, ext_mgr, mapper):
- """Returns a dict of RequestExtensionResource-s by collection."""
- request_ext_resources = {}
- for req_ext in ext_mgr.get_request_extensions():
- if not req_ext.key in request_ext_resources.keys():
- resource = RequestExtensionResource(application)
- mapper.connect(req_ext.url_route + '.:(format)',
- action='process',
- controller=resource,
- conditions=req_ext.conditions)
-
- mapper.connect(req_ext.url_route,
- action='process',
- controller=resource,
- conditions=req_ext.conditions)
- request_ext_resources[req_ext.key] = resource
-
- return request_ext_resources
-
- def __init__(self, application, ext_mgr=None):
-
- if ext_mgr is None:
- ext_mgr = ExtensionManager()
- self.ext_mgr = ext_mgr
-
- mapper = nova.api.openstack.ProjectMapper()
-
- # extended actions
- action_resources = self._action_ext_resources(application, ext_mgr,
- mapper)
- for action in ext_mgr.get_actions():
- LOG.debug(_('Extended action: %s'), action.action_name)
- resource = action_resources[action.collection]
- resource.add_action(action.action_name, action.handler)
-
- # extended requests
- req_controllers = self._request_ext_resources(application, ext_mgr,
- mapper)
- for request_ext in ext_mgr.get_request_extensions():
- LOG.debug(_('Extended request: %s'), request_ext.key)
- controller = req_controllers[request_ext.key]
- if request_ext.handler:
- controller.add_handler(request_ext.handler)
- if request_ext.pre_handler:
- controller.add_pre_handler(request_ext.pre_handler)
-
- self._router = routes.middleware.RoutesMiddleware(self._dispatch,
- mapper)
-
- super(ExtensionMiddleware, self).__init__(application)
-
- @webob.dec.wsgify(RequestClass=wsgi.Request)
- def __call__(self, req):
- """Route the incoming request with router."""
- req.environ['extended.app'] = self.application
- return self._router
-
- @staticmethod
- @webob.dec.wsgify(RequestClass=wsgi.Request)
- def _dispatch(req):
- """Dispatch the request.
-
- Returns the routed WSGI app's response or defers to the extended
- application.
+ """Extensions middleware for WSGI.
- """
- match = req.environ['wsgiorg.routing_args'][1]
- if not match:
- return req.environ['extended.app']
- app = match['controller']
- return app
+ Provided only for backwards compatibility with existing
+ api-paste.ini files. This middleware will be removed in future
+ versions of nova.
+ """
+
+ pass
class ExtensionManager(object):
@@ -391,12 +197,6 @@ class ExtensionManager(object):
"""
- _ext_mgr = None
-
- @classmethod
- def reset(cls):
- cls._ext_mgr = None
-
def register(self, ext):
# Do nothing if the extension doesn't check out
if not self._check_extension(ext):
@@ -425,30 +225,6 @@ class ExtensionManager(object):
pass
return resources
- def get_actions(self):
- """Returns a list of ActionExtension objects."""
- actions = []
- for ext in self.extensions.values():
- try:
- actions.extend(ext.get_actions())
- except AttributeError:
- # NOTE(dprince): Extension aren't required to have action
- # extensions
- pass
- return actions
-
- def get_request_extensions(self):
- """Returns a list of RequestExtension objects."""
- request_exts = []
- for ext in self.extensions.values():
- try:
- request_exts.extend(ext.get_request_extensions())
- except AttributeError:
- # NOTE(dprince): Extension aren't required to have request
- # extensions
- pass
- return request_exts
-
def get_controller_extensions(self):
"""Returns a list of ControllerExtension objects."""
controller_exts = []
@@ -525,32 +301,6 @@ class ControllerExtension(object):
self.controller = controller
-@utils.deprecated("Superseded by ControllerExtension")
-class RequestExtension(object):
- """Extend requests and responses of core nova OpenStack API resources.
-
- Provide a way to add data to responses and handle custom request data
- that is sent to core nova OpenStack API controllers.
-
- """
- def __init__(self, method, url_route, handler=None, pre_handler=None):
- self.url_route = url_route
- self.handler = handler
- self.conditions = dict(method=[method])
- self.key = "%s-%s" % (method, url_route)
- self.pre_handler = pre_handler
-
-
-@utils.deprecated("Superseded by ControllerExtension")
-class ActionExtension(object):
- """Add custom actions to core nova OpenStack API resources."""
-
- def __init__(self, collection, action_name, handler):
- self.collection = collection
- self.action_name = action_name
- self.handler = handler
-
-
class ResourceExtension(object):
"""Add top level resources to the OpenStack API in nova."""
@@ -570,14 +320,6 @@ class ResourceExtension(object):
self.serializer = serializer
-class ExtensionsXMLSerializer(xmlutil.XMLTemplateSerializer):
- def index(self):
- return ExtensionsTemplate()
-
- def show(self):
- return ExtensionTemplate()
-
-
def wrap_errors(fn):
"""Ensure errors are not passed along."""
def wrapped(*args, **kwargs):
diff --git a/nova/api/openstack/volume/__init__.py b/nova/api/openstack/volume/__init__.py
index 9e8a5d789..f8d0f28bd 100644
--- a/nova/api/openstack/volume/__init__.py
+++ b/nova/api/openstack/volume/__init__.py
@@ -62,8 +62,6 @@ class APIRouter(base_wsgi.Router):
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)
diff --git a/nova/api/openstack/volume/extensions.py b/nova/api/openstack/volume/extensions.py
index d1007629e..eccac660e 100644
--- a/nova/api/openstack/volume/extensions.py
+++ b/nova/api/openstack/volume/extensions.py
@@ -25,20 +25,20 @@ FLAGS = flags.FLAGS
class ExtensionManager(base_extensions.ExtensionManager):
- def __new__(cls):
- if cls._ext_mgr is None:
- LOG.audit(_('Initializing extension manager.'))
+ def __init__(self):
+ LOG.audit(_('Initializing extension manager.'))
- cls._ext_mgr = super(ExtensionManager, cls).__new__(cls)
+ self.cls_list = FLAGS.osapi_volume_extension
+ self.extensions = {}
+ self._load_extensions()
- cls.cls_list = FLAGS.osapi_volume_extension
- cls._ext_mgr.extensions = {}
- cls._ext_mgr._load_extensions()
- return cls._ext_mgr
+class ExtensionMiddleware(base_extensions.ExtensionMiddleware):
+ """Extensions middleware for WSGI.
+ Provided only for backwards compatibility with existing
+ api-paste.ini files. This middleware will be removed in future
+ versions of nova.
+ """
-class ExtensionMiddleware(base_extensions.ExtensionMiddleware):
- def __init__(self, application, ext_mgr=None):
- ext_mgr = ExtensionManager()
- super(ExtensionMiddleware, self).__init__(application, ext_mgr)
+ pass
diff --git a/nova/api/openstack/volume/snapshots.py b/nova/api/openstack/volume/snapshots.py
index ec12c052b..36687d736 100644
--- a/nova/api/openstack/volume/snapshots.py
+++ b/nova/api/openstack/volume/snapshots.py
@@ -57,6 +57,32 @@ def _translate_snapshot_summary_view(context, vol):
return d
+def make_snapshot(elem):
+ elem.set('id')
+ elem.set('status')
+ elem.set('size')
+ elem.set('createdAt')
+ elem.set('displayName')
+ elem.set('displayDescription')
+ elem.set('volumeId')
+
+
+class SnapshotTemplate(xmlutil.TemplateBuilder):
+ def construct(self):
+ root = xmlutil.TemplateElement('snapshot', selector='snapshot')
+ make_snapshot(root)
+ return xmlutil.MasterTemplate(root, 1)
+
+
+class SnapshotsTemplate(xmlutil.TemplateBuilder):
+ def construct(self):
+ root = xmlutil.TemplateElement('snapshots')
+ elem = xmlutil.SubTemplateElement(root, 'snapshot',
+ selector='snapshots')
+ make_snapshot(elem)
+ return xmlutil.MasterTemplate(root, 1)
+
+
class SnapshotsController(object):
"""The Volumes API controller for the OpenStack API."""
@@ -64,6 +90,7 @@ class SnapshotsController(object):
self.volume_api = volume.API()
super(SnapshotsController, self).__init__()
+ @wsgi.serializers(xml=SnapshotTemplate)
def show(self, req, id):
"""Return data about the given snapshot."""
context = req.environ['nova.context']
@@ -88,10 +115,12 @@ class SnapshotsController(object):
return exc.HTTPNotFound()
return webob.Response(status_int=202)
+ @wsgi.serializers(xml=SnapshotsTemplate)
def index(self, req):
"""Returns a summary list of snapshots."""
return self._items(req, entity_maker=_translate_snapshot_summary_view)
+ @wsgi.serializers(xml=SnapshotsTemplate)
def detail(self, req):
"""Returns a detailed list of snapshots."""
return self._items(req, entity_maker=_translate_snapshot_detail_view)
@@ -105,6 +134,7 @@ class SnapshotsController(object):
res = [entity_maker(context, snapshot) for snapshot in limited_list]
return {'snapshots': res}
+ @wsgi.serializers(xml=SnapshotTemplate)
def create(self, req, body):
"""Creates a new snapshot."""
context = req.environ['nova.context']
@@ -135,47 +165,5 @@ class SnapshotsController(object):
return {'snapshot': retval}
-def make_snapshot(elem):
- elem.set('id')
- elem.set('status')
- elem.set('size')
- elem.set('createdAt')
- elem.set('displayName')
- elem.set('displayDescription')
- elem.set('volumeId')
-
-
-class SnapshotTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('snapshot', selector='snapshot')
- make_snapshot(root)
- return xmlutil.MasterTemplate(root, 1)
-
-
-class SnapshotsTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('snapshots')
- elem = xmlutil.SubTemplateElement(root, 'snapshot',
- selector='snapshots')
- make_snapshot(elem)
- return xmlutil.MasterTemplate(root, 1)
-
-
-class SnapshotSerializer(xmlutil.XMLTemplateSerializer):
- def default(self):
- return SnapshotTemplate()
-
- def index(self):
- return SnapshotsTemplate()
-
- def detail(self):
- return SnapshotsTemplate()
-
-
def create_resource():
- body_serializers = {
- 'application/xml': SnapshotSerializer(),
- }
- serializer = wsgi.ResponseSerializer(body_serializers)
-
- return wsgi.Resource(SnapshotsController(), serializer=serializer)
+ return wsgi.Resource(SnapshotsController())
diff --git a/nova/api/openstack/volume/types.py b/nova/api/openstack/volume/types.py
index d324914a4..609a6cfc9 100644
--- a/nova/api/openstack/volume/types.py
+++ b/nova/api/openstack/volume/types.py
@@ -25,26 +25,6 @@ from nova import exception
from nova.volume import volume_types
-class VolumeTypesController(object):
- """ The volume types API controller for the Openstack API """
-
- def index(self, req):
- """ Returns the list of volume types """
- context = req.environ['nova.context']
- return volume_types.get_all_types(context)
-
- def show(self, req, id):
- """ Return a single volume type item """
- context = req.environ['nova.context']
-
- try:
- vol_type = volume_types.get_volume_type(context, id)
- except exception.NotFound or exception.ApiError:
- raise exc.HTTPNotFound()
-
- return {'volume_type': vol_type}
-
-
def make_voltype(elem):
elem.set('id')
elem.set('name')
@@ -68,20 +48,27 @@ class VolumeTypesTemplate(xmlutil.TemplateBuilder):
return xmlutil.MasterTemplate(root, 1)
-class VolumeTypesSerializer(xmlutil.XMLTemplateSerializer):
- def index(self):
- return VolumeTypesTemplate()
+class VolumeTypesController(object):
+ """ The volume types API controller for the Openstack API """
- def default(self):
- return VolumeTypeTemplate()
+ @wsgi.serializers(xml=VolumeTypesTemplate)
+ def index(self, req):
+ """ Returns the list of volume types """
+ context = req.environ['nova.context']
+ return volume_types.get_all_types(context)
+
+ @wsgi.serializers(xml=VolumeTypeTemplate)
+ def show(self, req, id):
+ """ Return a single volume type item """
+ context = req.environ['nova.context']
+ try:
+ vol_type = volume_types.get_volume_type(context, id)
+ except exception.NotFound or exception.ApiError:
+ raise exc.HTTPNotFound()
-def create_resource():
- body_serializers = {
- 'application/xml': VolumeTypesSerializer(),
- }
- serializer = wsgi.ResponseSerializer(body_serializers)
+ return {'volume_type': vol_type}
- deserializer = wsgi.RequestDeserializer()
- return wsgi.Resource(VolumeTypesController(), serializer=serializer)
+def create_resource():
+ return wsgi.Resource(VolumeTypesController())
diff --git a/nova/api/openstack/volume/volumes.py b/nova/api/openstack/volume/volumes.py
index b37a56374..397358ca1 100644
--- a/nova/api/openstack/volume/volumes.py
+++ b/nova/api/openstack/volume/volumes.py
@@ -109,6 +109,48 @@ def _translate_volume_summary_view(context, vol):
return d
+def make_attachment(elem):
+ elem.set('id')
+ elem.set('serverId')
+ elem.set('volumeId')
+ elem.set('device')
+
+
+def make_volume(elem):
+ elem.set('id')
+ elem.set('status')
+ elem.set('size')
+ elem.set('availabilityZone')
+ elem.set('createdAt')
+ elem.set('displayName')
+ elem.set('displayDescription')
+ elem.set('volumeType')
+ elem.set('snapshotId')
+
+ attachments = xmlutil.SubTemplateElement(elem, 'attachments')
+ attachment = xmlutil.SubTemplateElement(attachments, 'attachment',
+ selector='attachments')
+ make_attachment(attachment)
+
+ metadata = xmlutil.make_flat_dict('metadata')
+ elem.append(metadata)
+
+
+class VolumeTemplate(xmlutil.TemplateBuilder):
+ def construct(self):
+ root = xmlutil.TemplateElement('volume', selector='volume')
+ make_volume(root)
+ return xmlutil.MasterTemplate(root, 1)
+
+
+class VolumesTemplate(xmlutil.TemplateBuilder):
+ def construct(self):
+ root = xmlutil.TemplateElement('volumes')
+ elem = xmlutil.SubTemplateElement(root, 'volume', selector='volumes')
+ make_volume(elem)
+ return xmlutil.MasterTemplate(root, 1)
+
+
class VolumeController(object):
"""The Volumes API controller for the OpenStack API."""
@@ -116,6 +158,7 @@ class VolumeController(object):
self.volume_api = volume.API()
super(VolumeController, self).__init__()
+ @wsgi.serializers(xml=VolumeTemplate)
def show(self, req, id):
"""Return data about the given volume."""
context = req.environ['nova.context']
@@ -140,10 +183,12 @@ class VolumeController(object):
raise exc.HTTPNotFound()
return webob.Response(status_int=202)
+ @wsgi.serializers(xml=VolumesTemplate)
def index(self, req):
"""Returns a summary list of volumes."""
return self._items(req, entity_maker=_translate_volume_summary_view)
+ @wsgi.serializers(xml=VolumesTemplate)
def detail(self, req):
"""Returns a detailed list of volumes."""
return self._items(req, entity_maker=_translate_volume_detail_view)
@@ -157,6 +202,7 @@ class VolumeController(object):
res = [entity_maker(context, vol) for vol in limited_list]
return {'volumes': res}
+ @wsgi.serializers(xml=VolumeTemplate)
def create(self, req, body):
"""Creates a new volume."""
context = req.environ['nova.context']
@@ -201,90 +247,5 @@ class VolumeController(object):
return {'volume': retval}
-class VolumeAttachmentTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('volumeAttachment',
- selector='volumeAttachment')
- make_attachment(root)
- return xmlutil.MasterTemplate(root, 1)
-
-
-class VolumeAttachmentsTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('volumeAttachments')
- elem = xmlutil.SubTemplateElement(root, 'volumeAttachment',
- selector='volumeAttachments')
- make_attachment(elem)
- return xmlutil.MasterTemplate(root, 1)
-
-
-class VolumeAttachmentSerializer(xmlutil.XMLTemplateSerializer):
- def default(self):
- return VolumeAttachmentTemplate()
-
- def index(self):
- return VolumeAttachmentsTemplate()
-
-
-def make_attachment(elem):
- elem.set('id')
- elem.set('serverId')
- elem.set('volumeId')
- elem.set('device')
-
-
-def make_volume(elem):
- elem.set('id')
- elem.set('status')
- elem.set('size')
- elem.set('availabilityZone')
- elem.set('createdAt')
- elem.set('displayName')
- elem.set('displayDescription')
- elem.set('volumeType')
- elem.set('snapshotId')
-
- attachments = xmlutil.SubTemplateElement(elem, 'attachments')
- attachment = xmlutil.SubTemplateElement(attachments, 'attachment',
- selector='attachments')
- make_attachment(attachment)
-
- metadata = xmlutil.make_flat_dict('metadata')
- elem.append(metadata)
-
-
-class VolumeTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('volume', selector='volume')
- make_volume(root)
- return xmlutil.MasterTemplate(root, 1)
-
-
-class VolumesTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('volumes')
- elem = xmlutil.SubTemplateElement(root, 'volume', selector='volumes')
- make_volume(elem)
- return xmlutil.MasterTemplate(root, 1)
-
-
-class VolumeSerializer(xmlutil.XMLTemplateSerializer):
- def default(self):
- return VolumeTemplate()
-
- def index(self):
- return VolumesTemplate()
-
- def detail(self):
- return VolumesTemplate()
-
-
def create_resource():
- body_serializers = {
- 'application/xml': VolumeSerializer(),
- }
- serializer = wsgi.ResponseSerializer(body_serializers)
-
- deserializer = wsgi.RequestDeserializer()
-
- return wsgi.Resource(VolumeController(), serializer=serializer)
+ return wsgi.Resource(VolumeController())
diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py
index 3bf1bef00..d5a3d95b3 100644
--- a/nova/api/openstack/wsgi.py
+++ b/nova/api/openstack/wsgi.py
@@ -216,104 +216,6 @@ class MetadataXMLDeserializer(XMLDeserializer):
return metadata
-class RequestHeadersDeserializer(ActionDispatcher):
- """Default request headers deserializer"""
-
- def deserialize(self, request, action):
- return self.dispatch(request, action=action)
-
- def default(self, request):
- return {}
-
-
-class RequestDeserializer(object):
- """Break up a Request object into more useful pieces."""
-
- def __init__(self, body_deserializers=None, headers_deserializer=None):
- self.body_deserializers = {
- 'application/xml': XMLDeserializer(),
- 'application/json': JSONDeserializer(),
- }
- self.body_deserializers.update(body_deserializers or {})
-
- self.headers_deserializer = headers_deserializer or \
- RequestHeadersDeserializer()
-
- def deserialize(self, request):
- """Extract necessary pieces of the request.
-
- :param request: Request object
- :returns tuple of expected controller action name, dictionary of
- keyword arguments to pass to the controller, the expected
- content type of the response
-
- """
- action_args = self.get_action_args(request.environ)
- action = action_args.pop('action', None)
-
- action_args.update(self.deserialize_headers(request, action))
- action_args.update(self.deserialize_body(request, action))
-
- accept = self.get_expected_content_type(request)
-
- return (action, action_args, accept)
-
- def deserialize_headers(self, request, action):
- return self.headers_deserializer.deserialize(request, action)
-
- def deserialize_body(self, request, action):
- try:
- content_type = request.get_content_type()
- except exception.InvalidContentType:
- LOG.debug(_("Unrecognized Content-Type provided in request"))
- return {}
-
- if content_type is None:
- LOG.debug(_("No Content-Type provided in request"))
- return {}
-
- if not len(request.body) > 0:
- LOG.debug(_("Empty body provided in request"))
- return {}
-
- try:
- deserializer = self.get_body_deserializer(content_type)
- except exception.InvalidContentType:
- LOG.debug(_("Unable to deserialize body as provided Content-Type"))
- raise
-
- return deserializer.deserialize(request.body, action)
-
- def get_body_deserializer(self, content_type):
- try:
- ctype = _CONTENT_TYPE_MAP.get(content_type, content_type)
- return self.body_deserializers[ctype]
- except (KeyError, TypeError):
- raise exception.InvalidContentType(content_type=content_type)
-
- def get_expected_content_type(self, request):
- return request.best_match_content_type()
-
- def get_action_args(self, request_environment):
- """Parse dictionary created by routes library."""
- try:
- args = request_environment['wsgiorg.routing_args'][1].copy()
- except Exception:
- return {}
-
- try:
- del args['controller']
- except KeyError:
- pass
-
- try:
- del args['format']
- except KeyError:
- pass
-
- return args
-
-
class DictSerializer(ActionDispatcher):
"""Default request body serialization"""
@@ -435,104 +337,16 @@ class XMLDictSerializer(DictSerializer):
return etree.tostring(root, encoding='UTF-8', xml_declaration=True)
-class ResponseHeadersSerializer(ActionDispatcher):
- """Default response headers serialization"""
-
- def serialize(self, response, data, action):
- self.dispatch(response, data, action=action)
- context = response.request.environ.get('nova.context')
- if context:
- response.headers['X-Compute-Request-Id'] = context.request_id
-
- def default(self, response, data):
- response.status_int = 200
-
-
-class ResponseSerializer(object):
- """Encode the necessary pieces into a response object"""
-
- def __init__(self, body_serializers=None, headers_serializer=None):
- self.body_serializers = {
- 'application/xml': XMLDictSerializer(),
- 'application/json': JSONDictSerializer(),
- }
- self.body_serializers.update(body_serializers or {})
-
- self.headers_serializer = headers_serializer or \
- ResponseHeadersSerializer()
-
- def serialize(self, request, response_data, content_type,
- action='default'):
- """Serialize a dict into a string and wrap in a wsgi.Request object.
-
- :param response_data: dict produced by the Controller
- :param content_type: expected mimetype of serialized response body
-
- """
- response = webob.Response(request=request)
- self.serialize_headers(response, response_data, action)
- self.serialize_body(request, response, response_data, content_type,
- action)
- return response
-
- def serialize_headers(self, response, data, action):
- self.headers_serializer.serialize(response, data, action)
-
- def serialize_body(self, request, response, data, content_type, action):
- response.headers['Content-Type'] = content_type
- if data is not None:
- serializer = self.get_body_serializer(content_type)
- lazy_serialize = request.environ.get('nova.lazy_serialize', False)
- if lazy_serialize:
- response.body = utils.dumps(data)
- request.environ['nova.serializer'] = serializer
- request.environ['nova.action'] = action
- if (hasattr(serializer, 'get_template') and
- 'nova.template' not in request.environ):
-
- template = serializer.get_template(action)
- request.environ['nova.template'] = template
- else:
- response.body = serializer.serialize(data, action)
-
- def get_body_serializer(self, content_type):
- try:
- ctype = _CONTENT_TYPE_MAP.get(content_type, content_type)
- return self.body_serializers[ctype]
- except (KeyError, TypeError):
- raise exception.InvalidContentType(content_type=content_type)
+@utils.deprecated("The lazy serialization middleware is no longer necessary.")
+class LazySerializationMiddleware(wsgi.Middleware):
+ """Lazy serialization middleware.
+ Provided only for backwards compatibility with existing
+ api-paste.ini files. This middleware will be removed in future
+ versions of nova.
+ """
-class LazySerializationMiddleware(wsgi.Middleware):
- """Lazy serialization middleware."""
- @webob.dec.wsgify(RequestClass=Request)
- def __call__(self, req):
- # Request lazy serialization
- req.environ['nova.lazy_serialize'] = True
-
- response = req.get_response(self.application)
-
- # See if we're using the simple serialization driver
- simple_serial = req.environ.get('nova.simple_serial')
- if simple_serial is not None:
- body_obj = utils.loads(response.body)
- response.body = simple_serial.serialize(body_obj)
- return response
-
- # See if there's a serializer...
- serializer = req.environ.get('nova.serializer')
- if serializer is None:
- return response
-
- # OK, build up the arguments for the serialize() method
- kwargs = dict(action=req.environ['nova.action'])
- if 'nova.template' in req.environ:
- kwargs['template'] = req.environ['nova.template']
-
- # Re-serialize the body
- response.body = serializer.serialize(utils.loads(response.body),
- **kwargs)
- return response
+ pass
def serializers(**serializers):
@@ -698,20 +512,7 @@ class ResponseObject(object):
response.headers[hdr] = value
response.headers['Content-Type'] = content_type
if self.obj is not None:
- # TODO(Vek): When lazy serialization is retired, so can
- # this inner 'if'...
- lazy_serialize = request.environ.get('nova.lazy_serialize', False)
- if lazy_serialize:
- response.body = utils.dumps(self.obj)
- request.environ['nova.simple_serial'] = serializer
- # NOTE(Vek): Temporary ugly hack to support xml
- # templates in extensions, until we can
- # fold extensions into Resource and do away
- # with lazy serialization...
- if _MEDIA_TYPE_MAP.get(content_type) == 'xml':
- request.environ['nova.template'] = serializer
- else:
- response.body = serializer.serialize(self.obj)
+ response.body = serializer.serialize(self.obj)
return response
diff --git a/nova/api/openstack/xmlutil.py b/nova/api/openstack/xmlutil.py
index 4b64d4a8f..2485ef2c5 100644
--- a/nova/api/openstack/xmlutil.py
+++ b/nova/api/openstack/xmlutil.py
@@ -858,48 +858,6 @@ class TemplateBuilder(object):
raise NotImplementedError(_("subclasses must implement construct()!"))
-class XMLTemplateSerializer(wsgi.ActionDispatcher):
- """Template-based XML serializer.
-
- Data serializer that uses templates to perform its serialization.
- """
-
- def get_template(self, action='default'):
- """Retrieve the template to use for serialization."""
-
- return self.dispatch(action=action)
-
- def serialize(self, data, action='default', template=None):
- """Serialize data.
-
- :param data: The data to serialize.
- :param action: The action, for identifying the template to
- use. If no template is provided,
- get_template() will be called with this action
- to retrieve the template.
- :param template: The template to use in serialization.
- """
-
- # No template provided, look one up
- if template is None:
- template = self.get_template(action)
-
- # Still couldn't find a template; try the base
- # XMLDictSerializer
- if template is None:
- serial = wsgi.XMLDictSerializer()
- return serial.serialize(data, action=action)
-
- # Serialize the template
- return template.serialize(data, encoding='UTF-8',
- xml_declaration=True)
-
- def default(self):
- """Retrieve the default template to use."""
-
- return None
-
-
def make_links(parent, selector=None):
"""
Attach an Atom <links> element to the parent.
diff --git a/nova/tests/api/openstack/compute/contrib/test_admin_actions.py b/nova/tests/api/openstack/compute/contrib/test_admin_actions.py
index 0ffb4fdd1..3878ce676 100644
--- a/nova/tests/api/openstack/compute/contrib/test_admin_actions.py
+++ b/nova/tests/api/openstack/compute/contrib/test_admin_actions.py
@@ -123,9 +123,7 @@ class CreateBackupTests(test.TestCase):
self.backup_stubs = fakes.stub_out_compute_api_backup(self.stubs)
self.flags(allow_admin_api=True)
- router = compute_api.APIRouter()
- ext_middleware = extensions.ExtensionMiddleware(router)
- self.app = wsgi.LazySerializationMiddleware(ext_middleware)
+ self.app = compute_api.APIRouter()
self.uuid = utils.gen_uuid()
diff --git a/nova/tests/api/openstack/compute/contrib/test_disk_config.py b/nova/tests/api/openstack/compute/contrib/test_disk_config.py
index b897c5e71..87b21beb1 100644
--- a/nova/tests/api/openstack/compute/contrib/test_disk_config.py
+++ b/nova/tests/api/openstack/compute/contrib/test_disk_config.py
@@ -120,10 +120,7 @@ class DiskConfigTestCase(test.TestCase):
self.stubs.Set(nova.db, 'instance_create', fake_instance_create)
- app = compute.APIRouter()
- app = extensions.ExtensionMiddleware(app)
- app = wsgi.LazySerializationMiddleware(app)
- self.app = app
+ self.app = compute.APIRouter()
def assertDiskConfig(self, dict_, value):
self.assert_(API_DISK_CONFIG in dict_)
diff --git a/nova/tests/api/openstack/compute/contrib/test_floating_ip_pools.py b/nova/tests/api/openstack/compute/contrib/test_floating_ip_pools.py
index ffe84a1ba..1f0f0a424 100644
--- a/nova/tests/api/openstack/compute/contrib/test_floating_ip_pools.py
+++ b/nova/tests/api/openstack/compute/contrib/test_floating_ip_pools.py
@@ -56,12 +56,12 @@ class FloatingIpPoolTest(test.TestCase):
class FloatingIpPoolSerializerTest(test.TestCase):
def test_index_serializer(self):
- serializer = floating_ip_pools.FloatingIPPoolsSerializer()
+ serializer = floating_ip_pools.FloatingIPPoolsTemplate()
text = serializer.serialize(dict(
floating_ip_pools=[
dict(name='nova'),
dict(name='other')
- ]), 'index')
+ ]))
tree = etree.fromstring(text)
diff --git a/nova/tests/api/openstack/compute/contrib/test_server_action_list.py b/nova/tests/api/openstack/compute/contrib/test_server_action_list.py
index aa5a7275c..ffd4f744d 100644
--- a/nova/tests/api/openstack/compute/contrib/test_server_action_list.py
+++ b/nova/tests/api/openstack/compute/contrib/test_server_action_list.py
@@ -54,13 +54,11 @@ class ServerActionsTest(test.TestCase):
self.compute_api = nova.compute.API()
self.router = compute.APIRouter()
- ext_middleware = extensions.ExtensionMiddleware(self.router)
- self.app = wsgi.LazySerializationMiddleware(ext_middleware)
def test_get_actions(self):
uuid = nova.utils.gen_uuid()
req = fakes.HTTPRequest.blank('/fake/servers/%s/actions' % uuid)
- res = req.get_response(self.app)
+ res = req.get_response(self.router)
output = json.loads(res.body)
expected = {'actions': [
{'action': 'rebuild', 'error': None, 'created_at': str(dt)},
diff --git a/nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py b/nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py
index 69aabdc26..688940e3d 100644
--- a/nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py
+++ b/nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py
@@ -48,13 +48,11 @@ class ServerDiagnosticsTest(test.TestCase):
self.compute_api = nova.compute.API()
self.router = compute.APIRouter()
- ext_middleware = extensions.ExtensionMiddleware(self.router)
- self.app = wsgi.LazySerializationMiddleware(ext_middleware)
def test_get_diagnostics(self):
uuid = nova.utils.gen_uuid()
req = fakes.HTTPRequest.blank('/fake/servers/%s/diagnostics' % uuid)
- res = req.get_response(self.app)
+ res = req.get_response(self.router)
output = json.loads(res.body)
self.assertEqual(output, {'data': 'Some diagnostic info'})
diff --git a/nova/tests/api/openstack/compute/extensions/foxinsocks.py b/nova/tests/api/openstack/compute/extensions/foxinsocks.py
index 302fe7ddf..cf901472c 100644
--- a/nova/tests/api/openstack/compute/extensions/foxinsocks.py
+++ b/nova/tests/api/openstack/compute/extensions/foxinsocks.py
@@ -18,6 +18,7 @@
import webob.exc
from nova.api.openstack import extensions
+from nova.api.openstack import wsgi
class FoxInSocksController(object):
@@ -26,6 +27,39 @@ class FoxInSocksController(object):
return "Try to say this Mr. Knox, sir..."
+class FoxInSocksServerControllerExtension(wsgi.Controller):
+ @wsgi.action('add_tweedle')
+ def _add_tweedle(self, req, id, body):
+
+ return "Tweedle Beetle Added."
+
+ @wsgi.action('delete_tweedle')
+ def _delete_tweedle(self, req, id, body):
+
+ return "Tweedle Beetle Deleted."
+
+ @wsgi.action('fail')
+ def _fail(self, req, id, body):
+
+ raise webob.exc.HTTPBadRequest(explanation='Tweedle fail')
+
+
+class FoxInSocksFlavorGooseControllerExtension(wsgi.Controller):
+ @wsgi.extends
+ def show(self, req, resp_obj, id):
+ #NOTE: This only handles JSON responses.
+ # You can use content type header to test for XML.
+ resp_obj.obj['flavor']['googoose'] = req.GET.get('chewing')
+
+
+class FoxInSocksFlavorBandsControllerExtension(wsgi.Controller):
+ @wsgi.extends
+ def show(self, req, resp_obj, id):
+ #NOTE: This only handles JSON responses.
+ # You can use content type header to test for XML.
+ resp_obj.obj['big_bands'] = 'Pig Bands!'
+
+
class Foxinsocks(extensions.ExtensionDescriptor):
"""The Fox In Socks Extension"""
@@ -44,50 +78,17 @@ class Foxinsocks(extensions.ExtensionDescriptor):
resources.append(resource)
return resources
- def get_actions(self):
- actions = []
- actions.append(extensions.ActionExtension('servers', 'add_tweedle',
- self._add_tweedle))
- actions.append(extensions.ActionExtension('servers', 'delete_tweedle',
- self._delete_tweedle))
- actions.append(extensions.ActionExtension('servers', 'fail',
- self._fail))
- return actions
-
- def get_request_extensions(self):
- request_exts = []
-
- def _goose_handler(req, res, body):
- #NOTE: This only handles JSON responses.
- # You can use content type header to test for XML.
- body['flavor']['googoose'] = req.GET.get('chewing')
- return res
-
- req_ext1 = extensions.RequestExtension('GET',
- '/v2/:(project_id)/flavors/:(id)',
- _goose_handler)
- request_exts.append(req_ext1)
-
- def _bands_handler(req, res, body):
- #NOTE: This only handles JSON responses.
- # You can use content type header to test for XML.
- body['big_bands'] = 'Pig Bands!'
- return res
-
- req_ext2 = extensions.RequestExtension('GET',
- '/v2/:(project_id)/flavors/:(id)',
- _bands_handler)
- request_exts.append(req_ext2)
- return request_exts
-
- def _add_tweedle(self, input_dict, req, id):
-
- return "Tweedle Beetle Added."
-
- def _delete_tweedle(self, input_dict, req, id):
+ def get_controller_extensions(self):
+ extension_list = []
- return "Tweedle Beetle Deleted."
+ extension_set = [
+ (FoxInSocksServerControllerExtension, 'servers'),
+ (FoxInSocksFlavorGooseControllerExtension, 'flavors'),
+ (FoxInSocksFlavorBandsControllerExtension, 'flavors'),
+ ]
+ for klass, collection in extension_set:
+ controller = klass()
+ ext = extensions.ControllerExtension(self, collection, controller)
+ extension_list.append(ext)
- def _fail(self, input_dict, req, id):
-
- raise webob.exc.HTTPBadRequest(explanation='Tweedle fail')
+ return extension_list
diff --git a/nova/tests/api/openstack/compute/test_extensions.py b/nova/tests/api/openstack/compute/test_extensions.py
index 02356bc44..61cfea04f 100644
--- a/nova/tests/api/openstack/compute/test_extensions.py
+++ b/nova/tests/api/openstack/compute/test_extensions.py
@@ -144,7 +144,6 @@ class ExtensionTestCase(test.TestCase):
if fox not in ext_list:
ext_list.append(fox)
self.flags(osapi_compute_extension=ext_list)
- compute_extensions.ExtensionManager.reset()
class ExtensionControllerTest(ExtensionTestCase):
@@ -189,10 +188,8 @@ class ExtensionControllerTest(ExtensionTestCase):
def test_list_extensions_json(self):
app = compute.APIRouter()
- ext_midware = compute_extensions.ExtensionMiddleware(app)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
request = webob.Request.blank("/fake/extensions")
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
self.assertEqual(200, response.status_int)
# Make sure we have all the extensions.
@@ -218,10 +215,8 @@ class ExtensionControllerTest(ExtensionTestCase):
def test_get_extension_json(self):
app = compute.APIRouter()
- ext_midware = compute_extensions.ExtensionMiddleware(app)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
request = webob.Request.blank("/fake/extensions/FOXNSOX")
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
self.assertEqual(200, response.status_int)
data = json.loads(response.body)
@@ -235,18 +230,15 @@ class ExtensionControllerTest(ExtensionTestCase):
def test_get_non_existing_extension_json(self):
app = compute.APIRouter()
- ext_midware = compute_extensions.ExtensionMiddleware(app)
request = webob.Request.blank("/fake/extensions/4")
- response = request.get_response(ext_midware)
+ response = request.get_response(app)
self.assertEqual(404, response.status_int)
def test_list_extensions_xml(self):
app = compute.APIRouter()
- ext_midware = compute_extensions.ExtensionMiddleware(app)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
request = webob.Request.blank("/fake/extensions")
request.accept = "application/xml"
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
self.assertEqual(200, response.status_int)
print response.body
@@ -270,11 +262,9 @@ class ExtensionControllerTest(ExtensionTestCase):
def test_get_extension_xml(self):
app = compute.APIRouter()
- ext_midware = compute_extensions.ExtensionMiddleware(app)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
request = webob.Request.blank("/fake/extensions/FOXNSOX")
request.accept = "application/xml"
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
self.assertEqual(200, response.status_int)
xml = response.body
print xml
@@ -297,10 +287,8 @@ class ResourceExtensionTest(ExtensionTestCase):
def test_no_extension_present(self):
manager = StubExtensionManager(None)
app = compute.APIRouter(manager)
- ext_midware = compute_extensions.ExtensionMiddleware(app, manager)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
request = webob.Request.blank("/blah")
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
self.assertEqual(404, response.status_int)
def test_get_resources(self):
@@ -308,10 +296,8 @@ class ResourceExtensionTest(ExtensionTestCase):
StubController(response_body))
manager = StubExtensionManager(res_ext)
app = compute.APIRouter(manager)
- ext_midware = compute_extensions.ExtensionMiddleware(app, manager)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
request = webob.Request.blank("/fake/tweedles")
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
self.assertEqual(200, response.status_int)
self.assertEqual(response_body, response.body)
@@ -320,10 +306,8 @@ class ResourceExtensionTest(ExtensionTestCase):
StubController(response_body))
manager = StubExtensionManager(res_ext)
app = compute.APIRouter(manager)
- ext_midware = compute_extensions.ExtensionMiddleware(app, manager)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
request = webob.Request.blank("/fake/tweedles")
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
self.assertEqual(200, response.status_int)
self.assertEqual(response_body, response.body)
@@ -332,11 +316,9 @@ class ResourceExtensionTest(ExtensionTestCase):
StubController(response_body))
manager = StubExtensionManager(res_ext)
app = compute.APIRouter(manager)
- ext_midware = compute_extensions.ExtensionMiddleware(app, manager)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
request = webob.Request.blank("/fake/tweedles")
request.method = "POST"
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
self.assertEqual(400, response.status_int)
self.assertEqual('application/json', response.content_type)
body = json.loads(response.body)
@@ -353,10 +335,8 @@ class ResourceExtensionTest(ExtensionTestCase):
StubController(response_body))
manager = StubExtensionManager(res_ext)
app = compute.APIRouter(manager)
- ext_midware = compute_extensions.ExtensionMiddleware(app, manager)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
request = webob.Request.blank("/fake/tweedles/1")
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
self.assertEqual(404, response.status_int)
self.assertEqual('application/json', response.content_type)
body = json.loads(response.body)
@@ -393,10 +373,8 @@ class ExtensionManagerTest(ExtensionTestCase):
def test_get_resources(self):
app = compute.APIRouter()
- ext_midware = compute_extensions.ExtensionMiddleware(app)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
request = webob.Request.blank("/fake/foxnsocks")
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
self.assertEqual(200, response.status_int)
self.assertEqual(response_body, response.body)
@@ -404,8 +382,7 @@ class ExtensionManagerTest(ExtensionTestCase):
# Don't need the serialization middleware here because we're
# not testing any serialization
app = compute.APIRouter()
- ext_midware = compute_extensions.ExtensionMiddleware(app)
- ext_mgr = ext_midware.ext_mgr
+ ext_mgr = compute_extensions.ExtensionManager()
ext_mgr.register(InvalidExtension())
self.assertTrue('FOXNSOX' in ext_mgr.extensions)
self.assertTrue('THIRD' not in ext_mgr.extensions)
@@ -413,8 +390,7 @@ class ExtensionManagerTest(ExtensionTestCase):
def test_admin_extensions(self):
self.flags(allow_admin_api=True)
app = compute.APIRouter()
- ext_midware = compute_extensions.ExtensionMiddleware(app)
- ext_mgr = ext_midware.ext_mgr
+ ext_mgr = compute_extensions.ExtensionManager()
ext_mgr.register(AdminExtension())
self.assertTrue('FOXNSOX' in ext_mgr.extensions)
self.assertTrue('ADMIN' in ext_mgr.extensions)
@@ -422,8 +398,7 @@ class ExtensionManagerTest(ExtensionTestCase):
def test_admin_extensions_no_admin_api(self):
self.flags(allow_admin_api=False)
app = compute.APIRouter()
- ext_midware = compute_extensions.ExtensionMiddleware(app)
- ext_mgr = ext_midware.ext_mgr
+ ext_mgr = compute_extensions.ExtensionManager()
ext_mgr.register(AdminExtension())
self.assertTrue('FOXNSOX' in ext_mgr.extensions)
self.assertTrue('ADMIN' not in ext_mgr.extensions)
@@ -433,13 +408,11 @@ class ActionExtensionTest(ExtensionTestCase):
def _send_server_action_request(self, url, body):
app = compute.APIRouter()
- ext_midware = compute_extensions.ExtensionMiddleware(app)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
request = webob.Request.blank(url)
request.method = 'POST'
request.content_type = 'application/json'
request.body = json.dumps(body)
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
return response
def test_extended_action(self):
@@ -494,35 +467,30 @@ class ActionExtensionTest(ExtensionTestCase):
class RequestExtensionTest(ExtensionTestCase):
def test_get_resources_with_stub_mgr(self):
+ class GooGoose(wsgi.Controller):
+ @wsgi.extends
+ def show(self, req, resp_obj, id):
+ # only handle JSON responses
+ resp_obj.obj['flavor']['googoose'] = req.GET.get('chewing')
- def _req_handler(req, res, body):
- # only handle JSON responses
- body['flavor']['googoose'] = req.GET.get('chewing')
- return res
+ req_ext = base_extensions.ControllerExtension(
+ StubControllerExtension(), 'flavors', GooGoose())
- req_ext = base_extensions.RequestExtension('GET',
- '/v2/fake/flavors/:(id)',
- _req_handler)
-
- manager = StubExtensionManager(None, None, req_ext)
- app = fakes.wsgi_app(serialization=base_wsgi.Middleware)
- ext_midware = compute_extensions.ExtensionMiddleware(app, manager)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
+ manager = StubExtensionManager(None, None, None, req_ext)
+ app = fakes.wsgi_app(ext_mgr=manager)
request = webob.Request.blank("/v2/fake/flavors/1?chewing=bluegoo")
request.environ['api.version'] = '2'
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
self.assertEqual(200, response.status_int)
response_data = json.loads(response.body)
self.assertEqual('bluegoo', response_data['flavor']['googoose'])
def test_get_resources_with_mgr(self):
- app = fakes.wsgi_app(serialization=base_wsgi.Middleware)
- ext_midware = compute_extensions.ExtensionMiddleware(app)
- ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
+ app = fakes.wsgi_app()
request = webob.Request.blank("/v2/fake/flavors/1?chewing=newblue")
request.environ['api.version'] = '2'
- response = request.get_response(ser_midware)
+ response = request.get_response(app)
self.assertEqual(200, response.status_int)
response_data = json.loads(response.body)
print response_data
@@ -611,7 +579,7 @@ class ControllerExtensionTest(ExtensionTestCase):
class ExtensionsXMLSerializerTest(test.TestCase):
def test_serialize_extension(self):
- serializer = base_extensions.ExtensionsXMLSerializer()
+ serializer = base_extensions.ExtensionTemplate()
data = {'extension': {
'name': 'ext1',
'namespace': 'http://docs.rack.com/servers/api/ext/pie/v1.0',
@@ -625,7 +593,7 @@ class ExtensionsXMLSerializerTest(test.TestCase):
'type': 'application/vnd.sun.wadl+xml',
'href': 'http://docs.rack.com/servers/api/ext/cs.wadl'}]}}
- xml = serializer.serialize(data, 'show')
+ xml = serializer.serialize(data)
print xml
root = etree.XML(xml)
ext_dict = data['extension']
@@ -644,7 +612,7 @@ class ExtensionsXMLSerializerTest(test.TestCase):
xmlutil.validate_schema(root, 'extension')
def test_serialize_extensions(self):
- serializer = base_extensions.ExtensionsXMLSerializer()
+ serializer = base_extensions.ExtensionsTemplate()
data = {"extensions": [{
"name": "Public Image Extension",
"namespace": "http://foo.com/api/ext/pie/v1.0",
@@ -670,7 +638,7 @@ class ExtensionsXMLSerializerTest(test.TestCase):
"type": "application/vnd.sun.wadl+xml",
"href": "http://foo.com/api/ext/cs-cbs.wadl"}]}]}
- xml = serializer.serialize(data, 'index')
+ xml = serializer.serialize(data)
print xml
root = etree.XML(xml)
ext_elems = root.findall('{0}extension'.format(NS))
diff --git a/nova/tests/api/openstack/compute/test_limits.py b/nova/tests/api/openstack/compute/test_limits.py
index 20ec0d1a0..e6b5b58ae 100644
--- a/nova/tests/api/openstack/compute/test_limits.py
+++ b/nova/tests/api/openstack/compute/test_limits.py
@@ -81,8 +81,7 @@ class LimitsControllerTest(BaseLimitTestSuite):
def setUp(self):
"""Run before each test."""
BaseLimitTestSuite.setUp(self)
- self.controller = wsgi.LazySerializationMiddleware(
- limits.create_resource())
+ self.controller = limits.create_resource()
self.maxDiff = None
def _get_index_request(self, accept_header="application/json"):
diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py
index d3289623e..103f3678c 100644
--- a/nova/tests/api/openstack/fakes.py
+++ b/nova/tests/api/openstack/fakes.py
@@ -50,7 +50,7 @@ class Context(object):
class FakeRouter(wsgi.Router):
- def __init__(self):
+ def __init__(self, ext_mgr=None):
pass
@webob.dec.wsgify
@@ -74,10 +74,9 @@ def fake_wsgi(self, req):
def wsgi_app(inner_app_v2=None, fake_auth=True, fake_auth_context=None,
- serialization=os_wsgi.LazySerializationMiddleware,
- use_no_auth=False):
+ use_no_auth=False, ext_mgr=None):
if not inner_app_v2:
- inner_app_v2 = compute.APIRouter()
+ inner_app_v2 = compute.APIRouter(ext_mgr)
if fake_auth:
if fake_auth_context is not None:
@@ -85,19 +84,13 @@ def wsgi_app(inner_app_v2=None, fake_auth=True, fake_auth_context=None,
else:
ctxt = context.RequestContext('fake', 'fake', auth_token=True)
api_v2 = openstack_api.FaultWrapper(api_auth.InjectContext(ctxt,
- limits.RateLimitingMiddleware(
- serialization(
- extensions.ExtensionMiddleware(inner_app_v2)))))
+ limits.RateLimitingMiddleware(inner_app_v2)))
elif use_no_auth:
api_v2 = openstack_api.FaultWrapper(auth.NoAuthMiddleware(
- limits.RateLimitingMiddleware(
- serialization(
- extensions.ExtensionMiddleware(inner_app_v2)))))
+ limits.RateLimitingMiddleware(inner_app_v2)))
else:
api_v2 = openstack_api.FaultWrapper(auth.AuthMiddleware(
- limits.RateLimitingMiddleware(
- serialization(
- extensions.ExtensionMiddleware(inner_app_v2)))))
+ limits.RateLimitingMiddleware(inner_app_v2)))
mapper = urlmap.URLMap()
mapper['/v2'] = api_v2
diff --git a/nova/tests/api/openstack/test_common.py b/nova/tests/api/openstack/test_common.py
index cd85208b9..e8f967976 100644
--- a/nova/tests/api/openstack/test_common.py
+++ b/nova/tests/api/openstack/test_common.py
@@ -372,7 +372,7 @@ class MetadataXMLDeserializationTest(test.TestCase):
class MetadataXMLSerializationTest(test.TestCase):
def test_xml_declaration(self):
- serializer = common.MetadataXMLSerializer()
+ serializer = common.MetadataTemplate()
fixture = {
'metadata': {
'one': 'two',
@@ -380,20 +380,20 @@ class MetadataXMLSerializationTest(test.TestCase):
},
}
- output = serializer.serialize(fixture, 'index')
+ output = serializer.serialize(fixture)
print output
has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
self.assertTrue(has_dec)
def test_index(self):
- serializer = common.MetadataXMLSerializer()
+ serializer = common.MetadataTemplate()
fixture = {
'metadata': {
'one': 'two',
'three': 'four',
},
}
- output = serializer.serialize(fixture, 'index')
+ output = serializer.serialize(fixture)
print output
root = etree.XML(output)
xmlutil.validate_schema(root, 'metadata')
@@ -406,13 +406,13 @@ class MetadataXMLSerializationTest(test.TestCase):
self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
def test_index_null(self):
- serializer = common.MetadataXMLSerializer()
+ serializer = common.MetadataTemplate()
fixture = {
'metadata': {
None: None,
},
}
- output = serializer.serialize(fixture, 'index')
+ output = serializer.serialize(fixture)
print output
root = etree.XML(output)
xmlutil.validate_schema(root, 'metadata')
@@ -425,13 +425,13 @@ class MetadataXMLSerializationTest(test.TestCase):
self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
def test_index_unicode(self):
- serializer = common.MetadataXMLSerializer()
+ serializer = common.MetadataTemplate()
fixture = {
'metadata': {
u'three': u'Jos\xe9',
},
}
- output = serializer.serialize(fixture, 'index')
+ output = serializer.serialize(fixture)
print output
root = etree.XML(output)
xmlutil.validate_schema(root, 'metadata')
@@ -444,13 +444,13 @@ class MetadataXMLSerializationTest(test.TestCase):
self.assertEqual(metadata_elem.text.strip(), meta_value)
def test_show(self):
- serializer = common.MetadataXMLSerializer()
+ serializer = common.MetaItemTemplate()
fixture = {
'meta': {
'one': 'two',
},
}
- output = serializer.serialize(fixture, 'show')
+ output = serializer.serialize(fixture)
print output
root = etree.XML(output)
meta_dict = fixture['meta']
@@ -459,14 +459,14 @@ class MetadataXMLSerializationTest(test.TestCase):
self.assertEqual(root.text.strip(), meta_value)
def test_update_all(self):
- serializer = common.MetadataXMLSerializer()
+ serializer = common.MetadataTemplate()
fixture = {
'metadata': {
'key6': 'value6',
'key4': 'value4',
},
}
- output = serializer.serialize(fixture, 'update_all')
+ output = serializer.serialize(fixture)
print output
root = etree.XML(output)
xmlutil.validate_schema(root, 'metadata')
@@ -479,13 +479,13 @@ class MetadataXMLSerializationTest(test.TestCase):
self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
def test_update_item(self):
- serializer = common.MetadataXMLSerializer()
+ serializer = common.MetaItemTemplate()
fixture = {
'meta': {
'one': 'two',
},
}
- output = serializer.serialize(fixture, 'update')
+ output = serializer.serialize(fixture)
print output
root = etree.XML(output)
meta_dict = fixture['meta']
@@ -494,7 +494,7 @@ class MetadataXMLSerializationTest(test.TestCase):
self.assertEqual(root.text.strip(), meta_value)
def test_create(self):
- serializer = common.MetadataXMLSerializer()
+ serializer = common.MetadataTemplate()
fixture = {
'metadata': {
'key9': 'value9',
@@ -502,7 +502,7 @@ class MetadataXMLSerializationTest(test.TestCase):
'key1': 'value1',
},
}
- output = serializer.serialize(fixture, 'create')
+ output = serializer.serialize(fixture)
print output
root = etree.XML(output)
xmlutil.validate_schema(root, 'metadata')
@@ -524,8 +524,3 @@ class MetadataXMLSerializationTest(test.TestCase):
""".replace(" ", "").replace("\n", ""))
self.assertEqual(expected.toxml(), actual.toxml())
-
- def test_delete(self):
- serializer = common.MetadataXMLSerializer()
- output = serializer.serialize(None, 'delete')
- self.assertEqual(output, '')
diff --git a/nova/tests/api/openstack/test_wsgi.py b/nova/tests/api/openstack/test_wsgi.py
index a0bbb6b9d..90d048443 100644
--- a/nova/tests/api/openstack/test_wsgi.py
+++ b/nova/tests/api/openstack/test_wsgi.py
@@ -98,29 +98,6 @@ class ActionDispatcherTest(test.TestCase):
self.assertEqual(serializer.dispatch({}, action='update'), 'trousers')
-class ResponseHeadersSerializerTest(test.TestCase):
- def test_default(self):
- serializer = wsgi.ResponseHeadersSerializer()
- context = nova.context.get_admin_context()
- req = webob.Request.blank('/', environ={'nova.context': context})
- response = webob.Response(request=req)
- serializer.serialize(response, {'v': '123'}, 'asdf')
- self.assertEqual(response.status_int, 200)
-
- def test_custom(self):
- class Serializer(wsgi.ResponseHeadersSerializer):
- def update(self, response, data):
- response.status_int = 404
- response.headers['X-Custom-Header'] = data['v']
- serializer = Serializer()
- context = nova.context.get_admin_context()
- req = webob.Request.blank('/', environ={'nova.context': context})
- response = webob.Response(request=req)
- serializer.serialize(response, {'v': '123'}, 'update')
- self.assertEqual(response.status_int, 404)
- self.assertEqual(response.headers['X-Custom-Header'], '123')
-
-
class DictSerializerTest(test.TestCase):
def test_dispatch_default(self):
serializer = wsgi.DictSerializer()
@@ -207,226 +184,6 @@ class XMLDeserializerTest(test.TestCase):
self.assertEqual(deserializer.deserialize(xml), as_dict)
-class RequestHeadersDeserializerTest(test.TestCase):
- def test_default(self):
- deserializer = wsgi.RequestHeadersDeserializer()
- req = wsgi.Request.blank('/')
- self.assertEqual(deserializer.deserialize(req, 'asdf'), {})
-
- def test_custom(self):
- class Deserializer(wsgi.RequestHeadersDeserializer):
- def update(self, request):
- return {'a': request.headers['X-Custom-Header']}
- deserializer = Deserializer()
- req = wsgi.Request.blank('/')
- req.headers['X-Custom-Header'] = 'b'
- self.assertEqual(deserializer.deserialize(req, 'update'), {'a': 'b'})
-
-
-class ResponseHeadersSerializerTest(test.TestCase):
- def test_request_id(self):
- serializer = wsgi.ResponseHeadersSerializer()
-
- context = nova.context.get_admin_context()
- req = webob.Request.blank('/', environ={'nova.context': context})
- res = webob.Response(request=req)
- serializer.serialize(res, {}, 'foo')
- h1 = res.headers.get('X-Compute-Request-Id')
- self.assertTrue(h1)
-
- context = nova.context.get_admin_context()
- req = webob.Request.blank('/', environ={'nova.context': context})
- res = webob.Response(request=req)
- serializer.serialize(res, {}, 'foo')
- h2 = res.headers.get('X-Compute-Request-Id')
- self.assertTrue(h2)
-
- self.assertNotEqual(h1, h2)
-
-
-class JSONSerializer(object):
- def serialize(self, data, action='default'):
- return 'pew_json'
-
-
-class XMLSerializer(object):
- def serialize(self, data, action='default'):
- return 'pew_xml'
-
-
-class HeadersSerializer(object):
- def serialize(self, response, data, action):
- response.status_int = 404
-
-
-class ResponseSerializerTest(test.TestCase):
- def setUp(self):
- self.body_serializers = {
- 'application/json': JSONSerializer(),
- 'application/xml': XMLSerializer(),
- }
-
- self.serializer = wsgi.ResponseSerializer(self.body_serializers,
- HeadersSerializer())
-
- def tearDown(self):
- pass
-
- def test_get_serializer(self):
- ctype = 'application/json'
- self.assertEqual(self.serializer.get_body_serializer(ctype),
- self.body_serializers[ctype])
-
- def test_get_serializer_unknown_content_type(self):
- self.assertRaises(exception.InvalidContentType,
- self.serializer.get_body_serializer,
- 'application/unknown')
-
- def test_serialize_response_json(self):
- for content_type in ('application/json',
- 'application/vnd.openstack.compute+json'):
- request = wsgi.Request.blank('/')
- response = self.serializer.serialize(request, {}, content_type)
- self.assertEqual(response.headers['Content-Type'], content_type)
- self.assertEqual(response.body, 'pew_json')
- self.assertEqual(response.status_int, 404)
-
- def test_serialize_response_xml(self):
- for content_type in ('application/xml',
- 'application/vnd.openstack.compute+xml'):
- request = wsgi.Request.blank('/')
- response = self.serializer.serialize(request, {}, content_type)
- self.assertEqual(response.headers['Content-Type'], content_type)
- self.assertEqual(response.body, 'pew_xml')
- self.assertEqual(response.status_int, 404)
-
- def test_serialize_response_None(self):
- request = wsgi.Request.blank('/')
- response = self.serializer.serialize(request, None, 'application/json')
- self.assertEqual(response.headers['Content-Type'], 'application/json')
- self.assertEqual(response.body, '')
- self.assertEqual(response.status_int, 404)
-
- def test_serialize_response_dict_to_unknown_content_type(self):
- request = wsgi.Request.blank('/')
- self.assertRaises(exception.InvalidContentType,
- self.serializer.serialize,
- request, {}, 'application/unknown')
-
-
-class LazySerializationTest(test.TestCase):
- def setUp(self):
- self.body_serializers = {
- 'application/json': JSONSerializer(),
- 'application/xml': XMLSerializer(),
- }
-
- self.serializer = wsgi.ResponseSerializer(self.body_serializers,
- HeadersSerializer())
-
- def tearDown(self):
- pass
-
- def test_serialize_response_json(self):
- for content_type in ('application/json',
- 'application/vnd.openstack.compute+json'):
- request = wsgi.Request.blank('/')
- request.environ['nova.lazy_serialize'] = True
- response = self.serializer.serialize(request, {}, content_type)
- self.assertEqual(response.headers['Content-Type'], content_type)
- self.assertEqual(response.status_int, 404)
- body = json.loads(response.body)
- self.assertEqual(body, {})
- serializer = request.environ['nova.serializer']
- self.assertEqual(serializer.serialize(body), 'pew_json')
-
- def test_serialize_response_xml(self):
- for content_type in ('application/xml',
- 'application/vnd.openstack.compute+xml'):
- request = wsgi.Request.blank('/')
- request.environ['nova.lazy_serialize'] = True
- response = self.serializer.serialize(request, {}, content_type)
- self.assertEqual(response.headers['Content-Type'], content_type)
- self.assertEqual(response.status_int, 404)
- body = json.loads(response.body)
- self.assertEqual(body, {})
- serializer = request.environ['nova.serializer']
- self.assertEqual(serializer.serialize(body), 'pew_xml')
-
- def test_serialize_response_None(self):
- request = wsgi.Request.blank('/')
- request.environ['nova.lazy_serialize'] = True
- response = self.serializer.serialize(request, None, 'application/json')
- self.assertEqual(response.headers['Content-Type'], 'application/json')
- self.assertEqual(response.status_int, 404)
- self.assertEqual(response.body, '')
-
-
-class RequestDeserializerTest(test.TestCase):
- def setUp(self):
- class JSONDeserializer(object):
- def deserialize(self, data, action='default'):
- return 'pew_json'
-
- class XMLDeserializer(object):
- def deserialize(self, data, action='default'):
- return 'pew_xml'
-
- self.body_deserializers = {
- 'application/json': JSONDeserializer(),
- 'application/xml': XMLDeserializer(),
- }
-
- self.deserializer = wsgi.RequestDeserializer(self.body_deserializers)
-
- def tearDown(self):
- pass
-
- def test_get_deserializer(self):
- ctype = 'application/json'
- expected = self.deserializer.get_body_deserializer(ctype)
- self.assertEqual(expected, self.body_deserializers[ctype])
-
- def test_get_deserializer_unknown_content_type(self):
- self.assertRaises(exception.InvalidContentType,
- self.deserializer.get_body_deserializer,
- 'application/unknown')
-
- def test_get_expected_content_type(self):
- ctype = 'application/json'
- request = wsgi.Request.blank('/')
- request.headers['Accept'] = ctype
- self.assertEqual(self.deserializer.get_expected_content_type(request),
- ctype)
-
- def test_get_action_args(self):
- env = {
- 'wsgiorg.routing_args': [None, {
- 'controller': None,
- 'format': None,
- 'action': 'update',
- 'id': 12,
- }],
- }
-
- expected = {'action': 'update', 'id': 12}
-
- self.assertEqual(self.deserializer.get_action_args(env), expected)
-
- def test_deserialize(self):
- def fake_get_routing_args(request):
- return {'action': 'create'}
- self.deserializer.get_action_args = fake_get_routing_args
-
- request = wsgi.Request.blank('/')
- request.headers['Accept'] = 'application/xml'
-
- deserialized = self.deserializer.deserialize(request)
- expected = ('create', {}, 'application/xml')
-
- self.assertEqual(expected, deserialized)
-
-
class ResourceTest(test.TestCase):
def test_resource_call(self):
class Controller(object):
diff --git a/nova/tests/api/openstack/test_xmlutil.py b/nova/tests/api/openstack/test_xmlutil.py
index de15cfe1f..87e374c95 100644
--- a/nova/tests/api/openstack/test_xmlutil.py
+++ b/nova/tests/api/openstack/test_xmlutil.py
@@ -712,78 +712,6 @@ class TemplateBuilderTest(test.TestCase):
self.assertEqual(tmpl1, tmpl2)
-class SerializerTest(xmlutil.XMLTemplateSerializer):
- def test(self):
- root = xmlutil.TemplateElement('servers')
- a = xmlutil.SubTemplateElement(root, 'a', selector='servers')
- a.text = xmlutil.Selector('a')
- return xmlutil.MasterTemplate(root, 1, nsmap={None: "asdf"})
-
-
-class XMLTemplateSerializerTest(test.TestCase):
- def setUp(self):
- self.tmpl_serializer = SerializerTest()
- self.data = dict(servers=dict(a=(2, 3)))
- self.data_multi = dict(servers=[dict(a=(2, 3)), dict(a=(3, 4))])
- super(XMLTemplateSerializerTest, self).setUp()
-
- def test_get_template(self):
- # First, check what happens when we fall back on the default
- # option
- self.assertEqual(self.tmpl_serializer.get_template(), None)
- self.assertEqual(self.tmpl_serializer.get_template('nosuch'), None)
-
- # Now, check that we get back a template
- tmpl = self.tmpl_serializer.get_template('test')
- self.assertNotEqual(tmpl, None)
- self.assertEqual(tmpl.root.tag, 'servers')
-
- def test_serialize_default(self):
- expected_xml = '<servers><a>(2,3)</a></servers>'
- result = self.tmpl_serializer.serialize(self.data)
- result = result.replace('\n', '').replace(' ', '')
- self.assertEqual(result, expected_xml)
-
- def test_serialize_multi_default(self):
- expected_xml = ('<servers><server><a>(2,3)</a></server>'
- '<server><a>(3,4)</a></server></servers>')
- result = self.tmpl_serializer.serialize(self.data_multi)
- result = result.replace('\n', '').replace(' ', '')
- self.assertEqual(result, expected_xml)
-
- def test_serialize_explicit(self):
- expected_xml = ("<?xmlversion='1.0'encoding='UTF-8'?>"
- '<serversxmlns="asdf"><a>(2,3)</a></servers>')
- tmpl = self.tmpl_serializer.get_template('test')
- result = self.tmpl_serializer.serialize(self.data, template=tmpl)
- result = result.replace('\n', '').replace(' ', '')
- self.assertEqual(result, expected_xml)
-
- def test_serialize_multi_explicit(self):
- expected_xml = ("<?xmlversion='1.0'encoding='UTF-8'?>"
- '<serversxmlns="asdf"><a>(2,3)</a>'
- '<a>(3,4)</a></servers>')
- tmpl = self.tmpl_serializer.get_template('test')
- result = self.tmpl_serializer.serialize(self.data_multi, template=tmpl)
- result = result.replace('\n', '').replace(' ', '')
- self.assertEqual(result, expected_xml)
-
- def test_serialize(self):
- expected_xml = ("<?xmlversion='1.0'encoding='UTF-8'?>"
- '<serversxmlns="asdf"><a>(2,3)</a></servers>')
- result = self.tmpl_serializer.serialize(self.data, 'test')
- result = result.replace('\n', '').replace(' ', '')
- self.assertEqual(result, expected_xml)
-
- def test_serialize_multi(self):
- expected_xml = ("<?xmlversion='1.0'encoding='UTF-8'?>"
- '<serversxmlns="asdf"><a>(2,3)</a>'
- '<a>(3,4)</a></servers>')
- result = self.tmpl_serializer.serialize(self.data_multi, 'test')
- result = result.replace('\n', '').replace(' ', '')
- self.assertEqual(result, expected_xml)
-
-
class MiscellaneousXMLUtilTests(test.TestCase):
def test_make_flat_dict(self):
expected_xml = ("<?xml version='1.0' encoding='UTF-8'?>\n"
diff --git a/nova/tests/api/openstack/volume/test_snapshots.py b/nova/tests/api/openstack/volume/test_snapshots.py
index 06543ae5f..0d2220727 100644
--- a/nova/tests/api/openstack/volume/test_snapshots.py
+++ b/nova/tests/api/openstack/volume/test_snapshots.py
@@ -251,7 +251,7 @@ class SnapshotSerializerTest(test.TestCase):
self.assertEqual(str(snap[attr]), tree.get(attr))
def test_snapshot_show_create_serializer(self):
- serializer = snapshots.SnapshotSerializer()
+ serializer = snapshots.SnapshotTemplate()
raw_snapshot = dict(
id='snap_id',
status='snap_status',
@@ -261,7 +261,7 @@ class SnapshotSerializerTest(test.TestCase):
displayDescription='snap_desc',
volumeId='vol_id',
)
- text = serializer.serialize(dict(snapshot=raw_snapshot), 'show')
+ text = serializer.serialize(dict(snapshot=raw_snapshot))
print text
tree = etree.fromstring(text)
@@ -269,7 +269,7 @@ class SnapshotSerializerTest(test.TestCase):
self._verify_snapshot(raw_snapshot, tree)
def test_snapshot_index_detail_serializer(self):
- serializer = snapshots.SnapshotSerializer()
+ serializer = snapshots.SnapshotsTemplate()
raw_snapshots = [dict(
id='snap1_id',
status='snap1_status',
@@ -288,7 +288,7 @@ class SnapshotSerializerTest(test.TestCase):
displayDescription='snap2_desc',
volumeId='vol2_id',
)]
- text = serializer.serialize(dict(snapshots=raw_snapshots), 'index')
+ text = serializer.serialize(dict(snapshots=raw_snapshots))
print text
tree = etree.fromstring(text)
diff --git a/nova/tests/api/openstack/volume/test_types.py b/nova/tests/api/openstack/volume/test_types.py
index 34d861bed..a6253c7af 100644
--- a/nova/tests/api/openstack/volume/test_types.py
+++ b/nova/tests/api/openstack/volume/test_types.py
@@ -123,10 +123,6 @@ class VolumeTypesApiTest(test.TestCase):
class VolumeTypesSerializerTest(test.TestCase):
- def setUp(self):
- super(VolumeTypesSerializerTest, self).setUp()
- self.serializer = types.VolumeTypesSerializer()
-
def _verify_volume_type(self, vtype, tree):
self.assertEqual('volume_type', tree.tag)
self.assertEqual(vtype['name'], tree.get('name'))
@@ -142,9 +138,11 @@ class VolumeTypesSerializerTest(test.TestCase):
self.assertEqual(len(seen), 0)
def test_index_serializer(self):
+ serializer = types.VolumeTypesTemplate()
+
# Just getting some input data
vtypes = return_volume_types_get_all_types(None)
- text = self.serializer.serialize(vtypes, 'index')
+ text = serializer.serialize(vtypes)
print text
tree = etree.fromstring(text)
@@ -157,8 +155,10 @@ class VolumeTypesSerializerTest(test.TestCase):
self._verify_volume_type(vtypes[name], child)
def test_voltype_serializer(self):
+ serializer = types.VolumeTypeTemplate()
+
vtype = stub_volume_type(1)
- text = self.serializer.serialize(dict(volume_type=vtype))
+ text = serializer.serialize(dict(volume_type=vtype))
print text
tree = etree.fromstring(text)
diff --git a/nova/tests/api/openstack/volume/test_volumes.py b/nova/tests/api/openstack/volume/test_volumes.py
index 8e936fd56..51ad2c536 100644
--- a/nova/tests/api/openstack/volume/test_volumes.py
+++ b/nova/tests/api/openstack/volume/test_volumes.py
@@ -134,47 +134,8 @@ class VolumeSerializerTest(test.TestCase):
not_seen.remove(gr_child.tag)
self.assertEqual(0, len(not_seen))
- def test_attach_show_create_serializer(self):
- serializer = volumes.VolumeAttachmentSerializer()
- raw_attach = dict(
- id='vol_id',
- volumeId='vol_id',
- serverId='instance_uuid',
- device='/foo')
- text = serializer.serialize(dict(volumeAttachment=raw_attach), 'show')
-
- print text
- tree = etree.fromstring(text)
-
- self.assertEqual('volumeAttachment', tree.tag)
- self._verify_volume_attachment(raw_attach, tree)
-
- def test_attach_index_serializer(self):
- serializer = volumes.VolumeAttachmentSerializer()
- raw_attaches = [dict(
- id='vol_id1',
- volumeId='vol_id1',
- serverId='instance1_uuid',
- device='/foo1'),
- dict(
- id='vol_id2',
- volumeId='vol_id2',
- serverId='instance2_uuid',
- device='/foo2')]
- text = serializer.serialize(dict(volumeAttachments=raw_attaches),
- 'index')
-
- print text
- tree = etree.fromstring(text)
-
- self.assertEqual('volumeAttachments', tree.tag)
- self.assertEqual(len(raw_attaches), len(tree))
- for idx, child in enumerate(tree):
- self.assertEqual('volumeAttachment', child.tag)
- self._verify_volume_attachment(raw_attaches[idx], child)
-
def test_volume_show_create_serializer(self):
- serializer = volumes.VolumeSerializer()
+ serializer = volumes.VolumeTemplate()
raw_volume = dict(
id='vol_id',
status='vol_status',
@@ -195,7 +156,7 @@ class VolumeSerializerTest(test.TestCase):
baz='quux',
),
)
- text = serializer.serialize(dict(volume=raw_volume), 'show')
+ text = serializer.serialize(dict(volume=raw_volume))
print text
tree = etree.fromstring(text)
@@ -203,7 +164,7 @@ class VolumeSerializerTest(test.TestCase):
self._verify_volume(raw_volume, tree)
def test_volume_index_detail_serializer(self):
- serializer = volumes.VolumeSerializer()
+ serializer = volumes.VolumesTemplate()
raw_volumes = [dict(
id='vol1_id',
status='vol1_status',
@@ -244,7 +205,7 @@ class VolumeSerializerTest(test.TestCase):
bar='vol2_bar',
),
)]
- text = serializer.serialize(dict(volumes=raw_volumes), 'index')
+ text = serializer.serialize(dict(volumes=raw_volumes))
print text
tree = etree.fromstring(text)
diff --git a/nova/tests/integrated/test_extensions.py b/nova/tests/integrated/test_extensions.py
index e30419ed9..64e29dbf8 100644
--- a/nova/tests/integrated/test_extensions.py
+++ b/nova/tests/integrated/test_extensions.py
@@ -27,8 +27,6 @@ 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_compute_extension'] = FLAGS.osapi_compute_extension[:]
f['osapi_compute_extension'].append(