@@ -180,9 +180,6 @@ def _handle_get_application_request(self, app_id, semver, key, logical_id):
180
180
warning_message = "{}. Unable to verify access to {}/{}." .format (e , app_id , semver )
181
181
LOG .warning (warning_message )
182
182
self ._applications [key ] = {"Unable to verify" }
183
- except ClientError as e :
184
- LOG .exception (e )
185
- raise e
186
183
187
184
def _handle_create_cfn_template_request (self , app_id , semver , key , logical_id ):
188
185
"""
@@ -197,11 +194,7 @@ def _handle_create_cfn_template_request(self, app_id, semver, key, logical_id):
197
194
create_cfn_template = lambda app_id , semver : self ._sar_client .create_cloud_formation_template (
198
195
ApplicationId = self ._sanitize_sar_str_param (app_id ), SemanticVersion = self ._sanitize_sar_str_param (semver )
199
196
)
200
- try :
201
- response = self ._sar_service_call (create_cfn_template , logical_id , app_id , semver )
202
- except ClientError as e :
203
- LOG .exception (e )
204
- raise e
197
+ response = self ._sar_service_call (create_cfn_template , logical_id , app_id , semver )
205
198
206
199
LOG .info ("Requested to create CFN template {}/{} in serverless application repo." .format (app_id , semver ))
207
200
self ._applications [key ] = response [self .TEMPLATE_URL_KEY ]
@@ -311,78 +304,73 @@ def on_after_transform_template(self, template):
311
304
:param dict template: Dictionary of the SAM template
312
305
:return: Nothing
313
306
"""
314
- if self ._wait_for_template_active_status and not self ._validate_only :
315
- start_time = time ()
316
- while (time () - start_time ) < self .TEMPLATE_WAIT_TIMEOUT_SECONDS :
317
- temp = self ._in_progress_templates
318
- self ._in_progress_templates = []
319
- # it's either our first time in this loop or we just slept SLEEP_TIME_SECONDS so we can
320
- # try calling SAR
321
- throttled = False
322
-
323
- # Check each resource to make sure it's active
324
- LOG .info ("Checking resources in serverless application repo..." )
325
- for application_id , template_id in temp :
326
- get_cfn_template = (
327
- lambda application_id , template_id : self ._sar_client .get_cloud_formation_template (
328
- ApplicationId = self ._sanitize_sar_str_param (application_id ),
329
- TemplateId = self ._sanitize_sar_str_param (template_id ),
330
- )
331
- )
332
- response = {"Status" : "PREPARING" } # default response if we can't reach SAR
333
-
334
- try :
335
- if not throttled :
336
- response = self ._sar_service_call (
337
- get_cfn_template , application_id , application_id , template_id
338
- )
339
- except ClientError as e :
340
- error_code = e .response ["Error" ]["Code" ]
341
- if error_code == "TooManyRequestsException" :
342
- # We were throttled by SAR, don't hammer SAR with more calls in this for loop
343
- throttled = True
344
- LOG .debug ("SAR call timed out for application id {}" .format (application_id ))
345
- # don't re-raise, fall through to regular processing as if the template wasn't ready yet
346
- else :
347
- LOG .exception (e )
348
- raise e
349
-
350
- self ._handle_get_cfn_template_response (response , application_id , template_id )
351
-
352
- LOG .info ("Finished checking resources in serverless application repo." )
353
-
354
- # Don't sleep if there are no more templates with PREPARING status
355
- if len (self ._in_progress_templates ) == 0 :
356
- break
357
-
358
- # Sleep a little so we don't spam service calls
359
- sleep (self .SLEEP_TIME_SECONDS )
360
-
361
- # Not all templates reached active status
362
- if len (self ._in_progress_templates ) != 0 :
363
- application_ids = [items [0 ] for items in self ._in_progress_templates ]
364
- raise InvalidResourceException (
365
- application_ids , "Timed out waiting for nested stack templates " "to reach ACTIVE status."
307
+ if not self ._wait_for_template_active_status or self ._validate_only :
308
+ return
309
+
310
+ start_time = time ()
311
+ while (time () - start_time ) < self .TEMPLATE_WAIT_TIMEOUT_SECONDS :
312
+ # Check each resource to make sure it's active
313
+ LOG .info ("Checking resources in serverless application repo..." )
314
+ idx = 0
315
+ while idx < len (self ._in_progress_templates ):
316
+ application_id , template_id = self ._in_progress_templates [idx ]
317
+ get_cfn_template = lambda application_id , template_id : self ._sar_client .get_cloud_formation_template (
318
+ ApplicationId = self ._sanitize_sar_str_param (application_id ),
319
+ TemplateId = self ._sanitize_sar_str_param (template_id ),
366
320
)
367
321
368
- def _handle_get_cfn_template_response (self , response , application_id , template_id ):
322
+ try :
323
+ response = self ._sar_service_call (get_cfn_template , application_id , application_id , template_id )
324
+ except ClientError as e :
325
+ error_code = e .response ["Error" ]["Code" ]
326
+ if error_code == "TooManyRequestsException" :
327
+ LOG .debug ("SAR call timed out for application id {}" .format (application_id ))
328
+ break # We were throttled by SAR, break out to a sleep
329
+ else :
330
+ raise e
331
+
332
+ if self ._is_template_active (response , application_id , template_id ):
333
+ self ._in_progress_templates .remove ((application_id , template_id ))
334
+ else :
335
+ idx += 1 # check next template
336
+
337
+ LOG .info ("Finished checking resources in serverless application repo." )
338
+
339
+ # Don't sleep if there are no more templates with PREPARING status
340
+ if len (self ._in_progress_templates ) == 0 :
341
+ break
342
+
343
+ # Sleep a little so we don't spam service calls
344
+ sleep (self ._get_sleep_time_sec ())
345
+
346
+ # Not all templates reached active status
347
+ if len (self ._in_progress_templates ) != 0 :
348
+ application_ids = [items [0 ] for items in self ._in_progress_templates ]
349
+ raise InvalidResourceException (
350
+ application_ids , "Timed out waiting for nested stack templates " "to reach ACTIVE status."
351
+ )
352
+
353
+ def _get_sleep_time_sec (self ):
354
+ return self .SLEEP_TIME_SECONDS
355
+
356
+ def _is_template_active (self , response , application_id , template_id ):
369
357
"""
370
- Handles the response from the SAR service call
358
+ Checks the response from a SAR service call; returns True if the template is active,
359
+ throws an exception if the request expired and returns False in all other cases.
371
360
372
361
:param dict response: the response dictionary from the app repo
373
362
:param string application_id: the ApplicationId
374
363
:param string template_id: the unique TemplateId for this application
375
364
"""
376
- status = response ["Status" ]
377
- if status != "ACTIVE" :
378
- # Other options are PREPARING and EXPIRED.
379
- if status == "EXPIRED" :
380
- message = (
381
- "Template for {} with id {} returned status: {}. Cannot access an expired "
382
- "template." .format (application_id , template_id , status )
383
- )
384
- raise InvalidResourceException (application_id , message )
385
- self ._in_progress_templates .append ((application_id , template_id ))
365
+ status = response ["Status" ] # options: PREPARING, EXPIRED or ACTIVE
366
+
367
+ if status == "EXPIRED" :
368
+ message = "Template for {} with id {} returned status: {}. Cannot access an expired " "template." .format (
369
+ application_id , template_id , status
370
+ )
371
+ raise InvalidResourceException (application_id , message )
372
+
373
+ return status == "ACTIVE"
386
374
387
375
@cw_timer (prefix = "External" , name = "SAR" )
388
376
def _sar_service_call (self , service_call_lambda , logical_id , * args ):
0 commit comments