Allow compatibility headers for request_id

We discovered that Nova is using a local version of the request_id
header code because it's x-compute-request-id predates
x-openstack-request-id, and things were never migrated after the oslo
code was extracted. In order to let Nova use the base code (which may
become more complicated with inbound request-id setting) we need to
support a compat headers field, which is additional http header names
that should be set with the request-id value.

Change-Id: I18a92f8bf2f85fcf30d32be68bae58f64b135df0
This commit is contained in:
Sean Dague 2017-05-15 07:33:07 -04:00
parent 2eaf1ebaf5
commit 9b94bae73c
3 changed files with 45 additions and 2 deletions

View File

@ -30,11 +30,21 @@ class RequestId(base.ConfigurableMiddleware):
request environment. The request ID is also added to API response.
"""
# if compat_headers is set, we also return the request_id in those
# headers as well. This allows projects like Nova to adopt
# oslo.middleware without impacting existing users.
compat_headers = []
@webob.dec.wsgify
def __call__(self, req):
req_id = context.generate_request_id()
req.environ[ENV_REQUEST_ID] = req_id
response = req.get_response(self.application)
if HTTP_RESP_HEADER_REQUEST_ID not in response.headers:
response.headers.add(HTTP_RESP_HEADER_REQUEST_ID, req_id)
return_headers = [HTTP_RESP_HEADER_REQUEST_ID]
return_headers.extend(self.compat_headers)
for header in return_headers:
if header not in response.headers:
response.headers.add(header, req_id)
return response

View File

@ -22,6 +22,10 @@ import webob.dec
from oslo_middleware import request_id
class AltHeader(request_id.RequestId):
compat_headers = ["x-compute-req-id", "x-silly-id"]
class RequestIdTest(test_base.BaseTestCase):
def test_generate_request_id(self):
@webob.dec.wsgify
@ -37,3 +41,25 @@ class RequestIdTest(test_base.BaseTestCase):
self.assertThat(res_req_id, matchers.StartsWith('req-'))
# request-id in request environ is returned as response body
self.assertEqual(res.body.decode('utf-8'), res_req_id)
def test_compat_headers(self):
"""Test that compat headers are set
Compat headers might exist on a super class to support
previous API contracts. This ensures that you can set that to
a list of headers and those values are the same as the
request_id.
"""
@webob.dec.wsgify
def application(req):
return req.environ[request_id.ENV_REQUEST_ID]
app = AltHeader(application)
req = webob.Request.blank('/test')
res = req.get_response(app)
res_req_id = res.headers.get(request_id.HTTP_RESP_HEADER_REQUEST_ID)
self.assertEqual(res.headers.get("x-compute-req-id"), res_req_id)
self.assertEqual(res.headers.get("x-silly-id"), res_req_id)

View File

@ -0,0 +1,7 @@
---
features:
- |
This adds a new ``compat_headers`` class attribute to the
``RequestId`` middleware. That allows projects like Nova that have
API contracts on alternative request-id headers to adopt the oslo
``RequestId`` middleware but still retain their API contract.