diff --git a/README.md b/README.md index f7eb06de..c141d4fe 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ from the packages can result in unexpected behavior. Check out the per-module release notes: - [aws-lambda-java-core](aws-lambda-java-core/RELEASE.CHANGELOG.md) - [aws-lambda-java-events](aws-lambda-java-events/RELEASE.CHANGELOG.md) +- [aws-lambda-java-events-sdk-transformer](aws-lambda-java-events-sdk-transformer/RELEASE.CHANGELOG.md) - [aws-lambda-java-log4j](aws-lambda-java-log4j/RELEASE.CHANGELOG.md) - [aws-lambda-java-log4j2](aws-lambda-java-log4j2/RELEASE.CHANGELOG.md) @@ -36,6 +37,11 @@ ___ aws-lambda-java-events 2.2.8 + + com.amazonaws + aws-lambda-java-events-sdk-transformer + 1.0.0 + com.amazonaws aws-lambda-java-log4j @@ -53,6 +59,7 @@ ___ ```groovy 'com.amazonaws:aws-lambda-java-core:1.2.1' 'com.amazonaws:aws-lambda-java-events:2.2.8' +'com.amazonaws:aws-lambda-java-events-sdk-transformer:1.0.0' 'com.amazonaws:aws-lambda-java-log4j:1.0.1' 'com.amazonaws:aws-lambda-java-log4j2:1.1.1' ``` @@ -62,6 +69,7 @@ ___ ```clojure [com.amazonaws/aws-lambda-java-core "1.2.1"] [com.amazonaws/aws-lambda-java-events "2.2.8"] +[com.amazonaws/aws-lambda-java-events-sdk-transformer "1.0.0"] [com.amazonaws/aws-lambda-java-log4j "1.0.1"] [com.amazonaws/aws-lambda-java-log4j2 "1.1.1"] ``` @@ -71,6 +79,7 @@ ___ ```scala "com.amazonaws" % "aws-lambda-java-core" % "1.2.1" "com.amazonaws" % "aws-lambda-java-events" % "2.2.8" +"com.amazonaws" % "aws-lambda-java-events-sdk-transformer" % "1.0.0" "com.amazonaws" % "aws-lambda-java-log4j" % "1.0.1" "com.amazonaws" % "aws-lambda-java-log4j2" % "1.1.1" ``` @@ -85,6 +94,12 @@ This package defines the Lambda [Context](http://docs.aws.amazon.com/lambda/late This package defines [event sources](http://docs.aws.amazon.com/lambda/latest/dg/intro-invocation-modes.html) that AWS Lambda natively accepts. See the [documentation](aws-lambda-java-events/README.md) for more information. +# Using aws-lambda-java-events-sdk-transformer + +This package provides helper classes/methods to use alongside `aws-lambda-java-events` in order to transform + Lambda input event model objects into SDK-compatible output model objects. +See the [documentation](aws-lambda-java-events-sdk-transformer/README.md) for more information. + # Using aws-lambda-java-log4j2 This package defines the Lambda adapter to use with log4j version 2. diff --git a/aws-lambda-java-events-sdk-transformer/README.md b/aws-lambda-java-events-sdk-transformer/README.md new file mode 100644 index 00000000..572021ba --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/README.md @@ -0,0 +1,121 @@ +# AWS Lambda Java Events SDK Transformer Library + +### About + +Provides helper classes/methods to use alongside `aws-lambda-java-events` in order to transform Lambda input event model + objects into SDK-compatible output model objects + (eg. DynamodbEvent to a List of records writable back to DynamoDB through the AWS DynamoDB SDK v2). + + +### Getting started + +Add the following Apache Maven dependencies to your `pom.xml` file: + +```xml + + + com.amazonaws + aws-lambda-java-events-sdk-transformer + 1.0.0 + + + com.amazonaws + aws-lambda-java-events + 2.2.8 + + +``` + +To use this library as a transformer to the AWS DynamoDB Java SDK v2, also add the following dependencies to your `pom.xml` file: + +```xml + + + software.amazon.awssdk + dynamodb + 2.11.12 + + + com.amazonaws + aws-java-sdk-dynamodb + 1.11.163 + + +``` +*Note that because `aws-lambda-java-events` version 2 requires the DynamoDB v1 SDK, this is also required for this library.* + + +### Example Usage + +To convert a full `DynamodbEvent` object to an SDK v2 compatible `List`: +```java +import com.amazonaws.services.lambda.runtime.events.transformers.DynamodbEventTransformer; + +public class DDBEventProcessor implements RequestHandler { + + public String handleRequest(DynamodbEvent ddbEvent, Context context) { + // Process input event + List convertedRecords = DynamodbEventTransformer.toRecordsV2(ddbEvent); + // Modify records as needed and write back to DynamoDB using the DynamoDB AWS SDK for Java 2.0 + } +} +``` + +To convert a single `DynamodbEvent.DynamodbStreamRecord` object to an SDK v2 compatible `Record`: +```java +import com.amazonaws.services.lambda.runtime.events.transformers.dynamodb.DynamodbRecordTransformer; + +public class MyClass { + + public void myMethod(DynamodbEvent.DynamodbStreamRecord record) { + // ... + Record convertedRecord = DynamodbRecordTransformer.toRecordV2(record); + // ... + } +} +``` + +To convert a `StreamRecord` object originating from a `DynamodbEvent` to an SDK v2 compatible `StreamRecord`: +```java +import com.amazonaws.services.lambda.runtime.events.transformers.dynamodb.DynamodbStreamRecordTransformer; + +public class MyClass { + + public void myMethod(StreamRecord streamRecord) { + // ... + software.amazon.awssdk.services.dynamodb.model.StreamRecord convertedStreamRecord = + DynamodbStreamRecordTransformer.toStreamRecordV2(streamRecord); + // ... + } +} +``` + +To convert an `AttributeValue` object originating from a `DynamodbEvent` to an SDK v2 compatible `AttributeValue`: +```java +import com.amazonaws.services.lambda.runtime.events.transformers.dynamodb.DynamodbAttributeValueTransformer; + +public class MyClass { + + public void myMethod(AttributeValue attributeValue) { + // ... + software.amazon.awssdk.services.dynamodb.model.AttributeValue convertedAttributeValue = + DynamodbAttributeValueTransformer.toAttributeValueV2(attributeValue); + // ... + } +} +``` + +To convert an `Identity` object originating from a `DynamodbEvent` to an SDK v2 compatible `Identity`: +```java +import com.amazonaws.services.lambda.runtime.events.transformers.dynamodb.DynamodbIdentityTransformer; + +public class MyClass { + + public void myMethod(Identity identity) { + // ... + software.amazon.awssdk.services.dynamodb.model.Identity convertedIdentity = + DynamodbIdentityTransformer.toIdentityV2(identity); + // ... + } +} +``` \ No newline at end of file diff --git a/aws-lambda-java-events-sdk-transformer/RELEASE.CHANGELOG.md b/aws-lambda-java-events-sdk-transformer/RELEASE.CHANGELOG.md new file mode 100644 index 00000000..3f33134b --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/RELEASE.CHANGELOG.md @@ -0,0 +1,3 @@ +### Apr 29, 2020 +`1.0.0`: +- Added AWS SDK V2 transformers for `DynamodbEvent` in `aws-lambda-java-events` versions up to and including `2.2.8` diff --git a/aws-lambda-java-events-sdk-transformer/pom.xml b/aws-lambda-java-events-sdk-transformer/pom.xml new file mode 100644 index 00000000..8f345b6f --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/pom.xml @@ -0,0 +1,175 @@ + + 4.0.0 + + com.amazonaws + aws-lambda-java-events-sdk-transformer + 1.0.0 + jar + + AWS Lambda Java Events SDK Transformer Library + + Provides helper classes/methods to use alongside aws-lambda-java-events in order to transform Lambda input event model + objects into SDK-compatible output model objects (eg. DynamodbEvent to a List of records writable back to DynamoDB + through the AWS DynamoDB SDK v2) + + https://aws.amazon.com/lambda/ + + + Apache License, Version 2.0 + https://aws.amazon.com/apache2.0 + repo + + + + https://github.com/aws/aws-lambda-java-libs.git + + + + AWS Lambda team + Amazon Web Services + https://aws.amazon.com/ + + + + + 1.8 + 1.8 + + + + + sonatype-nexus-staging + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + software.amazon.awssdk + dynamodb + 2.11.12 + provided + + + com.amazonaws + aws-java-sdk-dynamodb + 1.11.163 + provided + + + com.amazonaws + aws-lambda-java-events + 2.2.8 + provided + + + + org.junit.jupiter + junit-jupiter-engine + 5.6.2 + test + + + + + + + maven-surefire-plugin + 2.22.2 + + + maven-failsafe-plugin + 2.22.2 + + + + + + + dev + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + -Xdoclint:none + + + + attach-javadocs + + jar + + + + + + + + + release + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + -Xdoclint:none + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.3 + true + + sonatype-nexus-staging + https://aws.oss.sonatype.org/ + false + + + + + + + diff --git a/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/DynamodbEventTransformer.java b/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/DynamodbEventTransformer.java new file mode 100644 index 00000000..c2c81ec5 --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/DynamodbEventTransformer.java @@ -0,0 +1,21 @@ +package com.amazonaws.services.lambda.runtime.events.transformers; + +import com.amazonaws.services.lambda.runtime.events.DynamodbEvent; +import com.amazonaws.services.lambda.runtime.events.transformers.dynamodb.DynamodbRecordTransformer; +import software.amazon.awssdk.services.dynamodb.model.Record; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class DynamodbEventTransformer { + + public static List toRecordsV2(final DynamodbEvent dynamodbEvent) { + return dynamodbEvent + .getRecords() + .stream() + .filter(record -> !Objects.isNull(record)) + .map(DynamodbRecordTransformer::toRecordV2) + .collect(Collectors.toList()); + } +} diff --git a/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbAttributeValueTransformer.java b/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbAttributeValueTransformer.java new file mode 100644 index 00000000..b4275173 --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbAttributeValueTransformer.java @@ -0,0 +1,84 @@ +package com.amazonaws.services.lambda.runtime.events.transformers.dynamodb; + +import software.amazon.awssdk.core.SdkBytes; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; + +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +public class DynamodbAttributeValueTransformer { + + public static AttributeValue toAttributeValueV2(final com.amazonaws.services.dynamodbv2.model.AttributeValue value) { + if (Objects.nonNull(value.getS())) { + return AttributeValue.builder() + .s(value.getS()) + .build(); + + } else if (Objects.nonNull(value.getSS())) { + return AttributeValue.builder() + .ss(value.getSS()) + .build(); + + } else if (Objects.nonNull(value.getN())) { + return AttributeValue.builder() + .n(value.getN()) + .build(); + + } else if (Objects.nonNull(value.getNS())) { + return AttributeValue.builder() + .ns(value.getNS()) + .build(); + + } else if (Objects.nonNull(value.getB())) { + return AttributeValue.builder() + .b(SdkBytes.fromByteBuffer(value.getB())) + .build(); + + } else if (Objects.nonNull(value.getBS())) { + return AttributeValue.builder() + .bs(value.getBS().stream() + .map(SdkBytes::fromByteBuffer) + .collect(Collectors.toList())) + .build(); + + } else if (Objects.nonNull(value.getBOOL())) { + return AttributeValue.builder() + .bool(value.getBOOL()) + .build(); + + } else if (Objects.nonNull(value.getL())) { + return AttributeValue.builder() + .l(value.getL().stream() + .map(DynamodbAttributeValueTransformer::toAttributeValueV2) + .collect(Collectors.toList())) + .build(); + + } else if (Objects.nonNull(value.getM())) { + return AttributeValue.builder() + .m(toAttributeValueMapV2(value.getM())) + .build(); + + } else if (Objects.nonNull(value.getNULL())) { + return AttributeValue.builder() + .nul(value.getNULL()) + .build(); + + } else { + throw new IllegalArgumentException( + String.format("Unsupported attributeValue type: %s", value)); + } + } + + static Map toAttributeValueMapV2( + final Map attributeValueMap + ) { + return attributeValueMap + .entrySet() + .stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + entry -> toAttributeValueV2(entry.getValue()) + )); + } +} diff --git a/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbIdentityTransformer.java b/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbIdentityTransformer.java new file mode 100644 index 00000000..4bab4a85 --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbIdentityTransformer.java @@ -0,0 +1,13 @@ +package com.amazonaws.services.lambda.runtime.events.transformers.dynamodb; + +import software.amazon.awssdk.services.dynamodb.model.Identity; + +public class DynamodbIdentityTransformer { + + public static Identity toIdentityV2(final com.amazonaws.services.dynamodbv2.model.Identity identity) { + return Identity.builder() + .principalId(identity.getPrincipalId()) + .type(identity.getType()) + .build(); + } +} diff --git a/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbRecordTransformer.java b/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbRecordTransformer.java new file mode 100644 index 00000000..d9547a76 --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbRecordTransformer.java @@ -0,0 +1,23 @@ +package com.amazonaws.services.lambda.runtime.events.transformers.dynamodb; + +import com.amazonaws.services.lambda.runtime.events.DynamodbEvent; +import software.amazon.awssdk.services.dynamodb.model.Record; + +public class DynamodbRecordTransformer { + + public static Record toRecordV2(final DynamodbEvent.DynamodbStreamRecord record) { + return Record.builder() + .awsRegion(record.getAwsRegion()) + .dynamodb( + DynamodbStreamRecordTransformer.toStreamRecordV2(record.getDynamodb()) + ) + .eventID(record.getEventID()) + .eventName(record.getEventName()) + .eventSource(record.getEventSource()) + .eventVersion(record.getEventVersion()) + .userIdentity( + DynamodbIdentityTransformer.toIdentityV2(record.getUserIdentity()) + ) + .build(); + } +} diff --git a/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbStreamRecordTransformer.java b/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbStreamRecordTransformer.java new file mode 100644 index 00000000..160e7ab0 --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/src/main/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbStreamRecordTransformer.java @@ -0,0 +1,26 @@ +package com.amazonaws.services.lambda.runtime.events.transformers.dynamodb; + +import software.amazon.awssdk.services.dynamodb.model.StreamRecord; + +public class DynamodbStreamRecordTransformer { + + public static StreamRecord toStreamRecordV2(final com.amazonaws.services.dynamodbv2.model.StreamRecord streamRecord) { + return StreamRecord.builder() + .approximateCreationDateTime( + streamRecord.getApproximateCreationDateTime().toInstant() + ) + .keys( + DynamodbAttributeValueTransformer.toAttributeValueMapV2(streamRecord.getKeys()) + ) + .newImage( + DynamodbAttributeValueTransformer.toAttributeValueMapV2(streamRecord.getNewImage()) + ) + .oldImage( + DynamodbAttributeValueTransformer.toAttributeValueMapV2(streamRecord.getOldImage()) + ) + .sequenceNumber(streamRecord.getSequenceNumber()) + .sizeBytes(streamRecord.getSizeBytes()) + .streamViewType(streamRecord.getStreamViewType()) + .build(); + } +} diff --git a/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/DynamodbEventTransformerTest.java b/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/DynamodbEventTransformerTest.java new file mode 100644 index 00000000..6fedb3fe --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/DynamodbEventTransformerTest.java @@ -0,0 +1,42 @@ +package com.amazonaws.services.lambda.runtime.events.transformers; + +import com.amazonaws.services.lambda.runtime.events.DynamodbEvent; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.Record; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static com.amazonaws.services.lambda.runtime.events.transformers.dynamodb.DynamodbRecordTransformerTest.record_event; +import static com.amazonaws.services.lambda.runtime.events.transformers.dynamodb.DynamodbRecordTransformerTest.record_v2; + +public class DynamodbEventTransformerTest { + + private final DynamodbEvent dynamodbEvent; + { + record_event.setEventSourceARN("arn:aws:dynamodb:us-west-2:account-id:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899"); + dynamodbEvent = new DynamodbEvent(); + dynamodbEvent.setRecords(Collections.singletonList(record_event)); + } + + private final List expectedRecordsV2 = Collections.singletonList(record_v2); + + @Test + public void testDynamodbEventToRecordsV2() { + List convertedRecords = DynamodbEventTransformer.toRecordsV2(dynamodbEvent); + Assertions.assertEquals(expectedRecordsV2, convertedRecords); + } + + @Test + public void testDynamodbEventToRecordsV2_FiltersNullRecords() { + DynamodbEvent event = dynamodbEvent.clone(); + event.setRecords(Arrays.asList(record_event, null)); + Assertions.assertEquals(2, event.getRecords().size()); + + List convertedRecords = DynamodbEventTransformer.toRecordsV2(event); + Assertions.assertEquals(expectedRecordsV2, convertedRecords); + Assertions.assertEquals(1, convertedRecords.size()); + } +} \ No newline at end of file diff --git a/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbAttributeValueTransformerTest.java b/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbAttributeValueTransformerTest.java new file mode 100644 index 00000000..b3dcfa86 --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbAttributeValueTransformerTest.java @@ -0,0 +1,317 @@ +package com.amazonaws.services.lambda.runtime.events.transformers.dynamodb; + +import com.amazonaws.services.dynamodbv2.model.AttributeValue; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.core.SdkBytes; +import software.amazon.awssdk.utils.ImmutableMap; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +class DynamodbAttributeValueTransformerTest { + + private static final String valueN = "101"; + private static final List valueNS = Arrays.asList("1", "2", "3"); + private static final String valueS = "SVal"; + private static final List valueSS = Arrays.asList("first", "second", "third"); + private static final ByteBuffer valueB = ByteBuffer.wrap("BVal".getBytes()); + private static final List valueBS = Arrays.asList( + ByteBuffer.wrap("first".getBytes()), + ByteBuffer.wrap("second".getBytes()), + ByteBuffer.wrap("third".getBytes())); + private static final boolean valueBOOL = true; + private static final boolean valueNUL = true; + + private static final String keyM1 = "NestedMapKey1"; + private static final String keyM2 = "NestedMapKey2"; + + //region AttributeValue_event + public static final AttributeValue attributeValueN_event = new AttributeValue().withN(valueN); + public static final AttributeValue attributeValueNS_event = new AttributeValue().withNS(valueNS); + public static final AttributeValue attributeValueS_event = new AttributeValue().withS(valueS); + public static final AttributeValue attributeValueSS_event = new AttributeValue().withSS(valueSS); + public static final AttributeValue attributeValueB_event = new AttributeValue().withB(valueB); + public static final AttributeValue attributeValueBS_event = new AttributeValue().withBS(valueBS); + public static final AttributeValue attributeValueBOOL_event = new AttributeValue().withBOOL(valueBOOL); + public static final AttributeValue attributeValueNUL_event = new AttributeValue().withNULL(valueNUL); + public static final AttributeValue attributeValueM_event = new AttributeValue().withM(ImmutableMap.of( + keyM1, attributeValueN_event, + keyM2, attributeValueS_event + )); + public static final AttributeValue attributeValueL_event = new AttributeValue().withL(Arrays.asList( + attributeValueN_event, + attributeValueNS_event, + attributeValueS_event, + attributeValueSS_event, + attributeValueB_event, + attributeValueBS_event, + attributeValueBOOL_event, + attributeValueNUL_event, + attributeValueM_event, + new AttributeValue().withL(Arrays.asList( + attributeValueN_event, + attributeValueNS_event, + attributeValueS_event, + attributeValueSS_event, + attributeValueB_event, + attributeValueBS_event, + attributeValueBOOL_event, + attributeValueNUL_event, + attributeValueM_event + )) + )); + //endregion + + //region AttributeValue_v2 + public static final software.amazon.awssdk.services.dynamodb.model.AttributeValue attributeValueN_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().n(valueN).build(); + public static final software.amazon.awssdk.services.dynamodb.model.AttributeValue attributeValueNS_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().ns(valueNS).build(); + public static final software.amazon.awssdk.services.dynamodb.model.AttributeValue attributeValueS_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().s(valueS).build(); + public static final software.amazon.awssdk.services.dynamodb.model.AttributeValue attributeValueSS_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().ss(valueSS).build(); + public static final software.amazon.awssdk.services.dynamodb.model.AttributeValue attributeValueB_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().b(SdkBytes.fromByteBuffer(valueB)).build(); + public static final software.amazon.awssdk.services.dynamodb.model.AttributeValue attributeValueBS_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().bs(valueBS.stream() + .map(SdkBytes::fromByteBuffer) + .collect(Collectors.toList())).build(); + public static final software.amazon.awssdk.services.dynamodb.model.AttributeValue attributeValueBOOL_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().bool(valueBOOL).build(); + public static final software.amazon.awssdk.services.dynamodb.model.AttributeValue attributeValueNUL_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().nul(valueNUL).build(); + public static final software.amazon.awssdk.services.dynamodb.model.AttributeValue attributeValueM_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().m(ImmutableMap.of( + keyM1, attributeValueN_v2, + keyM2, attributeValueS_v2 + )).build(); + public static final software.amazon.awssdk.services.dynamodb.model.AttributeValue attributeValueL_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().l(Arrays.asList( + attributeValueN_v2, + attributeValueNS_v2, + attributeValueS_v2, + attributeValueSS_v2, + attributeValueB_v2, + attributeValueBS_v2, + attributeValueBOOL_v2, + attributeValueNUL_v2, + attributeValueM_v2, + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().l(Arrays.asList( + attributeValueN_v2, + attributeValueNS_v2, + attributeValueS_v2, + attributeValueSS_v2, + attributeValueB_v2, + attributeValueBS_v2, + attributeValueBOOL_v2, + attributeValueNUL_v2, + attributeValueM_v2 + )).build() + )).build(); + //endregion + + @Test + public void testToAttributeValueV2_N() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue convertedAttributeValueN = + DynamodbAttributeValueTransformer.toAttributeValueV2(attributeValueN_event); + Assertions.assertEquals(attributeValueN_v2, convertedAttributeValueN); + } + + @Test + public void testToAttributeValueV2_NS() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue convertedAttributeValueNS = + DynamodbAttributeValueTransformer.toAttributeValueV2(attributeValueNS_event); + Assertions.assertEquals(attributeValueNS_v2, convertedAttributeValueNS); + } + + @Test + public void testToAttributeValueV2_S() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue convertedAttributeValueS = + DynamodbAttributeValueTransformer.toAttributeValueV2(attributeValueS_event); + Assertions.assertEquals(attributeValueS_v2, convertedAttributeValueS); + } + + @Test + public void testToAttributeValueV2_SS() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue convertedAttributeValueSS = + DynamodbAttributeValueTransformer.toAttributeValueV2(attributeValueSS_event); + Assertions.assertEquals(attributeValueSS_v2, convertedAttributeValueSS); + } + + @Test + public void testToAttributeValueV2_B() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue convertedAttributeValueB = + DynamodbAttributeValueTransformer.toAttributeValueV2(attributeValueB_event); + Assertions.assertEquals(attributeValueB_v2, convertedAttributeValueB); + } + + @Test + public void testToAttributeValueV2_BS() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue convertedAttributeValueBS = + DynamodbAttributeValueTransformer.toAttributeValueV2(attributeValueBS_event); + Assertions.assertEquals(attributeValueBS_v2, convertedAttributeValueBS); + } + + @Test + public void testToAttributeValueV2_BOOL() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue convertedAttributeValueBOOL = + DynamodbAttributeValueTransformer.toAttributeValueV2(attributeValueBOOL_event); + Assertions.assertEquals(attributeValueBOOL_v2, convertedAttributeValueBOOL); + } + + @Test + public void testToAttributeValueV2_NUL() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue convertedAttributeValueNUL = + DynamodbAttributeValueTransformer.toAttributeValueV2(attributeValueNUL_event); + Assertions.assertEquals(attributeValueNUL_v2, convertedAttributeValueNUL); + } + + @Test + public void testToAttributeValueV2_M() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue convertedAttributeValueM = + DynamodbAttributeValueTransformer.toAttributeValueV2(attributeValueM_event); + Assertions.assertEquals(attributeValueM_v2, convertedAttributeValueM); + } + + @Test + public void testToAttributeValueV2_L() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue convertedAttributeValueL = + DynamodbAttributeValueTransformer.toAttributeValueV2(attributeValueL_event); + Assertions.assertEquals(attributeValueL_v2, convertedAttributeValueL); + } + + @Test + public void testToAttributeValueV2_IllegalArgumentWhenNull() { + Assertions.assertThrows(IllegalArgumentException.class, () -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue()) + ); + } + + @Test + public void testToAttributeValueV2_IllegalArgumentWhenNull_N() { + Assertions.assertThrows(IllegalArgumentException.class, () -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withN(null)) + ); + } + + @Test + public void testToAttributeValueV2_IllegalArgumentWhenNull_S() { + Assertions.assertThrows(IllegalArgumentException.class, () -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withS(null)) + ); + } + + @Test + public void testToAttributeValueV2_IllegalArgumentWhenNull_B() { + Assertions.assertThrows(IllegalArgumentException.class, () -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withB(null)) + ); + } + + @Test + public void testToAttributeValueV2_IllegalArgumentWhenNull_BOOL() { + Assertions.assertThrows(IllegalArgumentException.class, () -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withBOOL(null)) + ); + } + + @Test + public void testToAttributeValueV2_IllegalArgumentWhenNull_NUL() { + Assertions.assertThrows(IllegalArgumentException.class, () -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withNULL(null)) + ); + } + + @Test + public void testToAttributeValueV2_IllegalArgumentWhenNull_M() { + Assertions.assertThrows(IllegalArgumentException.class, () -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withM(null)) + ); + } + + @Test + public void testToAttributeValueV2_DoesNotThrowWhenEmpty_NS() { + Assertions.assertDoesNotThrow(() -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withNS()) + ); + Assertions.assertDoesNotThrow(() -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withNS(Collections.emptyList())) + ); + } + + @Test + public void testToAttributeValueV2_DoesNotThrowWhenEmpty_SS() { + Assertions.assertDoesNotThrow(() -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withSS()) + ); + Assertions.assertDoesNotThrow(() -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withSS(Collections.emptyList())) + ); + } + + @Test + public void testToAttributeValueV2_DoesNotThrowWhenEmpty_BS() { + Assertions.assertDoesNotThrow(() -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withBS()) + ); + Assertions.assertDoesNotThrow(() -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withBS(Collections.emptyList())) + ); + } + + @Test + public void testToAttributeValueV2_DoesNotThrowWhenEmpty_L() { + Assertions.assertDoesNotThrow(() -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withL()) + ); + Assertions.assertDoesNotThrow(() -> + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withL(Collections.emptyList())) + ); + } + + @Test + public void testToAttributeValueV2_EmptyV2ObjectWhenEmpty_NS() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue expectedAttributeValue_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().build(); + Assertions.assertEquals(expectedAttributeValue_v2, + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withNS())); + Assertions.assertEquals(expectedAttributeValue_v2, + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withNS(Collections.emptyList()))); + } + + @Test + public void testToAttributeValueV2_EmptyV2ObjectWhenEmpty_SS() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue expectedAttributeValue_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().build(); + Assertions.assertEquals(expectedAttributeValue_v2, + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withSS())); + Assertions.assertEquals(expectedAttributeValue_v2, + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withSS(Collections.emptyList()))); + } + + @Test + public void testToAttributeValueV2_EmptyV2ObjectWhenEmpty_BS() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue expectedAttributeValue_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().build(); + Assertions.assertEquals(expectedAttributeValue_v2, + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withBS())); + Assertions.assertEquals(expectedAttributeValue_v2, + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withBS(Collections.emptyList()))); + } + + @Test + public void testToAttributeValueV2_EmptyV2ObjectWhenEmpty_L() { + software.amazon.awssdk.services.dynamodb.model.AttributeValue expectedAttributeValue_v2 = + software.amazon.awssdk.services.dynamodb.model.AttributeValue.builder().build(); + Assertions.assertEquals(expectedAttributeValue_v2, + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withL())); + Assertions.assertEquals(expectedAttributeValue_v2, + DynamodbAttributeValueTransformer.toAttributeValueV2(new AttributeValue().withL(Collections.emptyList()))); + } + +} \ No newline at end of file diff --git a/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbIdentityTransformerTest.java b/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbIdentityTransformerTest.java new file mode 100644 index 00000000..05356095 --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbIdentityTransformerTest.java @@ -0,0 +1,31 @@ +package com.amazonaws.services.lambda.runtime.events.transformers.dynamodb; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.Identity; + +class DynamodbIdentityTransformerTest { + + private static final String principalId = "1234567890"; + private static final String identityType = "type"; + + //region Identity_event + public static final com.amazonaws.services.dynamodbv2.model.Identity identity_event = new com.amazonaws.services.dynamodbv2.model.Identity() + .withPrincipalId(principalId) + .withType(identityType); + //endregion + + //region Identity_v2 + public static final Identity identity_v2 = Identity.builder() + .principalId(principalId) + .type(identityType) + .build(); + //endregion + + @Test + public void testToIdentityV2() { + Identity convertedIdentity = DynamodbIdentityTransformer.toIdentityV2(identity_event); + Assertions.assertEquals(identity_v2, convertedIdentity); + } + +} \ No newline at end of file diff --git a/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbRecordTransformerTest.java b/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbRecordTransformerTest.java new file mode 100644 index 00000000..69645844 --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbRecordTransformerTest.java @@ -0,0 +1,53 @@ +package com.amazonaws.services.lambda.runtime.events.transformers.dynamodb; + +import com.amazonaws.services.lambda.runtime.events.DynamodbEvent; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.OperationType; +import software.amazon.awssdk.services.dynamodb.model.Record; + +import static com.amazonaws.services.lambda.runtime.events.transformers.dynamodb.DynamodbIdentityTransformerTest.identity_event; +import static com.amazonaws.services.lambda.runtime.events.transformers.dynamodb.DynamodbIdentityTransformerTest.identity_v2; +import static com.amazonaws.services.lambda.runtime.events.transformers.dynamodb.DynamodbStreamRecordTransformerTest.streamRecord_event; +import static com.amazonaws.services.lambda.runtime.events.transformers.dynamodb.DynamodbStreamRecordTransformerTest.streamRecord_v2; + +public class DynamodbRecordTransformerTest { + + private static final String eventId = "2"; + private static final String eventName = OperationType.MODIFY.toString(); + private static final String eventVersion = "1.0"; + private static final String eventSource = "aws:dynamodb"; + private static final String awsRegion = "us-west-2"; + + //region Record_event + public static final DynamodbEvent.DynamodbStreamRecord record_event = (DynamodbEvent.DynamodbStreamRecord) + new DynamodbEvent.DynamodbStreamRecord() + .withEventID(eventId) + .withEventName(eventName) + .withEventVersion(eventVersion) + .withEventSource(eventSource) + .withAwsRegion(awsRegion) + .withDynamodb(streamRecord_event) + .withUserIdentity(identity_event); + //endregion + + //region Record_v2 + public static final Record record_v2 = + Record.builder() + .eventID(eventId) + .eventName(eventName) + .eventVersion(eventVersion) + .eventSource(eventSource) + .awsRegion(awsRegion) + .dynamodb(streamRecord_v2) + .userIdentity(identity_v2) + .build(); + //endregion + + @Test + public void testToRecordV2() { + Record convertedRecord = DynamodbRecordTransformer.toRecordV2(record_event); + Assertions.assertEquals(record_v2, convertedRecord); + } + +} \ No newline at end of file diff --git a/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbStreamRecordTransformerTest.java b/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbStreamRecordTransformerTest.java new file mode 100644 index 00000000..774f0648 --- /dev/null +++ b/aws-lambda-java-events-sdk-transformer/src/test/java/com/amazonaws/services/lambda/runtime/events/transformers/dynamodb/DynamodbStreamRecordTransformerTest.java @@ -0,0 +1,103 @@ +package com.amazonaws.services.lambda.runtime.events.transformers.dynamodb; + +import com.amazonaws.services.dynamodbv2.model.AttributeValue; +import com.amazonaws.services.dynamodbv2.model.StreamViewType; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.StreamRecord; +import software.amazon.awssdk.utils.ImmutableMap; + +import java.util.Date; + +import static com.amazonaws.services.lambda.runtime.events.transformers.dynamodb.DynamodbAttributeValueTransformerTest.*; + +class DynamodbStreamRecordTransformerTest { + + private static final String keyNK = "Id"; + private static final String keyNSK = "KeyNS"; + + private static final String keySK = "SKey"; + private static final String keySSK = "KeySS"; + + private static final String keyBK = "BKey"; + private static final String keyBSK = "KeyBS"; + + private static final String keyBOOLK = "IsBool"; + private static final String keyNULK = "nil"; + + private static final String keyMK = "MapKey"; + + private static final String keyLK = "LongNum"; + + private static final String oldImageSK = "Message"; + private static final String newImageSK = "Message"; + private static final String streamViewType = StreamViewType.NEW_AND_OLD_IMAGES.toString(); + private static final String sequenceNumber = "222"; + private static final Long sizeBytes = 59L; + private static final Date approximateCreationDateTime = new Date(); + + //region StreamRecord_event + public static final com.amazonaws.services.dynamodbv2.model.StreamRecord streamRecord_event = new com.amazonaws.services.dynamodbv2.model.StreamRecord() + .withKeys(ImmutableMap. builder() + .put(keyNK, attributeValueN_event) + .put(keyNSK, attributeValueNS_event) + .put(keySK, attributeValueS_event) + .put(keySSK, attributeValueSS_event) + .put(keyBK, attributeValueB_event) + .put(keyBSK, attributeValueBS_event) + .put(keyBOOLK, attributeValueBOOL_event) + .put(keyNULK, attributeValueNUL_event) + .put(keyMK, attributeValueM_event) + .put(keyLK, attributeValueL_event) + .build() + ) + .withOldImage(ImmutableMap.of( + oldImageSK, attributeValueS_event, + keyNK, attributeValueN_event + )) + .withNewImage(ImmutableMap.of( + newImageSK, attributeValueS_event, + keyNK, attributeValueN_event + )) + .withStreamViewType(StreamViewType.fromValue(streamViewType)) + .withSequenceNumber(sequenceNumber) + .withSizeBytes(sizeBytes) + .withApproximateCreationDateTime(approximateCreationDateTime); + //endregion + + //region StreamRecord_v2 + public static final StreamRecord streamRecord_v2 = StreamRecord.builder() + .approximateCreationDateTime(approximateCreationDateTime.toInstant()) + .keys(ImmutableMap. builder() + .put(keyNK, attributeValueN_v2) + .put(keyNSK, attributeValueNS_v2) + .put(keySK, attributeValueS_v2) + .put(keySSK, attributeValueSS_v2) + .put(keyBK, attributeValueB_v2) + .put(keyBSK, attributeValueBS_v2) + .put(keyBOOLK, attributeValueBOOL_v2) + .put(keyNULK, attributeValueNUL_v2) + .put(keyMK, attributeValueM_v2) + .put(keyLK, attributeValueL_v2) + .build() + ) + .oldImage(ImmutableMap.of( + oldImageSK, attributeValueS_v2, + keyNK, attributeValueN_v2 + )) + .newImage(ImmutableMap.of( + newImageSK, attributeValueS_v2, + keyNK, attributeValueN_v2 + )) + .sequenceNumber(sequenceNumber) + .sizeBytes(sizeBytes) + .streamViewType(streamViewType) + .build(); + //endregion + + @Test + public void testToStreamRecordV2() { + StreamRecord convertedStreamRecord = DynamodbStreamRecordTransformer.toStreamRecordV2(streamRecord_event); + Assertions.assertEquals(streamRecord_v2, convertedStreamRecord); + } +} \ No newline at end of file