Skip to content

Commit 60ba23a

Browse files
committed
MB-55961 changing api request to support multithreaded requests.
+ This change has been made to avoid race condition for multithreaded api requests where some of our request fails and while retrying we overwrite the auth to default self.auth values instead of using bucket creds in elixir Change-Id: I2083f6f301f6c5a9f6ce94d167fbb69d8b225cf3 Reviewed-on: https://review.couchbase.org/c/perfrunner/+/188817 Tested-by: Devansh Srivastava <[email protected]> Reviewed-by: Daniel Nagy <[email protected]>
1 parent f863466 commit 60ba23a

File tree

2 files changed

+31
-59
lines changed

2 files changed

+31
-59
lines changed

perfrunner/helpers/rest.py

Lines changed: 26 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
import os
44
import time
55
from collections import namedtuple
6-
from contextlib import contextmanager
76
from json import JSONDecodeError
8-
from typing import Callable, Dict, Iterator, List, Optional
7+
from typing import Callable, Dict, Iterator, List, Optional, Tuple
98

109
import requests
1110
from capella.dedicated.CapellaAPI import CapellaAPI as CapellaAPIDedicated
@@ -79,24 +78,28 @@ def __init__(self, cluster_spec: ClusterSpec, test_config: TestConfig):
7978

8079
@retry
8180
def get(self, **kwargs) -> requests.Response:
82-
return requests.get(auth=self.auth, verify=False, **kwargs)
81+
auth = kwargs.pop('auth', self.auth)
82+
return requests.get(auth=auth, verify=False, **kwargs)
8383

8484
def _post(self, **kwargs) -> requests.Response:
85-
return requests.post(auth=self.auth, verify=False, **kwargs)
85+
auth = kwargs.pop('auth', self.auth)
86+
return requests.post(auth=auth, verify=False, **kwargs)
8687

8788
@retry
8889
def post(self, **kwargs) -> requests.Response:
8990
return self._post(**kwargs)
9091

9192
def _put(self, **kwargs) -> requests.Response:
92-
return requests.put(auth=self.auth, verify=False, **kwargs)
93+
auth = kwargs.pop('auth', self.auth)
94+
return requests.put(auth=auth, verify=False, **kwargs)
9395

9496
@retry
9597
def put(self, **kwargs) -> requests.Response:
9698
return self._put(**kwargs)
9799

98100
def _delete(self, **kwargs) -> requests.Response:
99-
return requests.delete(auth=self.auth, verify=False, **kwargs)
101+
auth = kwargs.pop('auth', self.auth)
102+
return requests.delete(auth=auth, verify=False, **kwargs)
100103

101104
def delete(self, **kwargs) -> requests.Response:
102105
return self._delete(**kwargs)
@@ -1974,17 +1977,12 @@ def __init__(self, cluster_spec, test_config):
19741977
)
19751978
self.admin_credentials = self.cluster_spec.capella_admin_credentials
19761979

1977-
@contextmanager
1978-
def _admin_creds(self, host: str):
1980+
def _admin_creds(self, host: str) -> Tuple[str, str]:
19791981
for i, (_, hostnames) in enumerate(self.cluster_spec.clusters):
19801982
if host in hostnames:
19811983
username, password = self.admin_credentials[i]
1982-
self.auth = username, password
1983-
1984-
try:
1985-
yield
1986-
finally:
1987-
self.auth = self.rest_username, self.rest_password
1984+
return (username, password)
1985+
return (self.rest_username, self.rest_password)
19881986

19891987
@property
19901988
def _cbc_user(self):
@@ -2043,7 +2041,7 @@ def wait_until_all_logs_uploaded(self):
20432041

20442042
while (time.time() - t0) < timeout_mins * 60:
20452043
cluster_ids_not_uploaded = \
2046-
self._check_if_given_clusters_are_uploaded(cluster_ids_not_uploaded)
2044+
self._check_if_given_clusters_are_uploaded(cluster_ids_not_uploaded)
20472045
if not cluster_ids_not_uploaded:
20482046
logger.info('All cluster logs have been successfully uploaded')
20492047
return
@@ -2083,8 +2081,8 @@ def hostname_to_cluster_id(self, host: str):
20832081
def get_remote_clusters(self, host: str) -> List[Dict]:
20842082
logger.info('Getting remote clusters')
20852083
api = 'https://{}:18091/pools/default/remoteClusters'.format(host)
2086-
with self._admin_creds(host):
2087-
response = self.get(url=api)
2084+
auth = self._admin_creds(host)
2085+
response = self.get(url=api, auth=auth)
20882086
return response.json()
20892087

20902088
def get_active_nodes_by_role(self, master_node: str, role: str) -> List[str]:
@@ -2301,21 +2299,14 @@ def get_sgversion(self, host: str) -> str:
23012299

