* To be used in conjunction with {@link EventPart#as(Class)} or {@link EventPart#asListOf(Class)}
* for the deserialization.
*
- * @param object the event of your Lambda function handler method
+ * @param event the event of your Lambda function handler method
* @return the part of the event which is meaningful (ex: body of the API Gateway).
*/
- public static EventPart extractDataFrom(Object object) {
- if (object instanceof String) {
- return new EventPart((String) object);
- } else if (object instanceof Map) {
- return new EventPart((Map) object);
- } else if (object instanceof APIGatewayProxyRequestEvent) {
- APIGatewayProxyRequestEvent event = (APIGatewayProxyRequestEvent) object;
- return new EventPart(event.getBody());
- } else if (object instanceof APIGatewayV2HTTPEvent) {
- APIGatewayV2HTTPEvent event = (APIGatewayV2HTTPEvent) object;
- return new EventPart(event.getBody());
- } else if (object instanceof SNSEvent) {
- SNSEvent event = (SNSEvent) object;
- return new EventPart(event.getRecords().get(0).getSNS().getMessage());
- } else if (object instanceof SQSEvent) {
- SQSEvent event = (SQSEvent) object;
- return new EventPart(event.getRecords().stream()
- .map(SQSEvent.SQSMessage::getBody)
- .collect(Collectors.toList()));
- } else if (object instanceof ScheduledEvent) {
- ScheduledEvent event = (ScheduledEvent) object;
- return new EventPart(event.getDetail());
- } else if (object instanceof ApplicationLoadBalancerRequestEvent) {
- ApplicationLoadBalancerRequestEvent event = (ApplicationLoadBalancerRequestEvent) object;
- return new EventPart(event.getBody());
- } else if (object instanceof CloudWatchLogsEvent) {
- CloudWatchLogsEvent event = (CloudWatchLogsEvent) object;
- return new EventPart(decompress(decode(event.getAwsLogs().getData().getBytes(UTF_8))));
- } else if (object instanceof CloudFormationCustomResourceEvent) {
- CloudFormationCustomResourceEvent event = (CloudFormationCustomResourceEvent) object;
- return new EventPart(event.getResourceProperties());
- } else if (object instanceof KinesisEvent) {
- KinesisEvent event = (KinesisEvent) object;
- return new EventPart(event.getRecords().stream()
- .map(r -> decode(r.getKinesis().getData()))
- .collect(Collectors.toList()));
- } else if (object instanceof KinesisFirehoseEvent) {
- KinesisFirehoseEvent event = (KinesisFirehoseEvent) object;
- return new EventPart(event.getRecords().stream()
- .map(r -> decode(r.getData()))
- .collect(Collectors.toList()));
- } else if (object instanceof KafkaEvent) {
- KafkaEvent event = (KafkaEvent) object;
- return new EventPart(event.getRecords().values().stream()
- .flatMap(List::stream)
- .map(r -> decode(r.getValue()))
- .collect(Collectors.toList()));
- } else if (object instanceof ActiveMQEvent) {
- ActiveMQEvent event = (ActiveMQEvent) object;
- return new EventPart(event.getMessages().stream()
- .map(m -> decode(m.getData()))
- .collect(Collectors.toList()));
- } else if (object instanceof RabbitMQEvent) {
- RabbitMQEvent event = (RabbitMQEvent) object;
- return new EventPart(event.getRmqMessagesByQueue().values().stream()
- .flatMap(List::stream)
- .map(r -> decode(r.getData()))
- .collect(Collectors.toList()));
- } else if (object instanceof KinesisAnalyticsFirehoseInputPreprocessingEvent) {
- KinesisAnalyticsFirehoseInputPreprocessingEvent event = (KinesisAnalyticsFirehoseInputPreprocessingEvent) object;
- return new EventPart(event.getRecords().stream()
- .map(r -> decode(r.getData()))
- .collect(Collectors.toList()));
- } else if (object instanceof KinesisAnalyticsStreamsInputPreprocessingEvent) {
- KinesisAnalyticsStreamsInputPreprocessingEvent event = (KinesisAnalyticsStreamsInputPreprocessingEvent) object;
- return new EventPart(event.getRecords().stream()
- .map(r -> decode(r.getData()))
- .collect(Collectors.toList()));
- } else {
- // does not really make sense to use this EventDeserializer when you already have a typed object
- // just not to throw an exception
- LOG.warn("Consider using your object directly instead of using EventDeserializer");
- return new EventPart(object);
- }
+ public static EventPart extractDataFrom(Object event) {
+ EventPartResolverFactory factory = new EventPartResolverFactory();
+ EventPartResolver generator = factory.resolveEventType(event);
+ return generator.createEventPart(event);
}
/**
@@ -149,19 +60,19 @@ public static class EventPart {
private List contentList;
private Object contentObject;
- private EventPart(List contentList) {
+ public EventPart(List contentList) {
this.contentList = contentList;
}
- private EventPart(String content) {
+ public EventPart(String content) {
this.content = content;
}
- private EventPart(Map contentMap) {
+ public EventPart(Map contentMap) {
this.contentMap = contentMap;
}
- private EventPart(Object content) {
+ public EventPart(Object content) {
this.contentObject = content;
}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/factory/EventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/factory/EventPartResolver.java
new file mode 100644
index 000000000..1499dc219
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/factory/EventPartResolver.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.factory;
+
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+
+/**
+ * Interface implemented by the event resolvers.
+ * Different type of event resolvers can implement it to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ */
+public interface EventPartResolver {
+
+ /**
+ * Extract the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart} from the {@param event}
+ *
+ * @param event the event of the Lambda function handler method
+ * @return the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart} which contains the event data (e.g. body)
+ */
+ EventDeserializer.EventPart createEventPart(Object event);
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/factory/EventPartResolverFactory.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/factory/EventPartResolverFactory.java
new file mode 100644
index 000000000..e818be725
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/factory/EventPartResolverFactory.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.factory;
+
+import com.amazonaws.services.lambda.runtime.events.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import software.amazon.lambda.powertools.utilities.eventpart.resolvers.*;
+
+import java.util.Map;
+
+/**
+ * Factory Class that identifies the event type and invokes the appropriate implementation of an {@link EventPartResolver}
+ *
+ * Main events are built-in:
+ *
+ *
{@link APIGatewayProxyRequestEventPartResolver} -> body
+ *
{@link APIGatewayV2HTTPEvent} -> body
+ *
{@link SNSEvent} -> Records[0].Sns.Message
+ *
{@link SQSEvent} -> Records[*].body (list)
+ *
{@link ScheduledEvent} -> detail
+ *
{@link ApplicationLoadBalancerRequestEvent} -> body
+ */
+public class EventPartResolverFactory {
+
+ private static final Logger LOG = LoggerFactory.getLogger(EventPartResolverFactory.class);
+
+ public EventPartResolver resolveEventType(Object eventType) {
+
+ if (eventType instanceof APIGatewayProxyRequestEvent) {
+ return new APIGatewayProxyRequestEventPartResolver();
+ } else if (eventType instanceof String) {
+ return new StringEventPartResolver();
+ } else if (eventType instanceof Map) {
+ return new MapEventPartResolver();
+ } else if (eventType instanceof APIGatewayV2HTTPEvent) {
+ return new APIGatewayV2HTTPEventPartResolver();
+ } else if (eventType instanceof SNSEvent) {
+ return new SNSEventPartResolver();
+ } else if (eventType instanceof SQSEvent) {
+ return new SQSEventPartResolver();
+ } else if (eventType instanceof ScheduledEvent) {
+ return new ScheduledEventPartResolver();
+ } else if (eventType instanceof ApplicationLoadBalancerRequestEvent) {
+ return new ApplicationLoadBalancerRequestEventPartResolver();
+ } else if (eventType instanceof CloudWatchLogsEvent) {
+ return new CloudWatchLogsEventPartResolver();
+ } else if (eventType instanceof CloudFormationCustomResourceEvent) {
+ return new CloudFormationCustomResourceEventPartResolver();
+ } else if (eventType instanceof KinesisEvent) {
+ return new KinesisEventPartResolver();
+ } else if (eventType instanceof KinesisFirehoseEvent) {
+ return new KinesisFirehoseEventPartResolver();
+ } else if (eventType instanceof KafkaEvent) {
+ return new KafkaEventPartResolver();
+ } else if (eventType instanceof ActiveMQEvent) {
+ return new ActiveMQEventPartResolver();
+ } else if (eventType instanceof RabbitMQEvent) {
+ return new RabbitMQEventPartResolver();
+ } else if (eventType instanceof KinesisAnalyticsFirehoseInputPreprocessingEvent) {
+ return new KinesisAnalyticsFirehoseInputPreprocessingEventPartResolver();
+ } else if (eventType instanceof KinesisAnalyticsStreamsInputPreprocessingEvent) {
+ return new KinesisAnalyticsStreamsInputPreprocessingEventPartResolver();
+ } else {
+ // does not really make sense to use this EventDeserializer when you already have a typed object
+ // this is used to avoid throwing an exception
+ LOG.warn("Consider using your object directly instead of using EventDeserializer");
+ return new GenericEventPartResolver();
+ }
+ }
+
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/APIGatewayProxyRequestEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/APIGatewayProxyRequestEventPartResolver.java
new file mode 100644
index 000000000..6f172fb12
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/APIGatewayProxyRequestEventPartResolver.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link APIGatewayProxyRequestEvent}
+ */
+public class APIGatewayProxyRequestEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ APIGatewayProxyRequestEvent apiGatewayProxyRequestEvent = (APIGatewayProxyRequestEvent) event;
+ return new EventDeserializer.EventPart((apiGatewayProxyRequestEvent).getBody());
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/APIGatewayV2HTTPEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/APIGatewayV2HTTPEventPartResolver.java
new file mode 100644
index 000000000..5538669ee
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/APIGatewayV2HTTPEventPartResolver.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link APIGatewayV2HTTPEvent}
+ */
+public class APIGatewayV2HTTPEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ APIGatewayV2HTTPEvent apiGatewayV2HTTPEvent = (APIGatewayV2HTTPEvent) event;
+ return new EventDeserializer.EventPart(apiGatewayV2HTTPEvent.getBody());
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/ActiveMQEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/ActiveMQEventPartResolver.java
new file mode 100644
index 000000000..ec75b1602
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/ActiveMQEventPartResolver.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.ActiveMQEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+import java.util.stream.Collectors;
+
+import static software.amazon.lambda.powertools.utilities.jmespath.Base64Function.decode;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link ActiveMQEvent}
+ */
+public class ActiveMQEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ ActiveMQEvent activeMQevent = (ActiveMQEvent) event;
+ return new EventDeserializer.EventPart(activeMQevent.getMessages().stream()
+ .map(m -> decode(m.getData()))
+ .collect(Collectors.toList()));
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/ApplicationLoadBalancerRequestEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/ApplicationLoadBalancerRequestEventPartResolver.java
new file mode 100644
index 000000000..6dc84da69
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/ApplicationLoadBalancerRequestEventPartResolver.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.ApplicationLoadBalancerRequestEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link ApplicationLoadBalancerRequestEvent}
+ */
+public class ApplicationLoadBalancerRequestEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ ApplicationLoadBalancerRequestEvent appLBEvent = (ApplicationLoadBalancerRequestEvent) event;
+ return new EventDeserializer.EventPart(appLBEvent.getBody());
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/CloudFormationCustomResourceEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/CloudFormationCustomResourceEventPartResolver.java
new file mode 100644
index 000000000..dbb5cd885
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/CloudFormationCustomResourceEventPartResolver.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.CloudFormationCustomResourceEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link CloudFormationCustomResourceEvent}
+ */
+public class CloudFormationCustomResourceEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ CloudFormationCustomResourceEvent cfcrEvent = (CloudFormationCustomResourceEvent) event;
+ return new EventDeserializer.EventPart(cfcrEvent.getResourceProperties());
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/CloudWatchLogsEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/CloudWatchLogsEventPartResolver.java
new file mode 100644
index 000000000..8aa3557ae
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/CloudWatchLogsEventPartResolver.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.CloudWatchLogsEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static software.amazon.lambda.powertools.utilities.jmespath.Base64Function.decode;
+import static software.amazon.lambda.powertools.utilities.jmespath.Base64GZipFunction.decompress;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link CloudWatchLogsEvent}
+ */
+public class CloudWatchLogsEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ CloudWatchLogsEvent cwlEvent = (CloudWatchLogsEvent) event;
+ return new EventDeserializer.EventPart(decompress(decode(cwlEvent.getAwsLogs().getData().getBytes(UTF_8))));
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/GenericEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/GenericEventPartResolver.java
new file mode 100644
index 000000000..62e271e56
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/GenericEventPartResolver.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for unknown event types.
+ */
+public class GenericEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ return new EventDeserializer.EventPart(event);
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KafkaEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KafkaEventPartResolver.java
new file mode 100644
index 000000000..aa4d6d07d
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KafkaEventPartResolver.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.KafkaEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static software.amazon.lambda.powertools.utilities.jmespath.Base64Function.decode;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link KafkaEvent}
+ */
+public class KafkaEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ KafkaEvent kafkaEvent = (KafkaEvent) event;
+ return new EventDeserializer.EventPart(kafkaEvent.getRecords().values().stream()
+ .flatMap(List::stream)
+ .map(r -> decode(r.getValue()))
+ .collect(Collectors.toList()));
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KinesisAnalyticsFirehoseInputPreprocessingEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KinesisAnalyticsFirehoseInputPreprocessingEventPartResolver.java
new file mode 100644
index 000000000..266c554b2
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KinesisAnalyticsFirehoseInputPreprocessingEventPartResolver.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.KinesisAnalyticsFirehoseInputPreprocessingEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+import java.util.stream.Collectors;
+
+import static software.amazon.lambda.powertools.utilities.jmespath.Base64Function.decode;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link KinesisAnalyticsFirehoseInputPreprocessingEvent}
+ */
+public class KinesisAnalyticsFirehoseInputPreprocessingEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ KinesisAnalyticsFirehoseInputPreprocessingEvent kafipEvent = (KinesisAnalyticsFirehoseInputPreprocessingEvent) event;
+ return new EventDeserializer.EventPart(kafipEvent.getRecords().stream()
+ .map(r -> decode(r.getData()))
+ .collect(Collectors.toList()));
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KinesisAnalyticsStreamsInputPreprocessingEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KinesisAnalyticsStreamsInputPreprocessingEventPartResolver.java
new file mode 100644
index 000000000..83a483813
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KinesisAnalyticsStreamsInputPreprocessingEventPartResolver.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.KinesisAnalyticsStreamsInputPreprocessingEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+import java.util.stream.Collectors;
+
+import static software.amazon.lambda.powertools.utilities.jmespath.Base64Function.decode;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link KinesisAnalyticsStreamsInputPreprocessingEvent}
+ */
+public class KinesisAnalyticsStreamsInputPreprocessingEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ KinesisAnalyticsStreamsInputPreprocessingEvent kasipEvent = (KinesisAnalyticsStreamsInputPreprocessingEvent) event;
+ return new EventDeserializer.EventPart(kasipEvent.getRecords().stream()
+ .map(r -> decode(r.getData()))
+ .collect(Collectors.toList()));
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KinesisEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KinesisEventPartResolver.java
new file mode 100644
index 000000000..c702ac34f
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KinesisEventPartResolver.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+import java.util.stream.Collectors;
+
+import static software.amazon.lambda.powertools.utilities.jmespath.Base64Function.decode;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link KinesisEvent}
+ */
+public class KinesisEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ KinesisEvent kinesisEvent = (KinesisEvent) event;
+ return new EventDeserializer.EventPart(kinesisEvent.getRecords().stream()
+ .map(r -> decode(r.getKinesis().getData()))
+ .collect(Collectors.toList()));
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KinesisFirehoseEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KinesisFirehoseEventPartResolver.java
new file mode 100644
index 000000000..5c93a8c5c
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/KinesisFirehoseEventPartResolver.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.KinesisFirehoseEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+import java.util.stream.Collectors;
+
+import static software.amazon.lambda.powertools.utilities.jmespath.Base64Function.decode;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link KinesisFirehoseEvent}
+ */
+public class KinesisFirehoseEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ KinesisFirehoseEvent kfEvent = (KinesisFirehoseEvent) event;
+ return new EventDeserializer.EventPart(kfEvent.getRecords().stream()
+ .map(r -> decode(r.getData()))
+ .collect(Collectors.toList()));
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/MapEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/MapEventPartResolver.java
new file mode 100644
index 000000000..4e24bee90
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/MapEventPartResolver.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+import java.util.Map;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link Map}
+ */
+public class MapEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ return new EventDeserializer.EventPart((Map) event);
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/RabbitMQEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/RabbitMQEventPartResolver.java
new file mode 100644
index 000000000..619403298
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/RabbitMQEventPartResolver.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.RabbitMQEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static software.amazon.lambda.powertools.utilities.jmespath.Base64Function.decode;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link RabbitMQEvent}
+ */
+public class RabbitMQEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ RabbitMQEvent rmqEvent = (RabbitMQEvent) event;
+ return new EventDeserializer.EventPart(rmqEvent.getRmqMessagesByQueue().values().stream()
+ .flatMap(List::stream)
+ .map(r -> decode(r.getData()))
+ .collect(Collectors.toList()));
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/SNSEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/SNSEventPartResolver.java
new file mode 100644
index 000000000..675ee41ce
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/SNSEventPartResolver.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.SNSEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link SNSEvent}
+ */
+public class SNSEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object object) {
+ SNSEvent event = (SNSEvent) object;
+ return new EventDeserializer.EventPart(event.getRecords().get(0).getSNS().getMessage());
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/SQSEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/SQSEventPartResolver.java
new file mode 100644
index 000000000..93e8616e8
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/SQSEventPartResolver.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.SQSEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+import java.util.stream.Collectors;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link SQSEvent}
+ */
+public class SQSEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ SQSEvent sqsEvent = (SQSEvent) event;
+ return new EventDeserializer.EventPart(sqsEvent.getRecords().stream()
+ .map(SQSEvent.SQSMessage::getBody)
+ .collect(Collectors.toList()));
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/ScheduledEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/ScheduledEventPartResolver.java
new file mode 100644
index 000000000..4648c65e7
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/ScheduledEventPartResolver.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import com.amazonaws.services.lambda.runtime.events.ScheduledEvent;
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link ScheduledEvent}
+ */
+public class ScheduledEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ ScheduledEvent scheduledEvent = (ScheduledEvent) event;
+ return new EventDeserializer.EventPart(scheduledEvent.getDetail());
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/StringEventPartResolver.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/StringEventPartResolver.java
new file mode 100644
index 000000000..f44b822aa
--- /dev/null
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/eventpart/resolvers/StringEventPartResolver.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2023 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package software.amazon.lambda.powertools.utilities.eventpart.resolvers;
+
+import software.amazon.lambda.powertools.utilities.EventDeserializer;
+import software.amazon.lambda.powertools.utilities.eventpart.factory.EventPartResolver;
+
+/**
+ * Implements the {@link EventPartResolver} to retrieve the {@link software.amazon.lambda.powertools.utilities.EventDeserializer.EventPart}
+ * for events of type {@link String}
+ */
+public class StringEventPartResolver implements EventPartResolver {
+ @Override
+ public EventDeserializer.EventPart createEventPart(Object event) {
+ return new EventDeserializer.EventPart((String) event);
+ }
+}
diff --git a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/jmespath/Base64GZipFunction.java b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/jmespath/Base64GZipFunction.java
index 6b097af62..e97c03989 100644
--- a/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/jmespath/Base64GZipFunction.java
+++ b/powertools-serialization/src/main/java/software/amazon/lambda/powertools/utilities/jmespath/Base64GZipFunction.java
@@ -50,21 +50,21 @@ protected T callFunction(Adapter runtime, List> argum
}
public static String decompress(byte[] compressed) {
- if ((compressed == null) || (compressed.length == 0)) {
+ if (compressed.length == 0) {
return "";
}
+ if (!isCompressed(compressed)) {
+ new String(compressed, UTF_8);
+ }
try {
StringBuilder out = new StringBuilder();
- if (isCompressed(compressed)) {
- GZIPInputStream gzipStream = new GZIPInputStream(new ByteArrayInputStream(compressed));
- BufferedReader bf = new BufferedReader(new InputStreamReader(gzipStream, UTF_8));
- String line;
- while ((line = bf.readLine()) != null) {
- out.append(line);
- }
- } else {
- out.append(Arrays.toString(compressed));
+ GZIPInputStream gzipStream = new GZIPInputStream(new ByteArrayInputStream(compressed));
+ BufferedReader bf = new BufferedReader(new InputStreamReader(gzipStream, UTF_8));
+
+ String line;
+ while ((line = bf.readLine()) != null) {
+ out.append(line);
}
return out.toString();
} catch (IOException e) {
diff --git a/powertools-serialization/src/test/java/software/amazon/lambda/powertools/utilities/EventDeserializerTest.java b/powertools-serialization/src/test/java/software/amazon/lambda/powertools/utilities/EventDeserializerTest.java
index 90143b2a0..2660c1f77 100644
--- a/powertools-serialization/src/test/java/software/amazon/lambda/powertools/utilities/EventDeserializerTest.java
+++ b/powertools-serialization/src/test/java/software/amazon/lambda/powertools/utilities/EventDeserializerTest.java
@@ -129,7 +129,23 @@ public void testDeserializeSQSEventMessageAsObject_shouldThrowException(SQSEvent
public void testDeserializeAPIGatewayEventAsList_shouldThrowException(APIGatewayProxyRequestEvent event) {
assertThatThrownBy(() -> extractDataFrom(event).asListOf(Product.class))
.isInstanceOf(EventDeserializationException.class)
- .hasMessageContaining("consider using 'as' instead");
+ .hasMessageContaining("consider using 'as' instead")
+ .hasMessageContaining("Cannot load the event as a list of");
+ }
+
+ @ParameterizedTest
+ @Event(value = "apigw_event.json", type = HashMap.class)
+ public void testDeserializeAPIGatewayMapEventAsList_shouldThrowException(Map event) {
+ assertThatThrownBy(() -> extractDataFrom(event).asListOf(Product.class))
+ .isInstanceOf(EventDeserializationException.class)
+ .hasMessage("The content of this event is not a list, consider using 'as' instead");
+ }
+
+ @Test
+ public void testDeserializeEmptyEventAsList_shouldThrowException() {
+ assertThatThrownBy(() -> extractDataFrom(null).asListOf(Product.class))
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessage("Event content is null: the event may be malformed (missing fields)");
}
@ParameterizedTest
@@ -145,7 +161,14 @@ public void testDeserializeSQSEventBodyAsWrongObjectType_shouldThrowException(SQ
public void testDeserializeAPIGatewayNoBody_shouldThrowException(APIGatewayProxyRequestEvent event) {
assertThatThrownBy(() -> extractDataFrom(event).as(Product.class))
.isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("Event content is null");
+ .hasMessage("Event content is null: the event may be malformed (missing fields)");
+ }
+
+ @Test
+ public void testDeserializeAPIGatewayNoBodyAsList_shouldThrowException() {
+ assertThatThrownBy(() -> extractDataFrom(new Object()).asListOf(Product.class))
+ .isInstanceOf(EventDeserializationException.class)
+ .hasMessage("The content of this event is not a list, consider using 'as' instead");
}
@ParameterizedTest
@@ -164,9 +187,83 @@ public void testDeserializeProductAsProduct_shouldReturnProduct() {
private void assertProduct(Product product) {
-assertThat(product)
+ assertThat(product)
.isEqualTo(new Product(1234, "product", 42))
.usingRecursiveComparison();
}
+ @ParameterizedTest
+ @Event(value = "scheduled_event.json", type = ScheduledEvent.class)
+ public void testDeserializeScheduledEventMessageAsObject_shouldReturnObject(ScheduledEvent event) {
+ Product product = extractDataFrom(event).as(Product.class);
+ assertProduct(product);
+ }
+ @ParameterizedTest
+ @Event(value = "alb_event.json", type = ApplicationLoadBalancerRequestEvent.class)
+ public void testDeserializeALBEventMessageAsObjectShouldReturnObject(ApplicationLoadBalancerRequestEvent event) {
+ Product product = extractDataFrom(event).as(Product.class);
+ assertProduct(product);
+ }
+
+ @ParameterizedTest
+ @Event(value = "cwl_event.json", type = CloudWatchLogsEvent.class)
+ public void testDeserializeCWLEventMessageAsObjectShouldReturnObject(CloudWatchLogsEvent event) {
+ Product product = extractDataFrom(event).as(Product.class);
+ assertProduct(product);
+ }
+
+ @ParameterizedTest
+ @Event(value = "kf_event.json", type = KinesisFirehoseEvent.class)
+ public void testDeserializeKFEventMessageAsListShouldReturnList(KinesisFirehoseEvent event) {
+ List products = extractDataFrom(event).asListOf(Product.class);
+ assertThat(products).hasSize(1);
+ assertProduct(products.get(0));
+ }
+
+ @ParameterizedTest
+ @Event(value = "amq_event.json", type = ActiveMQEvent.class)
+ public void testDeserializeAMQEventMessageAsListShouldReturnList(ActiveMQEvent event) {
+ List products = extractDataFrom(event).asListOf(Product.class);
+ assertThat(products).hasSize(1);
+ assertProduct(products.get(0));
+ }
+
+ @ParameterizedTest
+ @Event(value = "rabbitmq_event.json", type = RabbitMQEvent.class)
+ public void testDeserializeRabbitMQEventMessageAsListShouldReturnList(RabbitMQEvent event) {
+ List products = extractDataFrom(event).asListOf(Product.class);
+ assertThat(products).hasSize(1);
+ assertProduct(products.get(0));
+ }
+
+ @ParameterizedTest
+ @Event(value = "kasip_event.json", type = KinesisAnalyticsStreamsInputPreprocessingEvent.class)
+ public void testDeserializeKasipEventMessageAsListShouldReturnList(KinesisAnalyticsStreamsInputPreprocessingEvent event) {
+ List products = extractDataFrom(event).asListOf(Product.class);
+ assertThat(products).hasSize(1);
+ assertProduct(products.get(0));
+ }
+
+ @ParameterizedTest
+ @Event(value = "kafip_event.json", type = KinesisAnalyticsFirehoseInputPreprocessingEvent.class)
+ public void testDeserializeKafipEventMessageAsListShouldReturnList(KinesisAnalyticsFirehoseInputPreprocessingEvent event) {
+ List products = extractDataFrom(event).asListOf(Product.class);
+ assertThat(products).hasSize(1);
+ assertProduct(products.get(0));
+ }
+
+ @ParameterizedTest
+ @Event(value = "apigwv2_event.json", type = APIGatewayV2HTTPEvent.class)
+ public void testDeserializeApiGWV2EventMessageAsObjectShouldReturnObject(APIGatewayV2HTTPEvent event) {
+ Product product = extractDataFrom(event).as(Product.class);
+ assertProduct(product);
+ }
+
+ @ParameterizedTest
+ @Event(value = "cfcr_event.json", type = CloudFormationCustomResourceEvent.class)
+ public void testDeserializeCfcrEventMessageAsObjectShouldReturnObject(CloudFormationCustomResourceEvent event) {
+ Product product = extractDataFrom(event).as(Product.class);
+ assertProduct(product);
+ }
+
}
diff --git a/powertools-serialization/src/test/java/software/amazon/lambda/powertools/utilities/jmespath/Base64GZipFunctionTest.java b/powertools-serialization/src/test/java/software/amazon/lambda/powertools/utilities/jmespath/Base64GZipFunctionTest.java
index 8c617a634..0dbbd57b9 100644
--- a/powertools-serialization/src/test/java/software/amazon/lambda/powertools/utilities/jmespath/Base64GZipFunctionTest.java
+++ b/powertools-serialization/src/test/java/software/amazon/lambda/powertools/utilities/jmespath/Base64GZipFunctionTest.java
@@ -16,15 +16,28 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import io.burt.jmespath.Expression;
+import io.burt.jmespath.JmesPathType;
+import io.burt.jmespath.function.ArgumentConstraints;
import org.junit.jupiter.api.Test;
import software.amazon.lambda.powertools.utilities.JsonConfig;
import java.io.IOException;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
public class Base64GZipFunctionTest {
+ @Test
+ public void testConstructor() {
+ Base64GZipFunction base64GZipFunction = new Base64GZipFunction();
+ assertEquals(base64GZipFunction.name(), "powertools_base64_gzip");
+ assertEquals(base64GZipFunction.argumentConstraints().expectedType().toLowerCase(), JmesPathType.STRING.name().toLowerCase());
+ assertEquals(base64GZipFunction.argumentConstraints().minArity(), 1);
+ assertEquals(base64GZipFunction.argumentConstraints().minArity(), 1);
+
+ }
+
@Test
public void testPowertoolsGzip() throws IOException {
JsonNode event = JsonConfig.get().getObjectMapper().readTree(this.getClass().getResourceAsStream("/custom_event_gzip.json"));
@@ -33,4 +46,24 @@ public void testPowertoolsGzip() throws IOException {
assertThat(result.getNodeType()).isEqualTo(JsonNodeType.STRING);
assertThat(result.asText()).isEqualTo("{ \"id\": 43242, \"name\": \"FooBar XY\", \"price\": 258}");
}
+
+ @Test
+ public void testPowertoolsGdzipEmptyJsonAttribute() throws IOException {
+ JsonNode event = JsonConfig.get().getObjectMapper().readTree(this.getClass().getResourceAsStream("/custom_event_gzip.json"));
+ Expression expression = JsonConfig.get().getJmesPath().compile("basket.powertools_base64_gzip('')");
+ JsonNode result = expression.search(event);
+ assertThat(result.getNodeType()).isEqualTo(JsonNodeType.STRING);
+ assertThat(result.asText()).isEqualTo("");
+ }
+
+ @Test
+ public void testPowertoolsGdzipNotCompressedJsonAttribute() throws IOException {
+ JsonNode event = JsonConfig.get().getObjectMapper().readTree(this.getClass().getResourceAsStream("/custom_event_gzip.json"));
+ Expression expression = JsonConfig.get().getJmesPath().compile("basket.powertools_base64_gzip(encodedString)");
+ JsonNode result = expression.search(event);
+ assertThat(result.getNodeType()).isEqualTo(JsonNodeType.STRING);
+ assertThat(result.asText()).isEqualTo("test");
+ }
+
+
}
diff --git a/powertools-serialization/src/test/resources/alb_event.json b/powertools-serialization/src/test/resources/alb_event.json
new file mode 100644
index 000000000..d2b0d3cda
--- /dev/null
+++ b/powertools-serialization/src/test/resources/alb_event.json
@@ -0,0 +1,28 @@
+{
+ "requestContext": {
+ "elb": {
+ "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a"
+ }
+ },
+ "httpMethod": "GET",
+ "path": "/lambda",
+ "queryStringParameters": {
+ "query": "1234ABCD"
+ },
+ "headers": {
+ "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
+ "accept-encoding": "gzip",
+ "accept-language": "en-US,en;q=0.9",
+ "connection": "keep-alive",
+ "host": "lambda-alb-123578498.us-east-1.elb.amazonaws.com",
+ "upgrade-insecure-requests": "1",
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
+ "x-amzn-trace-id": "Root=1-5c536348-3d683b8b04734faae651f476",
+ "x-forwarded-for": "72.12.164.125",
+ "x-forwarded-port": "80",
+ "x-forwarded-proto": "http",
+ "x-imforwards": "20"
+ },
+ "body": "{\"id\":1234, \"name\":\"product\", \"price\":42}",
+ "isBase64Encoded": false
+}
\ No newline at end of file
diff --git a/powertools-serialization/src/test/resources/amq_event.json b/powertools-serialization/src/test/resources/amq_event.json
new file mode 100644
index 000000000..2b27ab4bf
--- /dev/null
+++ b/powertools-serialization/src/test/resources/amq_event.json
@@ -0,0 +1,29 @@
+{
+ "eventSource": "aws:mq",
+ "eventSourceArn": "arn:aws:mq:us-west-2:111122223333:broker:test:b-9bcfa592-423a-4942-879d-eb284b418fc8",
+ "messages": [
+ {
+ "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1.mq.us-west-2.amazonaws.com-37557-1234520418293-4:1:1:1:1",
+ "messageType": "jms/text-message",
+ "deliveryMode": 1,
+ "replyTo": null,
+ "type": null,
+ "expiration": "60000",
+ "priority": 1,
+ "correlationId": "myJMSCoID",
+ "redelivered": false,
+ "destination": {
+ "physicalName": "testQueue"
+ },
+ "data":"ewogICJpZCI6IDEyMzQsCiAgIm5hbWUiOiAicHJvZHVjdCIsCiAgInByaWNlIjogNDIKfQ==",
+ "timestamp": 1598827811958,
+ "brokerInTime": 1598827811958,
+ "brokerOutTime": 1598827811959,
+ "properties": {
+ "index": "1",
+ "doAlarm": "false",
+ "myCustomProperty": "value"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/powertools-serialization/src/test/resources/apigwv2_event.json b/powertools-serialization/src/test/resources/apigwv2_event.json
new file mode 100644
index 000000000..db4fc0f95
--- /dev/null
+++ b/powertools-serialization/src/test/resources/apigwv2_event.json
@@ -0,0 +1,57 @@
+{
+ "version": "V2",
+ "routeKey": "routeKey",
+ "rawPath": "rawPath",
+ "rawQueryString": "rawQueryString",
+ "cookies":
+ ["foo", "bar"]
+ ,
+ "headers": {
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
+ "Accept-Encoding": "gzip, deflate, sdch",
+ "Accept-Language": "en-US,en;q=0.8",
+ "Cache-Control": "max-age=0",
+ "CloudFront-Forwarded-Proto": "https",
+ "CloudFront-Is-Desktop-Viewer": "true",
+ "CloudFront-Is-Mobile-Viewer": "false",
+ "CloudFront-Is-SmartTV-Viewer": "false",
+ "CloudFront-Is-Tablet-Viewer": "false",
+ "CloudFront-Viewer-Country": "US",
+ "Host": "1234567890.execute-api.us-east-1.amazonaws.com",
+ "Upgrade-Insecure-Requests": "1",
+ "User-Agent": "Custom User Agent String",
+ "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
+ "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
+ "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
+ "X-Forwarded-Port": "443",
+ "X-Forwarded-Proto": "https"
+ },
+ "queryStringParameters": {
+ "foo": "bar"
+ },
+ "pathParameters": {
+ "proxy": "/path/to/resource"
+ },
+ "stageVariables": {
+ "baz": "qux"
+ },
+ "body": "{\"id\":1234, \"name\":\"product\", \"price\":42}",
+ "isBase64Encoded": false,
+ "requestContext": {
+ "routeKey": "routeKey",
+ "accountId": "123456789012",
+ "stage": "prod",
+ "apiId": "1234567890",
+ "domainName": "domainName",
+ "domainPrefix": "domainPrefix",
+ "time": "09/Apr/2015:12:34:56 +0000",
+ "timeEpoch": 1428582896000,
+ "http": {
+ "method": "POST",
+ "path": "/path/to/resource",
+ "protocol": "HTTP/1.1",
+ "sourceIp": "1.1.1.1",
+ "userAgent": "Chrome"
+ }
+ }
+}
diff --git a/powertools-serialization/src/test/resources/cfcr_event.json b/powertools-serialization/src/test/resources/cfcr_event.json
new file mode 100644
index 000000000..d754cec2c
--- /dev/null
+++ b/powertools-serialization/src/test/resources/cfcr_event.json
@@ -0,0 +1,20 @@
+{
+ "RequestType": "requestType",
+ "ServiceToken": "serviceToken",
+ "ResponseUrl": "responseUrl",
+ "StackId": "stackId",
+ "RequestId": "requestId",
+ "LogicalResourceId": "logicalResourceId",
+ "ResourceType": "resourceType",
+ "ResourceProperties": {
+ "id":1234,
+ "name": "product",
+ "price": 42
+ },
+ "OldResourceProperties": {
+ "id":1234,
+ "name": "product",
+ "price": 40
+ }
+}
+
diff --git a/powertools-serialization/src/test/resources/custom_event_gzip.json b/powertools-serialization/src/test/resources/custom_event_gzip.json
index d212052d0..75c873510 100644
--- a/powertools-serialization/src/test/resources/custom_event_gzip.json
+++ b/powertools-serialization/src/test/resources/custom_event_gzip.json
@@ -7,6 +7,7 @@
"price": 258
}
],
- "hiddenProduct": "H4sIAAAAAAAA/6vmUlBQykxRslIwMTYyMdIBcfMSc1OBAkpu+flOiUUKEZFKYOGCosxkkLiRqQVXLQDnWo6bOAAAAA=="
+ "hiddenProduct": "H4sIAAAAAAAA/6vmUlBQykxRslIwMTYyMdIBcfMSc1OBAkpu+flOiUUKEZFKYOGCosxkkLiRqQVXLQDnWo6bOAAAAA==",
+ "encodedString": "dGVzdA=="
}
}
\ No newline at end of file
diff --git a/powertools-serialization/src/test/resources/cwl_event.json b/powertools-serialization/src/test/resources/cwl_event.json
new file mode 100644
index 000000000..911ab1b3a
--- /dev/null
+++ b/powertools-serialization/src/test/resources/cwl_event.json
@@ -0,0 +1,5 @@
+{
+ "awslogs": {
+ "data": "ewogICJpZCI6IDEyMzQsCiAgIm5hbWUiOiAicHJvZHVjdCIsCiAgInByaWNlIjogNDIKfQ=="
+ }
+}
\ No newline at end of file
diff --git a/powertools-serialization/src/test/resources/kafip_event.json b/powertools-serialization/src/test/resources/kafip_event.json
new file mode 100644
index 000000000..01196256c
--- /dev/null
+++ b/powertools-serialization/src/test/resources/kafip_event.json
@@ -0,0 +1,14 @@
+{
+ "invocationId": "arn:aws:iam::EXAMPLE",
+ "applicationArn": "arn:aws:kinesis:EXAMPLE",
+ "streamArn": "arn:aws:kinesis:EXAMPLE",
+ "records": [
+ {
+ "kinesisFirehoseRecordMetadata": {
+ "approximateArrivalTimestamp": 1428537600
+ },
+ "recordId": "record-id",
+ "data": "eyJpZCI6MTIzNCwgIm5hbWUiOiJwcm9kdWN0IiwgInByaWNlIjo0Mn0="
+ }
+ ]
+}
\ No newline at end of file
diff --git a/powertools-serialization/src/test/resources/kasip_event.json b/powertools-serialization/src/test/resources/kasip_event.json
new file mode 100644
index 000000000..78bc9a3fb
--- /dev/null
+++ b/powertools-serialization/src/test/resources/kasip_event.json
@@ -0,0 +1,17 @@
+{
+ "invocationId": "arn:aws:iam::EXAMPLE",
+ "applicationArn": "arn:aws:kinesis:EXAMPLE",
+ "streamArn": "arn:aws:kinesis:EXAMPLE",
+ "records": [
+ {
+ "kinesisStreamRecordMetadata": {
+ "sequenceNumber": "49545115243490985018280067714973144582180062593244200961",
+ "partitionKey": "partitionKey-03",
+ "shardId": "12",
+ "approximateArrivalTimestamp": 1428537600
+ },
+ "recordId": "record-id",
+ "data": "eyJpZCI6MTIzNCwgIm5hbWUiOiJwcm9kdWN0IiwgInByaWNlIjo0Mn0="
+ }
+ ]
+}
\ No newline at end of file
diff --git a/powertools-serialization/src/test/resources/kf_event.json b/powertools-serialization/src/test/resources/kf_event.json
new file mode 100644
index 000000000..e36bc4c3f
--- /dev/null
+++ b/powertools-serialization/src/test/resources/kf_event.json
@@ -0,0 +1,12 @@
+{
+ "invocationId": "invocationIdExample",
+ "deliveryStreamArn": "arn:aws:kinesis:EXAMPLE",
+ "region": "us-east-1",
+ "records": [
+ {
+ "recordId": "49546986683135544286507457936321625675700192471156785154",
+ "approximateArrivalTimestamp": 1495072949453,
+ "data": "ewogICJpZCI6IDEyMzQsCiAgIm5hbWUiOiAicHJvZHVjdCIsCiAgInByaWNlIjogNDIKfQ=="
+ }
+ ]
+}
\ No newline at end of file
diff --git a/powertools-serialization/src/test/resources/rabbitmq_event.json b/powertools-serialization/src/test/resources/rabbitmq_event.json
new file mode 100644
index 000000000..698e37143
--- /dev/null
+++ b/powertools-serialization/src/test/resources/rabbitmq_event.json
@@ -0,0 +1,51 @@
+{
+ "eventSource": "aws:rmq",
+ "eventSourceArn": "arn:aws:mq:us-west-2:111122223333:broker:pizzaBroker:b-9bcfa592-423a-4942-879d-eb284b418fc8",
+ "rmqMessagesByQueue": {
+ "pizzaQueue::/": [
+ {
+ "basicProperties": {
+ "contentType": "text/plain",
+ "contentEncoding": null,
+ "headers": {
+ "header1": {
+ "bytes": [
+ 118,
+ 97,
+ 108,
+ 117,
+ 101,
+ 49
+ ]
+ },
+ "header2": {
+ "bytes": [
+ 118,
+ 97,
+ 108,
+ 117,
+ 101,
+ 50
+ ]
+ },
+ "numberInHeader": 10
+ },
+ "deliveryMode": 1,
+ "priority": 34,
+ "correlationId": null,
+ "replyTo": null,
+ "expiration": "60000",
+ "messageId": null,
+ "timestamp": "Jan 1, 1970, 12:33:41 AM",
+ "type": null,
+ "userId": "AIDACKCEVSQ6C2EXAMPLE",
+ "appId": null,
+ "clusterId": null,
+ "bodySize": 80
+ },
+ "redelivered": false,
+ "data": "ewogICJpZCI6IDEyMzQsCiAgIm5hbWUiOiAicHJvZHVjdCIsCiAgInByaWNlIjogNDIKfQ=="
+ }
+ ]
+ }
+}
diff --git a/powertools-serialization/src/test/resources/scheduled_event.json b/powertools-serialization/src/test/resources/scheduled_event.json
new file mode 100644
index 000000000..9a65f4bd4
--- /dev/null
+++ b/powertools-serialization/src/test/resources/scheduled_event.json
@@ -0,0 +1,12 @@
+{
+ "id": "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c",
+ "detail-type": "Scheduled Event",
+ "source": "aws.events",
+ "account": "123456789012",
+ "time": "1970-01-01T00:00:00Z",
+ "region": "eu-central-1",
+ "resources": [
+ "arn:aws:events:eu-central-1:123456789012:rule/my-schedule"
+ ],
+ "detail": {"id":1234, "name":"product", "price":42}
+}
\ No newline at end of file
From f207d471472210e86c2b1300de474a2c45834c1c Mon Sep 17 00:00:00 2001
From: Eleni Dimitropoulou <12170229+eldimi@users.noreply.github.com>
Date: Tue, 4 Jul 2023 14:51:54 +0300
Subject: [PATCH 04/14] chore(unit-tests): add unit tests to
powertools-validation
---
powertools-validation/pom.xml | 9 +-
.../validation/ValidationConfig.java | 24 ++---
.../validation/ValidationUtils.java | 30 +++---
.../validation/ValidationUtilsTest.java | 64 ++++++++---
...ndler.java => GenericSchemaV7Handler.java} | 7 +-
.../validation/handlers/KinesisHandler.java | 28 -----
.../ValidationInboundClasspathHandler.java | 29 -----
.../ValidationInboundStringHandler.java | 2 +-
.../ResponseEventsArgumentsProvider.java | 53 +++++++++
.../internal/ValidationAspectTest.java | 101 +++++++++++++++---
.../powertools/validation/model/Basket.java | 6 +-
.../src/test/resources/alb_event.json | 28 +++++
.../src/test/resources/amq_event.json | 28 +++++
.../src/test/resources/cfcr_event.json | 20 ++++
.../src/test/resources/custom_event.json | 2 +-
.../src/test/resources/custom_event_gzip.json | 2 +-
.../src/test/resources/cwl_event.json | 5 +
.../src/test/resources/kafip_event.json | 14 +++
.../src/test/resources/kafka_event.json | 27 +++++
.../src/test/resources/kasip_event.json | 17 +++
.../src/test/resources/kf_event.json | 12 +++
.../src/test/resources/rabbitmq_event.json | 51 +++++++++
.../src/test/resources/scheduled_event.json | 14 +++
.../src/test/resources/schema_v4.json | 6 +-
.../src/test/resources/sns_event.json | 26 +++++
.../src/test/resources/sqs.json | 1 -
.../src/test/resources/sqs_message.json | 1 -
27 files changed, 479 insertions(+), 128 deletions(-)
rename powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/{SQSHandler.java => GenericSchemaV7Handler.java} (82%)
delete mode 100644 powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/KinesisHandler.java
delete mode 100644 powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/ValidationInboundClasspathHandler.java
create mode 100644 powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/internal/ResponseEventsArgumentsProvider.java
create mode 100644 powertools-validation/src/test/resources/alb_event.json
create mode 100644 powertools-validation/src/test/resources/amq_event.json
create mode 100644 powertools-validation/src/test/resources/cfcr_event.json
create mode 100644 powertools-validation/src/test/resources/cwl_event.json
create mode 100644 powertools-validation/src/test/resources/kafip_event.json
create mode 100644 powertools-validation/src/test/resources/kafka_event.json
create mode 100644 powertools-validation/src/test/resources/kasip_event.json
create mode 100644 powertools-validation/src/test/resources/kf_event.json
create mode 100644 powertools-validation/src/test/resources/rabbitmq_event.json
create mode 100644 powertools-validation/src/test/resources/scheduled_event.json
create mode 100644 powertools-validation/src/test/resources/sns_event.json
diff --git a/powertools-validation/pom.xml b/powertools-validation/pom.xml
index 7ab43831e..226b39079 100644
--- a/powertools-validation/pom.xml
+++ b/powertools-validation/pom.xml
@@ -1,6 +1,6 @@
-4.0.0
@@ -112,6 +112,11 @@
assertj-coretest
+
+ org.junit.jupiter
+ junit-jupiter-params
+ test
+
\ No newline at end of file
diff --git a/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationConfig.java b/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationConfig.java
index 3fd964226..c91531601 100644
--- a/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationConfig.java
+++ b/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationConfig.java
@@ -26,24 +26,24 @@
/**
* Use this if you need to customize some part of the JSON Schema validation
* (eg. specification version, Jackson ObjectMapper, or adding functions to JMESPath).
- *
+ *
* For everything but the validation features (factory, schemaVersion), {@link ValidationConfig}
* is just a wrapper of {@link JsonConfig}.
*/
public class ValidationConfig {
- private ValidationConfig() {
- }
+ private SpecVersion.VersionFlag jsonSchemaVersion = SpecVersion.VersionFlag.V7;
+ private JsonSchemaFactory factory = JsonSchemaFactory.getInstance(jsonSchemaVersion);
- private static class ConfigHolder {
- private final static ValidationConfig instance = new ValidationConfig();
+ private ValidationConfig() {
}
public static ValidationConfig get() {
return ConfigHolder.instance;
}
- private SpecVersion.VersionFlag jsonSchemaVersion = SpecVersion.VersionFlag.V7;
- private JsonSchemaFactory factory = JsonSchemaFactory.getInstance(jsonSchemaVersion);
+ public SpecVersion.VersionFlag getSchemaVersion() {
+ return jsonSchemaVersion;
+ }
/**
* Set the version of the json schema specifications (default is V7)
@@ -57,16 +57,12 @@ public void setSchemaVersion(SpecVersion.VersionFlag version) {
}
}
- public SpecVersion.VersionFlag getSchemaVersion() {
- return jsonSchemaVersion;
- }
-
/**
* Add a custom {@link io.burt.jmespath.function.Function} to JMESPath
* {@link Base64Function} and {@link Base64GZipFunction} are already built-in.
*
* @param function the function to add
- * @param Must extends {@link BaseFunction}
+ * @param Must extends {@link BaseFunction}
*/
public void addFunction(T function) {
JsonConfig.get().addFunction(function);
@@ -98,4 +94,8 @@ public JmesPath getJmesPath() {
public ObjectMapper getObjectMapper() {
return JsonConfig.get().getObjectMapper();
}
+
+ private static class ConfigHolder {
+ private final static ValidationConfig instance = new ValidationConfig();
+ }
}
diff --git a/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationUtils.java b/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationUtils.java
index 9b73806a5..3c2322edc 100644
--- a/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationUtils.java
+++ b/powertools-validation/src/main/java/software/amazon/lambda/powertools/validation/ValidationUtils.java
@@ -13,15 +13,6 @@
*/
package software.amazon.lambda.powertools.validation;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
-
import com.amazonaws.services.lambda.runtime.serialization.PojoSerializer;
import com.amazonaws.services.lambda.runtime.serialization.events.LambdaEventSerializers;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -33,6 +24,14 @@
import io.burt.jmespath.Expression;
import software.amazon.lambda.powertools.validation.internal.ValidationAspect;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
/**
* Validation utility, used to manually validate Json against Json Schema
*/
@@ -79,7 +78,7 @@ public static void validate(Object obj, JsonSchema jsonSchema, String envelope)
throw new ValidationException("Envelope not found in the object");
}
} catch (Exception e) {
- throw new ValidationException("Cannot find envelope <"+envelope+"> in the object <"+obj+">", e);
+ throw new ValidationException("Cannot find envelope <" + envelope + "> in the object <" + obj + ">", e);
}
if (subNode.getNodeType() == JsonNodeType.ARRAY) {
subNode.forEach(jsonNode -> validate(jsonNode, jsonSchema));
@@ -120,7 +119,7 @@ public static void validate(Object obj, JsonSchema jsonSchema) throws Validation
try {
jsonNode = ValidationConfig.get().getObjectMapper().valueToTree(obj);
} catch (Exception e) {
- throw new ValidationException("Object <"+obj+"> is not valid against the schema provided", e);
+ throw new ValidationException("Object <" + obj + "> is not valid against the schema provided", e);
}
validate(jsonNode, jsonSchema);
@@ -149,7 +148,7 @@ public static void validate(String json, JsonSchema jsonSchema) throws Validatio
try {
jsonNode = ValidationConfig.get().getObjectMapper().readTree(json);
} catch (Exception e) {
- throw new ValidationException("Json <"+json+"> is not valid against the schema provided", e);
+ throw new ValidationException("Json <" + json + "> is not valid against the schema provided", e);
}
validate(jsonNode, jsonSchema);
@@ -178,7 +177,7 @@ public static void validate(Map map, JsonSchema jsonSchema) thro
try {
jsonNode = ValidationConfig.get().getObjectMapper().valueToTree(map);
} catch (Exception e) {
- throw new ValidationException("Map <"+map+"> cannot be converted to json for validation", e);
+ throw new ValidationException("Map <" + map + "> cannot be converted to json for validation", e);
}
validate(jsonNode, jsonSchema);
@@ -253,12 +252,9 @@ private static JsonSchema createJsonSchema(String schema) {
if (schema.startsWith(CLASSPATH)) {
String filePath = schema.substring(CLASSPATH.length());
try (InputStream schemaStream = ValidationAspect.class.getResourceAsStream(filePath)) {
- if (schemaStream == null) {
- throw new IllegalArgumentException("'" + schema + "' is invalid, verify '" + filePath + "' is in your classpath");
- }
jsonSchema = ValidationConfig.get().getFactory().getSchema(schemaStream);
- } catch (IOException e) {
+ } catch (Exception e) {
throw new IllegalArgumentException("'" + schema + "' is invalid, verify '" + filePath + "' is in your classpath");
}
} else {
diff --git a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java
index d5e9332ed..239498c19 100644
--- a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java
+++ b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/ValidationUtilsTest.java
@@ -19,7 +19,8 @@
public class ValidationUtilsTest {
- private JsonSchema schema = getJsonSchema("classpath:/schema_v7.json");
+ private String schemaString = "classpath:/schema_v7.json";
+ private JsonSchema schema = getJsonSchema(schemaString);
@BeforeEach
public void setup() {
@@ -44,8 +45,11 @@ public void testLoadSchemaV7KO() {
@Test
public void testLoadMetaSchema_NoValidation() {
- ValidationConfig.get().setSchemaVersion(SpecVersion.VersionFlag.V201909);
- getJsonSchema("classpath:/schemas/meta_schema_V201909", false);
+ ValidationConfig.get().setSchemaVersion(SpecVersion.VersionFlag.V7);
+
+ assertThatNoException().isThrownBy(() -> {
+ getJsonSchema("classpath:/schema_v7_ko.json", false);
+ });
}
@Test
@@ -94,7 +98,9 @@ public void testLoadSchemaNotFound() {
public void testValidateJsonNodeOK() throws IOException {
JsonNode node = ValidationConfig.get().getObjectMapper().readTree(this.getClass().getResourceAsStream("/json_ok.json"));
- validate(node, schema);
+ assertThatNoException().isThrownBy(() -> {
+ validate(node, schemaString);
+ });
}
@Test
@@ -106,12 +112,15 @@ public void testValidateJsonNodeKO() throws IOException {
@Test
public void testValidateMapOK() {
+
Map map = new HashMap<>();
map.put("id", 43242);
map.put("name", "FooBar XY");
map.put("price", 258);
- validate(map, schema);
+ assertThatNoException().isThrownBy(() -> {
+ validate(map, schemaString);
+ });
}
@Test
@@ -123,11 +132,21 @@ public void testValidateMapKO() {
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> validate(map, schema));
}
+ @Test
+ public void testValidateMapNotValidJsonObject() {
+ Map map = new HashMap<>();
+ map.put("1234", new Object());
+
+ assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> validate(map, schema));
+ }
+
@Test
public void testValidateStringOK() {
String json = "{\n \"id\": 43242,\n \"name\": \"FooBar XY\",\n \"price\": 258\n}";
- validate(json, schema);
+ assertThatNoException().isThrownBy(() -> {
+ validate(json, schemaString);
+ });
}
@Test
@@ -140,14 +159,22 @@ public void testValidateStringKO() {
@Test
public void testValidateObjectOK() {
Product product = new Product(42, "FooBar", 42);
- validate(product, schema);
+
+ assertThatNoException().isThrownBy(() -> {
+ validate(product, schemaString);
+ });
}
@Test
public void testValidateObjectKO() {
- Product product = new Product(42, "FooBar", -12);
- assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> validate(product, schema));
+ assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> validate(new Object(), schema));
+ }
+
+ @Test
+ public void testValidateObjectNotValidJson() {
+
+ assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> validate(new Object(), schema));
}
@Test
@@ -158,7 +185,10 @@ public void testValidateSubObjectOK() {
basket.add(product);
basket.add(product2);
MyCustomEvent event = new MyCustomEvent(basket);
- validate(event, schema, "basket.products[0]");
+
+ assertThatNoException().isThrownBy(() -> {
+ validate(event, schemaString, "basket.products[0]");
+ });
}
@Test
@@ -182,7 +212,7 @@ public void testValidateSubObjectListOK() {
basket.add(product2);
MyCustomEvent event = new MyCustomEvent(basket);
- validate(event, schema, "basket.products[*]");
+ assertThatNoException().isThrownBy(() -> validate(event, schema, "basket.products[*]"));
}
@Test
@@ -203,7 +233,7 @@ public void testValidateSubObjectNotFound() {
Basket basket = new Basket();
basket.add(product);
MyCustomEvent event = new MyCustomEvent(basket);
- assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> validate(event, schema, "basket.product"));
+ assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> validate(event, schema, "basket."));
}
@Test
@@ -226,7 +256,7 @@ public void testValidateSubObjectJsonString() {
basket.setHiddenProduct("ewogICJpZCI6IDQzMjQyLAogICJuYW1lIjogIkZvb0JhciBYWSIsCiAgInByaWNlIjogMjU4Cn0=");
MyCustomEvent event = new MyCustomEvent(basket);
- validate(event, schema, "basket.powertools_base64(hiddenProduct)");
+ assertThatNoException().isThrownBy(() -> validate(event, schema, "basket.powertools_base64(hiddenProduct)"));
}
@Test
@@ -243,7 +273,13 @@ public void testValidateSubObjectSimpleString() {
@Test
public void testValidateSubObjectWithoutEnvelope() {
Product product = new Product(42, "BarBazFoo", 42);
- validate(product, schema, null);
+ assertThatNoException().isThrownBy(() -> validate(product, schema, null));
+ }
+
+ @Test
+ public void testValidateSubObjectWithEmptyEnvelope() {
+ Product product = new Product(42, "BarBazFoo", 42);
+ assertThatNoException().isThrownBy(() -> validate(product, schema, ""));
}
}
diff --git a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/SQSHandler.java b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/GenericSchemaV7Handler.java
similarity index 82%
rename from powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/SQSHandler.java
rename to powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/GenericSchemaV7Handler.java
index cd6719b0f..1c64e7da1 100644
--- a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/SQSHandler.java
+++ b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/GenericSchemaV7Handler.java
@@ -15,14 +15,13 @@
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import software.amazon.lambda.powertools.validation.Validation;
-public class SQSHandler implements RequestHandler {
+public class GenericSchemaV7Handler implements RequestHandler {
- @Override
@Validation(inboundSchema = "classpath:/schema_v7.json")
- public String handleRequest(SQSEvent input, Context context) {
+ @Override
+ public String handleRequest(T input, Context context) {
return "OK";
}
}
diff --git a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/KinesisHandler.java b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/KinesisHandler.java
deleted file mode 100644
index 7132fcb9b..000000000
--- a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/KinesisHandler.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package software.amazon.lambda.powertools.validation.handlers;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
-import software.amazon.lambda.powertools.validation.Validation;
-
-public class KinesisHandler implements RequestHandler {
-
- @Validation(inboundSchema = "classpath:/schema_v7.json")
- @Override
- public String handleRequest(KinesisEvent input, Context context) {
- return "OK";
- }
-}
diff --git a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/ValidationInboundClasspathHandler.java b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/ValidationInboundClasspathHandler.java
deleted file mode 100644
index 59b6cc7b5..000000000
--- a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/ValidationInboundClasspathHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package software.amazon.lambda.powertools.validation.handlers;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
-import software.amazon.lambda.powertools.validation.Validation;
-
-
-public class ValidationInboundClasspathHandler implements RequestHandler {
-
- @Override
- @Validation(inboundSchema = "classpath:/schema_v7.json")
- public String handleRequest(APIGatewayProxyRequestEvent input, Context context) {
- return "OK";
- }
-}
diff --git a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/ValidationInboundStringHandler.java b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/ValidationInboundStringHandler.java
index e27f31129..2e62ba88d 100644
--- a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/ValidationInboundStringHandler.java
+++ b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/handlers/ValidationInboundStringHandler.java
@@ -76,7 +76,7 @@ public class ValidationInboundStringHandler implements RequestHandler provideArguments(ExtensionContext context) {
+
+ String body = "{id";
+
+ final APIGatewayProxyResponseEvent apiGWProxyResponseEvent = new APIGatewayProxyResponseEvent().withBody(body);
+
+ APIGatewayV2HTTPResponse apiGWV2HTTPResponse = new APIGatewayV2HTTPResponse();
+ apiGWV2HTTPResponse.setBody(body);
+
+ APIGatewayV2WebSocketResponse apiGWV2WebSocketResponse = new APIGatewayV2WebSocketResponse();
+ apiGWV2WebSocketResponse.setBody(body);
+
+ ApplicationLoadBalancerResponseEvent albResponseEvent = new ApplicationLoadBalancerResponseEvent();
+ albResponseEvent.setBody(body);
+
+ KinesisAnalyticsInputPreprocessingResponse kaipResponse = new KinesisAnalyticsInputPreprocessingResponse();
+ List records = new ArrayList();
+ ByteBuffer buffer = ByteBuffer.wrap(body.getBytes(StandardCharsets.UTF_8));
+ records.add(new KinesisAnalyticsInputPreprocessingResponse.Record("1", KinesisAnalyticsInputPreprocessingResponse.Result.Ok, buffer));
+ kaipResponse.setRecords(records);
+
+ return Stream.of(apiGWProxyResponseEvent, apiGWV2HTTPResponse, apiGWV2WebSocketResponse, albResponseEvent, kaipResponse).map(Arguments::of);
+ }
+}
diff --git a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/internal/ValidationAspectTest.java b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/internal/ValidationAspectTest.java
index 2c66885d6..45df137c9 100644
--- a/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/internal/ValidationAspectTest.java
+++ b/powertools-validation/src/test/java/software/amazon/lambda/powertools/validation/internal/ValidationAspectTest.java
@@ -14,39 +14,113 @@
package software.amazon.lambda.powertools.validation.internal;
import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
-import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent;
-import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.amazonaws.services.lambda.runtime.events.*;
import com.amazonaws.services.lambda.runtime.serialization.PojoSerializer;
import com.amazonaws.services.lambda.runtime.serialization.events.LambdaEventSerializers;
+import com.networknt.schema.SpecVersion;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.Signature;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsSource;
+import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import software.amazon.lambda.powertools.validation.Validation;
import software.amazon.lambda.powertools.validation.ValidationConfig;
import software.amazon.lambda.powertools.validation.ValidationException;
-import software.amazon.lambda.powertools.validation.handlers.*;
+import software.amazon.lambda.powertools.validation.handlers.GenericSchemaV7Handler;
+import software.amazon.lambda.powertools.validation.handlers.SQSWithCustomEnvelopeHandler;
+import software.amazon.lambda.powertools.validation.handlers.SQSWithWrongEnvelopeHandler;
+import software.amazon.lambda.powertools.validation.handlers.ValidationInboundStringHandler;
import software.amazon.lambda.powertools.validation.model.MyCustomEvent;
import java.io.IOException;
+import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.mockito.Mockito.when;
+
public class ValidationAspectTest {
+ @Mock
+ Validation validation;
+ @Mock
+ Signature signature;
@Mock
private Context context;
+ @Mock
+ private ProceedingJoinPoint pjp;
+ private ValidationAspect validationAspect = new ValidationAspect();
+
+ private static Stream provideEventAndEventType() {
+ return Stream.of(
+ Arguments.of("/sns_event.json", SNSEvent.class),
+ Arguments.of("/scheduled_event.json", ScheduledEvent.class),
+ Arguments.of("/alb_event.json", ApplicationLoadBalancerRequestEvent.class),
+ Arguments.of("/cwl_event.json", CloudWatchLogsEvent.class),
+ Arguments.of("/cfcr_event.json", CloudFormationCustomResourceEvent.class),
+ Arguments.of("/kf_event.json", KinesisFirehoseEvent.class),
+ Arguments.of("/kafka_event.json", KafkaEvent.class),
+ Arguments.of("/amq_event.json", ActiveMQEvent.class),
+ Arguments.of("/rabbitmq_event.json", RabbitMQEvent.class),
+ Arguments.of("/kafip_event.json", KinesisAnalyticsFirehoseInputPreprocessingEvent.class),
+ Arguments.of("/kasip_event.json", KinesisAnalyticsStreamsInputPreprocessingEvent.class),
+ Arguments.of("/custom_event.json", MyCustomEvent.class)
+
+ );
+ }
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
+ @ParameterizedTest
+ @ArgumentsSource(ResponseEventsArgumentsProvider.class)
+ public void testValidateOutboundJsonSchema(Object object) throws Throwable {
+ when(validation.schemaVersion()).thenReturn(SpecVersion.VersionFlag.V7);
+ when(pjp.getSignature()).thenReturn(signature);
+ when(pjp.getSignature().getDeclaringType()).thenReturn(RequestHandler.class);
+ Object[] args = {new Object(), context};
+ when(pjp.getArgs()).thenReturn(args);
+ when(pjp.proceed(args)).thenReturn(object);
+ when(validation.inboundSchema()).thenReturn("");
+ when(validation.outboundSchema()).thenReturn("classpath:/schema_v7.json");
+
+ assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> {
+ validationAspect.around(pjp, validation);
+ });
+ }
+
+ @Test
+ public void testValidateOutboundJsonSchema_APIGWV2() throws Throwable {
+ when(validation.schemaVersion()).thenReturn(SpecVersion.VersionFlag.V7);
+ when(pjp.getSignature()).thenReturn(signature);
+ when(pjp.getSignature().getDeclaringType()).thenReturn(RequestHandler.class);
+ Object[] args = {new Object(), context};
+ when(pjp.getArgs()).thenReturn(args);
+ APIGatewayV2HTTPResponse apiGatewayV2HTTPResponse = new APIGatewayV2HTTPResponse();
+ apiGatewayV2HTTPResponse.setBody("{" +
+ " \"id\": 1," +
+ " \"name\": \"Lampshade\"," +
+ " \"price\": 42" +
+ "}");
+ when(pjp.proceed(args)).thenReturn(apiGatewayV2HTTPResponse);
+ when(validation.inboundSchema()).thenReturn("");
+ when(validation.outboundSchema()).thenReturn("classpath:/schema_v7.json");
+
+ validationAspect.around(pjp, validation);
+ }
+
@Test
public void validate_inputOK_schemaInClasspath_shouldValidate() {
- ValidationInboundClasspathHandler handler = new ValidationInboundClasspathHandler();
+ GenericSchemaV7Handler handler = new GenericSchemaV7Handler();
APIGatewayProxyRequestEvent event = new APIGatewayProxyRequestEvent();
event.setBody("{" +
" \"id\": 1," +
@@ -58,7 +132,7 @@ public void validate_inputOK_schemaInClasspath_shouldValidate() {
@Test
public void validate_inputKO_schemaInClasspath_shouldThrowValidationException() {
- ValidationInboundClasspathHandler handler = new ValidationInboundClasspathHandler();
+ GenericSchemaV7Handler handler = new GenericSchemaV7Handler();
APIGatewayProxyRequestEvent event = new APIGatewayProxyRequestEvent();
event.setBody("{" +
" \"id\": 1," +
@@ -97,7 +171,7 @@ public void validate_SQS() {
PojoSerializer pojoSerializer = LambdaEventSerializers.serializerFor(SQSEvent.class, ClassLoader.getSystemClassLoader());
SQSEvent event = pojoSerializer.fromJson(this.getClass().getResourceAsStream("/sqs.json"));
- SQSHandler handler = new SQSHandler();
+ GenericSchemaV7Handler handler = new GenericSchemaV7Handler();
assertThat(handler.handleRequest(event, context)).isEqualTo("OK");
}
@@ -124,15 +198,16 @@ public void validate_Kinesis() {
PojoSerializer pojoSerializer = LambdaEventSerializers.serializerFor(KinesisEvent.class, ClassLoader.getSystemClassLoader());
KinesisEvent event = pojoSerializer.fromJson(this.getClass().getResourceAsStream("/kinesis.json"));
- KinesisHandler handler = new KinesisHandler();
+ GenericSchemaV7Handler handler = new GenericSchemaV7Handler();
assertThat(handler.handleRequest(event, context)).isEqualTo("OK");
}
- @Test
- public void validate_CustomObject() throws IOException {
- MyCustomEvent event = ValidationConfig.get().getObjectMapper().readValue(this.getClass().getResourceAsStream("/custom_event.json"), MyCustomEvent.class);
+ @ParameterizedTest
+ @MethodSource("provideEventAndEventType")
+ public void validateEEvent(String jsonResource, Class eventClass) throws IOException {
+ Object event = ValidationConfig.get().getObjectMapper().readValue(this.getClass().getResourceAsStream(jsonResource), eventClass);
- MyCustomEventHandler handler = new MyCustomEventHandler();
+ GenericSchemaV7Handler