From d0fe922904c8016267e89c97bef16052a2c3bb7e Mon Sep 17 00:00:00 2001 From: karen chan Date: Mon, 17 Oct 2016 03:37:35 -0700 Subject: [PATCH] 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 --- api-ref/source/parameters.yaml | 8 ++++ ...unt-containers-list-http-response-json.txt | 3 +- ...ount-containers-list-http-response-xml.txt | 3 +- .../objects-list-http-response-json.txt | 3 +- .../objects-list-http-response-xml.txt | 3 +- api-ref/source/storage-account-services.inc | 7 +++ doc/source/api/object_versioning.rst | 13 ++++++ .../use_the_content-disposition_metadata.rst | 1 + doc/source/policies_saio.rst | 1 + install-guide/source/verify.rst | 1 + swift/common/middleware/catch_errors.py | 2 + swift/proxy/controllers/base.py | 1 + test/unit/common/middleware/test_except.py | 44 ++++++++----------- 13 files changed, 60 insertions(+), 30 deletions(-) diff --git a/api-ref/source/parameters.yaml b/api-ref/source/parameters.yaml index d69f866b9c..23ab88a1a1 100644 --- a/api-ref/source/parameters.yaml +++ b/api-ref/source/parameters.yaml @@ -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``. diff --git a/api-ref/source/samples/account-containers-list-http-response-json.txt b/api-ref/source/samples/account-containers-list-http-response-json.txt index 0cdba62a8a..6c86e00ca5 100644 --- a/api-ref/source/samples/account-containers-list-http-response-json.txt +++ b/api-ref/source/samples/account-containers-list-http-response-json.txt @@ -8,4 +8,5 @@ X-Account-Container-Count: 2 Content-Type: application/json; charset=utf-8 Accept-Ranges: bytes X-Trans-Id: tx274a77a8975c4a66aeb24-0052d95365 -Date: Fri, 17 Jan 2014 15:59:33 GMT \ No newline at end of file +X-Openstack-Request-Id: tx274a77a8975c4a66aeb24-0052d95365 +Date: Fri, 17 Jan 2014 15:59:33 GMT diff --git a/api-ref/source/samples/account-containers-list-http-response-xml.txt b/api-ref/source/samples/account-containers-list-http-response-xml.txt index 6ad781aaec..c477638567 100644 --- a/api-ref/source/samples/account-containers-list-http-response-xml.txt +++ b/api-ref/source/samples/account-containers-list-http-response-xml.txt @@ -8,4 +8,5 @@ X-Account-Container-Count: 2 Content-Type: application/xml; charset=utf-8 Accept-Ranges: bytes X-Trans-Id: tx69f60bc9f7634a01988e6-0052d9544b -Date: Fri, 17 Jan 2014 16:03:23 GMT \ No newline at end of file +X-Openstack-Request-Id: tx69f60bc9f7634a01988e6-0052d9544b +Date: Fri, 17 Jan 2014 16:03:23 GMT diff --git a/api-ref/source/samples/objects-list-http-response-json.txt b/api-ref/source/samples/objects-list-http-response-json.txt index 2efe63a3f2..aa0f6b4297 100644 --- a/api-ref/source/samples/objects-list-http-response-json.txt +++ b/api-ref/source/samples/objects-list-http-response-json.txt @@ -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 -Date: Wed, 15 Jan 2014 16:57:35 GMT \ No newline at end of file +X-Openstack-Request-Id: tx26377fe5fab74869825d1-0052d6bdff +Date: Wed, 15 Jan 2014 16:57:35 GMT diff --git a/api-ref/source/samples/objects-list-http-response-xml.txt b/api-ref/source/samples/objects-list-http-response-xml.txt index eb17bb2a6a..b9804cb583 100644 --- a/api-ref/source/samples/objects-list-http-response-xml.txt +++ b/api-ref/source/samples/objects-list-http-response-xml.txt @@ -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 -Date: Wed, 15 Jan 2014 16:59:35 GMT \ No newline at end of file +X-Openstack-Request-Id: txc75ea9a6e66f47d79e0c5-0052d6be76 +Date: Wed, 15 Jan 2014 16:59:35 GMT diff --git a/api-ref/source/storage-account-services.inc b/api-ref/source/storage-account-services.inc index e792b814b9..8834c1a6db 100644 --- a/api-ref/source/storage-account-services.inc +++ b/api-ref/source/storage-account-services.inc @@ -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 diff --git a/doc/source/api/object_versioning.rst b/doc/source/api/object_versioning.rst index 1b78a132be..347f940ec9 100644 --- a/doc/source/api/object_versioning.rst +++ b/doc/source/api/object_versioning.rst @@ -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

Accepted

The request is accepted for processing.

diff --git a/doc/source/api/use_the_content-disposition_metadata.rst b/doc/source/api/use_the_content-disposition_metadata.rst index 17c671f27f..8ee6287ff6 100644 --- a/doc/source/api/use_the_content-disposition_metadata.rst +++ b/doc/source/api/use_the_content-disposition_metadata.rst @@ -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

Accepted

The request is accepted for processing.

diff --git a/doc/source/policies_saio.rst b/doc/source/policies_saio.rst index ee2dcf6043..bc03a3ec89 100644 --- a/doc/source/policies_saio.rst +++ b/doc/source/policies_saio.rst @@ -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 diff --git a/install-guide/source/verify.rst b/install-guide/source/verify.rst index 838644b9a0..2580cdd7cd 100644 --- a/install-guide/source/verify.rst +++ b/install-guide/source/verify.rst @@ -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 diff --git a/swift/common/middleware/catch_errors.py b/swift/common/middleware/catch_errors.py index feeca6ea8c..6e9334795a 100644 --- a/swift/common/middleware/catch_errors.py +++ b/swift/common/middleware/catch_errors.py @@ -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 diff --git a/swift/proxy/controllers/base.py b/swift/proxy/controllers/base.py index 080d726aa7..61ef64f473 100644 --- a/swift/proxy/controllers/base.py +++ b/swift/proxy/controllers/base.py @@ -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 diff --git a/test/unit/common/middleware/test_except.py b/test/unit/common/middleware/test_except.py index 494887224c..a3b2587d9b 100644 --- a/test/unit/common/middleware/test_except.py +++ b/test/unit/common/middleware/test_except.py @@ -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'])