1414
1515package software .amazon .lambda .powertools .cloudformation ;
1616
17+ import com .amazonaws .services .lambda .runtime .Context ;
18+ import com .amazonaws .services .lambda .runtime .events .CloudFormationCustomResourceEvent ;
19+ import com .fasterxml .jackson .databind .JsonNode ;
20+ import com .fasterxml .jackson .databind .ObjectMapper ;
21+ import com .fasterxml .jackson .databind .PropertyNamingStrategies ;
22+ import com .fasterxml .jackson .databind .node .ObjectNode ;
1723import java .io .IOException ;
1824import java .net .URI ;
1925import java .util .Collections ;
2026import java .util .HashMap ;
2127import java .util .List ;
2228import java .util .Map ;
2329import java .util .Objects ;
24-
2530import org .slf4j .Logger ;
2631import org .slf4j .LoggerFactory ;
27-
28- import com .amazonaws .services .lambda .runtime .Context ;
29- import com .amazonaws .services .lambda .runtime .events .CloudFormationCustomResourceEvent ;
30- import com .fasterxml .jackson .databind .JsonNode ;
31- import com .fasterxml .jackson .databind .ObjectMapper ;
32- import com .fasterxml .jackson .databind .PropertyNamingStrategies ;
33- import com .fasterxml .jackson .databind .node .ObjectNode ;
34-
3532import software .amazon .awssdk .http .Header ;
3633import software .amazon .awssdk .http .HttpExecuteRequest ;
3734import software .amazon .awssdk .http .HttpExecuteResponse ;
4239import software .amazon .awssdk .utils .StringUtils ;
4340
4441/**
45- * Client for sending responses to AWS CloudFormation custom resources by way of
46- * a response URL, which is an Amazon S3
42+ * Client for sending responses to AWS CloudFormation custom resources by way of a response URL, which is an Amazon S3
4743 * pre-signed URL.
4844 * <p>
49- * See
50- * https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-lambda-function-code-cfnresponsemodule.html
45+ * See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-lambda-function-code-cfnresponsemodule.html
5146 * <p>
52- * This class is thread-safe provided the SdkHttpClient instance used is also
53- * thread-safe.
47+ * This class is thread-safe provided the SdkHttpClient instance used is also thread-safe.
5448 */
55- public class CloudFormationResponse {
49+ class CloudFormationResponse {
5650
5751 private static final Logger LOG = LoggerFactory .getLogger (CloudFormationResponse .class );
5852 private final SdkHttpClient client ;
5953
6054 /**
61- * Creates a new CloudFormationResponse that uses the provided HTTP client and
62- * default JSON serialization format.
55+ * Creates a new CloudFormationResponse that uses the provided HTTP client and default JSON serialization format.
6356 *
6457 * @param client HTTP client to use for sending requests; cannot be null
6558 */
@@ -77,46 +70,36 @@ SdkHttpClient getClient() {
7770 }
7871
7972 /**
80- * Forwards a response containing a custom payload to the target resource
81- * specified by the event. The payload is
73+ * Forwards a response containing a custom payload to the target resource specified by the event. The payload is
8274 * formed from the event and context data. Status is assumed to be SUCCESS.
8375 *
8476 * @param event custom CF resource event. Cannot be null.
85- * @param context used to specify when the function and any callbacks have
86- * completed execution, or to
87- * access information from within the Lambda execution
88- * environment. Cannot be null.
77+ * @param context used to specify when the function and any callbacks have completed execution, or to
78+ * access information from within the Lambda execution environment. Cannot be null.
8979 * @return the response object
9080 * @throws IOException when unable to send the request
91- * @throws CustomResourceResponseException when unable to synthesize or
92- * serialize the response payload
81+ * @throws CustomResourceResponseException when unable to synthesize or serialize the response payload
9382 */
9483 public HttpExecuteResponse send (CloudFormationCustomResourceEvent event ,
95- Context context ) throws IOException , CustomResourceResponseException {
84+ Context context ) throws IOException , CustomResourceResponseException {
9685 return send (event , context , null );
9786 }
9887
9988 /**
100- * Forwards a response containing a custom payload to the target resource
101- * specified by the event. The payload is
89+ * Forwards a response containing a custom payload to the target resource specified by the event. The payload is
10290 * formed from the event, context, and response data.
10391 *
10492 * @param event custom CF resource event. Cannot be null.
105- * @param context used to specify when the function and any callbacks have
106- * completed execution, or to
107- * access information from within the Lambda execution
108- * environment. Cannot be null.
109- * @param responseData response to send, e.g. a list of name-value pairs. If
110- * null, an empty success is assumed.
93+ * @param context used to specify when the function and any callbacks have completed execution, or to
94+ * access information from within the Lambda execution environment. Cannot be null.
95+ * @param responseData response to send, e.g. a list of name-value pairs. If null, an empty success is assumed.
11196 * @return the response object
112- * @throws IOException when unable to generate or send the
113- * request
114- * @throws CustomResourceResponseException when unable to serialize the response
115- * payload
97+ * @throws IOException when unable to generate or send the request
98+ * @throws CustomResourceResponseException when unable to serialize the response payload
11699 */
117100 public HttpExecuteResponse send (CloudFormationCustomResourceEvent event ,
118- Context context ,
119- Response responseData ) throws IOException , CustomResourceResponseException {
101+ Context context ,
102+ Response responseData ) throws IOException , CustomResourceResponseException {
120103 // no need to explicitly close in-memory stream
121104 StringInputStream stream = responseBodyStream (event , context , responseData );
122105 URI uri = URI .create (event .getResponseUrl ());
@@ -146,23 +129,20 @@ protected Map<String, List<String>> headers(int contentLength) {
146129 }
147130
148131 /**
149- * Returns the response body as an input stream, for supplying with the HTTP
150- * request to the custom resource.
132+ * Returns the response body as an input stream, for supplying with the HTTP request to the custom resource.
151133 * <p>
152- * If PhysicalResourceId is null at this point it will be replaced with the
153- * Lambda LogStreamName.
134+ * If PhysicalResourceId is null at this point it will be replaced with the Lambda LogStreamName.
154135 *
155- * @throws CustomResourceResponseException if unable to generate the response
156- * stream
136+ * @throws CustomResourceResponseException if unable to generate the response stream
157137 */
158138 StringInputStream responseBodyStream (CloudFormationCustomResourceEvent event ,
159- Context context ,
160- Response resp ) throws CustomResourceResponseException {
139+ Context context ,
140+ Response resp ) throws CustomResourceResponseException {
161141 try {
162142 String reason = "See the details in CloudWatch Log Stream: " + context .getLogStreamName ();
163143 if (resp == null ) {
164- String physicalResourceId = event .getPhysicalResourceId () != null ? event .getPhysicalResourceId ()
165- : context .getLogStreamName ();
144+ String physicalResourceId = event .getPhysicalResourceId () != null ? event .getPhysicalResourceId () :
145+ context .getLogStreamName ();
166146
167147 ResponseBody body = new ResponseBody (event , Response .Status .SUCCESS , physicalResourceId , false , reason );
168148 LOG .debug ("ResponseBody: {}" , body );
@@ -172,12 +152,12 @@ StringInputStream responseBodyStream(CloudFormationCustomResourceEvent event,
172152 if (!StringUtils .isBlank (resp .getReason ())) {
173153 reason = resp .getReason ();
174154 }
175- String physicalResourceId = resp .getPhysicalResourceId () != null ? resp .getPhysicalResourceId ()
176- : event .getPhysicalResourceId () != null ? event .getPhysicalResourceId ()
177- : context .getLogStreamName ();
155+ String physicalResourceId = resp .getPhysicalResourceId () != null ? resp .getPhysicalResourceId () :
156+ event .getPhysicalResourceId () != null ? event .getPhysicalResourceId () :
157+ context .getLogStreamName ();
178158
179- ResponseBody body = new ResponseBody ( event , resp . getStatus (), physicalResourceId , resp . isNoEcho (),
180- reason );
159+ ResponseBody body =
160+ new ResponseBody ( event , resp . getStatus (), physicalResourceId , resp . isNoEcho (), reason );
181161 LOG .debug ("ResponseBody: {}" , body );
182162 ObjectNode node = body .toObjectNode (resp .getJsonNode ());
183163 return new StringInputStream (node .toString ());
@@ -189,14 +169,10 @@ StringInputStream responseBodyStream(CloudFormationCustomResourceEvent event,
189169 }
190170
191171 /**
192- * Internal representation of the payload to be sent to the event target URL.
193- * Retains all properties of the payload
194- * except for "Data". This is done so that the serialization of the non-"Data"
195- * properties and the serialization of
196- * the value of "Data" can be handled by separate ObjectMappers, if need be. The
197- * former properties are dictated by
198- * the custom resource but the latter is dictated by the implementor of the
199- * custom resource handler.
172+ * Internal representation of the payload to be sent to the event target URL. Retains all properties of the payload
173+ * except for "Data". This is done so that the serialization of the non-"Data" properties and the serialization of
174+ * the value of "Data" can be handled by separate ObjectMappers, if need be. The former properties are dictated by
175+ * the custom resource but the latter is dictated by the implementor of the custom resource handler.
200176 */
201177 @ SuppressWarnings ("unused" )
202178 static class ResponseBody {
@@ -213,10 +189,10 @@ static class ResponseBody {
213189 private final boolean noEcho ;
214190
215191 ResponseBody (CloudFormationCustomResourceEvent event ,
216- Response .Status responseStatus ,
217- String physicalResourceId ,
218- boolean noEcho ,
219- String reason ) {
192+ Response .Status responseStatus ,
193+ String physicalResourceId ,
194+ boolean noEcho ,
195+ String reason ) {
220196 Objects .requireNonNull (event , "CloudFormationCustomResourceEvent cannot be null" );
221197
222198 this .physicalResourceId = physicalResourceId ;
@@ -257,13 +233,10 @@ public boolean isNoEcho() {
257233 }
258234
259235 /**
260- * Returns this ResponseBody as an ObjectNode with the provided JsonNode as the
261- * value of its "Data" property.
236+ * Returns this ResponseBody as an ObjectNode with the provided JsonNode as the value of its "Data" property.
262237 *
263- * @param dataNode the value of the "Data" property for the returned node; may
264- * be null
265- * @return an ObjectNode representation of this ResponseBody and the provided
266- * dataNode
238+ * @param dataNode the value of the "Data" property for the returned node; may be null
239+ * @return an ObjectNode representation of this ResponseBody and the provided dataNode
267240 */
268241 ObjectNode toObjectNode (JsonNode dataNode ) {
269242 ObjectNode node = MAPPER .valueToTree (this );
0 commit comments