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