This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git
The following commit(s) were added to refs/heads/main by this push: new 86d6469 CAMEL-17846 add tests in camel-aws2-ddb-starter (#481) 86d6469 is described below commit 86d6469810082d17e21ab8e75984b6e8ac03c7ea Author: JiriOndrusek <ondrusek.j...@gmail.com> AuthorDate: Mon Mar 28 11:42:13 2022 +0200 CAMEL-17846 add tests in camel-aws2-ddb-starter (#481) --- components-starter/camel-aws2-ddb-starter/pom.xml | 12 ++ .../org/apache/camel/component/aws2/BaseDdb2.java | 38 +++++ .../component/aws2/ddb/Ddb2BatchGetItemsTest.java | 159 +++++++++++++++++ .../component/aws2/ddb/Ddb2DeleteItemTest.java | 118 +++++++++++++ .../component/aws2/ddb/Ddb2DeleteTableTest.java | 99 +++++++++++ .../aws2/ddb/Ddb2DescribeTableRuleIT.java | 90 ++++++++++ .../camel/component/aws2/ddb/Ddb2GetItemTest.java | 116 +++++++++++++ .../camel/component/aws2/ddb/Ddb2QueryTest.java | 169 ++++++++++++++++++ .../camel/component/aws2/ddb/Ddb2ScanTest.java | 169 ++++++++++++++++++ .../component/aws2/ddb/Ddb2UpdateItemTest.java | 131 ++++++++++++++ .../aws2/ddb/Ddb2UpdateTableByIdTest.java | 88 ++++++++++ .../component/aws2/ddbstream/Ddb2StreamTest.java | 190 +++++++++++++++++++++ 12 files changed, 1379 insertions(+) diff --git a/components-starter/camel-aws2-ddb-starter/pom.xml b/components-starter/camel-aws2-ddb-starter/pom.xml index 6ab92d4..f14870a 100644 --- a/components-starter/camel-aws2-ddb-starter/pom.xml +++ b/components-starter/camel-aws2-ddb-starter/pom.xml @@ -47,6 +47,18 @@ </exclusions> <!--END OF GENERATED CODE--> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test-infra-aws-v2</artifactId> + <version>${camel-version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.awaitility</groupId> + <artifactId>awaitility</artifactId> + <scope>test</scope> + </dependency> <!--START OF GENERATED CODE--> <dependency> <groupId>org.apache.camel.springboot</groupId> diff --git a/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/BaseDdb2.java b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/BaseDdb2.java new file mode 100644 index 0000000..2347f4e --- /dev/null +++ b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/BaseDdb2.java @@ -0,0 +1,38 @@ +package org.apache.camel.component.aws2; + +import org.apache.camel.CamelContext; +import org.apache.camel.Configuration; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.infra.aws2.clients.AWSSDKClientUtils; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.apache.camel.test.infra.aws.common.services.AWSService; +import org.apache.camel.test.infra.aws2.services.AWSServiceFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; + +public class BaseDdb2 { + + @Autowired + protected CamelContext context; + + @Autowired + protected ProducerTemplate template; + + @RegisterExtension + public static AWSService service = AWSServiceFactory.createDynamodbService(); + + // ************************************* + // Config + // ************************************* + + @Configuration + public static class TestConfiguration { + + @Bean + public DynamoDbClient dynamnoDbClient() { + return AWSSDKClientUtils.newDynamoDBClient(); + } + } +} diff --git a/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2BatchGetItemsTest.java b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2BatchGetItemsTest.java new file mode 100644 index 0000000..55520f0 --- /dev/null +++ b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2BatchGetItemsTest.java @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.component.aws2.ddb; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.BaseDdb2; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.infra.aws2.clients.AWSSDKClientUtils; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; +import software.amazon.awssdk.services.dynamodb.model.DeleteTableRequest; +import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.KeysAndAttributes; +import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + Ddb2BatchGetItemsTest.class, + Ddb2BatchGetItemsTest.TestConfiguration.class + } +) +public class Ddb2BatchGetItemsTest extends BaseDdb2 { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private static final String attributeName = "clave"; + private final String secondaryAttributeName = "secondary_attribute"; + private static final String tableName = "TestTableGetBatch"; + private final String retrieveValue = "retrieve"; + private final String notRetrieveValue = "ignore"; + + + @BeforeAll + protected static void setupResources() throws Exception { + DynamoDbClient ddbClient = AWSSDKClientUtils.newDynamoDBClient(); + CreateTableRequest createTableRequest = CreateTableRequest.builder() + .tableName(tableName) + .keySchema( + KeySchemaElement.builder() + .attributeName(attributeName) + .keyType(KeyType.HASH) + .build()) + .attributeDefinitions( + AttributeDefinition.builder() + .attributeType(ScalarAttributeType.S) + .attributeName(attributeName) + .build()) + .provisionedThroughput(ProvisionedThroughput.builder() + .readCapacityUnits(5L) + .writeCapacityUnits(5L) + .build()) + .build(); + ddbClient.createTable(createTableRequest); + } + + @AfterAll + protected static void cleanupResources() throws Exception { + DynamoDbClient ddbClient = AWSSDKClientUtils.newDynamoDBClient(); + DeleteTableRequest deleteTableRequest = DeleteTableRequest.builder() + .tableName(tableName) + .build(); + ddbClient.deleteTable(deleteTableRequest); + } + + @Test + public void batchGetItems() { + putItem(retrieveValue, "1"); + putItem(notRetrieveValue, "0"); + + Exchange exchange = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.BatchGetItems); + e.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + + Map<String, AttributeValue> key = new HashMap<>(); + key.put(attributeName, AttributeValue.builder().s(retrieveValue).build()); + Map<String, KeysAndAttributes> keysAndAttributesMap = new HashMap<>(); + KeysAndAttributes keysAndAttributes = KeysAndAttributes.builder() + .keys(key) + .build(); + keysAndAttributesMap.put(tableName, keysAndAttributes); + e.getIn().setHeader(Ddb2Constants.BATCH_ITEMS, keysAndAttributesMap); + + }); + + assertNull(exchange.getIn().getExchange().getException()); + assertNotNull(exchange.getIn().getHeader(Ddb2Constants.BATCH_RESPONSE)); + assertNotNull(exchange.getIn().getHeader(Ddb2Constants.UNPROCESSED_KEYS)); + } + + private void putItem(String value1, String value2) { + final Map<String, AttributeValue> attributeMap = new HashMap<>(); + attributeMap.put(attributeName, AttributeValue.builder().s(value1).build()); + attributeMap.put(secondaryAttributeName, AttributeValue.builder().s(value2).build()); + + template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.BatchGetItems); + e.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, "true"); + e.getIn().setHeader(Ddb2Constants.RETURN_VALUES, "ALL_OLD"); + e.getIn().setHeader(Ddb2Constants.ITEM, attributeMap); + e.getIn().setHeader(Ddb2Constants.ATTRIBUTE_NAMES, attributeMap.keySet()); + }); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseDdb2.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start").to("aws2-ddb://" + tableName); + } + }; + } + } +} diff --git a/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2DeleteItemTest.java b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2DeleteItemTest.java new file mode 100644 index 0000000..08a9d7b --- /dev/null +++ b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2DeleteItemTest.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.component.aws2.ddb; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.BaseDdb2; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ReturnValue; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + Ddb2DeleteItemTest.class, + Ddb2DeleteItemTest.TestConfiguration.class + } +) +public class Ddb2DeleteItemTest extends BaseDdb2 { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private final String attributeName = "clave"; + private final String tableName = "TestTable"; + + @Test + public void putItem() { + final Map<String, AttributeValue> attributeMap = new HashMap<>(); + AttributeValue attributeValue = AttributeValue.builder().s("hello").build(); + attributeMap.put(attributeName, attributeValue); + attributeMap.put("secondary_attribute", AttributeValue.builder().s("value").build()); + + Exchange exchange = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.PutItem); + exchange.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, "true"); + exchange.getIn().setHeader(Ddb2Constants.RETURN_VALUES, "ALL_OLD"); + exchange.getIn().setHeader(Ddb2Constants.ITEM, attributeMap); + exchange.getIn().setHeader(Ddb2Constants.ATTRIBUTE_NAMES, attributeMap.keySet()); + } + }); + + assertNotNull(exchange.getIn().getHeader(Ddb2Constants.ITEM)); + + HashMap<String, AttributeValue> itemKey = new HashMap<String, AttributeValue>(); + + itemKey.put(attributeName, AttributeValue.builder().s("hello").build()); + + exchange = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.DeleteItem); + exchange.getIn().setHeader(Ddb2Constants.RETURN_VALUES, ReturnValue.ALL_OLD); + exchange.getIn().setHeader(Ddb2Constants.KEY, itemKey); + exchange.getIn().setHeader(Ddb2Constants.ATTRIBUTE_NAMES, attributeMap.keySet()); + } + }); + + assertNotNull(exchange.getIn().getHeader(Ddb2Constants.ATTRIBUTES)); + Map<String, AttributeValue> attributes = exchange.getIn().getHeader(Ddb2Constants.ATTRIBUTES, Map.class); + assertEquals("value", attributes.get("secondary_attribute").s()); + assertEquals("hello", attributes.get("clave").s()); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseDdb2.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start").to( + "aws2-ddb://" + tableName + "?keyAttributeName=" + attributeName + "&keyAttributeType=" + KeyType.HASH + + "&keyScalarType=" + ScalarAttributeType.S + + "&readCapacity=1&writeCapacity=1"); + } + }; + } + } +} diff --git a/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2DeleteTableTest.java b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2DeleteTableTest.java new file mode 100644 index 0000000..765b94e --- /dev/null +++ b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2DeleteTableTest.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.component.aws2.ddb; + +import org.apache.camel.Configuration; +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.BaseDdb2; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.test.annotation.DirtiesContext; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; +import software.amazon.awssdk.services.dynamodb.model.TableStatus; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + Ddb2DeleteTableTest.class, + Ddb2DeleteTableTest.TestConfiguration.class + } +) +public class Ddb2DeleteTableTest extends BaseDdb2 { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private final String attributeName = "clave"; + private final String tableName = "randomTable"; + + @Test + public void deleteTable() { + + //First we run the delete command, which will say the table is still active + Exchange exchange = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.DeleteTable); + exchange.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + } + }); + + assertEquals(tableName, exchange.getIn().getHeader(Ddb2Constants.TABLE_NAME)); + assertEquals(TableStatus.ACTIVE, exchange.getIn().getHeader(Ddb2Constants.TABLE_STATUS)); + + //And... it's gone. + exchange = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.DeleteTable); + exchange.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + } + }); + assertEquals(null, exchange.getIn().getHeader(Ddb2Constants.TABLE_STATUS)); + } + + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseDdb2.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start").to( + "aws2-ddb://" + tableName + "?keyAttributeName=" + attributeName + "&keyAttributeType=" + KeyType.HASH + + "&keyScalarType=" + ScalarAttributeType.S + + "&readCapacity=1&writeCapacity=1"); + } + }; + } + } +} diff --git a/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2DescribeTableRuleIT.java b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2DescribeTableRuleIT.java new file mode 100644 index 0000000..efbe563 --- /dev/null +++ b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2DescribeTableRuleIT.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.component.aws2.ddb; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.BaseDdb2; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; +import software.amazon.awssdk.services.dynamodb.model.TableStatus; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + Ddb2BatchGetItemsTest.class, + Ddb2BatchGetItemsTest.TestConfiguration.class + } +) +public class Ddb2DescribeTableRuleIT extends BaseDdb2 { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private final String attributeName = "clave"; + private final String tableName = "randomTable"; + + @Test + public void describeTable() { + + Exchange exchange = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.DescribeTable); + exchange.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + } + }); + + assertEquals(tableName, exchange.getIn().getHeader(Ddb2Constants.TABLE_NAME)); + assertEquals(TableStatus.ACTIVE, exchange.getIn().getHeader(Ddb2Constants.TABLE_STATUS)); + assertEquals(0L, exchange.getIn().getHeader(Ddb2Constants.TABLE_SIZE)); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseDdb2.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start").to( + "aws2-ddb://" + tableName + "?keyAttributeName=" + attributeName + "&keyAttributeType=" + KeyType.HASH + + "&keyScalarType=" + ScalarAttributeType.S + + "&readCapacity=1&writeCapacity=1"); + } + }; + } + } + +} diff --git a/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2GetItemTest.java b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2GetItemTest.java new file mode 100644 index 0000000..a72d857 --- /dev/null +++ b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2GetItemTest.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.component.aws2.ddb; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.BaseDdb2; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + Ddb2GetItemTest.class, + Ddb2GetItemTest.TestConfiguration.class + } +) +public class Ddb2GetItemTest extends BaseDdb2 { + private Exchange exchange; + + private final String attributeName = "clave"; + private final String tableName = "TestTable"; + + @Autowired + CamelContext context; + + @Test + public void getItem() throws InterruptedException { + final Map<String, AttributeValue> attributeMap = new HashMap<>(); + AttributeValue attributeValue = AttributeValue.builder().s("hello").build(); + attributeMap.put(attributeName, attributeValue); + attributeMap.put("secondary_attribute", AttributeValue.builder().s("value").build()); + + exchange = template.request("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.PutItem); + exchange.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, "true"); + exchange.getIn().setHeader(Ddb2Constants.RETURN_VALUES, "ALL_OLD"); + exchange.getIn().setHeader(Ddb2Constants.ITEM, attributeMap); + exchange.getIn().setHeader(Ddb2Constants.ATTRIBUTE_NAMES, attributeMap.keySet()); + } + }); + assertNotNull(exchange.getIn().getHeader(Ddb2Constants.ITEM)); + + HashMap<String, AttributeValue> itemKey = new HashMap<String, AttributeValue>(); + + itemKey.put(attributeName, AttributeValue.builder().s("hello").build()); + + exchange = template.request("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.GetItem); + exchange.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + exchange.getIn().setHeader(Ddb2Constants.KEY, itemKey); + exchange.getIn().setHeader(Ddb2Constants.ATTRIBUTE_NAMES, attributeMap.keySet()); + } + }); + + assertNotNull(exchange.getIn().getHeader(Ddb2Constants.ATTRIBUTES)); + Map<String, AttributeValue> attributes = exchange.getIn().getHeader(Ddb2Constants.ATTRIBUTES, Map.class); + assertEquals("value", attributes.get("secondary_attribute").s()); + assertEquals("hello", attributes.get("clave").s()); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseDdb2.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start").to( + "aws2-ddb://" + tableName + "?keyAttributeName=" + attributeName + "&keyAttributeType=" + KeyType.HASH + + "&keyScalarType=" + ScalarAttributeType.S + + "&readCapacity=1&writeCapacity=1"); + } + }; + } + } +} diff --git a/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2QueryTest.java b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2QueryTest.java new file mode 100644 index 0000000..78a5b3a --- /dev/null +++ b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2QueryTest.java @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.component.aws2.ddb; + +import org.apache.camel.Configuration; +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.BaseDdb2; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.infra.aws2.clients.AWSSDKClientUtils; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.test.annotation.DirtiesContext; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.ComparisonOperator; +import software.amazon.awssdk.services.dynamodb.model.Condition; +import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; +import software.amazon.awssdk.services.dynamodb.model.DeleteTableRequest; +import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + Ddb2QueryTest.class, + Ddb2QueryTest.TestConfiguration.class + } +) +public class Ddb2QueryTest extends BaseDdb2 { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private final static String attributeName = "clave"; + private final static String secondaryAttributeName = "secondary_attribute"; + private final static String tableName = "TestTableQuery"; + private final String retrieveValue = "retrieve"; + private final String notRetrieveValue = "ignore"; + + @BeforeAll + protected static void setupResources() { + DynamoDbClient ddbClient = AWSSDKClientUtils.newDynamoDBClient(); + + CreateTableRequest createTableRequest = CreateTableRequest.builder() + .tableName(tableName) + .keySchema( + KeySchemaElement.builder() + .attributeName(attributeName) + .keyType(KeyType.HASH) + .build(), + KeySchemaElement.builder() + .attributeName(secondaryAttributeName) + .keyType(KeyType.RANGE) + .build()) + .attributeDefinitions(AttributeDefinition.builder() + .attributeType(ScalarAttributeType.S) + .attributeName(secondaryAttributeName) + .build(), + AttributeDefinition.builder() + .attributeType(ScalarAttributeType.S) + .attributeName(attributeName) + .build()) + .provisionedThroughput(ProvisionedThroughput.builder() + .readCapacityUnits(5L) + .writeCapacityUnits(5L) + .build()) + .build(); + ddbClient.createTable(createTableRequest); + } + + @AfterAll + protected static void cleanupResources() { + DynamoDbClient ddbClient = AWSSDKClientUtils.newDynamoDBClient(); + + DeleteTableRequest deleteTableRequest = DeleteTableRequest.builder() + .tableName(tableName) + .build(); + ddbClient.deleteTable(deleteTableRequest); + } + + @Test + public void queryItems() { + + putItem(retrieveValue, "uno"); + putItem(retrieveValue, "dos"); + putItem(retrieveValue, "tres"); + putItem(notRetrieveValue, "Ignore me"); + putItem(notRetrieveValue, "I should not be returned"); + + Exchange exchange = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.Query); + e.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + Map<String, Condition> keyConditions = new HashMap<>(); + keyConditions.put(attributeName, Condition.builder().comparisonOperator( + ComparisonOperator.EQ.toString()) + .attributeValueList(AttributeValue.builder().s(retrieveValue).build()) + .build()); + e.getIn().setHeader(Ddb2Constants.KEY_CONDITIONS, keyConditions); + }); + + assertNotNull(exchange.getIn().getHeader(Ddb2Constants.ITEMS)); + assertEquals(3, exchange.getIn().getHeader(Ddb2Constants.COUNT)); + } + + private void putItem(String value1, String value2) { + final Map<String, AttributeValue> attributeMap = new HashMap<>(); + attributeMap.put(attributeName, AttributeValue.builder().s(value1).build()); + attributeMap.put(secondaryAttributeName, AttributeValue.builder().s(value2).build()); + + Exchange ex = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.PutItem); + e.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, "true"); + e.getIn().setHeader(Ddb2Constants.RETURN_VALUES, "ALL_OLD"); + e.getIn().setHeader(Ddb2Constants.ITEM, attributeMap); + e.getIn().setHeader(Ddb2Constants.ATTRIBUTE_NAMES, attributeMap.keySet()); + }); + } + + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseDdb2.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start").to( + "aws2-ddb://" + tableName); + } + }; + } + } +} \ No newline at end of file diff --git a/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2ScanTest.java b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2ScanTest.java new file mode 100644 index 0000000..9e51529 --- /dev/null +++ b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2ScanTest.java @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.component.aws2.ddb; + +import org.apache.camel.Configuration; +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.BaseDdb2; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.infra.aws2.clients.AWSSDKClientUtils; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.test.annotation.DirtiesContext; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.ComparisonOperator; +import software.amazon.awssdk.services.dynamodb.model.Condition; +import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; +import software.amazon.awssdk.services.dynamodb.model.CreateTableResponse; +import software.amazon.awssdk.services.dynamodb.model.DeleteTableRequest; +import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + Ddb2ScanTest.class, + Ddb2ScanTest.TestConfiguration.class + } +) +public class Ddb2ScanTest extends BaseDdb2 { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private final static String attributeName = "clave"; + private final static String secondaryAttributeName = "secondary_attribute"; + private final static String tableName = "TestTableScan"; + private final String retrieveValue = "retrieve"; + private final String notRetrieveValue = "ignore"; + + @BeforeAll + protected static void setupResources() throws Exception { + DynamoDbClient ddbClient = AWSSDKClientUtils.newDynamoDBClient(); + + CreateTableRequest createTableRequest = CreateTableRequest.builder() + .tableName(tableName) + .keySchema( + KeySchemaElement.builder() + .attributeName(attributeName) + .keyType(KeyType.HASH) + .build(), + KeySchemaElement.builder() + .attributeName(secondaryAttributeName) + .keyType(KeyType.RANGE) + .build()) + .attributeDefinitions(AttributeDefinition.builder() + .attributeType(ScalarAttributeType.S) + .attributeName(secondaryAttributeName) + .build(), + AttributeDefinition.builder() + .attributeType(ScalarAttributeType.S) + .attributeName(attributeName) + .build()) + .provisionedThroughput(ProvisionedThroughput.builder() + .readCapacityUnits(5L) + .writeCapacityUnits(5L) + .build()) + .build(); + CreateTableResponse res = ddbClient.createTable(createTableRequest); + } + + @AfterAll + protected static void cleanupResources() { + DynamoDbClient ddbClient = AWSSDKClientUtils.newDynamoDBClient(); + + DeleteTableRequest deleteTableRequest = DeleteTableRequest.builder() + .tableName(tableName) + .build(); + ddbClient.deleteTable(deleteTableRequest); + } + + @Test + public void scan() { + + putItem(notRetrieveValue, "0"); + putItem(notRetrieveValue, "4"); + + putItem(retrieveValue, "1"); + putItem(retrieveValue, "2"); + putItem(retrieveValue, "3"); + + Exchange exchange = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.Scan); + e.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + Map<String, Condition> keyConditions = new HashMap<>(); + keyConditions.put(attributeName, Condition.builder().comparisonOperator( + ComparisonOperator.EQ.toString()) + .attributeValueList(AttributeValue.builder().s(retrieveValue).build()) + .build()); + e.getIn().setHeader(Ddb2Constants.SCAN_FILTER, keyConditions); + }); + + assertNotNull(exchange.getIn().getHeader(Ddb2Constants.ITEMS)); + assertEquals(3, exchange.getIn().getHeader(Ddb2Constants.COUNT)); + } + + private void putItem(String value1, String value2) { + final Map<String, AttributeValue> attributeMap = new HashMap<>(); + attributeMap.put(attributeName, AttributeValue.builder().s(value1).build()); + attributeMap.put(secondaryAttributeName, AttributeValue.builder().s(value2).build()); + + template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.PutItem); + e.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, "true"); + e.getIn().setHeader(Ddb2Constants.RETURN_VALUES, "ALL_OLD"); + e.getIn().setHeader(Ddb2Constants.ITEM, attributeMap); + e.getIn().setHeader(Ddb2Constants.ATTRIBUTE_NAMES, attributeMap.keySet()); + }); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseDdb2.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start").to("aws2-ddb://" + tableName); + } + }; + } + } +} diff --git a/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2UpdateItemTest.java b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2UpdateItemTest.java new file mode 100644 index 0000000..62bb452 --- /dev/null +++ b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2UpdateItemTest.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.component.aws2.ddb; + +import org.apache.camel.Configuration; +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.BaseDdb2; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.test.annotation.DirtiesContext; +import software.amazon.awssdk.services.dynamodb.model.AttributeAction; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.AttributeValueUpdate; +import software.amazon.awssdk.services.dynamodb.model.ComparisonOperator; +import software.amazon.awssdk.services.dynamodb.model.ExpectedAttributeValue; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + Ddb2UpdateItemTest.class, + Ddb2UpdateItemTest.TestConfiguration.class + } +) +public class Ddb2UpdateItemTest extends BaseDdb2 { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private final String attributeName = "clave"; + private final String tableName = "TestTable"; + + @Test + public void putItem() { + final Map<String, AttributeValue> attributeMap = new HashMap<>(); + AttributeValue attributeValue = AttributeValue.builder().s("hello").build(); + attributeMap.put(attributeName, attributeValue); + attributeMap.put("secondary_attribute", AttributeValue.builder().s("value").build()); + + Exchange exchange = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.PutItem); + exchange.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, "true"); + exchange.getIn().setHeader(Ddb2Constants.RETURN_VALUES, "ALL_OLD"); + exchange.getIn().setHeader(Ddb2Constants.ITEM, attributeMap); + exchange.getIn().setHeader(Ddb2Constants.ATTRIBUTE_NAMES, attributeMap.keySet()); + } + }); + + assertNotNull(exchange.getIn().getHeader(Ddb2Constants.ITEM)); + + HashMap<String, AttributeValue> itemKey = new HashMap<String, AttributeValue>(); + + itemKey.put(attributeName, AttributeValue.builder().s("hello").build()); + + Map<String, ExpectedAttributeValue> expectedAttributeValueMap = new HashMap<>(); + expectedAttributeValueMap.put(attributeName, + ExpectedAttributeValue.builder().comparisonOperator(ComparisonOperator.EQ) + .attributeValueList(AttributeValue.builder().s("hello").build()).build()); + HashMap<String, AttributeValueUpdate> attributeMapUpdated = new HashMap<String, AttributeValueUpdate>(); + + attributeMapUpdated.put("secondary_attribute", AttributeValueUpdate.builder() + .value(AttributeValue.builder().s("new").build()) + .action(AttributeAction.PUT) + .build()); + + exchange = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.KEY, itemKey); + exchange.getIn().setHeader(Ddb2Constants.UPDATE_VALUES, attributeMapUpdated); + exchange.getIn().setHeader(Ddb2Constants.RETURN_VALUES, "ALL_NEW"); + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.UpdateItem); + exchange.getIn().setHeader(Ddb2Constants.UPDATE_CONDITION, expectedAttributeValueMap); + } + }); + + assertNotNull(exchange.getIn().getHeader(Ddb2Constants.ATTRIBUTES)); + Map<String, AttributeValue> attributes = exchange.getIn().getHeader(Ddb2Constants.ATTRIBUTES, Map.class); + assertEquals("new", attributes.get("secondary_attribute").s()); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseDdb2.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start").to( + "aws2-ddb://" + tableName + "?keyAttributeName=" + attributeName + "&keyAttributeType=" + KeyType.HASH + + "&keyScalarType=" + ScalarAttributeType.S + + "&readCapacity=1&writeCapacity=1"); + } + }; + } + } +} diff --git a/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2UpdateTableByIdTest.java b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2UpdateTableByIdTest.java new file mode 100644 index 0000000..0acf42c --- /dev/null +++ b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddb/Ddb2UpdateTableByIdTest.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.component.aws2.ddb; + +import org.apache.camel.Configuration; +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.BaseDdb2; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.test.annotation.DirtiesContext; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + Ddb2UpdateTableByIdTest.class, + Ddb2UpdateTableByIdTest.TestConfiguration.class + } +) +public class Ddb2UpdateTableByIdTest extends BaseDdb2 { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private final String attributeName = "clave"; + private final String tableName = "TestTableUpdate"; + + @Test + public void updateTable() { + + Exchange exchange = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.UpdateTable); + exchange.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + exchange.getIn().setHeader(Ddb2Constants.READ_CAPACITY, 20L); + } + }); + + assertEquals(Long.valueOf(20), exchange.getIn().getHeader(Ddb2Constants.READ_CAPACITY)); + } + + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseDdb2.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start").to( + "aws2-ddb://" + tableName + "?keyAttributeName=" + attributeName + "&keyAttributeType=" + KeyType.HASH + + "&keyScalarType=" + ScalarAttributeType.S + + "&readCapacity=1&writeCapacity=1"); + } + }; + } + } +} diff --git a/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddbstream/Ddb2StreamTest.java b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddbstream/Ddb2StreamTest.java new file mode 100644 index 0000000..94b3fdc --- /dev/null +++ b/components-starter/camel-aws2-ddb-starter/src/test/java/org/apache/camel/component/aws2/ddbstream/Ddb2StreamTest.java @@ -0,0 +1,190 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.component.aws2.ddbstream; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import org.apache.camel.EndpointInject; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.BaseDdb2; +import org.apache.camel.component.aws2.ddb.Ddb2Constants; +import org.apache.camel.component.aws2.ddb.Ddb2Operations; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.infra.aws2.clients.AWSSDKClientUtils; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; +import software.amazon.awssdk.services.dynamodb.model.CreateTableResponse; +import software.amazon.awssdk.services.dynamodb.model.DeleteTableRequest; +import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; +import software.amazon.awssdk.services.dynamodb.model.StreamSpecification; +import software.amazon.awssdk.services.dynamodb.model.StreamViewType; + +import static org.awaitility.Awaitility.await; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + Ddb2StreamTest.class, + Ddb2StreamTest.TestConfiguration.class + } +) +class Ddb2StreamTest extends BaseDdb2{ + + private final static String tableName = "TestTable"; + + @EndpointInject("mock:result") + private MockEndpoint resultEndpoint; + + @BeforeAll + protected static void setupResources() throws Exception { + DynamoDbClient ddbClient = AWSSDKClientUtils.newDynamoDBClient(); + + CreateTableRequest createTableRequest = createTableRequest(tableName, "key").build(); + CreateTableResponse res = ddbClient.createTable(createTableRequest); + } + + @AfterAll + protected static void cleanupResources() { + DynamoDbClient ddbClient = AWSSDKClientUtils.newDynamoDBClient(); + + DeleteTableRequest deleteTableRequest = DeleteTableRequest.builder() + .tableName(tableName) + .build(); + ddbClient.deleteTable(deleteTableRequest); + } + + private static CreateTableRequest.Builder createTableRequest(String tableName, String keyColumn) { + CreateTableRequest.Builder builder = CreateTableRequest.builder() + .attributeDefinitions(AttributeDefinition.builder() + .attributeName(keyColumn) + .attributeType(ScalarAttributeType.S) + .build()) + .keySchema(KeySchemaElement.builder() + .attributeName(keyColumn) + .keyType(KeyType.HASH) + .build()) + .provisionedThroughput(ProvisionedThroughput.builder() + .readCapacityUnits(10L) + .writeCapacityUnits(10L) + .build()) + .streamSpecification(StreamSpecification.builder() + .streamEnabled(true) + .streamViewType(StreamViewType.NEW_AND_OLD_IMAGES) + .build()); + + return builder.tableName(tableName); + } + + @Test + public void stream() throws InterruptedException { + final String key1 = "key-" + UUID.randomUUID().toString().replace("-", ""); + final String msg1 = "val" + UUID.randomUUID().toString().replace("-", ""); + + //try periodically receive stream event. We do not know, when the consumer is started, therefore we try it several times + //if one event is returned, stream consumer works + await().pollInterval(2, TimeUnit.SECONDS).atMost(30, TimeUnit.SECONDS).until(() -> { + boolean res = !resultEndpoint.getReceivedExchanges().isEmpty(); + if(!res) { + resultEndpoint.reset(); + //insert new item for the test + insertItem(key1, msg1); + } + return res; + }); + } + + private void insertItem(String key1, String msg1) { + final Map<String, AttributeValue> item = new HashMap<>() { + { + put("key", AttributeValue.builder() + .s(key1).build()); + put("value", AttributeValue.builder() + .s(msg1).build()); + } + }; + + template.sendBodyAndHeaders( + "aws2-ddb://" + tableName + "?operation=" + Ddb2Operations.PutItem, + null, + new HashMap<>() { + { + put( + Ddb2Constants.CONSISTENT_READ, + true); + put( + Ddb2Constants.ITEM, + item); + } + }); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseDdb2.TestConfiguration{ + + @Bean + public RouteBuilder routeBuilder() { + return new RouteBuilder() { + + @Override + public void configure() { + //{aws.secret.key=secretkey, aws.region=us-east-1, aws.access.key=accesskey, aws.host=localhost:49242, aws.protocol=http} + String auth = service.getConnectionProperties().entrySet().stream() + .map(e1 -> { + switch (String.valueOf(e1.getKey())) { + case "aws.secret.key": + return "secretKey=" + e1.getValue(); + case "aws.region": + return "region=" + e1.getValue(); + case "aws.access.key": + return "accessKey=" + e1.getValue(); + case "aws.host": + return "overrideEndpoint=true&uriEndpointOverride=http://" + e1.getValue(); + default: return ""; + }}) + .filter(e -> !"".equals(e)) + .collect(Collectors.joining("&")); + + from("aws2-ddbstream://" + tableName + "?" + auth).to("mock:result"); + } + }; + } + } +}