2222import warnings
2323import json
2424import aliyunsdkcore
25+ import jmespath
2526from aliyunsdkcore .vendored .six .moves .urllib .parse import urlencode
2627from aliyunsdkcore .vendored .six .moves import http_client
2728
3940import aliyunsdkcore .retry .retry_policy as retry_policy
4041from aliyunsdkcore .retry .retry_condition import RetryCondition
4142from aliyunsdkcore .retry .retry_policy_context import RetryPolicyContext
43+ import aliyunsdkcore .utils
44+ import aliyunsdkcore .utils .parameter_helper
45+ import aliyunsdkcore .utils .validation
4246
4347"""
4448Acs default client module.
4549"""
4650
4751DEFAULT_SDK_CONNECTION_TIMEOUT_IN_SECONDS = 10
4852
53+ # TODO: replace it with TimeoutHandler
54+ _api_timeout_config_data = aliyunsdkcore .utils ._load_json_from_data_dir ("timeout_config.json" )
55+
4956
5057class AcsClient :
5158
@@ -105,10 +112,10 @@ def get_region_id(self):
105112 return self .__region_id
106113
107114 def get_access_key (self ):
108- return self .__ak
115+ return self ._ak
109116
110117 def get_access_secret (self ):
111- return self .__secret
118+ return self ._secret
112119
113120 def is_auto_retry (self ):
114121 return self .__auto_retry
@@ -147,7 +154,7 @@ def get_port(self):
147154 def get_location_service (self ):
148155 return None
149156
150- def _make_http_response (self , endpoint , request , specific_signer = None ):
157+ def _make_http_response (self , endpoint , request , timeout , specific_signer = None ):
151158 body_params = request .get_body_params ()
152159 if body_params :
153160 body = urlencode (body_params )
@@ -175,7 +182,7 @@ def _make_http_response(self, endpoint, request, specific_signer=None):
175182 protocol ,
176183 request .get_content (),
177184 self ._port ,
178- timeout = self . _timeout )
185+ timeout = timeout )
179186 if body_params :
180187 body = urlencode (request .get_body_params ())
181188 response .set_content (body , "utf-8" , format_type .APPLICATION_FORM )
@@ -202,31 +209,62 @@ def implementation_of_do_action(self, request, signer=None):
202209 return self ._handle_retry_and_timeout (endpoint , request , signer )
203210
204211 def _add_request_client_token (self , request ):
205- if hasattr (request , "set_ClientToken" ):
206-
212+ if hasattr (request , "set_ClientToken" ) and hasattr (request , "get_ClientToken" ):
213+ client_token = request .get_ClientToken ()
214+ if not client_token :
215+ # ClientToken has not been set
216+ client_token = aliyunsdkcore .utils .parameter_helper .get_uuid () # up to 60 chars
217+ request .set_ClientToken (client_token )
218+
219+ def _get_request_timeout (self , request ):
220+ # TODO: replace it with a timeout_handler
221+ path = "{0}.{1}.{2}" .format (request .get_product ().lower (), request .get_version (),
222+ request .get_action_name ())
223+ timeout = jmespath .search (path , _api_timeout_config_data )
224+ aliyunsdkcore .utils .validation .assert_integer_positive (timeout , "timeout" )
225+ if timeout is None :
226+ return self ._timeout
227+ else :
228+ return max (timeout , self ._timeout )
207229
208230 def _handle_retry_and_timeout (self , endpoint , request , signer ):
209- # it's a temporary implement. the long-term plan will be a group a normalized handlers
231+ # TODO: replace it with a retry_handler
232+ # it's a temporary implementation. the long-term plan will be a group a normalized handlers
210233 # which contains retry_handler and timeout_handler
234+
235+ # decide whether we should initialize a ClientToken for the request
236+ retry_policy_context = RetryPolicyContext (request , None , None , None )
237+ if self ._retry_policy .should_retry (retry_policy_context ) & \
238+ RetryCondition .SHOULD_RETRY_WITH_CLIENT_TOKEN :
239+ self ._add_request_client_token (request )
240+
241+ request_timeout = self ._get_request_timeout (request )
242+
211243 retryable = RetryCondition .SHOULD_RETRY
212244 retries = 0
213- while retryable & RetryCondition .SHOULD_RETRY :
214245
215- if retryable & RetryCondition .SHOULD_RETRY_WITH_CLIENT_TOKEN :
216- self ._add_request_client_token (request )
246+ while True :
217247
218248 status , headers , body , exception = self ._handle_single_request (endpoint ,
219249 request ,
250+ request_timeout ,
220251 signer )
221252 retry_policy_context = RetryPolicyContext (request , exception , retries , status )
222253 retryable = self ._retry_policy .should_retry (retry_policy_context )
254+ if not retryable & RetryCondition .SHOULD_RETRY :
255+ break
223256 retry_policy_context .retryable = retryable
224257 time_to_sleep = self ._retry_policy .compute_delay_before_next_retry (retry_policy_context )
225258 time .sleep (time_to_sleep / 1000.0 )
226259 retries += 1
227260
228- def _handle_single_request (self , endpoint , request , signer ):
229- http_response = self ._make_http_response (endpoint , request , signer )
261+ if isinstance (exception , ClientException ):
262+ raise exception
263+
264+ return status , headers , body , exception
265+
266+ def _handle_single_request (self , endpoint , request , timeout , signer ):
267+ http_response = self ._make_http_response (endpoint , request , timeout , signer )
230268
231269 exception = None
232270
0 commit comments