From 95e1da06e7d407cbdb427b19946021c8a95324d0 Mon Sep 17 00:00:00 2001 From: Pushkar Umaranikar Date: Tue, 7 Feb 2017 22:36:06 +0000 Subject: [PATCH] Placement api: set custom json_error_formatter in resource_class Change decorator for resource based actions in resource_class handler to wsgi_wrapper.PlacementWsgify This is a newly introduced wrapper class around webob.dec.wsgify to set json formatter in case of webob exceptions. Change-Id: Ic330d23b2eda3b3f299291b9cdc4489d02481786 Partial-Bug: #1635182 --- .../placement/handlers/resource_class.py | 29 ++++++++----------- .../placement/gabbits/resource-classes.yaml | 25 ++++++++++++++++ 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/nova/api/openstack/placement/handlers/resource_class.py b/nova/api/openstack/placement/handlers/resource_class.py index df15050bc422..2899e8a1f922 100644 --- a/nova/api/openstack/placement/handlers/resource_class.py +++ b/nova/api/openstack/placement/handlers/resource_class.py @@ -19,6 +19,7 @@ import webob from nova.api.openstack.placement import microversion from nova.api.openstack.placement import util +from nova.api.openstack.placement import wsgi_wrapper from nova import exception from nova.i18n import _ from nova import objects @@ -63,7 +64,7 @@ def _serialize_resource_classes(environ, rcs): return {"resource_classes": output} -@webob.dec.wsgify +@wsgi_wrapper.PlacementWsgify @microversion.version_handler(1.2) @util.require_content('application/json') def create_resource_class(req): @@ -81,15 +82,13 @@ def create_resource_class(req): except exception.ResourceClassExists: raise webob.exc.HTTPConflict( _('Conflicting resource class already exists: %(name)s') % - {'name': data['name']}, - json_formatter=util.json_error_formatter) + {'name': data['name']}) except exception.MaxDBRetriesExceeded: raise webob.exc.HTTPConflict( _('Max retries of DB transaction exceeded attempting ' 'to create resource class: %(name)s, please' 'try again.') % - {'name': data['name']}, - json_formatter=util.json_error_formatter) + {'name': data['name']}) req.response.location = util.resource_class_url(req.environ, rc) req.response.status = 201 @@ -97,7 +96,7 @@ def create_resource_class(req): return req.response -@webob.dec.wsgify +@wsgi_wrapper.PlacementWsgify @microversion.version_handler(1.2) def delete_resource_class(req): """DELETE to destroy a single resource class. @@ -113,19 +112,17 @@ def delete_resource_class(req): except exception.ResourceClassCannotDeleteStandard as exc: raise webob.exc.HTTPBadRequest( _('Cannot delete standard resource class %(rp_name)s: %(error)s') % - {'rp_name': name, 'error': exc}, - json_formatter=util.json_error_formatter) + {'rp_name': name, 'error': exc}) except exception.ResourceClassInUse as exc: raise webob.exc.HTTPConflict( _('Unable to delete resource class %(rp_name)s: %(error)s') % - {'rp_name': name, 'error': exc}, - json_formatter=util.json_error_formatter) + {'rp_name': name, 'error': exc}) req.response.status = 204 req.response.content_type = None return req.response -@webob.dec.wsgify +@wsgi_wrapper.PlacementWsgify @microversion.version_handler(1.2) @util.check_accept('application/json') def get_resource_class(req): @@ -146,7 +143,7 @@ def get_resource_class(req): return req.response -@webob.dec.wsgify +@wsgi_wrapper.PlacementWsgify @microversion.version_handler(1.2) @util.check_accept('application/json') def list_resource_classes(req): @@ -166,7 +163,7 @@ def list_resource_classes(req): return response -@webob.dec.wsgify +@wsgi_wrapper.PlacementWsgify @microversion.version_handler(1.2) @util.require_content('application/json') def update_resource_class(req): @@ -190,13 +187,11 @@ def update_resource_class(req): except exception.ResourceClassExists: raise webob.exc.HTTPConflict( _('Resource class already exists: %(name)s') % - {'name': rc.name}, - json_formatter=util.json_error_formatter) + {'name': rc.name}) except exception.ResourceClassCannotUpdateStandard: raise webob.exc.HTTPBadRequest( _('Cannot update standard resource class %(rp_name)s') % - {'rp_name': name}, - json_formatter=util.json_error_formatter) + {'rp_name': name}) req.response.body = encodeutils.to_utf8(jsonutils.dumps( _serialize_resource_class(req.environ, rc)) diff --git a/nova/tests/functional/api/openstack/placement/gabbits/resource-classes.yaml b/nova/tests/functional/api/openstack/placement/gabbits/resource-classes.yaml index 6c3c37e9b368..9c3dd5ea3c3e 100644 --- a/nova/tests/functional/api/openstack/placement/gabbits/resource-classes.yaml +++ b/nova/tests/functional/api/openstack/placement/gabbits/resource-classes.yaml @@ -4,6 +4,7 @@ fixtures: defaults: request_headers: x-auth-token: admin + accept: application/json OpenStack-API-Version: placement latest tests: @@ -14,6 +15,8 @@ tests: OpenStack-API-Version: placement 1.1 content-type: application/json status: 404 + response_json_paths: + $.errors[0].title: Not Found - name: test microversion mask when wrong content type desc: we want to get a 404 before a 415 @@ -67,6 +70,8 @@ tests: status: 400 response_strings: - JSON does not validate + response_json_paths: + $.errors[0].title: Bad Request - name: post new resource class POST: /resource_classes @@ -89,6 +94,8 @@ tests: status: 409 response_strings: - Conflicting resource class already exists + response_json_paths: + $.errors[0].title: Conflict - name: confirm the correct post GET: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS'] @@ -123,6 +130,8 @@ tests: status: 400 response_strings: - JSON does not validate + response_json_paths: + $.errors[0].title: Bad Request - name: update custom resource class to standard resource class name PUT: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS'] @@ -133,6 +142,8 @@ tests: status: 400 response_strings: - JSON does not validate + response_json_paths: + $.errors[0].title: Bad Request - name: post another custom resource class POST: /resource_classes @@ -152,6 +163,8 @@ tests: response_strings: - Resource class already exists - $ENVIRON['CUSTOM_RES_CLASS'] + response_json_paths: + $.errors[0].title: Conflict - name: update custom resource class PUT: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS'] @@ -169,6 +182,8 @@ tests: status: 400 response_strings: - Cannot delete standard resource class + response_json_paths: + $.errors[0].title: Bad Request - name: delete custom resource class DELETE: /resource_classes/CUSTOM_NFV_BAR @@ -177,6 +192,8 @@ tests: - name: 404 on deleted resource class DELETE: $LAST_URL status: 404 + response_json_paths: + $.errors[0].title: Not Found - name: post malformed json as json POST: /resource_classes @@ -186,6 +203,8 @@ tests: status: 400 response_strings: - 'Malformed JSON:' + response_json_paths: + $.errors[0].title: Bad Request - name: post bad resource class name IRON_NFV POST: /resource_classes @@ -196,6 +215,8 @@ tests: status: 400 response_strings: - JSON does not validate + response_json_paths: + $.errors[0].title: Bad Request - name: try to create resource class with name exceed max characters POST: /resource_classes @@ -206,6 +227,8 @@ tests: status: 400 response_strings: - "Failed validating 'maxLength'" + response_json_paths: + $.errors[0].title: Bad Request - name: try to update resource class with name exceed max characters PUT: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS'] @@ -216,3 +239,5 @@ tests: status: 400 response_strings: - "Failed validating 'maxLength'" + response_json_paths: + $.errors[0].title: Bad Request