|
20 | 20 | import org.slf4j.Logger; |
21 | 21 | import org.slf4j.LoggerFactory; |
22 | 22 |
|
23 | | -import java.io.IOException; |
24 | | -import java.io.OutputStreamWriter; |
25 | 23 | import java.net.HttpURLConnection; |
26 | | -import java.net.URL; |
| 24 | +import java.net.URI; |
| 25 | +import java.net.http.HttpClient; |
| 26 | +import java.net.http.HttpRequest; |
| 27 | +import java.net.http.HttpResponse; |
27 | 28 | import java.nio.charset.StandardCharsets; |
28 | 29 | import java.util.HashMap; |
29 | 30 | import java.util.Map; |
30 | 31 |
|
31 | 32 | public class CloudFormationResponse { |
32 | 33 |
|
33 | 34 | private static final Logger LOGGER = LoggerFactory.getLogger(CloudFormationResponse.class); |
| 35 | + private static final HttpClient http = HttpClient.newBuilder().build(); |
34 | 36 |
|
35 | 37 | private CloudFormationResponse() { |
36 | 38 | } |
37 | 39 |
|
38 | 40 | public static void send(Map<String, Object> event, Context context, String responseStatus, |
39 | 41 | Map<String, Object> responseData) { |
40 | | - Map<String, Object> responseBody = buildResponseBody(event, context, responseStatus, responseData); |
| 42 | + send(event, context, responseStatus, responseData, false); |
| 43 | + } |
| 44 | + |
| 45 | + public static void send(Map<String, Object> event, Context context, String responseStatus, |
| 46 | + Map<String, Object> responseData, boolean noEcho) { |
| 47 | + String responseBody = buildResponseBody(event, context, responseStatus, responseData, noEcho); |
41 | 48 | String responseUrl = (String) event.get("ResponseURL"); |
| 49 | + LOGGER.info("curl -H 'Content-Type: \"\"' -X PUT -d '" + responseBody + "' \"" + responseUrl + "\""); |
| 50 | + |
| 51 | + HttpRequest request = HttpRequest.newBuilder() |
| 52 | + .uri(URI.create(responseUrl)) |
| 53 | + .setHeader("Content-Type", "") |
| 54 | + .PUT(HttpRequest.BodyPublishers.ofString(responseBody, StandardCharsets.UTF_8)) |
| 55 | + .build(); |
42 | 56 | try { |
43 | | - URL url = new URL(responseUrl); |
44 | | - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); |
45 | | - connection.setDoOutput(true); |
46 | | - connection.setRequestProperty("Content-Type", ""); |
47 | | - connection.setRequestMethod("PUT"); |
48 | | - try (OutputStreamWriter response = new OutputStreamWriter(connection.getOutputStream(), |
49 | | - StandardCharsets.UTF_8)) { |
50 | | - response.write(Utils.toJson(responseBody)); |
51 | | - int responseCode = connection.getResponseCode(); |
52 | | - if (responseCode < 200 || responseCode > 299) { |
53 | | - LOGGER.error("Response from CFN S3 signed URL failed {}", responseUrl); |
54 | | - LOGGER.error("Response: {} {}", responseCode, connection.getResponseMessage()); |
55 | | - } |
56 | | - } catch (IOException ioe) { |
57 | | - LOGGER.error("Failed to complete HTTP request"); |
58 | | - LOGGER.error(Utils.getFullStackTrace(ioe)); |
| 57 | + HttpResponse<String> response = http.send(request, |
| 58 | + HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); |
| 59 | + if (HttpURLConnection.HTTP_OK != response.statusCode()) { |
| 60 | + LOGGER.error("Response from CFN S3 signed URL failed {} {}", response.statusCode(), response.body()); |
59 | 61 | } |
60 | | - connection.disconnect(); |
61 | | - } catch (IOException e) { |
62 | | - LOGGER.error("Failed to open connection to CFN response URL"); |
| 62 | + } catch (Exception e) { |
| 63 | + LOGGER.error("Failed to complete HTTP request"); |
63 | 64 | LOGGER.error(Utils.getFullStackTrace(e)); |
64 | 65 | } |
65 | 66 | } |
66 | 67 |
|
67 | | - protected static Map<String, Object> buildResponseBody(Map<String, Object> event, Context context, |
68 | | - String responseStatus, Map<String, Object> responseData) { |
| 68 | + protected static String buildResponseBody(Map<String, Object> event, Context context, String responseStatus, |
| 69 | + Map<String, Object> responseData, boolean noEcho) { |
69 | 70 | Map<String, Object> responseBody = new HashMap<>(); |
70 | 71 | responseBody.put("Status", responseStatus); |
71 | 72 | responseBody.put("RequestId", event.get("RequestId")); |
72 | 73 | responseBody.put("LogicalResourceId", event.get("LogicalResourceId")); |
73 | 74 | responseBody.put("StackId", event.get("StackId")); |
| 75 | + responseBody.put("NoEcho", noEcho); |
74 | 76 | // If the physical resource id changes between a CREATE and an UPDATE event, CloudFormation will DELETE |
75 | 77 | // the previous physical resource. Usually this doesn't matter -- unless you're actually creating something |
76 | 78 | // in your custom resource that you don't want deleted. |
77 | 79 | responseBody.put("PhysicalResourceId", context.getAwsRequestId()); |
78 | 80 | if (!"FAILED".equals(responseStatus)) { |
79 | | - responseBody.put("Data", responseData); |
| 81 | + if (responseData != null && !responseData.isEmpty()) { |
| 82 | + responseBody.put("Data", responseData); |
| 83 | + } |
80 | 84 | } else { |
81 | 85 | responseBody.put("Reason", responseData.get("Reason")); |
82 | 86 | } |
83 | | - LOGGER.info("Response Body: " + Utils.toJson(responseBody)); |
84 | | - return responseBody; |
| 87 | + return Utils.toJson(responseBody); |
85 | 88 | } |
86 | 89 | } |
0 commit comments