You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/03/28 09:42:18 UTC
[camel-spring-boot] branch main updated: CAMEL-17846 add tests in camel-aws2-ddb-starter (#481)
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 <on...@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");
+ }
+ };
+ }
+ }
+}