Merge "Set global_request_id if passed in as X-OpenStack-Request-ID."

This commit is contained in:
Jenkins 2017-05-24 06:27:18 +00:00 committed by Gerrit Code Review
commit 6b7b1b225d
3 changed files with 65 additions and 0 deletions

View File

@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import re
from oslo_context import context
import webob.dec
@ -20,7 +22,11 @@ from oslo_middleware import base
ENV_REQUEST_ID = 'openstack.request_id'
GLOBAL_REQ_ID = 'openstack.global_request_id'
HTTP_RESP_HEADER_REQUEST_ID = 'x-openstack-request-id'
INBOUND_HEADER = 'X-Openstack-Request-Id'
ID_FORMAT = (r'^req-[a-f0-9]{8}-[a-f0-9]{4}-'
r'[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$')
class RequestId(base.ConfigurableMiddleware):
@ -35,8 +41,18 @@ class RequestId(base.ConfigurableMiddleware):
# oslo.middleware without impacting existing users.
compat_headers = []
def set_global_req_id(self, req):
gr_id = req.headers.get(INBOUND_HEADER, "")
if re.match(ID_FORMAT, gr_id):
req.environ[GLOBAL_REQ_ID] = gr_id
# TODO(sdague): it would be nice to warn if we dropped a bogus
# request_id, but the infrastructure for doing that isn't yet
# setup at this stage.
@webob.dec.wsgify
def __call__(self, req):
self.set_global_req_id(req)
req_id = context.generate_request_id()
req.environ[ENV_REQUEST_ID] = req_id
response = req.get_response(self.application)

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import uuid
from oslotest import base as test_base
from testtools import matchers
@ -63,3 +64,43 @@ class RequestIdTest(test_base.BaseTestCase):
self.assertEqual(res.headers.get("x-compute-req-id"), res_req_id)
self.assertEqual(res.headers.get("x-silly-id"), res_req_id)
def test_global_request_id_set(self):
"""Test that global request_id is set."""
@webob.dec.wsgify
def application(req):
return req.environ[request_id.GLOBAL_REQ_ID]
global_req = "req-%s" % uuid.uuid4()
app = request_id.RequestId(application)
req = webob.Request.blank(
'/test',
headers={"X-OpenStack-Request-ID": global_req})
res = req.get_response(app)
res_req_id = res.headers.get(request_id.HTTP_RESP_HEADER_REQUEST_ID)
if isinstance(res_req_id, bytes):
res_req_id = res_req_id.decode('utf-8')
# global-request-id in request environ is returned as response body
self.assertEqual(res.body.decode('utf-8'), global_req)
self.assertNotEqual(res.body.decode('utf-8'), res_req_id)
def test_global_request_id_drop(self):
"""Test that bad format ids are dropped.
This ensures that badly formatted ids are dropped entirely.
"""
@webob.dec.wsgify
def application(req):
return req.environ.get(request_id.GLOBAL_REQ_ID)
global_req = "req-%s-bad" % uuid.uuid4()
app = request_id.RequestId(application)
req = webob.Request.blank(
'/test',
headers={"X-OpenStack-Request-ID": global_req})
res = req.get_response(app)
res_req_id = res.headers.get(request_id.HTTP_RESP_HEADER_REQUEST_ID)
if isinstance(res_req_id, bytes):
res_req_id = res_req_id.decode('utf-8')
# global-request-id in request environ is returned as response body
self.assertEqual(res.body.decode('utf-8'), '')

View File

@ -0,0 +1,8 @@
---
features:
- |
This adds support for ``global_request_id`` to the ``RequestId``
middleware. An inbound header of ``X-OpenStack-Request-ID`` is
accepted as long as it is of the format ``req-$uuid``, and made
available to oslo.context. This will allow for cross project
request id tracking.