Mirror X-Trans-Id to X-Openstack-Request-Id

Many other OpenStack services use a `[X-]OpenStack-Request-Id` header
to return a unique identifier for the request.  Swift will now return
`X-Trans-Id` as well as `X-Openstack-Request-Id`.

Change-Id: I56cd4738808b99c0a08463f83c100be51a62db05
Closes-Bug: #1572786
This commit is contained in:
karen chan 2016-10-17 03:37:35 -07:00
parent e55f3ad203
commit d0fe922904
13 changed files with 60 additions and 30 deletions

View File

@ -732,6 +732,14 @@ X-Object-Meta-name_resp:
in: header
required: false
type: string
X-Openstack-Request-Id:
description: |
A unique transaction ID for this request. Your
service provider might need this value if you report a problem.
(same as ``X-Trans-Id``)
in: header
required: true
type: string
X-Remove-Account-name:
description: |
Removes the metadata item named ``name``.

View File

@ -8,4 +8,5 @@ X-Account-Container-Count: 2
Content-Type: application/json; charset=utf-8
Accept-Ranges: bytes
X-Trans-Id: tx274a77a8975c4a66aeb24-0052d95365
X-Openstack-Request-Id: tx274a77a8975c4a66aeb24-0052d95365
Date: Fri, 17 Jan 2014 15:59:33 GMT

View File

@ -8,4 +8,5 @@ X-Account-Container-Count: 2
Content-Type: application/xml; charset=utf-8
Accept-Ranges: bytes
X-Trans-Id: tx69f60bc9f7634a01988e6-0052d9544b
X-Openstack-Request-Id: tx69f60bc9f7634a01988e6-0052d9544b
Date: Fri, 17 Jan 2014 16:03:23 GMT

View File

@ -7,4 +7,5 @@ X-Timestamp: 1389727543.65372
X-Container-Bytes-Used: 26
Content-Type: application/json; charset=utf-8
X-Trans-Id: tx26377fe5fab74869825d1-0052d6bdff
X-Openstack-Request-Id: tx26377fe5fab74869825d1-0052d6bdff
Date: Wed, 15 Jan 2014 16:57:35 GMT

View File

@ -7,4 +7,5 @@ X-Timestamp: 1389727543.65372
X-Container-Bytes-Used: 26
Content-Type: application/xml; charset=utf-8
X-Trans-Id: txc75ea9a6e66f47d79e0c5-0052d6be76
X-Openstack-Request-Id: txc75ea9a6e66f47d79e0c5-0052d6be76
Date: Wed, 15 Jan 2014 16:59:35 GMT

View File

@ -100,6 +100,7 @@ Response Parameters
- X-Account-Meta-Temp-URL-Key-2: X-Account-Meta-Temp-URL-Key-2_resp
- X-Timestamp: X-Timestamp
- X-Trans-Id: X-Trans-Id
- X-Openstack-Request-Id: X-Openstack-Request-Id
- Date: Date
- X-Account-Bytes-Used: X-Account-Bytes-Used
- X-Account-Container-Count: X-Account-Container-Count
@ -194,6 +195,7 @@ Example requests and responses:
Content-Length: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx8c2dd6aee35442a4a5646-0052d954fb
X-Openstack-Request-Id: tx8c2dd6aee35442a4a5646-0052d954fb
Date: Fri, 17 Jan 2014 16:06:19 GMT
@ -212,6 +214,7 @@ Example requests and responses:
Content-Length: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx1439b96137364ab581156-0052d95532
X-Openstack-Request-Id: tx1439b96137364ab581156-0052d95532
Date: Fri, 17 Jan 2014 16:07:14 GMT
@ -230,6 +233,7 @@ Example requests and responses:
Content-Length: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx411cf57701424da99948a-0052d9556f
X-Openstack-Request-Id: tx411cf57701424da99948a-0052d9556f
Date: Fri, 17 Jan 2014 16:08:15 GMT
@ -266,6 +270,7 @@ Response Parameters
- Content-Length: Content-Length_cud_resp
- Content-Type: Content-Type_cud_resp
- X-Trans-Id: X-Trans-Id
- X-Openstack-Request-Id: X-Openstack-Request-Id
Show account metadata
@ -312,6 +317,7 @@ Show account metadata request:
Content-Type: text/plain; charset=utf-8
Accept-Ranges: bytes
X-Trans-Id: txafb3504870144b8ca40f7-0052d955d4
X-Openstack-Request-Id: txafb3504870144b8ca40f7-0052d955d4
Date: Fri, 17 Jan 2014 16:09:56 GMT
@ -344,6 +350,7 @@ Response Parameters
- X-Account-Meta-Temp-URL-Key-2: X-Account-Meta-Temp-URL-Key-2_resp
- X-Timestamp: X-Timestamp
- X-Trans-Id: X-Trans-Id
- X-Openstack-Request-Id: X-Openstack-Request-Id
- Date: Date
- X-Account-Bytes-Used: X-Account-Bytes-Used
- X-Account-Object-Count: X-Account-Object-Count

