Skip to content

Commit 22bc928

Browse files
committed
GH-1033 Fix AWSTypesMessageConverter to ensure it takes the first path at converting AWS types
Resolves #1033
1 parent 1395424 commit 22bc928

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed

spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/main/java/org/springframework/cloud/function/adapter/aws/AWSTypesMessageConverter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ protected boolean canConvertFrom(Message<?> message, @Nullable Class<?> targetCl
6262
if (message.getHeaders().containsKey(AWSLambdaUtils.AWS_EVENT)) {
6363
return ((boolean) message.getHeaders().get(AWSLambdaUtils.AWS_EVENT));
6464
}
65+
//TODO Do we really need the ^^ above? It seems like the line below dows the trick
66+
else if (targetClass.getPackage().getName().startsWith("com.amazonaws.services.lambda.runtime.events")) {
67+
return true;
68+
}
6569
return false;
6670
}
6771

spring-cloud-function-adapters/spring-cloud-function-adapter-aws/src/test/java/org/springframework/cloud/function/adapter/aws/FunctionInvokerTests.java

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPResponse;
3838
import com.amazonaws.services.lambda.runtime.events.ApplicationLoadBalancerRequestEvent;
3939
import com.amazonaws.services.lambda.runtime.events.ApplicationLoadBalancerResponseEvent;
40+
import com.amazonaws.services.lambda.runtime.events.DynamodbEvent;
4041
import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
4142
import com.amazonaws.services.lambda.runtime.events.S3Event;
4243
import com.amazonaws.services.lambda.runtime.events.SNSEvent;
@@ -73,6 +74,159 @@ public class FunctionInvokerTests {
7374

7475
String jsonCollection = "[\"Ricky\",\"Julien\",\"Bubbles\"]";
7576

77+
String dynamoDbEvent = "{\n"
78+
+ " \"Records\": [\n"
79+
+ " {\n"
80+
+ " \"eventID\": \"f07f8ca4b0b26cb9c4e5e77e69f274ee\",\n"
81+
+ " \"eventName\": \"INSERT\",\n"
82+
+ " \"eventVersion\": \"1.1\",\n"
83+
+ " \"eventSource\": \"aws:dynamodb\",\n"
84+
+ " \"awsRegion\": \"us-east-1\",\n"
85+
+ " \"userIdentity\":{\n"
86+
+ " \"type\":\"Service\",\n"
87+
+ " \"principalId\":\"dynamodb.amazonaws.com\"\n"
88+
+ " },\n"
89+
+ " \"dynamodb\": {\n"
90+
+ " \"ApproximateCreationDateTime\": 1.684934517E9,\n"
91+
+ " \"Keys\": {\n"
92+
+ " \"val\": {\n"
93+
+ " \"S\": \"data\"\n"
94+
+ " },\n"
95+
+ " \"key\": {\n"
96+
+ " \"S\": \"binary\"\n"
97+
+ " }\n"
98+
+ " },\n"
99+
+ " \"NewImage\": {\n"
100+
+ " \"val\": {\n"
101+
+ " \"S\": \"data\"\n"
102+
+ " },\n"
103+
+ " \"asdf1\": {\n"
104+
+ " \"B\": \"AAEqQQ==\"\n"
105+
+ " },\n"
106+
+ " \"asdf2\": {\n"
107+
+ " \"BS\": [\n"
108+
+ " \"AAEqQQ==\",\n"
109+
+ " \"QSoBAA==\"\n"
110+
+ " ]\n"
111+
+ " },\n"
112+
+ " \"key\": {\n"
113+
+ " \"S\": \"binary\"\n"
114+
+ " }\n"
115+
+ " },\n"
116+
+ " \"SequenceNumber\": \"1405400000000002063282832\",\n"
117+
+ " \"SizeBytes\": 54,\n"
118+
+ " \"StreamViewType\": \"NEW_AND_OLD_IMAGES\"\n"
119+
+ " },\n"
120+
+ " \"eventSourceARN\": \"arn:aws:dynamodb:us-east-1:123456789012:table/Example-Table/stream/2016-12-01T00:00:00.000\"\n"
121+
+ " },\n"
122+
+ " {\n"
123+
+ " \"eventID\": \"f07f8ca4b0b26cb9c4e5e77e42f274ee\",\n"
124+
+ " \"eventName\": \"INSERT\",\n"
125+
+ " \"eventVersion\": \"1.1\",\n"
126+
+ " \"eventSource\": \"aws:dynamodb\",\n"
127+
+ " \"awsRegion\": \"us-east-1\",\n"
128+
+ " \"dynamodb\": {\n"
129+
+ " \"ApproximateCreationDateTime\": 1480642020,\n"
130+
+ " \"Keys\": {\n"
131+
+ " \"val\": {\n"
132+
+ " \"S\": \"data\"\n"
133+
+ " },\n"
134+
+ " \"key\": {\n"
135+
+ " \"S\": \"binary\"\n"
136+
+ " }\n"
137+
+ " },\n"
138+
+ " \"NewImage\": {\n"
139+
+ " \"val\": {\n"
140+
+ " \"S\": \"data\"\n"
141+
+ " },\n"
142+
+ " \"asdf1\": {\n"
143+
+ " \"B\": \"AAEqQQ==\"\n"
144+
+ " },\n"
145+
+ " \"b2\": {\n"
146+
+ " \"B\": \"test\"\n"
147+
+ " },\n"
148+
+ " \"asdf2\": {\n"
149+
+ " \"BS\": [\n"
150+
+ " \"AAEqQQ==\",\n"
151+
+ " \"QSoBAA==\",\n"
152+
+ " \"AAEqQQ==\"\n"
153+
+ " ]\n"
154+
+ " },\n"
155+
+ " \"key\": {\n"
156+
+ " \"S\": \"binary\"\n"
157+
+ " },\n"
158+
+ " \"Binary\": {\n"
159+
+ " \"B\": \"AAEqQQ==\"\n"
160+
+ " },\n"
161+
+ " \"Boolean\": {\n"
162+
+ " \"BOOL\": true\n"
163+
+ " },\n"
164+
+ " \"BinarySet\": {\n"
165+
+ " \"BS\": [\n"
166+
+ " \"AAEqQQ==\",\n"
167+
+ " \"AAEqQQ==\"\n"
168+
+ " ]\n"
169+
+ " },\n"
170+
+ " \"List\": {\n"
171+
+ " \"L\": [\n"
172+
+ " {\n"
173+
+ " \"S\": \"Cookies\"\n"
174+
+ " },\n"
175+
+ " {\n"
176+
+ " \"S\": \"Coffee\"\n"
177+
+ " },\n"
178+
+ " {\n"
179+
+ " \"N\": \"3.14159\"\n"
180+
+ " }\n"
181+
+ " ]\n"
182+
+ " },\n"
183+
+ " \"Map\": {\n"
184+
+ " \"M\": {\n"
185+
+ " \"Name\": {\n"
186+
+ " \"S\": \"Joe\"\n"
187+
+ " },\n"
188+
+ " \"Age\": {\n"
189+
+ " \"N\": \"35\"\n"
190+
+ " }\n"
191+
+ " }\n"
192+
+ " },\n"
193+
+ " \"FloatNumber\": {\n"
194+
+ " \"N\": \"123.45\"\n"
195+
+ " },\n"
196+
+ " \"IntegerNumber\": {\n"
197+
+ " \"N\": \"123\"\n"
198+
+ " },\n"
199+
+ " \"NumberSet\": {\n"
200+
+ " \"NS\": [\n"
201+
+ " \"1234\",\n"
202+
+ " \"567.8\"\n"
203+
+ " ]\n"
204+
+ " },\n"
205+
+ " \"Null\": {\n"
206+
+ " \"NULL\": true\n"
207+
+ " },\n"
208+
+ " \"String\": {\n"
209+
+ " \"S\": \"Hello\"\n"
210+
+ " },\n"
211+
+ " \"StringSet\": {\n"
212+
+ " \"SS\": [\n"
213+
+ " \"Giraffe\",\n"
214+
+ " \"Zebra\"\n"
215+
+ " ]\n"
216+
+ " },\n"
217+
+ " \"EmptyStringSet\": {\n"
218+
+ " \"SS\": []\n"
219+
+ " }\n"
220+
+ " },\n"
221+
+ " \"SequenceNumber\": \"1405400000000002063282832\",\n"
222+
+ " \"SizeBytes\": 54,\n"
223+
+ " \"StreamViewType\": \"NEW_AND_OLD_IMAGES\"\n"
224+
+ " },\n"
225+
+ " \"eventSourceARN\": \"arn:aws:dynamodb:us-east-1:123456789012:table/Example-Table/stream/2016-12-01T00:00:00.000\"\n"
226+
+ " }\n"
227+
+ " ]\n"
228+
+ "}";
229+
76230
String sampleLBEvent = "{\n"
77231
+ " \"requestContext\": {\n"
78232
+ " \"elb\": {\n"
@@ -570,6 +724,17 @@ public void testSQSStringEvent() throws Exception {
570724
assertThat(result.length()).isEqualTo(14); // some additional JSON formatting
571725
}
572726

727+
@Test
728+
public void testDynamoDb() throws Exception {
729+
System.setProperty("MAIN_CLASS", DynamoDbConfiguration.class.getName());
730+
System.setProperty("spring.cloud.function.definition", "consume");
731+
FunctionInvoker invoker = new FunctionInvoker();
732+
733+
InputStream targetStream = new ByteArrayInputStream(this.dynamoDbEvent.getBytes());
734+
ByteArrayOutputStream output = new ByteArrayOutputStream();
735+
invoker.handleRequest(targetStream, output, null);
736+
}
737+
573738
@Test
574739
public void testSQSEvent() throws Exception {
575740
System.setProperty("MAIN_CLASS", SQSConfiguration.class.getName());
@@ -1143,6 +1308,15 @@ public Function<APIGatewayCustomAuthorizerEvent, String> acceptAuthorizerEvent()
11431308
}
11441309
}
11451310

1311+
@EnableAutoConfiguration
1312+
@Configuration
1313+
public static class DynamoDbConfiguration {
1314+
@Bean
1315+
public Consumer<DynamodbEvent> consume() {
1316+
return event -> event.getRecords().forEach(System.out::println);
1317+
}
1318+
}
1319+
11461320
@EnableAutoConfiguration
11471321
@Configuration
11481322
public static class SampleConfiguration {

0 commit comments

Comments
 (0)