Allow global_request_id in Client constructor
This provides the facility to take global_request_id as a construction parameter for a neutron client, and pass it through the system. This will be used by Nova and others to set global_request_id so requests can be tracked across services. oslo spec I65de8261746b25d45e105394f4eeb95b9cb3bd42 Change-Id: I7ed48ad247676c71a3a7b12585572c398dda06e0
This commit is contained in:
@@ -46,6 +46,7 @@ else:
|
|||||||
logging.getLogger("requests").setLevel(_requests_log_level)
|
logging.getLogger("requests").setLevel(_requests_log_level)
|
||||||
MAX_URI_LEN = 8192
|
MAX_URI_LEN = 8192
|
||||||
USER_AGENT = 'python-neutronclient'
|
USER_AGENT = 'python-neutronclient'
|
||||||
|
REQ_ID_HEADER = 'X-OpenStack-Request-ID'
|
||||||
|
|
||||||
|
|
||||||
class HTTPClient(object):
|
class HTTPClient(object):
|
||||||
@@ -64,7 +65,7 @@ class HTTPClient(object):
|
|||||||
endpoint_url=None, insecure=False,
|
endpoint_url=None, insecure=False,
|
||||||
endpoint_type='publicURL',
|
endpoint_type='publicURL',
|
||||||
auth_strategy='keystone', ca_cert=None, log_credentials=False,
|
auth_strategy='keystone', ca_cert=None, log_credentials=False,
|
||||||
service_type='network',
|
service_type='network', global_request_id=None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
|
|
||||||
self.username = username
|
self.username = username
|
||||||
@@ -83,6 +84,7 @@ class HTTPClient(object):
|
|||||||
self.endpoint_url = endpoint_url
|
self.endpoint_url = endpoint_url
|
||||||
self.auth_strategy = auth_strategy
|
self.auth_strategy = auth_strategy
|
||||||
self.log_credentials = log_credentials
|
self.log_credentials = log_credentials
|
||||||
|
self.global_request_id = global_request_id
|
||||||
if insecure:
|
if insecure:
|
||||||
self.verify_cert = False
|
self.verify_cert = False
|
||||||
else:
|
else:
|
||||||
@@ -153,6 +155,9 @@ class HTTPClient(object):
|
|||||||
if body:
|
if body:
|
||||||
headers.setdefault('Content-Type', content_type)
|
headers.setdefault('Content-Type', content_type)
|
||||||
|
|
||||||
|
if self.global_request_id:
|
||||||
|
headers.setdefault(REQ_ID_HEADER, self.global_request_id)
|
||||||
|
|
||||||
headers['User-Agent'] = USER_AGENT
|
headers['User-Agent'] = USER_AGENT
|
||||||
# NOTE(dbelova): osprofiler_web.get_trace_id_headers does not add any
|
# NOTE(dbelova): osprofiler_web.get_trace_id_headers does not add any
|
||||||
# headers in case if osprofiler is not initialized.
|
# headers in case if osprofiler is not initialized.
|
||||||
@@ -299,6 +304,9 @@ class HTTPClient(object):
|
|||||||
|
|
||||||
|
|
||||||
class SessionClient(adapter.Adapter):
|
class SessionClient(adapter.Adapter):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.global_request_id = kwargs.pop("global_request_id", None)
|
||||||
|
super(SessionClient, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def request(self, *args, **kwargs):
|
def request(self, *args, **kwargs):
|
||||||
kwargs.setdefault('authenticated', False)
|
kwargs.setdefault('authenticated', False)
|
||||||
@@ -308,6 +316,9 @@ class SessionClient(adapter.Adapter):
|
|||||||
|
|
||||||
headers = kwargs.setdefault('headers', {})
|
headers = kwargs.setdefault('headers', {})
|
||||||
headers.setdefault('Accept', content_type)
|
headers.setdefault('Accept', content_type)
|
||||||
|
|
||||||
|
if self.global_request_id:
|
||||||
|
headers.setdefault(REQ_ID_HEADER, self.global_request_id)
|
||||||
# NOTE(dbelova): osprofiler_web.get_trace_id_headers does not add any
|
# NOTE(dbelova): osprofiler_web.get_trace_id_headers does not add any
|
||||||
# headers in case if osprofiler is not initialized.
|
# headers in case if osprofiler is not initialized.
|
||||||
if osprofiler_web:
|
if osprofiler_web:
|
||||||
@@ -397,6 +408,7 @@ def construct_http_client(username=None,
|
|||||||
ca_cert=None,
|
ca_cert=None,
|
||||||
service_type='network',
|
service_type='network',
|
||||||
session=None,
|
session=None,
|
||||||
|
global_request_id=None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
|
|
||||||
if session:
|
if session:
|
||||||
@@ -405,6 +417,7 @@ def construct_http_client(username=None,
|
|||||||
return SessionClient(session=session,
|
return SessionClient(session=session,
|
||||||
service_type=service_type,
|
service_type=service_type,
|
||||||
region_name=region_name,
|
region_name=region_name,
|
||||||
|
global_request_id=global_request_id,
|
||||||
**kwargs)
|
**kwargs)
|
||||||
else:
|
else:
|
||||||
# FIXME(bklei): username and password are now optional. Need
|
# FIXME(bklei): username and password are now optional. Need
|
||||||
@@ -425,4 +438,5 @@ def construct_http_client(username=None,
|
|||||||
service_type=service_type,
|
service_type=service_type,
|
||||||
ca_cert=ca_cert,
|
ca_cert=ca_cert,
|
||||||
log_credentials=log_credentials,
|
log_credentials=log_credentials,
|
||||||
auth_strategy=auth_strategy)
|
auth_strategy=auth_strategy,
|
||||||
|
global_request_id=global_request_id)
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
|
import uuid
|
||||||
|
|
||||||
import osprofiler.profiler
|
import osprofiler.profiler
|
||||||
import osprofiler.web
|
import osprofiler.web
|
||||||
@@ -121,3 +122,20 @@ class TestHTTPClient(TestHTTPClientMixin, testtools.TestCase):
|
|||||||
resp, resp_text = self.http._cs_request(URL, METHOD)
|
resp, resp_text = self.http._cs_request(URL, METHOD)
|
||||||
self.assertEqual(403, resp.status_code)
|
self.assertEqual(403, resp.status_code)
|
||||||
self.assertEqual(text, resp_text)
|
self.assertEqual(text, resp_text)
|
||||||
|
|
||||||
|
|
||||||
|
class TestHTTPClientWithReqId(TestHTTPClientMixin, testtools.TestCase):
|
||||||
|
"""Tests for when global_request_id is set."""
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
self.req_id = "req-%s" % uuid.uuid4()
|
||||||
|
return client.HTTPClient(token=AUTH_TOKEN, endpoint_url=END_URL,
|
||||||
|
global_request_id=self.req_id)
|
||||||
|
|
||||||
|
def test_request_success(self):
|
||||||
|
headers = {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'X-OpenStack-Request-ID': self.req_id
|
||||||
|
}
|
||||||
|
self.requests.register_uri(METHOD, URL, request_headers=headers)
|
||||||
|
self.http.request(URL, METHOD)
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds a new ``global_request_id`` parameter to the Client
|
||||||
|
constructors, which will pass that id on all requests as the
|
||||||
|
``X-OpenStack-Request-ID`` header.
|
Reference in New Issue
Block a user