View File

@ -58,6 +58,7 @@ Example Using ``X-Versions-Location``
Content-Length: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: txb91810fb717347d09eec8-0052e18997
X-Openstack-Request-Id: txb91810fb717347d09eec8-0052e18997
Date: Thu, 23 Jan 2014 21:28:55 GMT
#. Create the first version of an object in the ``current`` container:
@ -74,6 +75,7 @@ Example Using ``X-Versions-Location``
Etag: d41d8cd98f00b204e9800998ecf8427e
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx5992d536a4bd4fec973aa-0052e18a2a
X-Openstack-Request-Id: tx5992d536a4bd4fec973aa-0052e18a2a
Date: Thu, 23 Jan 2014 21:31:22 GMT
Nothing is written to the non-current version container when you
@ -106,6 +108,7 @@ Example Using ``X-Versions-Location``
Etag: d41d8cd98f00b204e9800998ecf8427e
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx468287ce4fc94eada96ec-0052e18c8c
X-Openstack-Request-Id: tx468287ce4fc94eada96ec-0052e18c8c
Date: Thu, 23 Jan 2014 21:41:32 GMT
#. Issue a **GET** request to a versioned object to get the current
@ -128,6 +131,7 @@ Example Using ``X-Versions-Location``
X-Container-Bytes-Used: 0
Content-Type: text/plain; charset=utf-8
X-Trans-Id: tx9a441884997542d3a5868-0052e18d8e
X-Openstack-Request-Id: tx9a441884997542d3a5868-0052e18d8e
Date: Thu, 23 Jan 2014 21:45:50 GMT
009my_object/1390512682.92052
@ -151,6 +155,7 @@ Example Using ``X-Versions-Location``
Content-Length: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx006d944e02494e229b8ee-0052e18edd
X-Openstack-Request-Id: tx006d944e02494e229b8ee-0052e18edd
Date: Thu, 23 Jan 2014 21:51:25 GMT
List objects in the ``archive`` container to show that the archived
@ -170,6 +175,7 @@ Example Using ``X-Versions-Location``
X-Container-Bytes-Used: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx044f2a05f56f4997af737-0052e18eed
X-Openstack-Request-Id: tx044f2a05f56f4997af737-0052e18eed
Date: Thu, 23 Jan 2014 21:51:41 GMT
This next-most current version carries with it any metadata last set
@ -191,6 +197,7 @@ Example Using ``X-History-Location``
Content-Length: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: txb91810fb717347d09eec8-0052e18997
X-Openstack-Request-Id: txb91810fb717347d09eec8-0052e18997
Date: Thu, 23 Jan 2014 21:28:55 GMT
#. Create the first version of an object in the ``current`` container:
@ -207,6 +214,7 @@ Example Using ``X-History-Location``
Etag: d41d8cd98f00b204e9800998ecf8427e
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx5992d536a4bd4fec973aa-0052e18a2a
X-Openstack-Request-Id: tx5992d536a4bd4fec973aa-0052e18a2a
Date: Thu, 23 Jan 2014 21:31:22 GMT
Nothing is written to the non-current version container when you
@ -239,6 +247,7 @@ Example Using ``X-History-Location``
Etag: d41d8cd98f00b204e9800998ecf8427e
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx468287ce4fc94eada96ec-0052e18c8c
X-Openstack-Request-Id: tx468287ce4fc94eada96ec-0052e18c8c
Date: Thu, 23 Jan 2014 21:41:32 GMT
#. Issue a **GET** request to a versioned object to get the current
@ -261,6 +270,7 @@ Example Using ``X-History-Location``
X-Container-Bytes-Used: 0
Content-Type: text/plain; charset=utf-8
X-Trans-Id: tx9a441884997542d3a5868-0052e18d8e
X-Openstack-Request-Id: tx9a441884997542d3a5868-0052e18d8e
Date: Thu, 23 Jan 2014 21:45:50 GMT
009my_object/1390512682.92052
@ -285,6 +295,7 @@ Example Using ``X-History-Location``
Content-Length: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx006d944e02494e229b8ee-0052e18edd
X-Openstack-Request-Id: tx006d944e02494e229b8ee-0052e18edd
Date: Thu, 23 Jan 2014 21:51:25 GMT
List older versions of the object in the ``archive`` container::
@ -303,6 +314,7 @@ Example Using ``X-History-Location``
X-Container-Bytes-Used: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx044f2a05f56f4997af737-0052e18eed
X-Openstack-Request-Id: tx044f2a05f56f4997af737-0052e18eed
Date: Thu, 23 Jan 2014 21:51:41 GMT
009my_object/1390512682.92052
@ -332,6 +344,7 @@ value.
Content-Length: 76
Content-Type: text/html; charset=UTF-8
X-Trans-Id: txe2476de217134549996d0-0052e19038
X-Openstack-Request-Id: txe2476de217134549996d0-0052e19038
Date: Thu, 23 Jan 2014 21:57:12 GMT
<html><h1>Accepted</h1><p>The request is accepted for processing.</p></html>

