Skip to content

Commit 35f7d24

Browse files
committed
Applied review changes
1 parent a771a94 commit 35f7d24

File tree

14 files changed

+908
-420
lines changed

14 files changed

+908
-420
lines changed

javav2/example_code/entityresolution/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@
9292
<groupId>software.amazon.awssdk</groupId>
9393
<artifactId>cloudformation</artifactId>
9494
</dependency>
95+
<dependency>
96+
<groupId>software.amazon.awssdk</groupId>
97+
<artifactId>sso</artifactId>
98+
</dependency>
99+
<dependency>
100+
<groupId>software.amazon.awssdk</groupId>
101+
<artifactId>ssooidc</artifactId>
102+
</dependency>
95103
<dependency>
96104
<groupId>org.apache.logging.log4j</groupId>
97105
<artifactId>log4j-core</artifactId>
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package com.example.entity.scenario;
5+
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
8+
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
9+
import software.amazon.awssdk.core.retry.RetryMode;
10+
import software.amazon.awssdk.http.async.SdkAsyncHttpClient;
11+
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
12+
import software.amazon.awssdk.services.cloudformation.CloudFormationAsyncClient;
13+
import software.amazon.awssdk.services.cloudformation.model.Capability;
14+
import software.amazon.awssdk.services.cloudformation.model.CloudFormationException;
15+
import software.amazon.awssdk.services.cloudformation.model.DescribeStacksRequest;
16+
import software.amazon.awssdk.services.cloudformation.model.DescribeStacksResponse;
17+
import software.amazon.awssdk.services.cloudformation.model.Output;
18+
import software.amazon.awssdk.services.cloudformation.model.Stack;
19+
import software.amazon.awssdk.services.cloudformation.waiters.CloudFormationAsyncWaiter;
20+
import software.amazon.awssdk.services.s3.S3AsyncClient;
21+
import software.amazon.awssdk.services.s3.model.DeleteObjectResponse;
22+
23+
import java.io.IOException;
24+
import java.net.URISyntaxException;
25+
import java.nio.file.Files;
26+
import java.nio.file.Path;
27+
import java.nio.file.Paths;
28+
import java.time.Duration;
29+
import java.util.HashMap;
30+
import java.util.List;
31+
import java.util.Map;
32+
import java.util.concurrent.CompletableFuture;
33+
import java.util.stream.Collectors;
34+
35+
public class CloudFormationHelper {
36+
private static final String CFN_TEMPLATE = "template.yaml";
37+
private static final Logger logger = LoggerFactory.getLogger(CloudFormationHelper.class);
38+
39+
private static CloudFormationAsyncClient cloudFormationClient;
40+
41+
public static void main(String[] args) {
42+
emptyS3Bucket(args[0]);
43+
}
44+
45+
private static CloudFormationAsyncClient getCloudFormationClient() {
46+
if (cloudFormationClient == null) {
47+
SdkAsyncHttpClient httpClient = NettyNioAsyncHttpClient.builder()
48+
.maxConcurrency(100)
49+
.connectionTimeout(Duration.ofSeconds(60))
50+
.readTimeout(Duration.ofSeconds(60))
51+
.writeTimeout(Duration.ofSeconds(60))
52+
.build();
53+
54+
ClientOverrideConfiguration overrideConfig = ClientOverrideConfiguration.builder()
55+
.apiCallTimeout(Duration.ofMinutes(2))
56+
.apiCallAttemptTimeout(Duration.ofSeconds(90))
57+
.retryStrategy(RetryMode.STANDARD)
58+
.build();
59+
60+
cloudFormationClient = CloudFormationAsyncClient.builder()
61+
.httpClient(httpClient)
62+
.overrideConfiguration(overrideConfig)
63+
.build();
64+
}
65+
return cloudFormationClient;
66+
}
67+
68+
public static void deployCloudFormationStack(String stackName) {
69+
String templateBody;
70+
boolean doesExist = describeStack(stackName);
71+
if (!doesExist) {
72+
try {
73+
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
74+
Path filePath = Paths.get(classLoader.getResource(CFN_TEMPLATE).toURI());
75+
templateBody = Files.readString(filePath);
76+
} catch (IOException | URISyntaxException e) {
77+
throw new RuntimeException(e);
78+
}
79+
80+
getCloudFormationClient().createStack(b -> b.stackName(stackName)
81+
.templateBody(templateBody)
82+
.capabilities(Capability.CAPABILITY_IAM))
83+
.whenComplete((csr, t) -> {
84+
if (csr != null) {
85+
System.out.println("Stack creation requested, ARN is " + csr.stackId());
86+
try (CloudFormationAsyncWaiter waiter = getCloudFormationClient().waiter()) {
87+
waiter.waitUntilStackCreateComplete(request -> request.stackName(stackName))
88+
.whenComplete((dsr, th) -> {
89+
if (th != null) {
90+
System.out.println("Error waiting for stack creation: " + th.getMessage());
91+
} else {
92+
dsr.matched().response().orElseThrow(() -> new RuntimeException("Failed to deploy"));
93+
System.out.println("Stack created successfully");
94+
}
95+
}).join();
96+
}
97+
} else {
98+
System.out.format("Error creating stack: " + t.getMessage(), t);
99+
throw new RuntimeException(t.getCause().getMessage(), t);
100+
}
101+
}).join();
102+
} else {
103+
logger.info("{} stack already exists", CFN_TEMPLATE);
104+
}
105+
}
106+
107+
// Check to see if the Stack exists before deploying it
108+
public static Boolean describeStack(String stackName) {
109+
try {
110+
CompletableFuture<?> future = getCloudFormationClient().describeStacks();
111+
DescribeStacksResponse stacksResponse = (DescribeStacksResponse) future.join();
112+
List<Stack> stacks = stacksResponse.stacks();
113+
for (Stack myStack : stacks) {
114+
if (myStack.stackName().compareTo(stackName) == 0) {
115+
return true;
116+
}
117+
}
118+
} catch (CloudFormationException e) {
119+
System.err.println(e.getMessage());
120+
}
121+
return false;
122+
}
123+
124+
public static void destroyCloudFormationStack(String stackName) {
125+
getCloudFormationClient().deleteStack(b -> b.stackName(stackName))
126+
.whenComplete((dsr, t) -> {
127+
if (dsr != null) {
128+
System.out.println("Delete stack requested ....");
129+
try (CloudFormationAsyncWaiter waiter = getCloudFormationClient().waiter()) {
130+
waiter.waitUntilStackDeleteComplete(request -> request.stackName(stackName))
131+
.whenComplete((waiterResponse, throwable) ->
132+
System.out.println("Stack deleted successfully."))
133+
.join();
134+
}
135+
} else {
136+
System.out.format("Error deleting stack: " + t.getMessage(), t);
137+
throw new RuntimeException(t.getCause().getMessage(), t);
138+
}
139+
}).join();
140+
}
141+
142+
public static CompletableFuture<Map<String, String>> getStackOutputsAsync(String stackName) {
143+
CloudFormationAsyncClient cloudFormationAsyncClient = getCloudFormationClient();
144+
145+
DescribeStacksRequest describeStacksRequest = DescribeStacksRequest.builder()
146+
.stackName(stackName)
147+
.build();
148+
149+
return cloudFormationAsyncClient.describeStacks(describeStacksRequest)
150+
.handle((describeStacksResponse, throwable) -> {
151+
if (throwable != null) {
152+
throw new RuntimeException("Failed to get stack outputs for: " + stackName, throwable);
153+
}
154+
155+
// Process the result
156+
if (describeStacksResponse.stacks().isEmpty()) {
157+
throw new RuntimeException("Stack not found: " + stackName);
158+
}
159+
160+
Stack stack = describeStacksResponse.stacks().get(0);
161+
Map<String, String> outputs = new HashMap<>();
162+
for (Output output : stack.outputs()) {
163+
outputs.put(output.outputKey(), output.outputValue());
164+
}
165+
166+
return outputs;
167+
});
168+
}
169+
170+
public static void emptyS3Bucket(String bucketName) {
171+
S3AsyncClient s3Client = S3AsyncClient.builder().build();
172+
173+
s3Client.listObjectsV2(req -> req.bucket(bucketName))
174+
.thenCompose(response -> {
175+
List<CompletableFuture<DeleteObjectResponse>> deleteFutures = response.contents().stream()
176+
.map(s3Object -> s3Client.deleteObject(req -> req
177+
.bucket(bucketName)
178+
.key(s3Object.key())))
179+
.collect(Collectors.toList());
180+
181+
return CompletableFuture.allOf(deleteFutures.toArray(new CompletableFuture[0]));
182+
})
183+
.join();
184+
185+
s3Client.close();
186+
}
187+
}
188+

0 commit comments

Comments
 (0)