From 9b94bae73c1cf5549a69e7798d175119cc1aaa2e Mon Sep 17 00:00:00 2001 From: Sean Dague Date: Mon, 15 May 2017 07:33:07 -0400 Subject: 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 --- oslo_middleware/request_id.py | 14 ++++++++++-- oslo_middleware/tests/test_request_id.py | 26 ++++++++++++++++++++++ .../notes/compat_headers-55a635b8ec01b6f1.yaml | 7 ++++++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/compat_headers-55a635b8ec01b6f1.yaml diff --git a/oslo_middleware/request_id.py b/oslo_middleware/request_id.py index 31a433b..5716c82 100644 --- a/oslo_middleware/request_id.py +++ b/oslo_middleware/request_id.py @@ -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 diff --git a/oslo_middleware/tests/test_request_id.py b/oslo_middleware/tests/test_request_id.py index 039b7af..5c79c21 100644 --- a/oslo_middleware/tests/test_request_id.py +++ b/oslo_middleware/tests/test_request_id.py @@ -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) diff --git a/releasenotes/notes/compat_headers-55a635b8ec01b6f1.yaml b/releasenotes/notes/compat_headers-55a635b8ec01b6f1.yaml new file mode 100644 index 0000000..489b33c --- /dev/null +++ b/releasenotes/notes/compat_headers-55a635b8ec01b6f1.yaml @@ -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. -- cgit v1.2.1