diff --git a/aws-lambda-java-serialization/RELEASE.CHANGELOG.md b/aws-lambda-java-serialization/RELEASE.CHANGELOG.md index 59ed3c8c..4a0e8ca2 100644 --- a/aws-lambda-java-serialization/RELEASE.CHANGELOG.md +++ b/aws-lambda-java-serialization/RELEASE.CHANGELOG.md @@ -1,3 +1,8 @@ +### March 19, 2026 +`1.3.1`: +- Revert `jackson-databind` dependency from 2.18.6 to 2.15.4 +- Revert `PropertyNamingStrategies.UpperCamelCaseStrategy` to `PropertyNamingStrategy.PascalCaseStrategy` + ### March 11, 2026 `1.3.0`: - Update `jackson-databind` dependency from 2.15.4 to 2.18.6 diff --git a/aws-lambda-java-serialization/pom.xml b/aws-lambda-java-serialization/pom.xml index 93c27d87..a71eb1f8 100644 --- a/aws-lambda-java-serialization/pom.xml +++ b/aws-lambda-java-serialization/pom.xml @@ -4,7 +4,7 @@ com.amazonaws aws-lambda-java-serialization - 1.3.0 + 1.3.1 jar AWS Lambda Java Runtime Serialization @@ -32,7 +32,7 @@ 1.8 1.8 com.amazonaws.lambda.thirdparty - 2.18.6 + 2.15.4 2.10.1 20231013 7.3.2 diff --git a/aws-lambda-java-serialization/src/main/java/com/amazonaws/services/lambda/runtime/serialization/events/LambdaEventSerializers.java b/aws-lambda-java-serialization/src/main/java/com/amazonaws/services/lambda/runtime/serialization/events/LambdaEventSerializers.java index 89401a91..3f01d99b 100644 --- a/aws-lambda-java-serialization/src/main/java/com/amazonaws/services/lambda/runtime/serialization/events/LambdaEventSerializers.java +++ b/aws-lambda-java-serialization/src/main/java/com/amazonaws/services/lambda/runtime/serialization/events/LambdaEventSerializers.java @@ -19,7 +19,6 @@ import com.amazonaws.services.lambda.runtime.serialization.PojoSerializer; import com.amazonaws.services.lambda.runtime.serialization.util.ReflectUtil; import com.amazonaws.services.lambda.runtime.serialization.util.SerializeUtil; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.amazonaws.services.lambda.runtime.serialization.events.modules.DateModule; import com.amazonaws.services.lambda.runtime.serialization.events.modules.DateTimeModule; @@ -40,279 +39,304 @@ * * Option 1 (Preferred): * 1. Add Class name to SUPPORTED_EVENTS - * 2. Add Mixin Class to com.amazonaws.services.lambda.runtime.serialization.events.mixins package (if needed) + * 2. Add Mixin Class to + * com.amazonaws.services.lambda.runtime.serialization.events.mixins package (if + * needed) * 3. Add entries to MIXIN_MAP for event class and sub classes (if needed) - * 4. Add entries to NESTED_CLASS_MAP for event class and sub classes (if needed) - * 5. Add entry to NAMING_STRATEGY_MAP (if needed i.e. Could be used in place of a mixin) + * 4. Add entries to NESTED_CLASS_MAP for event class and sub classes (if + * needed) + * 5. Add entry to NAMING_STRATEGY_MAP (if needed i.e. Could be used in place of + * a mixin) * * Option 2 (longer - for event models that do not work with Jackson or GSON): * 1. Add Class name to SUPPORTED_EVENTS - * 2. Add serializer (using org.json) to com.amazonaws.services.lambda.runtime.serialization.events.serializers + * 2. Add serializer (using org.json) to + * com.amazonaws.services.lambda.runtime.serialization.events.serializers * 3. Add class name and serializer to SERIALIZER_MAP */ public class LambdaEventSerializers { - /** - * list of supported events - */ - private static final List SUPPORTED_EVENTS = Stream.of( - "com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent", - "com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent", - "com.amazonaws.services.lambda.runtime.events.CloudFormationCustomResourceEvent", - "com.amazonaws.services.lambda.runtime.events.CloudFrontEvent", - "com.amazonaws.services.lambda.runtime.events.CloudWatchLogsEvent", - "com.amazonaws.services.lambda.runtime.events.CodeCommitEvent", - "com.amazonaws.services.lambda.runtime.events.CognitoEvent", - "com.amazonaws.services.lambda.runtime.events.ConfigEvent", - "com.amazonaws.services.lambda.runtime.events.ConnectEvent", - "com.amazonaws.services.lambda.runtime.events.DynamodbEvent", - "com.amazonaws.services.lambda.runtime.events.DynamodbTimeWindowEvent", - "com.amazonaws.services.lambda.runtime.events.IoTButtonEvent", - "com.amazonaws.services.lambda.runtime.events.KinesisEvent", - "com.amazonaws.services.lambda.runtime.events.KinesisTimeWindowEvent", - "com.amazonaws.services.lambda.runtime.events.KinesisFirehoseEvent", - "com.amazonaws.services.lambda.runtime.events.LambdaDestinationEvent", - "com.amazonaws.services.lambda.runtime.events.LexEvent", - "com.amazonaws.services.lambda.runtime.events.ScheduledEvent", - "com.amazonaws.services.lambda.runtime.events.SecretsManagerRotationEvent", - "com.amazonaws.services.s3.event.S3EventNotification", - "com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification", - "com.amazonaws.services.lambda.runtime.events.S3Event", - "com.amazonaws.services.lambda.runtime.events.SNSEvent", - "com.amazonaws.services.lambda.runtime.events.SQSEvent") - .collect(Collectors.toList()); + /** + * list of supported events + */ + private static final List SUPPORTED_EVENTS = Stream.of( + "com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent", + "com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent", + "com.amazonaws.services.lambda.runtime.events.CloudFormationCustomResourceEvent", + "com.amazonaws.services.lambda.runtime.events.CloudFrontEvent", + "com.amazonaws.services.lambda.runtime.events.CloudWatchLogsEvent", + "com.amazonaws.services.lambda.runtime.events.CodeCommitEvent", + "com.amazonaws.services.lambda.runtime.events.CognitoEvent", + "com.amazonaws.services.lambda.runtime.events.ConfigEvent", + "com.amazonaws.services.lambda.runtime.events.ConnectEvent", + "com.amazonaws.services.lambda.runtime.events.DynamodbEvent", + "com.amazonaws.services.lambda.runtime.events.DynamodbTimeWindowEvent", + "com.amazonaws.services.lambda.runtime.events.IoTButtonEvent", + "com.amazonaws.services.lambda.runtime.events.KinesisEvent", + "com.amazonaws.services.lambda.runtime.events.KinesisTimeWindowEvent", + "com.amazonaws.services.lambda.runtime.events.KinesisFirehoseEvent", + "com.amazonaws.services.lambda.runtime.events.LambdaDestinationEvent", + "com.amazonaws.services.lambda.runtime.events.LexEvent", + "com.amazonaws.services.lambda.runtime.events.ScheduledEvent", + "com.amazonaws.services.lambda.runtime.events.SecretsManagerRotationEvent", + "com.amazonaws.services.s3.event.S3EventNotification", + "com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification", + "com.amazonaws.services.lambda.runtime.events.S3Event", + "com.amazonaws.services.lambda.runtime.events.SNSEvent", + "com.amazonaws.services.lambda.runtime.events.SQSEvent") + .collect(Collectors.toList()); - /** - * list of events incompatible with Jackson, with serializers explicitly defined - * Classes are incompatible with Jackson for any of the following reasons: - * 1. different constructor/setter types from getter types - * 2. various bugs within Jackson - */ - private static final Map SERIALIZER_MAP = Stream.of( - new SimpleEntry<>("com.amazonaws.services.s3.event.S3EventNotification", new S3EventSerializer<>()), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification", new S3EventSerializer<>()), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.S3Event", new S3EventSerializer<>())) - .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); + /** + * list of events incompatible with Jackson, with serializers explicitly defined + * Classes are incompatible with Jackson for any of the following reasons: + * 1. different constructor/setter types from getter types + * 2. various bugs within Jackson + */ + private static final Map SERIALIZER_MAP = Stream.of( + new SimpleEntry<>("com.amazonaws.services.s3.event.S3EventNotification", + new S3EventSerializer<>()), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification", + new S3EventSerializer<>()), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.S3Event", + new S3EventSerializer<>())) + .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); - /** - * Maps supported event classes to mixin classes with Jackson annotations. - * Jackson annotations are not loaded through the ClassLoader so if a Java field is serialized or deserialized from a - * json field that does not match the Jave field name, then a Mixin is required. - */ - @SuppressWarnings("rawtypes") - private static final Map MIXIN_MAP = Stream.of( - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CloudFormationCustomResourceEvent", - CloudFormationCustomResourceEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CloudFrontEvent", - CloudFrontEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CloudWatchLogsEvent", - CloudWatchLogsEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CodeCommitEvent", - CodeCommitEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CodeCommitEvent$Record", - CodeCommitEventMixin.RecordMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent", - ConnectEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent$Details", - ConnectEventMixin.DetailsMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent$ContactData", - ConnectEventMixin.ContactDataMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent$CustomerEndpoint", - ConnectEventMixin.CustomerEndpointMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent$Queue", ConnectEventMixin.QueueMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent$SystemEndpoint", - ConnectEventMixin.SystemEndpointMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.DynamodbEvent", - DynamodbEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.DynamodbEvent$DynamodbStreamRecord", - DynamodbEventMixin.DynamodbStreamRecordMixin.class), - new SimpleEntry<>("com.amazonaws.services.dynamodbv2.model.StreamRecord", - DynamodbEventMixin.StreamRecordMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.models.dynamodb.StreamRecord", - DynamodbEventMixin.StreamRecordMixin.class), - new SimpleEntry<>("com.amazonaws.services.dynamodbv2.model.AttributeValue", - DynamodbEventMixin.AttributeValueMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.models.dynamodb.AttributeValue", - DynamodbEventMixin.AttributeValueMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.DynamodbTimeWindowEvent", - DynamodbTimeWindowEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.KinesisEvent", - KinesisEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.KinesisEvent$Record", - KinesisEventMixin.RecordMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.KinesisTimeWindowEvent", - KinesisTimeWindowEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ScheduledEvent", - ScheduledEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SecretsManagerRotationEvent", - SecretsManagerRotationEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SNSEvent", - SNSEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SNSEvent$SNSRecord", - SNSEventMixin.SNSRecordMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SQSEvent", - SQSEventMixin.class), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SQSEvent$SQSMessage", - SQSEventMixin.SQSMessageMixin.class)) - .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); + /** + * Maps supported event classes to mixin classes with Jackson annotations. + * Jackson annotations are not loaded through the ClassLoader so if a Java field + * is serialized or deserialized from a + * json field that does not match the Jave field name, then a Mixin is required. + */ + @SuppressWarnings("rawtypes") + private static final Map MIXIN_MAP = Stream.of( + new SimpleEntry<>( + "com.amazonaws.services.lambda.runtime.events.CloudFormationCustomResourceEvent", + CloudFormationCustomResourceEventMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CloudFrontEvent", + CloudFrontEventMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CloudWatchLogsEvent", + CloudWatchLogsEventMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CodeCommitEvent", + CodeCommitEventMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CodeCommitEvent$Record", + CodeCommitEventMixin.RecordMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent", + ConnectEventMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent$Details", + ConnectEventMixin.DetailsMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent$ContactData", + ConnectEventMixin.ContactDataMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent$CustomerEndpoint", + ConnectEventMixin.CustomerEndpointMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent$Queue", + ConnectEventMixin.QueueMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent$SystemEndpoint", + ConnectEventMixin.SystemEndpointMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.DynamodbEvent", + DynamodbEventMixin.class), + new SimpleEntry<>( + "com.amazonaws.services.lambda.runtime.events.DynamodbEvent$DynamodbStreamRecord", + DynamodbEventMixin.DynamodbStreamRecordMixin.class), + new SimpleEntry<>("com.amazonaws.services.dynamodbv2.model.StreamRecord", + DynamodbEventMixin.StreamRecordMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.models.dynamodb.StreamRecord", + DynamodbEventMixin.StreamRecordMixin.class), + new SimpleEntry<>("com.amazonaws.services.dynamodbv2.model.AttributeValue", + DynamodbEventMixin.AttributeValueMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.models.dynamodb.AttributeValue", + DynamodbEventMixin.AttributeValueMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.DynamodbTimeWindowEvent", + DynamodbTimeWindowEventMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.KinesisEvent", + KinesisEventMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.KinesisEvent$Record", + KinesisEventMixin.RecordMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.KinesisTimeWindowEvent", + KinesisTimeWindowEventMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ScheduledEvent", + ScheduledEventMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SecretsManagerRotationEvent", + SecretsManagerRotationEventMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SNSEvent", + SNSEventMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SNSEvent$SNSRecord", + SNSEventMixin.SNSRecordMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SQSEvent", + SQSEventMixin.class), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SQSEvent$SQSMessage", + SQSEventMixin.SQSMessageMixin.class)) + .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); - /** - * If mixins are required for inner classes of an event, then those nested classes must be specified here. - */ - @SuppressWarnings("rawtypes") - private static final Map> NESTED_CLASS_MAP = Stream.of( - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CodeCommitEvent", - Arrays.asList( - new NestedClass("com.amazonaws.services.lambda.runtime.events.CodeCommitEvent$Record"))), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CognitoEvent", - Arrays.asList( - new NestedClass("com.amazonaws.services.lambda.runtime.events.CognitoEvent$DatasetRecord"))), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent", - Arrays.asList( - new NestedClass("com.amazonaws.services.lambda.runtime.events.ConnectEvent$Details"), - new NestedClass("com.amazonaws.services.lambda.runtime.events.ConnectEvent$ContactData"), - new NestedClass("com.amazonaws.services.lambda.runtime.events.ConnectEvent$CustomerEndpoint"), - new NestedClass("com.amazonaws.services.lambda.runtime.events.ConnectEvent$Queue"), - new NestedClass("com.amazonaws.services.lambda.runtime.events.ConnectEvent$SystemEndpoint"))), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.DynamodbEvent", - Arrays.asList( - new AlternateNestedClass( - "com.amazonaws.services.lambda.runtime.events.models.dynamodb.AttributeValue", - "com.amazonaws.services.dynamodbv2.model.AttributeValue"), - new AlternateNestedClass( - "com.amazonaws.services.lambda.runtime.events.models.dynamodb.StreamRecord", - "com.amazonaws.services.dynamodbv2.model.StreamRecord"), - new NestedClass("com.amazonaws.services.lambda.runtime.events.DynamodbEvent$DynamodbStreamRecord"))), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.DynamodbEvent$DynamodbStreamRecord", - Arrays.asList( - new AlternateNestedClass( - "com.amazonaws.services.lambda.runtime.events.models.dynamodb.AttributeValue", - "com.amazonaws.services.dynamodbv2.model.AttributeValue"), - new AlternateNestedClass( - "com.amazonaws.services.lambda.runtime.events.models.dynamodb.StreamRecord", - "com.amazonaws.services.dynamodbv2.model.StreamRecord"))), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.DynamodbTimeWindowEvent", - Arrays.asList( - new AlternateNestedClass( - "com.amazonaws.services.lambda.runtime.events.models.dynamodb.AttributeValue", - "com.amazonaws.services.dynamodbv2.model.AttributeValue"), - new AlternateNestedClass( - "com.amazonaws.services.lambda.runtime.events.models.dynamodb.StreamRecord", - "com.amazonaws.services.dynamodbv2.model.StreamRecord"), - new NestedClass("com.amazonaws.services.lambda.runtime.events.DynamodbEvent$DynamodbStreamRecord"))), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.KinesisEvent", - Arrays.asList( - new NestedClass("com.amazonaws.services.lambda.runtime.events.KinesisEvent$Record"))), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SNSEvent", - Arrays.asList( - new NestedClass("com.amazonaws.services.lambda.runtime.events.SNSEvent$SNSRecord"))), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SQSEvent", - Arrays.asList( - new NestedClass("com.amazonaws.services.lambda.runtime.events.SQSEvent$SQSMessage")))) - .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); + /** + * If mixins are required for inner classes of an event, then those nested + * classes must be specified here. + */ + @SuppressWarnings("rawtypes") + private static final Map> NESTED_CLASS_MAP = Stream.of( + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CodeCommitEvent", + Arrays.asList( + new NestedClass("com.amazonaws.services.lambda.runtime.events.CodeCommitEvent$Record"))), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.CognitoEvent", + Arrays.asList( + new NestedClass("com.amazonaws.services.lambda.runtime.events.CognitoEvent$DatasetRecord"))), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent", + Arrays.asList( + new NestedClass("com.amazonaws.services.lambda.runtime.events.ConnectEvent$Details"), + new NestedClass("com.amazonaws.services.lambda.runtime.events.ConnectEvent$ContactData"), + new NestedClass("com.amazonaws.services.lambda.runtime.events.ConnectEvent$CustomerEndpoint"), + new NestedClass("com.amazonaws.services.lambda.runtime.events.ConnectEvent$Queue"), + new NestedClass("com.amazonaws.services.lambda.runtime.events.ConnectEvent$SystemEndpoint"))), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.DynamodbEvent", + Arrays.asList( + new AlternateNestedClass( + "com.amazonaws.services.lambda.runtime.events.models.dynamodb.AttributeValue", + "com.amazonaws.services.dynamodbv2.model.AttributeValue"), + new AlternateNestedClass( + "com.amazonaws.services.lambda.runtime.events.models.dynamodb.StreamRecord", + "com.amazonaws.services.dynamodbv2.model.StreamRecord"), + new NestedClass("com.amazonaws.services.lambda.runtime.events.DynamodbEvent$DynamodbStreamRecord"))), + new SimpleEntry<>( + "com.amazonaws.services.lambda.runtime.events.DynamodbEvent$DynamodbStreamRecord", + Arrays.asList( + new AlternateNestedClass( + "com.amazonaws.services.lambda.runtime.events.models.dynamodb.AttributeValue", + "com.amazonaws.services.dynamodbv2.model.AttributeValue"), + new AlternateNestedClass( + "com.amazonaws.services.lambda.runtime.events.models.dynamodb.StreamRecord", + "com.amazonaws.services.dynamodbv2.model.StreamRecord"))), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.DynamodbTimeWindowEvent", + Arrays.asList( + new AlternateNestedClass( + "com.amazonaws.services.lambda.runtime.events.models.dynamodb.AttributeValue", + "com.amazonaws.services.dynamodbv2.model.AttributeValue"), + new AlternateNestedClass( + "com.amazonaws.services.lambda.runtime.events.models.dynamodb.StreamRecord", + "com.amazonaws.services.dynamodbv2.model.StreamRecord"), + new NestedClass("com.amazonaws.services.lambda.runtime.events.DynamodbEvent$DynamodbStreamRecord"))), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.KinesisEvent", + Arrays.asList( + new NestedClass("com.amazonaws.services.lambda.runtime.events.KinesisEvent$Record"))), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SNSEvent", + Arrays.asList( + new NestedClass("com.amazonaws.services.lambda.runtime.events.SNSEvent$SNSRecord"))), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SQSEvent", + Arrays.asList( + new NestedClass("com.amazonaws.services.lambda.runtime.events.SQSEvent$SQSMessage")))) + .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); - /** - * If event requires a naming strategy. For example, when someone names the getter method getSNS and the setter - * method setSns, for some magical reasons, using both mixins and a naming strategy works - */ - private static final Map NAMING_STRATEGY_MAP = Stream.of( - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SNSEvent", - new PropertyNamingStrategies.UpperCamelCaseStrategy()), - new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent$Queue", - new PropertyNamingStrategies.UpperCamelCaseStrategy()) - ) - .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); + /** + * If event requires a naming strategy. For example, when someone names the + * getter method getSNS and the setter + * method setSns, for some magical reasons, using both mixins and a naming + * strategy works + */ + private static final Map NAMING_STRATEGY_MAP = Stream.of( + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SNSEvent", + new PropertyNamingStrategy.PascalCaseStrategy()), + new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.ConnectEvent$Queue", + new PropertyNamingStrategy.PascalCaseStrategy())) + .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); - /** - * Returns whether the class name is a Lambda supported event model. - * @param className class name as string - * @return whether the event model is supported - */ - public static boolean isLambdaSupportedEvent(String className) { - return SUPPORTED_EVENTS.contains(className); - } - - /** - * Return a serializer for the event class - * @return a specific PojoSerializer or modified JacksonFactory instance with mixins and modules added in - */ - @SuppressWarnings({"unchecked"}) - public static PojoSerializer serializerFor(Class eventClass, ClassLoader classLoader) { - // if serializer specifically defined for event then use that - if (SERIALIZER_MAP.containsKey(eventClass.getName())) { - return SERIALIZER_MAP.get(eventClass.getName()).withClass(eventClass).withClassLoader(classLoader); - } - // else use a Jackson ObjectMapper instance - JacksonFactory factory = JacksonFactory.getInstance(); - // if mixins required for class, then apply - if (MIXIN_MAP.containsKey(eventClass.getName())) { - factory = factory.withMixin(eventClass, MIXIN_MAP.get(eventClass.getName())); + /** + * Returns whether the class name is a Lambda supported event model. + * + * @param className class name as string + * @return whether the event model is supported + */ + public static boolean isLambdaSupportedEvent(String className) { + return SUPPORTED_EVENTS.contains(className); } - // if event model has nested classes then load those classes and check if mixins apply - if (NESTED_CLASS_MAP.containsKey(eventClass.getName())) { - List nestedClasses = NESTED_CLASS_MAP.get(eventClass.getName()); - for (NestedClass nestedClass: nestedClasses) { - // if mixin exists for nested class then apply - if (MIXIN_MAP.containsKey(nestedClass.className)) { - factory = tryLoadingNestedClass(classLoader, factory, nestedClass); + + /** + * Return a serializer for the event class + * + * @return a specific PojoSerializer or modified JacksonFactory instance with + * mixins and modules added in + */ + @SuppressWarnings({ "unchecked" }) + public static PojoSerializer serializerFor(Class eventClass, ClassLoader classLoader) { + // if serializer specifically defined for event then use that + if (SERIALIZER_MAP.containsKey(eventClass.getName())) { + return SERIALIZER_MAP.get(eventClass.getName()).withClass(eventClass) + .withClassLoader(classLoader); } - } - } - // load DateModules - factory.getMapper().registerModules(new DateModule(), new DateTimeModule(classLoader)); - // load naming strategy if needed - if (NAMING_STRATEGY_MAP.containsKey(eventClass.getName())) { - factory = factory.withNamingStrategy(NAMING_STRATEGY_MAP.get(eventClass.getName())); + // else use a Jackson ObjectMapper instance + JacksonFactory factory = JacksonFactory.getInstance(); + // if mixins required for class, then apply + if (MIXIN_MAP.containsKey(eventClass.getName())) { + factory = factory.withMixin(eventClass, MIXIN_MAP.get(eventClass.getName())); + } + // if event model has nested classes then load those classes and check if mixins + // apply + if (NESTED_CLASS_MAP.containsKey(eventClass.getName())) { + List nestedClasses = NESTED_CLASS_MAP.get(eventClass.getName()); + for (NestedClass nestedClass : nestedClasses) { + // if mixin exists for nested class then apply + if (MIXIN_MAP.containsKey(nestedClass.className)) { + factory = tryLoadingNestedClass(classLoader, factory, nestedClass); + } + } + } + // load DateModules + factory.getMapper().registerModules(new DateModule(), new DateTimeModule(classLoader)); + // load naming strategy if needed + if (NAMING_STRATEGY_MAP.containsKey(eventClass.getName())) { + factory = factory.withNamingStrategy(NAMING_STRATEGY_MAP.get(eventClass.getName())); + } + return factory.getSerializer(eventClass); } - return factory.getSerializer(eventClass); - } - /** - * Tries to load a nested class with its defined mixin from {@link #MIXIN_MAP} into the {@link JacksonFactory} object. - * Will allow initial failure for {@link AlternateNestedClass} objects and try again with their alternate class name - * @return a modified JacksonFactory instance with mixins added in - */ - private static JacksonFactory tryLoadingNestedClass(ClassLoader classLoader, JacksonFactory factory, NestedClass nestedClass) { - Class eventClazz; - Class mixinClazz; - try { - eventClazz = SerializeUtil.loadCustomerClass(nestedClass.getClassName(), classLoader); - mixinClazz = MIXIN_MAP.get(nestedClass.getClassName()); - } catch (ReflectUtil.ReflectException e) { - if (nestedClass instanceof AlternateNestedClass) { - AlternateNestedClass alternateNestedClass = (AlternateNestedClass) nestedClass; - eventClazz = SerializeUtil.loadCustomerClass(alternateNestedClass.getAlternateClassName(), classLoader); - mixinClazz = MIXIN_MAP.get(alternateNestedClass.getAlternateClassName()); - } else { - throw e; - } - } + /** + * Tries to load a nested class with its defined mixin from {@link #MIXIN_MAP} + * into the {@link JacksonFactory} object. + * Will allow initial failure for {@link AlternateNestedClass} objects and try + * again with their alternate class name + * + * @return a modified JacksonFactory instance with mixins added in + */ + private static JacksonFactory tryLoadingNestedClass(ClassLoader classLoader, JacksonFactory factory, + NestedClass nestedClass) { + Class eventClazz; + Class mixinClazz; + try { + eventClazz = SerializeUtil.loadCustomerClass(nestedClass.getClassName(), classLoader); + mixinClazz = MIXIN_MAP.get(nestedClass.getClassName()); + } catch (ReflectUtil.ReflectException e) { + if (nestedClass instanceof AlternateNestedClass) { + AlternateNestedClass alternateNestedClass = (AlternateNestedClass) nestedClass; + eventClazz = SerializeUtil.loadCustomerClass( + alternateNestedClass.getAlternateClassName(), classLoader); + mixinClazz = MIXIN_MAP.get(alternateNestedClass.getAlternateClassName()); + } else { + throw e; + } + } - return factory.withMixin(eventClazz, mixinClazz); - } + return factory.withMixin(eventClazz, mixinClazz); + } - private static class NestedClass { - private final String className; + private static class NestedClass { + private final String className; - protected NestedClass(String className) { - this.className = className; - } + protected NestedClass(String className) { + this.className = className; + } - protected String getClassName() { - return className; + protected String getClassName() { + return className; + } } - } - private static class AlternateNestedClass extends NestedClass { - private final String alternateClassName; + private static class AlternateNestedClass extends NestedClass { + private final String alternateClassName; - private AlternateNestedClass(String className, String alternateClassName) { - super(className); - this.alternateClassName = alternateClassName; - } + private AlternateNestedClass(String className, String alternateClassName) { + super(className); + this.alternateClassName = alternateClassName; + } - private String getAlternateClassName() { - return alternateClassName; + private String getAlternateClassName() { + return alternateClassName; + } } - } }