Skip to content

Commit 4b48514

Browse files
committed
added compression to handler response stream
1 parent e7fc59f commit 4b48514

5 files changed

Lines changed: 57 additions & 11 deletions

File tree

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@
6161
</dependencies>
6262
</dependencyManagement>
6363
<dependencies>
64+
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
65+
<dependency>
66+
<groupId>commons-codec</groupId>
67+
<artifactId>commons-codec</artifactId>
68+
<version>1.14</version>
69+
</dependency>
6470
<!-- https://mvnrepository.com/artifact/software.amazon.cloudformation/aws-cloudformation-resource-schema -->
6571
<dependency>
6672
<groupId>software.amazon.cloudformation</groupId>

src/main/java/software/amazon/cloudformation/LambdaWrapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,8 @@ public void handleRequest(final InputStream inputStream, final OutputStream outp
249249
throw new TerminalException("No request object received");
250250
}
251251

252-
String input = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
252+
String input = this.serializer.decompress(IOUtils.toString(inputStream, StandardCharsets.UTF_8));
253+
253254
JSONObject rawInput = new JSONObject(new JSONTokener(input));
254255

255256
// deserialize incoming payload to modelled request

src/main/java/software/amazon/cloudformation/resource/Serializer.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515
package software.amazon.cloudformation.resource;
1616

17+
import com.amazonaws.util.IOUtils;
1718
import com.fasterxml.jackson.annotation.JsonInclude;
1819
import com.fasterxml.jackson.core.JsonProcessingException;
1920
import com.fasterxml.jackson.core.type.TypeReference;
@@ -22,14 +23,24 @@
2223
import com.fasterxml.jackson.databind.ObjectMapper;
2324
import com.fasterxml.jackson.databind.SerializationFeature;
2425
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
26+
import java.io.ByteArrayInputStream;
27+
import java.io.ByteArrayOutputStream;
2528
import java.io.IOException;
29+
import java.nio.charset.StandardCharsets;
30+
import java.util.HashMap;
31+
import java.util.Map;
32+
import java.util.zip.GZIPInputStream;
33+
import java.util.zip.GZIPOutputStream;
34+
import org.apache.commons.codec.binary.Base64;
2635
import software.amazon.cloudformation.proxy.aws.AWSServiceSerdeModule;
2736

