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");
+                }
+            };
+        }
+    }
+}