Skip to content

Commit e54c4d9

Browse files
committed
handle event field names properly
ex: SQS Records with big R
1 parent 4bd8305 commit e54c4d9

File tree

5 files changed

+55
-7
lines changed

5 files changed

+55
-7
lines changed

powertools-validation/pom.xml

+5-5
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@
7575
<artifactId>json-schema-validator</artifactId>
7676
<version>1.0.73</version>
7777
</dependency>
78+
<dependency>
79+
<groupId>com.amazonaws</groupId>
80+
<artifactId>aws-lambda-java-serialization</artifactId>
81+
</dependency>
7882

7983
<!-- Test dependencies -->
8084
<dependency>
@@ -87,11 +91,7 @@
8791
<artifactId>junit-jupiter-engine</artifactId>
8892
<scope>test</scope>
8993
</dependency>
90-
<dependency>
91-
<groupId>com.amazonaws</groupId>
92-
<artifactId>aws-lambda-java-serialization</artifactId>
93-
<scope>test</scope>
94-
</dependency>
94+
9595
<dependency>
9696
<groupId>org.apache.commons</groupId>
9797
<artifactId>commons-lang3</artifactId>

powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationUtils.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*/
1414
package software.amazon.lambda.powertools.validation;
1515

16+
import java.io.ByteArrayOutputStream;
1617
import java.io.IOException;
1718
import java.io.InputStream;
1819
import java.util.Collections;
@@ -21,9 +22,12 @@
2122
import java.util.concurrent.ConcurrentHashMap;
2223
import java.util.stream.Collectors;
2324

25+
import com.amazonaws.services.lambda.runtime.serialization.PojoSerializer;
26+
import com.amazonaws.services.lambda.runtime.serialization.events.LambdaEventSerializers;
2427
import com.fasterxml.jackson.core.JsonProcessingException;
2528
import com.fasterxml.jackson.databind.JsonNode;
2629
import com.fasterxml.jackson.databind.node.JsonNodeType;
30+
import com.fasterxml.jackson.databind.node.NullNode;
2731
import com.networknt.schema.JsonSchema;
2832
import com.networknt.schema.ValidationMessage;
2933
import io.burt.jmespath.Expression;
@@ -65,9 +69,15 @@ public static void validate(Object obj, JsonSchema jsonSchema, String envelope)
6569
}
6670
JsonNode subNode;
6771
try {
68-
JsonNode jsonNode = ValidationConfig.get().getObjectMapper().valueToTree(obj);
72+
PojoSerializer pojoSerializer = LambdaEventSerializers.serializerFor(obj.getClass(), ClassLoader.getSystemClassLoader());
73+
ByteArrayOutputStream out = new ByteArrayOutputStream();
74+
pojoSerializer.toJson(obj, out);
75+
JsonNode jsonNode = ValidationConfig.get().getObjectMapper().readTree(out.toString("UTF-8"));
6976
Expression<JsonNode> expression = ValidationConfig.get().getJmesPath().compile(envelope);
7077
subNode = expression.search(jsonNode);
78+
if (subNode == null || subNode instanceof NullNode) {
79+
throw new ValidationException("Not found");
80+
}
7181
} catch (Exception e) {
7282
throw new ValidationException("Cannot find envelope <"+envelope+"> in the object <"+obj+">", e);
7383
}

powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/SQSWithCustomEnvelopeHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
public class SQSWithCustomEnvelopeHandler implements RequestHandler<SQSEvent, String> {
2222

2323
@Override
24-
@Validation(inboundSchema = "classpath:/schema_v7.json", envelope = "records[*].powertools_json(body).powertools_json(Message)")
24+
@Validation(inboundSchema = "classpath:/schema_v7.json", envelope = "Records[*].powertools_json(body).powertools_json(Message)")
2525
public String handleRequest(SQSEvent input, Context context) {
2626
return "OK";
2727
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2020 Amazon.com, Inc. or its affiliates.
3+
* Licensed under the Apache License, Version 2.0 (the
4+
* "License"); you may not use this file except in compliance
5+
* with the License. You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*
13+
*/
14+
package software.amazon.lambda.powertools.validation.handlers;
15+
16+
import com.amazonaws.services.lambda.runtime.Context;
17+
import com.amazonaws.services.lambda.runtime.RequestHandler;
18+
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
19+
import software.amazon.lambda.powertools.validation.Validation;
20+
21+
public class SQSWithWrongEnvelopeHandler implements RequestHandler<SQSEvent, String> {
22+
23+
@Override
24+
// real event contains Records with big R (https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html)
25+
@Validation(inboundSchema = "classpath:/schema_v7.json", envelope = "records[*].powertools_json(body).powertools_json(Message)")
26+
public String handleRequest(SQSEvent input, Context context) {
27+
return "OK";
28+
}
29+
}

powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/internal/ValidationAspectTest.java

+9
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,15 @@ public void validate_SQS_CustomEnvelopeTakePrecedence() {
110110
assertThat(handler.handleRequest(event, context)).isEqualTo("OK");
111111
}
112112

113+
@Test
114+
public void validate_SQS_WrongEnvelope_shouldThrowValidationException() {
115+
PojoSerializer<SQSEvent> pojoSerializer = LambdaEventSerializers.serializerFor(SQSEvent.class, ClassLoader.getSystemClassLoader());
116+
SQSEvent event = pojoSerializer.fromJson(this.getClass().getResourceAsStream("/sqs_message.json"));
117+
118+
SQSWithWrongEnvelopeHandler handler = new SQSWithWrongEnvelopeHandler();
119+
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> handler.handleRequest(event, context));
120+
}
121+
113122
@Test
114123
public void validate_Kinesis() {
115124
PojoSerializer<KinesisEvent> pojoSerializer = LambdaEventSerializers.serializerFor(KinesisEvent.class, ClassLoader.getSystemClassLoader());

0 commit comments

Comments
 (0)