44package com .example .iotsitewise .scenario ;
55import org .slf4j .Logger ;
66import org .slf4j .LoggerFactory ;
7- import software .amazon .awssdk .regions .Region ;
7+ import software .amazon .awssdk .core .client .config .ClientOverrideConfiguration ;
8+ import software .amazon .awssdk .core .retry .RetryMode ;
9+ import software .amazon .awssdk .http .async .SdkAsyncHttpClient ;
10+ import software .amazon .awssdk .http .nio .netty .NettyNioAsyncHttpClient ;
811import software .amazon .awssdk .services .cloudformation .CloudFormationAsyncClient ;
912import software .amazon .awssdk .services .cloudformation .CloudFormationClient ;
1013import software .amazon .awssdk .services .cloudformation .model .Capability ;
1417import software .amazon .awssdk .services .cloudformation .model .Output ;
1518import software .amazon .awssdk .services .cloudformation .model .Stack ;
1619import software .amazon .awssdk .services .cloudformation .waiters .CloudFormationAsyncWaiter ;
17-
1820import java .io .IOException ;
1921import java .net .URISyntaxException ;
2022import java .nio .file .Files ;
2123import java .nio .file .Path ;
2224import java .nio .file .Paths ;
25+ import java .time .Duration ;
2326import java .util .HashMap ;
2427import java .util .List ;
2528import java .util .Map ;
@@ -28,11 +31,29 @@ public class CloudFormationHelper {
2831 private static final String CFN_TEMPLATE = "SitewiseRoles-template.yaml" ;
2932 private static final Logger logger = LoggerFactory .getLogger (CloudFormationHelper .class );
3033
34+ private static CloudFormationAsyncClient cloudFormationClient ;
35+
3136 private static CloudFormationAsyncClient getCloudFormationClient () {
32- CloudFormationAsyncClient cfClient = CloudFormationAsyncClient .builder ()
33- .build ();
37+ if (cloudFormationClient == null ) {
38+ SdkAsyncHttpClient httpClient = NettyNioAsyncHttpClient .builder ()
39+ .maxConcurrency (100 )
40+ .connectionTimeout (Duration .ofSeconds (60 ))
41+ .readTimeout (Duration .ofSeconds (60 ))
42+ .writeTimeout (Duration .ofSeconds (60 ))
43+ .build ();
3444
35- return cfClient ;
45+ ClientOverrideConfiguration overrideConfig = ClientOverrideConfiguration .builder ()
46+ .apiCallTimeout (Duration .ofMinutes (2 ))
47+ .apiCallAttemptTimeout (Duration .ofSeconds (90 ))
48+ .retryStrategy (RetryMode .STANDARD )
49+ .build ();
50+
51+ cloudFormationClient = CloudFormationAsyncClient .builder ()
52+ .httpClient (httpClient )
53+ .overrideConfiguration (overrideConfig )
54+ .build ();
55+ }
56+ return cloudFormationClient ;
3657 }
3758
3859 public static void deployCloudFormationStack (String stackName ) {
@@ -75,7 +96,6 @@ public static void deployCloudFormationStack(String stackName) {
7596 }
7697
7798 // Check to see if the Stack exists before deploying it
78-
7999 public static Boolean describeStack (String stackName ) {
80100 try {
81101 CompletableFuture <?> future = getCloudFormationClient ().describeStacks ();
@@ -109,25 +129,31 @@ public static void destroyCloudFormationStack(String stackName) {
109129 }).join ();
110130 }
111131
112- public static Map <String , String > getStackOutputs (String stackName ) {
113- CloudFormationClient cfClient = CloudFormationClient .create ();
132+ public static CompletableFuture <Map <String , String >> getStackOutputsAsync (String stackName ) {
133+ CloudFormationAsyncClient cloudFormationAsyncClient = getCloudFormationClient ();
134+
114135 DescribeStacksRequest describeStacksRequest = DescribeStacksRequest .builder ()
115136 .stackName (stackName )
116137 .build ();
117138
118- DescribeStacksResponse describeStacksResponse = cfClient .describeStacks (describeStacksRequest );
119- List <Stack > stacks = describeStacksResponse .stacks ();
139+ return cloudFormationAsyncClient .describeStacks (describeStacksRequest )
140+ .handle ((describeStacksResponse , throwable ) -> {
141+ if (throwable != null ) {
142+ throw new RuntimeException ("Failed to get stack outputs for: " + stackName , throwable );
143+ }
120144
121- if (stacks .isEmpty ()) {
122- throw new RuntimeException ("Stack not found: " + stackName );
123- }
145+ // Process the result
146+ if (describeStacksResponse .stacks ().isEmpty ()) {
147+ throw new RuntimeException ("Stack not found: " + stackName );
148+ }
124149
125- Stack stack = stacks .get (0 );
126- Map <String , String > outputs = new HashMap <>();
127- for (Output output : stack .outputs ()) {
128- outputs .put (output .outputKey (), output .outputValue ());
129- }
150+ Stack stack = describeStacksResponse . stacks () .get (0 );
151+ Map <String , String > outputs = new HashMap <>();
152+ for (Output output : stack .outputs ()) {
153+ outputs .put (output .outputKey (), output .outputValue ());
154+ }
130155
131- return outputs ;
156+ return outputs ;
157+ });
132158 }
133159}
0 commit comments