View File

@ -24,6 +24,7 @@ as ``goodbye.txt``:
Content-Length: 76
Content-Type: text/html; charset=UTF-8
X-Trans-Id: txa9b5e57d7f354d7ea9f57-0052e17e13
X-Openstack-Request-Id: txa9b5e57d7f354d7ea9f57-0052e17e13
Date: Thu, 23 Jan 2014 20:39:47 GMT
<html><h1>Accepted</h1><p>The request is accepted for processing.</p></html>

View File

@ -145,4 +145,5 @@ Storage Policies effect placement of data in Swift.
Content-Type: text/plain; charset=utf-8
Accept-Ranges: bytes
X-Trans-Id: tx96e7496b19bb44abb55a3-0053482c75
X-Openstack-Request-Id: tx96e7496b19bb44abb55a3-0053482c75
Date: Fri, 11 Apr 2014 17:55:01 GMT

View File

@ -40,6 +40,7 @@ Verify operation of the Object Storage service.
X-Account-Project-Domain-Id: default
X-Timestamp: 1444143887.71539
X-Trans-Id: tx1396aeaf17254e94beb34-0056143bde
X-Openstack-Request-Id: tx1396aeaf17254e94beb34-0056143bde
Content-Type: text/plain; charset=utf-8
Accept-Ranges: bytes

View File

@ -45,12 +45,14 @@ class CatchErrorsContext(WSGIContext):
body='An error occurred',
content_type='text/plain')
resp.headers['X-Trans-Id'] = trans_id
resp.headers['X-Openstack-Request-Id'] = trans_id
return resp(env, start_response)
# make sure the response has the trans_id
if self._response_headers is None:
self._response_headers = []
self._response_headers.append(('X-Trans-Id', trans_id))
self._response_headers.append(('X-Openstack-Request-Id', trans_id))
start_response(self._response_status, self._response_headers,
self._response_exc_info)
return resp

View File

@ -1774,6 +1774,7 @@ class Controller(object):
path = '/%s' % account
headers = {'X-Timestamp': Timestamp(time.time()).internal,
'X-Trans-Id': self.trans_id,
'X-Openstack-Request-Id': self.trans_id,
'Connection': 'close'}
# transfer any x-account-sysmeta headers from original request
# to the autocreate PUT

View File

