Add request id to returned objects
Adding two classes RequestIdProxy and GeneratorProxy derived from wrapt.ObjectProxy to wrap objects returned from the API. GeneratorProxy class is used to wrap generator objects returned by cases like images.list() etc. whereas RequestIdProxy class is used to wrap non-generator object cases like images.create() etc. In all cases the returned object will have the same behavior as the wrapped(original) object. However now the returned objects will have an extra property 'request_ids' which is a list of exactly one request id. For generator cases the request_ids property will be an empty list until the underlying generator is invoked at-least once. Co-Authored-By: Abhishek Kekane <abhishek.kekane@nttdata.com> Closes-Bug: #1525259 Blueprint: return-request-id-to-caller Change-Id: If8c0e0843270ff718a37ca2697afeb8da22aa3b1
This commit is contained in:
committed by
Abhishek Kekane
parent
54e6faadf2
commit
610177a779
@@ -36,6 +36,7 @@ else:
|
||||
from oslo_utils import encodeutils
|
||||
from oslo_utils import strutils
|
||||
import prettytable
|
||||
import wrapt
|
||||
|
||||
from glanceclient._i18n import _
|
||||
from glanceclient import exc
|
||||
@@ -472,3 +473,76 @@ class IterableWithLength(object):
|
||||
|
||||
def __len__(self):
|
||||
return self.length
|
||||
|
||||
|
||||
class RequestIdProxy(wrapt.ObjectProxy):
|
||||
def __init__(self, wrapped):
|
||||
# `wrapped` is a tuple: (original_obj, response_obj)
|
||||
super(RequestIdProxy, self).__init__(wrapped[0])
|
||||
self._self_wrapped = wrapped[0]
|
||||
req_id = _extract_request_id(wrapped[1])
|
||||
self._self_request_ids = [req_id]
|
||||
|
||||
@property
|
||||
def request_ids(self):
|
||||
return self._self_request_ids
|
||||
|
||||
@property
|
||||
def wrapped(self):
|
||||
return self._self_wrapped
|
||||
|
||||
|
||||
class GeneratorProxy(wrapt.ObjectProxy):
|
||||
def __init__(self, wrapped):
|
||||
super(GeneratorProxy, self).__init__(wrapped)
|
||||
self._self_wrapped = wrapped
|
||||
self._self_request_ids = []
|
||||
|
||||
def _set_request_ids(self, resp):
|
||||
if self._self_request_ids == []:
|
||||
req_id = _extract_request_id(resp)
|
||||
self._self_request_ids = [req_id]
|
||||
|
||||
def _next(self):
|
||||
obj, resp = next(self._self_wrapped)
|
||||
self._set_request_ids(resp)
|
||||
return obj
|
||||
|
||||
# Override generator's next method to add
|
||||
# request id on each iteration
|
||||
def next(self):
|
||||
return self._next()
|
||||
|
||||
# For Python 3 compatibility
|
||||
def __next__(self):
|
||||
return self._next()
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
@property
|
||||
def request_ids(self):
|
||||
return self._self_request_ids
|
||||
|
||||
@property
|
||||
def wrapped(self):
|
||||
return self._self_wrapped
|
||||
|
||||
|
||||
def add_req_id_to_object():
|
||||
@wrapt.decorator
|
||||
def inner(wrapped, instance, args, kwargs):
|
||||
return RequestIdProxy(wrapped(*args, **kwargs))
|
||||
return inner
|
||||
|
||||
|
||||
def add_req_id_to_generator():
|
||||
@wrapt.decorator
|
||||
def inner(wrapped, instance, args, kwargs):
|
||||
return GeneratorProxy(wrapped(*args, **kwargs))
|
||||
return inner
|
||||
|
||||
|
||||
def _extract_request_id(resp):
|
||||
# TODO(rsjethani): Do we need more checks here?
|
||||
return resp.headers.get('x-openstack-request-id')
|
||||
|
||||
Reference in New Issue
Block a user