|
1 | 1 | import logging |
| 2 | +import time |
2 | 3 | from urllib.parse import urljoin |
3 | 4 |
|
| 5 | +import backoff |
4 | 6 | import requests |
5 | 7 |
|
6 | 8 | from threescale_api import errors, resources |
|
9 | 11 |
|
10 | 12 |
|
11 | 13 | class ThreeScaleClient: |
12 | | - def __init__(self, url: str, token: str, throws: bool = True, ssl_verify: bool = True): |
| 14 | + def __init__(self, url: str, token: str, |
| 15 | + throws: bool = True, ssl_verify: bool = True, wait: bool = False): |
13 | 16 | """Creates instance of the 3scale client |
14 | 17 | Args: |
15 | 18 | url: 3scale instance url |
16 | 19 | token: Access token |
17 | 20 | throws: Whether it should throw an error |
18 | 21 | ssl_verify: Whether to verify ssl |
| 22 | + wait: Whether to do extra checks of 3scale availability |
19 | 23 | """ |
20 | 24 | self._rest = RestApiClient(url=url, token=token, throws=throws, ssl_verify=ssl_verify) |
21 | 25 | self._services = resources.Services(self, instance_klass=resources.Service) |
@@ -46,6 +50,32 @@ def __init__(self, url: str, token: str, throws: bool = True, ssl_verify: bool = |
46 | 50 | self._fields_definitions =\ |
47 | 51 | resources.FieldsDefinitions(self, instance_klass=resources.FieldsDefinition) |
48 | 52 |
|
| 53 | + if wait: |
| 54 | + self.wait_for_tenant() |
| 55 | + # TODO: all the implemented checks aren't enough yet |
| 56 | + # 3scale can still return 404/409 error, therefore slight artificial sleep |
| 57 | + # here to mitigate the problem. This requires proper fix in checks |
| 58 | + time.sleep(16) |
| 59 | + |
| 60 | + @backoff.on_predicate(backoff.fibo, lambda ready: not ready, max_tries=8, jitter=None) |
| 61 | + def wait_for_tenant(self) -> bool: |
| 62 | + """ |
| 63 | + When True is returned, there is some chance the tenant is actually ready. |
| 64 | + """ |
| 65 | + # TODO: checks below were collected from various sources to craft |
| 66 | + # ultimate readiness check. There might be duplicates though, so |
| 67 | + # worth to review it one day |
| 68 | + try: |
| 69 | + return self.account_plans.exists() \ |
| 70 | + and len(self.account_plans.fetch()["plans"]) >= 1 \ |
| 71 | + and len(self.account_plans.list()) >= 1 \ |
| 72 | + and self.accounts.exists() \ |
| 73 | + and len(self.accounts.list()) >= 1 \ |
| 74 | + and self.services.exists() \ |
| 75 | + and len(self.services.list()) >= 1 |
| 76 | + except Exception: |
| 77 | + return False |
| 78 | + |
49 | 79 | @property |
50 | 80 | def rest(self) -> 'RestApiClient': |
51 | 81 | """Get REST api client instance |
|
0 commit comments