@ -43,106 +43,98 @@ class FakeApp(object):
return self.body_iter
def start_response(*args):
pass
class TestCatchErrors(unittest.TestCase):
def setUp(self):
self.logger = get_logger({})
self.logger.txn_id = None
def start_response(self, status, headers, *args):
request_ids = ('X-Trans-Id', 'X-Openstack-Request-Id')
hdict = dict(headers)
for key in request_ids:
self.assertIn(key, hdict)
for key1, key2 in zip(request_ids, request_ids[1:]):
self.assertEqual(hdict[key1], hdict[key2])
def test_catcherrors_passthrough(self):
app = catch_errors.CatchErrorMiddleware(FakeApp(), {})
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'})
resp = app(req.environ, start_response)
resp = app(req.environ, self.start_response)
self.assertEqual(list(resp), ['FAKE APP'])
def test_catcherrors(self):
app = catch_errors.CatchErrorMiddleware(FakeApp(True), {})
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'})
resp = app(req.environ, start_response)
resp = app(req.environ, self.start_response)
self.assertEqual(list(resp), ['An error occurred'])
def test_trans_id_header_pass(self):
self.assertEqual(self.logger.txn_id, None)
def start_response(status, headers, exc_info=None):
self.assertTrue('X-Trans-Id' in (x[0] for x in headers))
app = catch_errors.CatchErrorMiddleware(FakeApp(), {})
req = Request.blank('/v1/a/c/o')
app(req.environ, start_response)
app(req.environ, self.start_response)
self.assertEqual(len(self.logger.txn_id), 34) # 32 hex + 'tx'
def test_trans_id_header_fail(self):
self.assertEqual(self.logger.txn_id, None)
def start_response(status, headers, exc_info=None):
self.assertTrue('X-Trans-Id' in (x[0] for x in headers))
app = catch_errors.CatchErrorMiddleware(FakeApp(True), {})
req = Request.blank('/v1/a/c/o')
app(req.environ, start_response)
app(req.environ, self.start_response)
self.assertEqual(len(self.logger.txn_id), 34)
def test_error_in_iterator(self):
app = catch_errors.CatchErrorMiddleware(
FakeApp(body_iter=(int(x) for x in 'abcd')), {})
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'})
resp = app(req.environ, start_response)
resp = app(req.environ, self.start_response)
self.assertEqual(list(resp), ['An error occurred'])
def test_trans_id_header_suffix(self):
self.assertEqual(self.logger.txn_id, None)
def start_response(status, headers, exc_info=None):
self.assertTrue('X-Trans-Id' in (x[0] for x in headers))
app = catch_errors.CatchErrorMiddleware(
FakeApp(), {'trans_id_suffix': '-stuff'})
req = Request.blank('/v1/a/c/o')
app(req.environ, start_response)
app(req.environ, self.start_response)
self.assertTrue(self.logger.txn_id.endswith('-stuff'))
def test_trans_id_header_extra(self):
self.assertEqual(self.logger.txn_id, None)
def start_response(status, headers, exc_info=None):
self.assertTrue('X-Trans-Id' in (x[0] for x in headers))
app = catch_errors.CatchErrorMiddleware(
FakeApp(), {'trans_id_suffix': '-fromconf'})
req = Request.blank('/v1/a/c/o',
headers={'X-Trans-Id-Extra': 'fromuser'})
app(req.environ, start_response)
app(req.environ, self.start_response)
self.assertTrue(self.logger.txn_id.endswith('-fromconf-fromuser'))
def test_trans_id_header_extra_length_limit(self):
self.assertEqual(self.logger.txn_id, None)
def start_response(status, headers, exc_info=None):
self.assertTrue('X-Trans-Id' in (x[0] for x in headers))
app = catch_errors.CatchErrorMiddleware(
FakeApp(), {'trans_id_suffix': '-fromconf'})
req = Request.blank('/v1/a/c/o',
headers={'X-Trans-Id-Extra': 'a' * 1000})
app(req.environ, start_response)
app(req.environ, self.start_response)
self.assertTrue(self.logger.txn_id.endswith(
'-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'))
def test_trans_id_header_extra_quoted(self):
self.assertEqual(self.logger.txn_id, None)
def start_response(status, headers, exc_info=None):
self.assertTrue('X-Trans-Id' in (x[0] for x in headers))
app = catch_errors.CatchErrorMiddleware(FakeApp(), {})
req = Request.blank('/v1/a/c/o',
headers={'X-Trans-Id-Extra': 'xan than"gum'})
app(req.environ, start_response)
app(req.environ, self.start_response)
self.assertTrue(self.logger.txn_id.endswith('-xan%20than%22gum'))
def test_catcherrors_with_unexpected_error(self):
app = catch_errors.CatchErrorMiddleware(FakeApp(error='strange'), {})
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'})
resp = app(req.environ, start_response)
resp = app(req.environ, self.start_response)
self.assertEqual(list(resp), ['An error occurred'])