Skip to content

Commit 3c8019a

Browse files
committed
add precedence for the envelope over built-in types
1 parent f8d3b11 commit 3c8019a

File tree

4 files changed

+72
-4
lines changed

4 files changed

+72
-4
lines changed

powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/internal/ValidationAspect.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import org.aspectj.lang.annotation.Around;
2020
import org.aspectj.lang.annotation.Aspect;
2121
import org.aspectj.lang.annotation.Pointcut;
22+
import org.slf4j.Logger;
23+
import org.slf4j.LoggerFactory;
2224
import software.amazon.lambda.powertools.validation.Validation;
2325
import software.amazon.lambda.powertools.validation.ValidationConfig;
2426

@@ -36,6 +38,9 @@
3638
*/
3739
@Aspect
3840
public class ValidationAspect {
41+
private static final Logger LOG = LoggerFactory.getLogger(ValidationAspect.class);
42+
43+
3944
@SuppressWarnings({"EmptyMethod"})
4045
@Pointcut("@annotation(validation)")
4146
public void callAt(Validation validation) {
@@ -59,7 +64,9 @@ && placedOnRequestHandler(pjp)) {
5964
JsonSchema inboundJsonSchema = getJsonSchema(validation.inboundSchema(), true);
6065

6166
Object obj = pjp.getArgs()[0];
62-
if (obj instanceof APIGatewayProxyRequestEvent) {
67+
if (validation.envelope() != null && !validation.envelope().isEmpty()) {
68+
validate(obj, inboundJsonSchema, validation.envelope());
69+
} else if (obj instanceof APIGatewayProxyRequestEvent) {
6370
APIGatewayProxyRequestEvent event = (APIGatewayProxyRequestEvent) obj;
6471
validate(event.getBody(), inboundJsonSchema);
6572
} else if (obj instanceof APIGatewayV2HTTPEvent) {
@@ -105,7 +112,7 @@ && placedOnRequestHandler(pjp)) {
105112
KinesisAnalyticsStreamsInputPreprocessingEvent event = (KinesisAnalyticsStreamsInputPreprocessingEvent) obj;
106113
event.getRecords().forEach(record -> validate(decode(record.getData()), inboundJsonSchema));
107114
} else {
108-
validate(obj, inboundJsonSchema, validation.envelope());
115+
LOG.warn("Unhandled event type {}, please use the 'envelope' parameter to specify what to validate", obj.getClass().getName());
109116
}
110117
}
111118
}
@@ -115,7 +122,9 @@ && placedOnRequestHandler(pjp)) {
115122
if (validationNeeded && !validation.outboundSchema().isEmpty()) {
116123
JsonSchema outboundJsonSchema = getJsonSchema(validation.outboundSchema(), true);
117124

118-
if (result instanceof APIGatewayProxyResponseEvent) {
125+
if (validation.envelope() != null && !validation.envelope().isEmpty()) {
126+
validate(result, outboundJsonSchema, validation.envelope());
127+
} else if (result instanceof APIGatewayProxyResponseEvent) {
119128
APIGatewayProxyResponseEvent response = (APIGatewayProxyResponseEvent) result;
120129
validate(response.getBody(), outboundJsonSchema);
121130
} else if (result instanceof APIGatewayV2HTTPResponse) {
@@ -131,7 +140,7 @@ && placedOnRequestHandler(pjp)) {
131140
KinesisAnalyticsInputPreprocessingResponse response = (KinesisAnalyticsInputPreprocessingResponse) result;
132141
response.getRecords().forEach(record -> validate(decode(record.getData()), outboundJsonSchema));
133142
} else {
134-
validate(result, outboundJsonSchema, validation.envelope());
143+
LOG.warn("Unhandled response type {}, please use the 'envelope' parameter to specify what to validate", result.getClass().getName());
135144
}
136145
}
137146

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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 SQSWithCustomEnvelopeHandler implements RequestHandler<SQSEvent, String> {
22+
23+
@Override
24+
@Validation(inboundSchema = "classpath:/schema_v7.json", envelope = "records[*].powertools_json(body).powertools_json(Message)")
25+
public String handleRequest(SQSEvent input, Context context) {
26+
return "OK";
27+
}
28+
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,15 @@ public void validate_SQS() {
101101
assertThat(handler.handleRequest(event, context)).isEqualTo("OK");
102102
}
103103

104+
@Test
105+
public void validate_SQS_CustomEnvelopeTakePrecedence() {
106+
PojoSerializer<SQSEvent> pojoSerializer = LambdaEventSerializers.serializerFor(SQSEvent.class, ClassLoader.getSystemClassLoader());
107+
SQSEvent event = pojoSerializer.fromJson(this.getClass().getResourceAsStream("/sqs_message.json"));
108+
109+
SQSWithCustomEnvelopeHandler handler = new SQSWithCustomEnvelopeHandler();
110+
assertThat(handler.handleRequest(event, context)).isEqualTo("OK");
111+
}
112+
104113
@Test
105114
public void validate_Kinesis() {
106115
PojoSerializer<KinesisEvent> pojoSerializer = LambdaEventSerializers.serializerFor(KinesisEvent.class, ClassLoader.getSystemClassLoader());
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"Records": [
3+
{
4+
"messageId": "d9144555-9a4f-4ec3-99a0-fc4e625a8db2",
5+
"receiptHandle": "7kam5bfzbDsjtcjElvhSbxeLJbeey3A==",
6+
"body": "{\n \"Message\": \"{\\n \\\"id\\\": 43242,\\n \\\"name\\\": \\\"FooBar XY\\\",\\n \\\"price\\\": 258\\n}\"}",
7+
"attributes": {
8+
"ApproximateReceiveCount": "1",
9+
"SentTimestamp": "1601975709495",
10+
"SenderId": "AROAIFU457DVZ5L2J53F2",
11+
"ApproximateFirstReceiveTimestamp": "1601975709499"
12+
},
13+
"messageAttributes": {
14+
15+
},
16+
"md5OfBody": "0f96e88a291edb4429f2f7b9fdc3df96",
17+
"eventSource": "aws:sqs",
18+
"eventSourceARN": "arn:aws:sqs:eu-central-1:123456789012:TestLambda",
19+
"awsRegion": "eu-central-1"
20+
}
21+
]
22+
}

0 commit comments

Comments
 (0)