2837
public class Serializer {
2938

39+
public static final String COMPRESSED = "compressed";
3040
private static final ObjectMapper OBJECT_MAPPER;
31-
3241
private static final ObjectMapper STRICT_OBJECT_MAPPER;
42+
private static final TypeReference<Map<String, String>> MAP_TYPE_REFERENCE = new TypeReference<Map<String, String>>() {
43+
};
3344

3445
/**
3546
* Configures the specified ObjectMapper with the (de)serialization behaviours
@@ -76,10 +87,37 @@ public <T> String serialize(final T modelObject) throws JsonProcessingException
7687
return OBJECT_MAPPER.writeValueAsString(modelObject);
7788
}
7889

90+
public <T> String compress(final String modelInput) throws IOException {
91+
final Map<String, String> map = new HashMap<>();
92+
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
93+
GZIPOutputStream gzip = new GZIPOutputStream(byteArrayOutputStream);
94+
gzip.write(modelInput.getBytes(StandardCharsets.UTF_8));
95+
gzip.close();
96+
map.put(COMPRESSED, Base64.encodeBase64String(byteArrayOutputStream.toByteArray()));
97+
return OBJECT_MAPPER.writeValueAsString(map);
98+
}
99+
79100
public <T> T deserialize(final String s, final TypeReference<T> reference) throws IOException {
80101
return OBJECT_MAPPER.readValue(s, reference);
81102
}
82103

104+
public String decompress(final String s) {
105+
try {
106+
final Map<String, String> map = deserialize(s, MAP_TYPE_REFERENCE);
107+
108+
if (!map.containsKey(COMPRESSED)) {
109+
return s;
110+
}
111+
112+
final byte[] bytes = Base64.decodeBase64(map.get(COMPRESSED));
113+
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
114+
GZIPInputStream gzipInputStream = new GZIPInputStream(byteArrayInputStream);
115+
return new String(IOUtils.toByteArray(gzipInputStream), StandardCharsets.UTF_8);
116+
} catch (IOException e) {
117+
return s;
118+
}
119+
}
120+
83121
public <T> T deserializeStrict(final String s, final TypeReference<T> reference) throws IOException {
84122
return STRICT_OBJECT_MAPPER.readValue(s, reference);
85123
}

src/main/java/software/amazon/cloudformation/scheduler/CloudWatchScheduler.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*/
1515
package software.amazon.cloudformation.scheduler;
1616

17-
import com.fasterxml.jackson.core.JsonProcessingException;
17+
import java.io.IOException;
1818
import java.util.Objects;
1919
import java.util.UUID;
2020
import lombok.Data;
@@ -101,14 +101,14 @@ public <ResourceT, CallbackT> void rescheduleAfterMinutes(final String functionA
101101
String jsonRequest;
102102
try {
103103
// expect return type to be non-null
104-
jsonRequest = serializer.serialize(handlerRequest);
105-
} catch (JsonProcessingException e) {
104+
jsonRequest = serializer.compress(serializer.serialize(handlerRequest));
105+
} catch (IOException e) {
106106
throw new TerminalException("Unable to serialize the request for callback", e);
107107
}
108-
this.log(String.format("Scheduling re-invoke at %s (%s)%n", cronRule, rescheduleId));
109108

110109
PutRuleRequest putRuleRequest = PutRuleRequest.builder().name(ruleName).scheduleExpression(cronRule)
111110
.state(RuleState.ENABLED).build();
111+
112112
this.client.putRule(putRuleRequest);
113113

114114
Target target = Target.builder().arn(functionArn).id(targetId).input(jsonRequest).build();

src/test/java/software/amazon/cloudformation/scheduler/CloudWatchSchedulerTest.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
import static org.mockito.Mockito.times;
2222
import static org.mockito.Mockito.verify;
2323
import static org.mockito.Mockito.when;
24-
import java.util.Arrays;
24+
import java.io.IOException;
25+
import java.util.Collections;
2526
import java.util.List;
26-
import org.json.JSONObject;
2727
import org.junit.jupiter.api.Test;
2828
import org.junit.jupiter.api.extension.ExtendWith;
2929
import org.mockito.ArgumentCaptor;
@@ -148,7 +148,7 @@ public void test_cleanupCloudWatchEventsWithErrorDeletingRule() {
148148
}
149149

150150
@Test
151-
public void test_rescheduleAfterMinutes_1MinuteFloor() {
151+
public void test_rescheduleAfterMinutes_1MinuteFloor() throws IOException {
152152
final CloudWatchEventsProvider provider = mock(CloudWatchEventsProvider.class);
153153
final CloudWatchEventsClient client = getCloudWatchEvents();
154154
when(provider.get()).thenReturn(client);
@@ -166,8 +166,9 @@ public void test_rescheduleAfterMinutes_1MinuteFloor() {
166166
verify(requestContext, times(1)).setCloudWatchEventsRuleName(startsWith("reinvoke-handler-"));
167167
verify(requestContext, times(1)).setCloudWatchEventsTargetId(startsWith("reinvoke-target-"));
168168

169-
final List<TargetMatcher> targetMatchers = Arrays
170-
.asList(new TargetMatcher(FUNCTION_ARN, "reinvoke-target-", new JSONObject(request).toString()));
169+
final List<TargetMatcher> targetMatchers = Collections.singletonList(
170+
new TargetMatcher(FUNCTION_ARN, "reinvoke-target-", serializer.compress(serializer.serialize(request))));
171+
171172
verify(client, times(1))
172173
.putTargets(argThat(new PutTargetsRequestMatcher("reinvoke-handler-", new TargetsListMatcher(targetMatchers))));
173174
verify(client, times(1))

0 commit comments

Comments
 (0)