= AWS DynamoDB Component
:doctitle: AWS DynamoDB
:shortname: aws2-ddb
:artifactid: camel-aws2-ddb
:description: Store and retrieve data from AWS DynamoDB service using AWS SDK version 2.x.
:since: 3.1
:supportlevel: Stable
:component-header: Only producer is supported
//Manually maintained attributes
:group: AWS
:camel-spring-boot-name: aws2-ddb

*Since Camel {since}*

*{component-header}*

The AWS2 DynamoDB component supports storing and retrieving data from/to
https://aws.amazon.com/dynamodb[Amazon's DynamoDB] service.

Prerequisites

You must have a valid Amazon Web Services developer account, and be
signed up to use Amazon DynamoDB. More information is available at
https://aws.amazon.com/dynamodb[Amazon DynamoDB].


== URI Format

------------------------------
aws2-ddb://domainName[?options]
------------------------------

You can append query options to the URI in the following format,
?options=value&option2=value&...


// component-configure options: START

// component-configure options: END

// component options: START
include::partial$component-configure-options.adoc[]
include::partial$component-endpoint-options.adoc[]
// component options: END

// endpoint options: START

// endpoint options: END

Required DDB component options

You have to provide the amazonDDBClient in the
Registry or your accessKey and secretKey to access
the https://aws.amazon.com/dynamodb[Amazon's DynamoDB].

== Usage

=== Static credentials vs Default Credential Provider

You have the possibility of avoiding the usage of explicit static credentials, by specifying the useDefaultCredentialsProvider option and set it to true.

 - Java system properties - aws.accessKeyId and aws.secretKey
 - Environment variables - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
 - Web Identity Token from AWS STS.
 - The shared credentials and config files.
 - Amazon ECS container credentials - loaded from the Amazon ECS if the environment variable AWS_CONTAINER_CREDENTIALS_RELATIVE_URI is set.
 - Amazon EC2 Instance profile credentials. 

For more information about this you can look at https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials.html[AWS credentials documentation]

// component headers: START
include::partial$component-endpoint-headers.adoc[]
// component headers: END

=== Advanced AmazonDynamoDB configuration

If you need more control over the `AmazonDynamoDB` instance
configuration you can create your own instance and refer to it from the
URI:

[source,java]
----------------------------------------------------
public class MyRouteBuilder extends RouteBuilder {

    private String accessKey = "myaccessKey";
    private String secretKey = "secretKey";

    @Override
    public void configure() throws Exception {

        DynamoDbClient client = DynamoDbClient.builder()
        .region(Region.AP_SOUTHEAST_2)
        .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, secretKey)))
        .build();

        getCamelContext().getRegistry().bind("client", client);

    	from("direct:start")
        .to("aws2-ddb://domainName?amazonDDBClient=#client");
    }
}
----------------------------------------------------

The `#client` refers to a `DynamoDbClient` in the
Registry.

== Supported producer operations

- BatchGetItems
- DeleteItem
- DeleteTable
- DescribeTable
- GetItem
- PutItem
- Query
- Scan
- UpdateItem
- UpdateTable

== Dependencies

Maven users will need to add the following dependency to their pom.xml.

*pom.xml*

[source,xml]
---------------------------------------
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-aws2-ddb</artifactId>
    <version>${camel-version}</version>
</dependency>
---------------------------------------

where `$\{camel-version}` must be replaced by the actual version of Camel.

== Examples

=== Producer Examples

- PutItem: this operation will create an entry into DynamoDB

[source,java]
--------------------------------------------------------------------------------
Map<String, AttributeValue> attributeMap = new HashMap<>();
attributeMap.put("partitionKey", AttributeValue.builder().s("3000").build());
attributeMap.put("id", AttributeValue.builder().s("1001").build());
attributeMap.put("barcode", AttributeValue.builder().s("9002811220001").build());

from("direct:start")
  .setHeader(Ddb2Constants.OPERATION,  constant(Ddb2Operations.PutItem))
  .setHeader(Ddb2Constants.CONSISTENT_READ, constant("true"))
  .setHeader(Ddb2Constants.RETURN_VALUES, constant("ALL_OLD"))
  .setHeader(Ddb2Constants.ITEM, constant(attributeMap))
  .setHeader(Ddb2Constants.ATTRIBUTE_NAMES, constant(attributeMap.keySet()))
  .to("aws2-ddb://" + tableName + "?amazonDDBClient=#client");
--------------------------------------------------------------------------------

- UpdateItem: this operation will update an entry into DynamoDB

[source,java]
--------------------------------------------------------------------------------
Map<String, AttributeValueUpdate> attributeMap = new HashMap<>();
attributeMap.put("partitionKey", AttributeValueUpdate.builder().value(AttributeValue.builder().s("3000").build()).build());
attributeMap.put("sortKey",  AttributeValueUpdate.builder().value(AttributeValue.builder().s("1001").build()).build());
attributeMap.put("borcode",  AttributeValueUpdate.builder().value(AttributeValue.builder().s("900281122").build()).build());

Map<String, AttributeValue> keyMap = new HashMap<>();
keyMap.put("partitionKey", AttributeValue.builder().s("3000").build());
keyMap.put("sortKey", AttributeValue.builder().s("1001").build());

from("direct:start")
  .setHeader(Ddb2Constants.OPERATION,  constant(Ddb2Operations.UpdateItem))
  .setHeader(Ddb2Constants.ITEM,  constant(attributeMap))
  .setHeader(Ddb2Constants.KEY,  constant(keyMap))
  .to("aws2-ddb://" + tableName + "?amazonDDBClient=#client");
--------------------------------------------------------------------------------

- GetItem: this operation will retrieve an entry from DynamoDB

[source,java]
--------------------------------------------------------------------------------
from("direct:get")
  .process(exchange -> {
      final Map<String, AttributeValue> keyMap = new HashMap<>();
      keyMap.put("table-key", AttributeValue.builder().s("1").build());

      exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.GetItem);
      exchange.getIn().setHeader(Ddb2Constants.ATTRIBUTE_NAMES, constant(List.of("table-key", "message")));
      exchange.getIn().setHeader(Ddb2Constants.KEY, keyMap);
  })
  .toF("aws2-ddb://%s?amazonDDBClient=#client&consistentRead=true", tableName);
--------------------------------------------------------------------------------

- DeleteItem: this operation will delete an entry from DynamoDB

[source,java]
--------------------------------------------------------------------------------
from("direct:delete")
  .process(exchange -> {
      final Map<String, AttributeValue> keyMap = new HashMap<>();
      keyMap.put("table-key", AttributeValue.builder().s("1").build());

      exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.DeleteItem);
      exchange.getIn().setHeader(Ddb2Constants.KEY, keyMap);
  })
  .toF("aws2-ddb://%s?amazonDDBClient=#client&consistentRead=true", tableName);
--------------------------------------------------------------------------------


include::spring-boot:partial$starter.adoc[]