23022300
class ServerlessRestHelper(CapellaRestBase):
23032301
def __init__(self, cluster_spec: ClusterSpec, test_config: TestConfig):
2304-
DefaultRestHelper.__init__(self, cluster_spec=cluster_spec, test_config=test_config)
2302+
super().__init__(cluster_spec=cluster_spec, test_config=test_config)
23052303
self.base_url = 'https://cloudapi.{}.nonprod-project-avengers.com'.format(
23062304
self.cluster_spec.infrastructure_settings['cbc_env']
23072305
)
2308-
self.tenant_id = self.cluster_spec.infrastructure_settings['cbc_tenant']
2309-
self.project_id = self.cluster_spec.infrastructure_settings['cbc_project']
23102306
self.dp_id = self.cluster_spec.infrastructure_settings['cbc_dataplane']
2311-
self.cluster_ids = self.cluster_spec.infrastructure_settings['cbc_cluster'].split()
2312-
self.dedicated_client = CapellaAPIDedicated(
2313-
self.base_url, None, None, self._cbc_user, self._cbc_pwd, self._cbc_token
2314-
)
23152307
self.serverless_client = CapellaAPIServerless(
23162308
self.base_url, self._cbc_user, self._cbc_pwd, self._cbc_token
23172309
)
2318-
self.admin_credentials = self.cluster_spec.capella_admin_credentials
23192310

23202311
def get_db_info(self, db_id):
23212312
logger.info('Getting debug info for DB {}'.format(db_id))
@@ -2412,17 +2403,6 @@ def get_dapi_certificate(self):
24122403
intermediates = certs['intermediates']
24132404
return first_cert + intermediates
24142405

2415-
@contextmanager
2416-
def _bucket_creds(self, bucket: str):
2417-
access = self.test_config.serverless_db.db_map[bucket]['access']
2418-
secret = self.test_config.serverless_db.db_map[bucket]['secret']
2419-
self.auth = access, secret
2420-
2421-
try:
2422-
yield
2423-
finally:
2424-
self.auth = self.rest_username, self.rest_password
2425-
24262406
def create_fts_index(self, host: str, index: str, definition: dict):
24272407
logger.info('Creating a new FTS index: {}'.format(index))
24282408
if self.test_config.cluster.enable_n2n_encryption:
@@ -2432,16 +2412,16 @@ def create_fts_index(self, host: str, index: str, definition: dict):
24322412
headers = {'Content-Type': 'application/json'}
24332413
data = json.dumps(definition, ensure_ascii=False)
24342414
bucket = definition['sourceName']
2435-
with self._bucket_creds(bucket):
2436-
self.put(url=api, data=data, headers=headers)
2415+
auth = self.test_config.serverless_db.bucket_creds(bucket)
2416+
self.put(url=api, data=data, headers=headers, auth=auth)
24372417

24382418
def get_fts_doc_count(self, host: str, index: str, bucket: str) -> int:
24392419
if self.test_config.cluster.enable_n2n_encryption:
24402420
api = 'https://{}:18094/api/index/{}/count'.format(host, index)
24412421
else:
24422422
api = 'http://{}:8094/api/index/{}/count'.format(host, index)
2443-
with self._bucket_creds(bucket):
2444-
response = self.get(url=api).json()
2423+
auth = self.test_config.serverless_db.bucket_creds(bucket)
2424+
response = self.get(url=api, auth=auth).json()
24452425
return response['count']
24462426

24472427
def exec_n1ql_statement(self, host: str, statement: str, query_context: str) -> dict:
@@ -2453,9 +2433,8 @@ def exec_n1ql_statement(self, host: str, statement: str, query_context: str) ->
24532433
}
24542434

24552435
bucket = query_context.removeprefix('default:').split('.')[0].strip('`')
2456-
2457-
with self._bucket_creds(bucket):
2458-
response = self.post(url=api, data=data)
2436+
auth = self.test_config.serverless_db.bucket_creds(bucket)
2437+
response = self.post(url=api, data=data, auth=auth)
24592438

24602439
return response.json()
24612440

@@ -2473,27 +2452,15 @@ def get_bucket_fts_stats(self, host: str, bucket, index) -> dict:
24732452
api = 'https://{}:18094/api/nsstats/index/{}'.format(host, index)
24742453
else:
24752454
api = 'http://{}:8094/api/nsstats/index/{}'.format(host, index)
2476-
with self._bucket_creds(bucket):
2477-
response = self.get(url=api)
2455+
auth = self.test_config.serverless_db.bucket_creds(bucket)
2456+
response = self.get(url=api, auth=auth)
24782457
return response.json()
24792458

2480-
@contextmanager
2481-
def _admin_creds(self, host: str):
2482-
for i, (_, hostnames) in enumerate(self.cluster_spec.clusters):
2483-
if host in hostnames:
2484-
username, password = self.admin_credentials[i]
2485-
self.auth = username, password
2486-
2487-
try:
2488-
yield
2489-
finally:
2490-
self.auth = self.rest_username, self.rest_password
2491-
24922459
def get_fts_stats(self, host: str) -> dict:
24932460
if self.test_config.cluster.enable_n2n_encryption:
24942461
api = 'https://{}:18094/api/nsstats'.format(host)
24952462
else:
24962463
api = 'http://{}:8094/api/nsstats'.format(host)
2497-
with self._admin_creds(host):
2498-
response = self.get(url=api)
2464+
auth = self._admin_creds(host)
2465+
response = self.get(url=api, auth=auth)
24992466
return response.json()

perfrunner/settings.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,11 @@ def __init__(self, options: dict):
948948
except json.JSONDecodeError:
949949
self.db_map = {}
950950

951+
def bucket_creds(self, bucket: str) -> Tuple[str, str]:
952+
access = self.db_map[bucket]['access']
953+
secret = self.db_map[bucket]['secret']
954+
return (access, secret)
955+
951956
def update_db_map(self, db_map):
952957
with open(self.config, 'w') as f:
953958
json.dump(db_map, f, indent=4)

0 commit comments

Comments
 (0)