Merge "Don't return content when we set HTTP 204"

This commit is contained in:
Jenkins 2016-12-23 14:07:19 +00:00 committed by Gerrit Code Review
commit 4f90652ca5
4 changed files with 35 additions and 8 deletions

View File

@ -19,7 +19,6 @@ from oslo_config import cfg
from oslo_utils import importutils
import pecan
from pecan import request
from pecan import response
from neutron._i18n import _
from neutron.api.v2 import attributes
@ -112,12 +111,11 @@ class QuotaController(utils.NeutronPecanController):
neutron_context, self._tenant_id, key, value)
return get_tenant_quotas(self._tenant_id, self._driver)
@utils.when(index, method='DELETE')
@utils.when_delete(index)
def delete(self):
neutron_context = request.context.get('neutron_context')
self._driver.delete_tenant_quota(neutron_context,
self._tenant_id)
response.status = 204
@utils.when(index, method='POST')
def not_supported(self):

View File

@ -69,10 +69,8 @@ class ItemController(utils.NeutronPecanController):
updater_args.append(data)
return {self.resource: self.plugin_updater(*updater_args)}
@utils.when(index, method='DELETE')
@utils.when_delete(index)
def delete(self):
# TODO(kevinbenton): setting code could be in a decorator
pecan.response.status = 204
neutron_context = request.context['neutron_context']
deleter_args = [neutron_context, self.item]
if 'parent_id' in request.context:

View File

@ -88,6 +88,34 @@ def when(index, *args, **kwargs):
return _pecan_generator_wrapper(index.when, *args, **kwargs)
def when_delete(index, *args, **kwargs):
kwargs['method'] = 'DELETE'
deco = _pecan_generator_wrapper(index.when, *args, **kwargs)
return _composed(_set_del_code, deco)
def _set_del_code(f):
"""Handle logic of disabling json templating engine and setting HTTP code.
We return 204 on delete without content. However, pecan defaults empty
responses with the json template engine to 'null', which is not empty
content. This breaks connection re-use for some clients due to the
inconsistency. So we need to detect when there is no response and
disable the json templating engine.
See https://github.com/pecan/pecan/issues/72
"""
@functools.wraps(f)
def wrapped(*args, **kwargs):
f(*args, **kwargs)
pecan.response.status = 204
pecan.override_template(None)
# NOTE(kevinbenton): we are explicitly not returning the DELETE
# response from the controller because that is the legacy Neutron
# API behavior.
return wrapped
class NeutronPecanController(object):
LIST = 'list'
@ -241,11 +269,10 @@ class ShimItemController(NeutronPecanController):
else:
return self.controller_show(shim_request, self.item)
@when(index, method='DELETE')
@when_delete(index)
def delete(self):
if not self.controller_delete:
pecan.abort(405)
pecan.response.status = 204
shim_request = ShimRequest(request.context['neutron_context'])
uri_identifiers = request.context['uri_identifiers']
return self.controller_delete(shim_request, self.item,

View File

@ -229,6 +229,7 @@ class TestQuotasController(test_functional.PecanFunctionalTest):
response = self.app.delete(url, headers={'X-Project-Id': 'admin',
'X-Roles': 'admin'})
self.assertEqual(204, response.status_int)
self.assertFalse(response.body)
# As DELETE does not return a body we need another GET
response = self.app.get(url, headers={'X-Project-Id': 'foo'})
self.assertEqual(200, response.status_int)
@ -261,6 +262,7 @@ class TestQuotasController(test_functional.PecanFunctionalTest):
response = self.app.delete(url, headers={'X-Project-Id': 'admin',
'X-Roles': 'admin'})
self.assertEqual(204, response.status_int)
self.assertFalse(response.body)
response = self.app.get(self.base_url,
headers={'X-Project-Id': 'admin',
'X-Roles': 'admin'})
@ -405,6 +407,7 @@ class TestResourceController(TestRootController):
response = self.app.delete('/v2.0/ports/%s.json' % self.port['id'],
headers={'X-Project-Id': 'tenid'})
self.assertEqual(response.status_int, 204)
self.assertFalse(response.body)
def test_plugin_initialized(self):
self.assertIsNotNone(manager.NeutronManager._instance)
@ -836,6 +839,7 @@ class TestL3AgentShimControllers(test_functional.PecanFunctionalTest):
'/v2.0/agents/%(a)s/l3-routers/%(n)s.json' % {
'a': self.agent.id, 'n': self.router['id']}, headers=headers)
self.assertEqual(204, response.status_int)
self.assertFalse(response.body)
response = self.app.get(
'/v2.0/routers/%s/l3-agents.json' % self.router['id'],
headers=headers)