summaryrefslogtreecommitdiff
path: root/cinderclient/exceptions.py
diff options
context:
space:
mode:
authorYuriy Nesenenko <ynesenenko@mirantis.com>2016-06-22 17:36:49 +0300
committerYuriy Nesenenko <ynesenenko@mirantis.com>2016-07-06 11:42:20 +0300
commitf8eef18297ec2dba4abf45f8ca57c40c2380cad9 (patch)
tree85afe6c794d1bd58996064f19056aada532f4210 /cinderclient/exceptions.py
parent0a92c9fb199b4b6cc32d9081a721d36eaa78a77e (diff)
downloadpython-cinderclient-f8eef18297ec2dba4abf45f8ca57c40c2380cad9.tar.gz
Cinder client should retry with Retry-After value
If a request fails but the response contains a "Retry-After", the cinder client should wait the amount of time and then retry. Cinder client should report a warning to user and continue with retry, so that user can cancel the operation if not interested in retry. The value in "Retry-After" header will be in seconds or GMT value, client should handle both the cases. How many times client should retry will be controlled by user through "--retries" argument to cinder api example, $ cinder --retries 3 availability-zone-list If request was not sucessful within the retries, client should raise the exception. Change-Id: I99af957bfbbe3a202b148dc2fcafdd20b5d7cda0 Partial-Bug: #1263069
Diffstat (limited to 'cinderclient/exceptions.py')
-rw-r--r--cinderclient/exceptions.py31
1 files changed, 28 insertions, 3 deletions
diff --git a/cinderclient/exceptions.py b/cinderclient/exceptions.py
index cab74c6..03a50e7 100644
--- a/cinderclient/exceptions.py
+++ b/cinderclient/exceptions.py
@@ -16,6 +16,9 @@
"""
Exception definitions.
"""
+from datetime import datetime
+
+from oslo_utils import timeutils
class UnsupportedVersion(Exception):
@@ -80,7 +83,8 @@ class ClientException(Exception):
"""
The base exception class for all exceptions this library raises.
"""
- def __init__(self, code, message=None, details=None, request_id=None):
+ def __init__(self, code, message=None, details=None,
+ request_id=None, response=None):
self.code = code
# NOTE(mriedem): Use getattr on self.__class__.message since
# BaseException.message was dropped in python 3, see PEP 0352.
@@ -147,6 +151,27 @@ class OverLimit(ClientException):
http_status = 413
message = "Over limit"
+ def __init__(self, code, message=None, details=None,
+ request_id=None, response=None):
+ super(OverLimit, self).__init__(code, message=message,
+ details=details, request_id=request_id,
+ response=response)
+ self.retry_after = 0
+ self._get_rate_limit(response)
+
+ def _get_rate_limit(self, resp):
+ if resp.headers:
+ utc_now = timeutils.utcnow()
+ value = resp.headers.get('Retry-After', '0')
+ try:
+ value = datetime.strptime(value, '%a, %d %b %Y %H:%M:%S %Z')
+ if value > utc_now:
+ self.retry_after = ((value - utc_now).seconds)
+ else:
+ self.retry_after = 0
+ except ValueError:
+ self.retry_after = int(value)
+
# NotImplemented is a python keyword.
class HTTPNotImplemented(ClientException):
@@ -193,10 +218,10 @@ def from_response(response, body):
message = error.get('message', message)
details = error.get('details', details)
return cls(code=response.status_code, message=message, details=details,
- request_id=request_id)
+ request_id=request_id, response=response)
else:
return cls(code=response.status_code, request_id=request_id,
- message=response.reason)
+ message=response.reason, response=response)
class VersionNotFoundForAPIMethod(Exception):