This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch CAMEL-23229 in repository https://gitbox.apache.org/repos/asf/camel.git
commit 57d5e3c4948a5626c84399b12b3ebc790d619136 Author: Andrea Cosentino <[email protected]> AuthorDate: Mon Mar 23 10:36:19 2026 +0100 CAMEL-23229 - Camel-AWS2-DDB: Add PartiQL, transactional, and batch write operations Add 5 new operations to the AWS DynamoDB component: - ExecuteStatement: PartiQL single statement with pagination support - BatchExecuteStatement: PartiQL batch statement execution - TransactWriteItems: ACID transactional writes with idempotency token - TransactGetItems: ACID transactional reads - BatchWriteItem: Batch put/delete across tables Added 14 new header constants, 5 command classes, 5 unit test classes (7 tests), 5 LocalStack integration tests, and documentation with examples for all new operations. Signed-off-by: Andrea Cosentino <[email protected]> --- .../apache/camel/catalog/components/aws2-ddb.json | 26 +- .../apache/camel/component/aws2/ddb/aws2-ddb.json | 26 +- .../src/main/docs/aws2-ddb-component.adoc | 99 +++++++ .../aws2/ddb/BatchExecuteStatementCommand.java | 51 ++++ .../component/aws2/ddb/BatchWriteItemCommand.java | 51 ++++ .../camel/component/aws2/ddb/Ddb2Constants.java | 48 ++++ .../camel/component/aws2/ddb/Ddb2Operations.java | 5 + .../camel/component/aws2/ddb/Ddb2Producer.java | 15 + .../aws2/ddb/ExecuteStatementCommand.java | 68 +++++ .../aws2/ddb/TransactGetItemsCommand.java | 51 ++++ .../aws2/ddb/TransactWriteItemsCommand.java | 50 ++++ .../component/aws2/ddb/AmazonDDBClientMock.java | 56 ++++ .../aws2/ddb/BatchExecuteStatementCommandTest.java | 70 +++++ .../aws2/ddb/BatchWriteItemCommandTest.java | 77 +++++ .../aws2/ddb/ExecuteStatementCommandTest.java | 84 ++++++ .../aws2/ddb/TransactGetItemsCommandTest.java | 75 +++++ .../aws2/ddb/TransactWriteItemsCommandTest.java | 87 ++++++ .../AWS2BatchExecuteStatementRuleIT.java | 80 ++++++ .../ddb/localstack/AWS2BatchWriteItemRuleIT.java | 87 ++++++ .../ddb/localstack/AWS2ExecuteStatementRuleIT.java | 89 ++++++ .../ddb/localstack/AWS2NewOperationsRuleIT.java | 312 +++++++++++++++++++++ .../ddb/localstack/AWS2TransactGetItemsRuleIT.java | 94 +++++++ .../localstack/AWS2TransactWriteItemsRuleIT.java | 85 ++++++ .../endpoint/dsl/Ddb2EndpointBuilderFactory.java | 160 +++++++++++ 24 files changed, 1832 insertions(+), 14 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws2-ddb.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws2-ddb.json index dd56918fcf92..de317a7843b7 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws2-ddb.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws2-ddb.json @@ -31,7 +31,7 @@ "keyAttributeType": { "index": 4, "kind": "property", "displayName": "Key Attribute Type", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "Attribute type when creating table" }, "keyScalarType": { "index": 5, "kind": "property", "displayName": "Key Scalar Type", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "The key scalar type, it can be S (String), N (Number) and B (Bytes)" }, "lazyStartProducer": { "index": 6, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail [...] - "operation": { "index": 7, "kind": "property", "displayName": "Operation", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "org.apache.camel.component.aws2.ddb.Ddb2Operations", "enum": [ "BatchGetItems", "DeleteItem", "DeleteTable", "DescribeTable", "GetItem", "PutItem", "Query", "Scan", "UpdateItem", "UpdateTable" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "PutItem", "configurationClass": "org.apache.camel.component. [...] + "operation": { "index": 7, "kind": "property", "displayName": "Operation", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "org.apache.camel.component.aws2.ddb.Ddb2Operations", "enum": [ "BatchGetItems", "BatchWriteItem", "BatchExecuteStatement", "DeleteItem", "DeleteTable", "DescribeTable", "ExecuteStatement", "GetItem", "PutItem", "Query", "Scan", "TransactGetItems", "TransactWriteItems", "UpdateItem", "UpdateTable" ], "deprecated": false, "autowire [...] "overrideEndpoint": { "index": 8, "kind": "property", "displayName": "Override Endpoint", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "Set the need for overriding the endpoint. This option needs to be used in combination wi [...] "readCapacity": { "index": 9, "kind": "property", "displayName": "Read Capacity", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "The provisioned throughput to reserve for reading resources from your table" }, "region": { "index": 10, "kind": "property", "displayName": "Region", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "ap-south-2", "ap-south-1", "eu-south-1", "eu-south-2", "us-gov-east-1", "me-central-1", "il-central-1", "ca-central-1", "eu-central-1", "us-iso-west-1", "eu-central-2", "eu-isoe-west-1", "us-west-1", "us-west-2", "af-south-1", "eu-north-1", "eu-west-3", "eu-west-2", "eu-west-1", "ap-northeast-3", "ap-nort [...] @@ -72,7 +72,7 @@ "CamelAwsDdbLastEvaluatedKey": { "index": 15, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "Key", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Primary key of the item where the query operation stopped, inclusive of the previous result set.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#LAST_EVALUATED_KEY" }, "CamelAwsDdbIsTruncated": { "index": 16, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Whether the response has more results (is truncated). If true, use LAST_EVALUATED_KEY as START_KEY for the next page.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#IS_TRUNCATED" }, "CamelAwsDdbLimit": { "index": 17, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The maximum number of items to return.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#LIMIT" }, - "CamelAwsDdbOperation": { "index": 18, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "org.apache.camel.component.aws2.ddb.Ddb2Operations", "enum": [ "BatchGetItems", "DeleteItem", "DeleteTable", "DescribeTable", "GetItem", "PutItem", "Query", "Scan", "UpdateItem", "UpdateTable" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The operation to perform.", "constantName": "org.apac [...] + "CamelAwsDdbOperation": { "index": 18, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "org.apache.camel.component.aws2.ddb.Ddb2Operations", "enum": [ "BatchGetItems", "BatchWriteItem", "BatchExecuteStatement", "DeleteItem", "DeleteTable", "DescribeTable", "ExecuteStatement", "GetItem", "PutItem", "Query", "Scan", "TransactGetItems", "TransactWriteItems", "UpdateItem", "UpdateTable" ], "deprecated": false, "deprecationNote": "", " [...] "CamelAwsDdbProvisionedThroughput": { "index": 19, "kind": "header", "displayName": "", "group": "DeleteTable DescribeTable", "label": "DeleteTable DescribeTable", "required": false, "javaType": "software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughputDescription", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The value of the ProvisionedThroughput property for this table", "constantName": "org.apache.camel.component.aws2 [...] "CamelAwsDdbReadCapacity": { "index": 20, "kind": "header", "displayName": "", "group": "UpdateTable DescribeTable", "label": "UpdateTable DescribeTable", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "ReadCapacityUnits property of this table.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#READ_CAPACITY" }, "CamelAwsDdbReturnValues": { "index": 21, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Use this parameter if you want to get the attribute name-value pairs before or after they are modified(NONE, ALL_OLD, UPDATED_OLD, ALL_NEW, UPDATED_NEW).", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#RETURN_VALUES" }, @@ -87,10 +87,22 @@ "CamelAwsDdbUpdateValues": { "index": 30, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Map<String, AttributeValueUpdate>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Map of attribute name to the new value and action for the update.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#UPDATE_VALUES" }, "CamelAwsDdbUnprocessedKeys": { "index": 31, "kind": "header", "displayName": "", "group": "BatchGetItems", "label": "BatchGetItems", "required": false, "javaType": "Map<String,KeysAndAttributes>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Contains a map of tables and their respective keys that were not processed with the current response.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#UNPROCESSED_KEYS" }, "CamelAwsDdbWriteCapacity": { "index": 32, "kind": "header", "displayName": "", "group": "UpdateTable DescribeTable", "label": "UpdateTable DescribeTable", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "WriteCapacityUnits property of this table.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#WRITE_CAPACITY" }, - "CamelAwsDdbFilterExpression": { "index": 33, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Filter Expression.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#FILTER_EXPRESSION" }, - "CamelAwsDdbFilterExpressionAttributeNames": { "index": 34, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "Map<String, String>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Filter Expression Attribute Names.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#FILTER_EXPRESSION_ATTRIBUTE_NAMES" }, - "CamelAwsDdbFilterExpressionAttributeValues": { "index": 35, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "Map<String, String>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Filter Expression Attribute Values.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#FILTER_EXPRESSION_ATTRIBUTE_VALUES" }, - "CamelAwsDdbProjectExpression": { "index": 36, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Project Expression.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#PROJECT_EXPRESSION" } + "CamelAwsDdbStatement": { "index": 33, "kind": "header", "displayName": "", "group": "ExecuteStatement BatchExecuteStatement", "label": "ExecuteStatement BatchExecuteStatement", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "A PartiQL statement that uses parameters.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#STATEMENT" }, + "CamelAwsDdbStatementParameters": { "index": 34, "kind": "header", "displayName": "", "group": "ExecuteStatement BatchExecuteStatement", "label": "ExecuteStatement BatchExecuteStatement", "required": false, "javaType": "java.util.List<software.amazon.awssdk.services.dynamodb.model.AttributeValue>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The parameters for the PartiQL statement, if any.", "constantName": "org.apache.camel.compo [...] + "CamelAwsDdbBatchStatements": { "index": 35, "kind": "header", "displayName": "", "group": "BatchExecuteStatement", "label": "BatchExecuteStatement", "required": false, "javaType": "java.util.List<software.amazon.awssdk.services.dynamodb.model.BatchStatementRequest>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The list of PartiQL statements representing the batch to run.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2C [...] + "CamelAwsDdbExecuteStatementItems": { "index": 36, "kind": "header", "displayName": "", "group": "ExecuteStatement", "label": "ExecuteStatement", "required": false, "javaType": "java.util.List<java.util.Map<String, software.amazon.awssdk.services.dynamodb.model.AttributeValue>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response items from an ExecuteStatement operation.", "constantName": "org.apache.camel.component.aws2.ddb. [...] + "CamelAwsDdbExecuteStatementNextToken": { "index": 37, "kind": "header", "displayName": "", "group": "ExecuteStatement", "label": "ExecuteStatement", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The next token from an ExecuteStatement operation for pagination.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#EXECUTE_STATEMENT_NEXT_TOKEN" }, + "CamelAwsDdbBatchStatementResponse": { "index": 38, "kind": "header", "displayName": "", "group": "BatchExecuteStatement", "label": "BatchExecuteStatement", "required": false, "javaType": "java.util.List<software.amazon.awssdk.services.dynamodb.model.BatchStatementResponse>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response to each PartiQL statement in the batch.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Co [...] + "CamelAwsDdbTransactWriteItems": { "index": 39, "kind": "header", "displayName": "", "group": "TransactWriteItems", "label": "TransactWriteItems", "required": false, "javaType": "java.util.List<software.amazon.awssdk.services.dynamodb.model.TransactWriteItem>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The list of TransactWriteItem objects for a transactional write.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Const [...] + "CamelAwsDdbTransactClientRequestToken": { "index": 40, "kind": "header", "displayName": "", "group": "TransactWriteItems", "label": "TransactWriteItems", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "A unique client request token for idempotent TransactWriteItems calls.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#TRANSACT_CLIENT_REQUEST_TOKEN" }, + "CamelAwsDdbTransactGetItems": { "index": 41, "kind": "header", "displayName": "", "group": "TransactGetItems", "label": "TransactGetItems", "required": false, "javaType": "java.util.List<software.amazon.awssdk.services.dynamodb.model.TransactGetItem>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The list of TransactGetItem objects for a transactional read.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#TRANSA [...] + "CamelAwsDdbTransactGetResponse": { "index": 42, "kind": "header", "displayName": "", "group": "TransactGetItems", "label": "TransactGetItems", "required": false, "javaType": "java.util.List<software.amazon.awssdk.services.dynamodb.model.ItemResponse>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response from a TransactGetItems operation.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#TRANSACT_GET_RESPONSE" }, + "CamelAwsDdbBatchWriteItems": { "index": 43, "kind": "header", "displayName": "", "group": "BatchWriteItem", "label": "BatchWriteItem", "required": false, "javaType": "java.util.Map<String, java.util.List<software.amazon.awssdk.services.dynamodb.model.WriteRequest>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "A map of table names to lists of WriteRequest objects for batch writes.", "constantName": "org.apache.camel.component.aws2 [...] + "CamelAwsDdbBatchWriteUnprocessedItems": { "index": 44, "kind": "header", "displayName": "", "group": "BatchWriteItem", "label": "BatchWriteItem", "required": false, "javaType": "java.util.Map<String, java.util.List<software.amazon.awssdk.services.dynamodb.model.WriteRequest>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "A map of tables and their respective unprocessed items after a BatchWriteItem operation.", "constantName": "org [...] + "CamelAwsDdbFilterExpression": { "index": 45, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Filter Expression.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#FILTER_EXPRESSION" }, + "CamelAwsDdbFilterExpressionAttributeNames": { "index": 46, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "Map<String, String>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Filter Expression Attribute Names.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#FILTER_EXPRESSION_ATTRIBUTE_NAMES" }, + "CamelAwsDdbFilterExpressionAttributeValues": { "index": 47, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "Map<String, String>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Filter Expression Attribute Values.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#FILTER_EXPRESSION_ATTRIBUTE_VALUES" }, + "CamelAwsDdbProjectExpression": { "index": 48, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Project Expression.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#PROJECT_EXPRESSION" } }, "properties": { "tableName": { "index": 0, "kind": "path", "displayName": "Table Name", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "The name of the table currently worked with." }, @@ -99,7 +111,7 @@ "keyAttributeName": { "index": 3, "kind": "parameter", "displayName": "Key Attribute Name", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "Attribute name when creating table" }, "keyAttributeType": { "index": 4, "kind": "parameter", "displayName": "Key Attribute Type", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "Attribute type when creating table" }, "keyScalarType": { "index": 5, "kind": "parameter", "displayName": "Key Scalar Type", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "The key scalar type, it can be S (String), N (Number) and B (Bytes)" }, - "operation": { "index": 6, "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "org.apache.camel.component.aws2.ddb.Ddb2Operations", "enum": [ "BatchGetItems", "DeleteItem", "DeleteTable", "DescribeTable", "GetItem", "PutItem", "Query", "Scan", "UpdateItem", "UpdateTable" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "PutItem", "configurationClass": "org.apache.camel.component [...] + "operation": { "index": 6, "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "org.apache.camel.component.aws2.ddb.Ddb2Operations", "enum": [ "BatchGetItems", "BatchWriteItem", "BatchExecuteStatement", "DeleteItem", "DeleteTable", "DescribeTable", "ExecuteStatement", "GetItem", "PutItem", "Query", "Scan", "TransactGetItems", "TransactWriteItems", "UpdateItem", "UpdateTable" ], "deprecated": false, "autowir [...] "overrideEndpoint": { "index": 7, "kind": "parameter", "displayName": "Override Endpoint", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "Set the need for overriding the endpoint. This option needs to be used in combination w [...] "readCapacity": { "index": 8, "kind": "parameter", "displayName": "Read Capacity", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "The provisioned throughput to reserve for reading resources from your table" }, "region": { "index": 9, "kind": "parameter", "displayName": "Region", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "ap-south-2", "ap-south-1", "eu-south-1", "eu-south-2", "us-gov-east-1", "me-central-1", "il-central-1", "ca-central-1", "eu-central-1", "us-iso-west-1", "eu-central-2", "eu-isoe-west-1", "us-west-1", "us-west-2", "af-south-1", "eu-north-1", "eu-west-3", "eu-west-2", "eu-west-1", "ap-northeast-3", "ap-nort [...] diff --git a/components/camel-aws/camel-aws2-ddb/src/generated/resources/META-INF/org/apache/camel/component/aws2/ddb/aws2-ddb.json b/components/camel-aws/camel-aws2-ddb/src/generated/resources/META-INF/org/apache/camel/component/aws2/ddb/aws2-ddb.json index dd56918fcf92..de317a7843b7 100644 --- a/components/camel-aws/camel-aws2-ddb/src/generated/resources/META-INF/org/apache/camel/component/aws2/ddb/aws2-ddb.json +++ b/components/camel-aws/camel-aws2-ddb/src/generated/resources/META-INF/org/apache/camel/component/aws2/ddb/aws2-ddb.json @@ -31,7 +31,7 @@ "keyAttributeType": { "index": 4, "kind": "property", "displayName": "Key Attribute Type", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "Attribute type when creating table" }, "keyScalarType": { "index": 5, "kind": "property", "displayName": "Key Scalar Type", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "The key scalar type, it can be S (String), N (Number) and B (Bytes)" }, "lazyStartProducer": { "index": 6, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail [...] - "operation": { "index": 7, "kind": "property", "displayName": "Operation", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "org.apache.camel.component.aws2.ddb.Ddb2Operations", "enum": [ "BatchGetItems", "DeleteItem", "DeleteTable", "DescribeTable", "GetItem", "PutItem", "Query", "Scan", "UpdateItem", "UpdateTable" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "PutItem", "configurationClass": "org.apache.camel.component. [...] + "operation": { "index": 7, "kind": "property", "displayName": "Operation", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "org.apache.camel.component.aws2.ddb.Ddb2Operations", "enum": [ "BatchGetItems", "BatchWriteItem", "BatchExecuteStatement", "DeleteItem", "DeleteTable", "DescribeTable", "ExecuteStatement", "GetItem", "PutItem", "Query", "Scan", "TransactGetItems", "TransactWriteItems", "UpdateItem", "UpdateTable" ], "deprecated": false, "autowire [...] "overrideEndpoint": { "index": 8, "kind": "property", "displayName": "Override Endpoint", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "Set the need for overriding the endpoint. This option needs to be used in combination wi [...] "readCapacity": { "index": 9, "kind": "property", "displayName": "Read Capacity", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "The provisioned throughput to reserve for reading resources from your table" }, "region": { "index": 10, "kind": "property", "displayName": "Region", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "ap-south-2", "ap-south-1", "eu-south-1", "eu-south-2", "us-gov-east-1", "me-central-1", "il-central-1", "ca-central-1", "eu-central-1", "us-iso-west-1", "eu-central-2", "eu-isoe-west-1", "us-west-1", "us-west-2", "af-south-1", "eu-north-1", "eu-west-3", "eu-west-2", "eu-west-1", "ap-northeast-3", "ap-nort [...] @@ -72,7 +72,7 @@ "CamelAwsDdbLastEvaluatedKey": { "index": 15, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "Key", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Primary key of the item where the query operation stopped, inclusive of the previous result set.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#LAST_EVALUATED_KEY" }, "CamelAwsDdbIsTruncated": { "index": 16, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Whether the response has more results (is truncated). If true, use LAST_EVALUATED_KEY as START_KEY for the next page.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#IS_TRUNCATED" }, "CamelAwsDdbLimit": { "index": 17, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The maximum number of items to return.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#LIMIT" }, - "CamelAwsDdbOperation": { "index": 18, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "org.apache.camel.component.aws2.ddb.Ddb2Operations", "enum": [ "BatchGetItems", "DeleteItem", "DeleteTable", "DescribeTable", "GetItem", "PutItem", "Query", "Scan", "UpdateItem", "UpdateTable" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The operation to perform.", "constantName": "org.apac [...] + "CamelAwsDdbOperation": { "index": 18, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "org.apache.camel.component.aws2.ddb.Ddb2Operations", "enum": [ "BatchGetItems", "BatchWriteItem", "BatchExecuteStatement", "DeleteItem", "DeleteTable", "DescribeTable", "ExecuteStatement", "GetItem", "PutItem", "Query", "Scan", "TransactGetItems", "TransactWriteItems", "UpdateItem", "UpdateTable" ], "deprecated": false, "deprecationNote": "", " [...] "CamelAwsDdbProvisionedThroughput": { "index": 19, "kind": "header", "displayName": "", "group": "DeleteTable DescribeTable", "label": "DeleteTable DescribeTable", "required": false, "javaType": "software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughputDescription", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The value of the ProvisionedThroughput property for this table", "constantName": "org.apache.camel.component.aws2 [...] "CamelAwsDdbReadCapacity": { "index": 20, "kind": "header", "displayName": "", "group": "UpdateTable DescribeTable", "label": "UpdateTable DescribeTable", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "ReadCapacityUnits property of this table.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#READ_CAPACITY" }, "CamelAwsDdbReturnValues": { "index": 21, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Use this parameter if you want to get the attribute name-value pairs before or after they are modified(NONE, ALL_OLD, UPDATED_OLD, ALL_NEW, UPDATED_NEW).", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#RETURN_VALUES" }, @@ -87,10 +87,22 @@ "CamelAwsDdbUpdateValues": { "index": 30, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Map<String, AttributeValueUpdate>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Map of attribute name to the new value and action for the update.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#UPDATE_VALUES" }, "CamelAwsDdbUnprocessedKeys": { "index": 31, "kind": "header", "displayName": "", "group": "BatchGetItems", "label": "BatchGetItems", "required": false, "javaType": "Map<String,KeysAndAttributes>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Contains a map of tables and their respective keys that were not processed with the current response.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#UNPROCESSED_KEYS" }, "CamelAwsDdbWriteCapacity": { "index": 32, "kind": "header", "displayName": "", "group": "UpdateTable DescribeTable", "label": "UpdateTable DescribeTable", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "WriteCapacityUnits property of this table.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#WRITE_CAPACITY" }, - "CamelAwsDdbFilterExpression": { "index": 33, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Filter Expression.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#FILTER_EXPRESSION" }, - "CamelAwsDdbFilterExpressionAttributeNames": { "index": 34, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "Map<String, String>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Filter Expression Attribute Names.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#FILTER_EXPRESSION_ATTRIBUTE_NAMES" }, - "CamelAwsDdbFilterExpressionAttributeValues": { "index": 35, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "Map<String, String>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Filter Expression Attribute Values.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#FILTER_EXPRESSION_ATTRIBUTE_VALUES" }, - "CamelAwsDdbProjectExpression": { "index": 36, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Project Expression.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#PROJECT_EXPRESSION" } + "CamelAwsDdbStatement": { "index": 33, "kind": "header", "displayName": "", "group": "ExecuteStatement BatchExecuteStatement", "label": "ExecuteStatement BatchExecuteStatement", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "A PartiQL statement that uses parameters.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#STATEMENT" }, + "CamelAwsDdbStatementParameters": { "index": 34, "kind": "header", "displayName": "", "group": "ExecuteStatement BatchExecuteStatement", "label": "ExecuteStatement BatchExecuteStatement", "required": false, "javaType": "java.util.List<software.amazon.awssdk.services.dynamodb.model.AttributeValue>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The parameters for the PartiQL statement, if any.", "constantName": "org.apache.camel.compo [...] + "CamelAwsDdbBatchStatements": { "index": 35, "kind": "header", "displayName": "", "group": "BatchExecuteStatement", "label": "BatchExecuteStatement", "required": false, "javaType": "java.util.List<software.amazon.awssdk.services.dynamodb.model.BatchStatementRequest>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The list of PartiQL statements representing the batch to run.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2C [...] + "CamelAwsDdbExecuteStatementItems": { "index": 36, "kind": "header", "displayName": "", "group": "ExecuteStatement", "label": "ExecuteStatement", "required": false, "javaType": "java.util.List<java.util.Map<String, software.amazon.awssdk.services.dynamodb.model.AttributeValue>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response items from an ExecuteStatement operation.", "constantName": "org.apache.camel.component.aws2.ddb. [...] + "CamelAwsDdbExecuteStatementNextToken": { "index": 37, "kind": "header", "displayName": "", "group": "ExecuteStatement", "label": "ExecuteStatement", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The next token from an ExecuteStatement operation for pagination.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#EXECUTE_STATEMENT_NEXT_TOKEN" }, + "CamelAwsDdbBatchStatementResponse": { "index": 38, "kind": "header", "displayName": "", "group": "BatchExecuteStatement", "label": "BatchExecuteStatement", "required": false, "javaType": "java.util.List<software.amazon.awssdk.services.dynamodb.model.BatchStatementResponse>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response to each PartiQL statement in the batch.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Co [...] + "CamelAwsDdbTransactWriteItems": { "index": 39, "kind": "header", "displayName": "", "group": "TransactWriteItems", "label": "TransactWriteItems", "required": false, "javaType": "java.util.List<software.amazon.awssdk.services.dynamodb.model.TransactWriteItem>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The list of TransactWriteItem objects for a transactional write.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Const [...] + "CamelAwsDdbTransactClientRequestToken": { "index": 40, "kind": "header", "displayName": "", "group": "TransactWriteItems", "label": "TransactWriteItems", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "A unique client request token for idempotent TransactWriteItems calls.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#TRANSACT_CLIENT_REQUEST_TOKEN" }, + "CamelAwsDdbTransactGetItems": { "index": 41, "kind": "header", "displayName": "", "group": "TransactGetItems", "label": "TransactGetItems", "required": false, "javaType": "java.util.List<software.amazon.awssdk.services.dynamodb.model.TransactGetItem>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The list of TransactGetItem objects for a transactional read.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#TRANSA [...] + "CamelAwsDdbTransactGetResponse": { "index": 42, "kind": "header", "displayName": "", "group": "TransactGetItems", "label": "TransactGetItems", "required": false, "javaType": "java.util.List<software.amazon.awssdk.services.dynamodb.model.ItemResponse>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response from a TransactGetItems operation.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#TRANSACT_GET_RESPONSE" }, + "CamelAwsDdbBatchWriteItems": { "index": 43, "kind": "header", "displayName": "", "group": "BatchWriteItem", "label": "BatchWriteItem", "required": false, "javaType": "java.util.Map<String, java.util.List<software.amazon.awssdk.services.dynamodb.model.WriteRequest>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "A map of table names to lists of WriteRequest objects for batch writes.", "constantName": "org.apache.camel.component.aws2 [...] + "CamelAwsDdbBatchWriteUnprocessedItems": { "index": 44, "kind": "header", "displayName": "", "group": "BatchWriteItem", "label": "BatchWriteItem", "required": false, "javaType": "java.util.Map<String, java.util.List<software.amazon.awssdk.services.dynamodb.model.WriteRequest>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "A map of tables and their respective unprocessed items after a BatchWriteItem operation.", "constantName": "org [...] + "CamelAwsDdbFilterExpression": { "index": 45, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Filter Expression.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#FILTER_EXPRESSION" }, + "CamelAwsDdbFilterExpressionAttributeNames": { "index": 46, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "Map<String, String>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Filter Expression Attribute Names.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#FILTER_EXPRESSION_ATTRIBUTE_NAMES" }, + "CamelAwsDdbFilterExpressionAttributeValues": { "index": 47, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "Map<String, String>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Filter Expression Attribute Values.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#FILTER_EXPRESSION_ATTRIBUTE_VALUES" }, + "CamelAwsDdbProjectExpression": { "index": 48, "kind": "header", "displayName": "", "group": "Query Scan", "label": "Query Scan", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Project Expression.", "constantName": "org.apache.camel.component.aws2.ddb.Ddb2Constants#PROJECT_EXPRESSION" } }, "properties": { "tableName": { "index": 0, "kind": "path", "displayName": "Table Name", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "The name of the table currently worked with." }, @@ -99,7 +111,7 @@ "keyAttributeName": { "index": 3, "kind": "parameter", "displayName": "Key Attribute Name", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "Attribute name when creating table" }, "keyAttributeType": { "index": 4, "kind": "parameter", "displayName": "Key Attribute Type", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "Attribute type when creating table" }, "keyScalarType": { "index": 5, "kind": "parameter", "displayName": "Key Scalar Type", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "The key scalar type, it can be S (String), N (Number) and B (Bytes)" }, - "operation": { "index": 6, "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "org.apache.camel.component.aws2.ddb.Ddb2Operations", "enum": [ "BatchGetItems", "DeleteItem", "DeleteTable", "DescribeTable", "GetItem", "PutItem", "Query", "Scan", "UpdateItem", "UpdateTable" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "PutItem", "configurationClass": "org.apache.camel.component [...] + "operation": { "index": 6, "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "org.apache.camel.component.aws2.ddb.Ddb2Operations", "enum": [ "BatchGetItems", "BatchWriteItem", "BatchExecuteStatement", "DeleteItem", "DeleteTable", "DescribeTable", "ExecuteStatement", "GetItem", "PutItem", "Query", "Scan", "TransactGetItems", "TransactWriteItems", "UpdateItem", "UpdateTable" ], "deprecated": false, "autowir [...] "overrideEndpoint": { "index": 7, "kind": "parameter", "displayName": "Override Endpoint", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "Set the need for overriding the endpoint. This option needs to be used in combination w [...] "readCapacity": { "index": 8, "kind": "parameter", "displayName": "Read Capacity", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.ddb.Ddb2Configuration", "configurationField": "configuration", "description": "The provisioned throughput to reserve for reading resources from your table" }, "region": { "index": 9, "kind": "parameter", "displayName": "Region", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "ap-south-2", "ap-south-1", "eu-south-1", "eu-south-2", "us-gov-east-1", "me-central-1", "il-central-1", "ca-central-1", "eu-central-1", "us-iso-west-1", "eu-central-2", "eu-isoe-west-1", "us-west-1", "us-west-2", "af-south-1", "eu-north-1", "eu-west-3", "eu-west-2", "eu-west-1", "ap-northeast-3", "ap-nort [...] diff --git a/components/camel-aws/camel-aws2-ddb/src/main/docs/aws2-ddb-component.adoc b/components/camel-aws/camel-aws2-ddb/src/main/docs/aws2-ddb-component.adoc index 33d1b75ad6ce..158ca7bd4071 100644 --- a/components/camel-aws/camel-aws2-ddb/src/main/docs/aws2-ddb-component.adoc +++ b/components/camel-aws/camel-aws2-ddb/src/main/docs/aws2-ddb-component.adoc @@ -104,13 +104,18 @@ Registry. === Supported producer operations - BatchGetItems +- BatchWriteItem +- BatchExecuteStatement - DeleteItem - DeleteTable - DescribeTable +- ExecuteStatement - GetItem - PutItem - Query - Scan +- TransactGetItems +- TransactWriteItems - UpdateItem - UpdateTable @@ -205,4 +210,98 @@ from("direct:delete") -------------------------------------------------------------------------------- +- ExecuteStatement (PartiQL): this operation runs a PartiQL statement against DynamoDB + +[source,java] +-------------------------------------------------------------------------------- +from("direct:partiql") + .process(exchange -> { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.ExecuteStatement); + exchange.getIn().setHeader(Ddb2Constants.STATEMENT, + "SELECT * FROM \"MyTable\" WHERE \"key\" = ?"); + exchange.getIn().setHeader(Ddb2Constants.STATEMENT_PARAMETERS, + List.of(AttributeValue.builder().s("myKeyValue").build())); + exchange.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + }) + .toF("aws2-ddb://%s?amazonDDBClient=#client", tableName); +-------------------------------------------------------------------------------- + +- BatchExecuteStatement (PartiQL batch): this operation runs multiple PartiQL statements in a batch + +[source,java] +-------------------------------------------------------------------------------- +from("direct:batchPartiql") + .process(exchange -> { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.BatchExecuteStatement); + exchange.getIn().setHeader(Ddb2Constants.BATCH_STATEMENTS, List.of( + BatchStatementRequest.builder() + .statement("INSERT INTO \"MyTable\" VALUE {'key': 'k1', 'data': 'v1'}") + .build(), + BatchStatementRequest.builder() + .statement("INSERT INTO \"MyTable\" VALUE {'key': 'k2', 'data': 'v2'}") + .build())); + }) + .toF("aws2-ddb://%s?amazonDDBClient=#client", tableName); +-------------------------------------------------------------------------------- + +- TransactWriteItems: this operation performs a transactional write across one or more tables + +[source,java] +-------------------------------------------------------------------------------- +Map<String, AttributeValue> item = new HashMap<>(); +item.put("key", AttributeValue.builder().s("txKey").build()); +item.put("data", AttributeValue.builder().s("txValue").build()); + +from("direct:transactWrite") + .process(exchange -> { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.TransactWriteItems); + exchange.getIn().setHeader(Ddb2Constants.TRANSACT_WRITE_ITEMS, List.of( + TransactWriteItem.builder() + .put(Put.builder().tableName("MyTable").item(item).build()) + .build())); + }) + .toF("aws2-ddb://%s?amazonDDBClient=#client", tableName); +-------------------------------------------------------------------------------- + +- TransactGetItems: this operation performs a transactional read across one or more tables + +[source,java] +-------------------------------------------------------------------------------- +Map<String, AttributeValue> key = new HashMap<>(); +key.put("key", AttributeValue.builder().s("txKey").build()); + +from("direct:transactGet") + .process(exchange -> { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.TransactGetItems); + exchange.getIn().setHeader(Ddb2Constants.TRANSACT_GET_ITEMS, List.of( + TransactGetItem.builder() + .get(Get.builder().tableName("MyTable").key(key).build()) + .build())); + }) + .toF("aws2-ddb://%s?amazonDDBClient=#client", tableName); +-------------------------------------------------------------------------------- + +- BatchWriteItem: this operation puts or deletes multiple items in one or more tables in a single batch + +[source,java] +-------------------------------------------------------------------------------- +Map<String, AttributeValue> item1 = new HashMap<>(); +item1.put("key", AttributeValue.builder().s("bk1").build()); +item1.put("data", AttributeValue.builder().s("bv1").build()); + +Map<String, List<WriteRequest>> requestItems = new HashMap<>(); +requestItems.put("MyTable", List.of( + WriteRequest.builder() + .putRequest(PutRequest.builder().item(item1).build()) + .build())); + +from("direct:batchWrite") + .process(exchange -> { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.BatchWriteItem); + exchange.getIn().setHeader(Ddb2Constants.BATCH_WRITE_ITEMS, requestItems); + }) + .toF("aws2-ddb://%s?amazonDDBClient=#client", tableName); +-------------------------------------------------------------------------------- + + include::spring-boot:partial$starter.adoc[] diff --git a/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/BatchExecuteStatementCommand.java b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/BatchExecuteStatementCommand.java new file mode 100644 index 000000000000..60a298cad300 --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/BatchExecuteStatementCommand.java @@ -0,0 +1,51 @@ +/* + * 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 java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.camel.Exchange; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.BatchExecuteStatementRequest; +import software.amazon.awssdk.services.dynamodb.model.BatchExecuteStatementResponse; +import software.amazon.awssdk.services.dynamodb.model.BatchStatementRequest; + +public class BatchExecuteStatementCommand extends AbstractDdbCommand { + + public BatchExecuteStatementCommand(DynamoDbClient ddbClient, Ddb2Configuration configuration, Exchange exchange) { + super(ddbClient, configuration, exchange); + } + + @Override + public void execute() { + BatchExecuteStatementResponse result = ddbClient.batchExecuteStatement( + BatchExecuteStatementRequest.builder() + .statements(determineBatchStatements()) + .build()); + + Map<Object, Object> tmp = new HashMap<>(); + tmp.put(Ddb2Constants.BATCH_STATEMENT_RESPONSE, result.responses()); + addToResults(tmp); + } + + @SuppressWarnings("unchecked") + private List<BatchStatementRequest> determineBatchStatements() { + return exchange.getIn().getHeader(Ddb2Constants.BATCH_STATEMENTS, List.class); + } +} diff --git a/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/BatchWriteItemCommand.java b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/BatchWriteItemCommand.java new file mode 100644 index 000000000000..a808b18c83e9 --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/BatchWriteItemCommand.java @@ -0,0 +1,51 @@ +/* + * 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 java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.camel.Exchange; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.BatchWriteItemRequest; +import software.amazon.awssdk.services.dynamodb.model.BatchWriteItemResponse; +import software.amazon.awssdk.services.dynamodb.model.WriteRequest; + +public class BatchWriteItemCommand extends AbstractDdbCommand { + + public BatchWriteItemCommand(DynamoDbClient ddbClient, Ddb2Configuration configuration, Exchange exchange) { + super(ddbClient, configuration, exchange); + } + + @Override + public void execute() { + BatchWriteItemResponse result = ddbClient.batchWriteItem( + BatchWriteItemRequest.builder() + .requestItems(determineBatchWriteItems()) + .build()); + + Map<Object, Object> tmp = new HashMap<>(); + tmp.put(Ddb2Constants.BATCH_WRITE_UNPROCESSED_ITEMS, result.unprocessedItems()); + addToResults(tmp); + } + + @SuppressWarnings("unchecked") + private Map<String, List<WriteRequest>> determineBatchWriteItems() { + return exchange.getIn().getHeader(Ddb2Constants.BATCH_WRITE_ITEMS, Map.class); + } +} diff --git a/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/Ddb2Constants.java b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/Ddb2Constants.java index 5538cc9060f4..7fb5ab7695c4 100644 --- a/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/Ddb2Constants.java +++ b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/Ddb2Constants.java @@ -144,6 +144,54 @@ public interface Ddb2Constants { @Metadata(label = "UpdateTable DescribeTable", description = "WriteCapacityUnits property of this table.", javaType = "Long") String WRITE_CAPACITY = "CamelAwsDdbWriteCapacity"; + @Metadata(label = "ExecuteStatement BatchExecuteStatement", + description = "A PartiQL statement that uses parameters.", + javaType = "String") + String STATEMENT = "CamelAwsDdbStatement"; + @Metadata(label = "ExecuteStatement BatchExecuteStatement", + description = "The parameters for the PartiQL statement, if any.", + javaType = "java.util.List<software.amazon.awssdk.services.dynamodb.model.AttributeValue>") + String STATEMENT_PARAMETERS = "CamelAwsDdbStatementParameters"; + @Metadata(label = "BatchExecuteStatement", + description = "The list of PartiQL statements representing the batch to run.", + javaType = "java.util.List<software.amazon.awssdk.services.dynamodb.model.BatchStatementRequest>") + String BATCH_STATEMENTS = "CamelAwsDdbBatchStatements"; + @Metadata(label = "ExecuteStatement", + description = "The response items from an ExecuteStatement operation.", + javaType = "java.util.List<java.util.Map<String, software.amazon.awssdk.services.dynamodb.model.AttributeValue>>") + String EXECUTE_STATEMENT_ITEMS = "CamelAwsDdbExecuteStatementItems"; + @Metadata(label = "ExecuteStatement", + description = "The next token from an ExecuteStatement operation for pagination.", + javaType = "String") + String EXECUTE_STATEMENT_NEXT_TOKEN = "CamelAwsDdbExecuteStatementNextToken"; + @Metadata(label = "BatchExecuteStatement", + description = "The response to each PartiQL statement in the batch.", + javaType = "java.util.List<software.amazon.awssdk.services.dynamodb.model.BatchStatementResponse>") + String BATCH_STATEMENT_RESPONSE = "CamelAwsDdbBatchStatementResponse"; + @Metadata(label = "TransactWriteItems", + description = "The list of TransactWriteItem objects for a transactional write.", + javaType = "java.util.List<software.amazon.awssdk.services.dynamodb.model.TransactWriteItem>") + String TRANSACT_WRITE_ITEMS = "CamelAwsDdbTransactWriteItems"; + @Metadata(label = "TransactWriteItems", + description = "A unique client request token for idempotent TransactWriteItems calls.", + javaType = "String") + String TRANSACT_CLIENT_REQUEST_TOKEN = "CamelAwsDdbTransactClientRequestToken"; + @Metadata(label = "TransactGetItems", + description = "The list of TransactGetItem objects for a transactional read.", + javaType = "java.util.List<software.amazon.awssdk.services.dynamodb.model.TransactGetItem>") + String TRANSACT_GET_ITEMS = "CamelAwsDdbTransactGetItems"; + @Metadata(label = "TransactGetItems", + description = "The response from a TransactGetItems operation.", + javaType = "java.util.List<software.amazon.awssdk.services.dynamodb.model.ItemResponse>") + String TRANSACT_GET_RESPONSE = "CamelAwsDdbTransactGetResponse"; + @Metadata(label = "BatchWriteItem", + description = "A map of table names to lists of WriteRequest objects for batch writes.", + javaType = "java.util.Map<String, java.util.List<software.amazon.awssdk.services.dynamodb.model.WriteRequest>>") + String BATCH_WRITE_ITEMS = "CamelAwsDdbBatchWriteItems"; + @Metadata(label = "BatchWriteItem", + description = "A map of tables and their respective unprocessed items after a BatchWriteItem operation.", + javaType = "java.util.Map<String, java.util.List<software.amazon.awssdk.services.dynamodb.model.WriteRequest>>") + String BATCH_WRITE_UNPROCESSED_ITEMS = "CamelAwsDdbBatchWriteUnprocessedItems"; @Metadata(label = "Query Scan", description = "The Filter Expression.", javaType = "String") String FILTER_EXPRESSION = "CamelAwsDdbFilterExpression"; diff --git a/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/Ddb2Operations.java b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/Ddb2Operations.java index a6e51f0049cf..a410710b189e 100644 --- a/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/Ddb2Operations.java +++ b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/Ddb2Operations.java @@ -18,13 +18,18 @@ package org.apache.camel.component.aws2.ddb; public enum Ddb2Operations { BatchGetItems, + BatchWriteItem, + BatchExecuteStatement, DeleteItem, DeleteTable, DescribeTable, + ExecuteStatement, GetItem, PutItem, Query, Scan, + TransactGetItems, + TransactWriteItems, UpdateItem, UpdateTable } diff --git a/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/Ddb2Producer.java b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/Ddb2Producer.java index 5687c575b127..65745d53c09a 100644 --- a/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/Ddb2Producer.java +++ b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/Ddb2Producer.java @@ -45,6 +45,12 @@ public class Ddb2Producer extends DefaultProducer { case BatchGetItems: new BatchGetItemsCommand(getEndpoint().getDdbClient(), getConfiguration(), exchange).execute(); break; + case BatchWriteItem: + new BatchWriteItemCommand(getEndpoint().getDdbClient(), getConfiguration(), exchange).execute(); + break; + case BatchExecuteStatement: + new BatchExecuteStatementCommand(getEndpoint().getDdbClient(), getConfiguration(), exchange).execute(); + break; case DeleteItem: new DeleteItemCommand(getEndpoint().getDdbClient(), getConfiguration(), exchange).execute(); break; @@ -54,6 +60,9 @@ public class Ddb2Producer extends DefaultProducer { case DescribeTable: new DescribeTableCommand(getEndpoint().getDdbClient(), getConfiguration(), exchange).execute(); break; + case ExecuteStatement: + new ExecuteStatementCommand(getEndpoint().getDdbClient(), getConfiguration(), exchange).execute(); + break; case GetItem: new GetItemCommand(getEndpoint().getDdbClient(), getConfiguration(), exchange).execute(); break; @@ -66,6 +75,12 @@ public class Ddb2Producer extends DefaultProducer { case Scan: new ScanCommand(getEndpoint().getDdbClient(), getConfiguration(), exchange).execute(); break; + case TransactGetItems: + new TransactGetItemsCommand(getEndpoint().getDdbClient(), getConfiguration(), exchange).execute(); + break; + case TransactWriteItems: + new TransactWriteItemsCommand(getEndpoint().getDdbClient(), getConfiguration(), exchange).execute(); + break; case UpdateItem: new UpdateItemCommand(getEndpoint().getDdbClient(), getConfiguration(), exchange).execute(); break; diff --git a/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/ExecuteStatementCommand.java b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/ExecuteStatementCommand.java new file mode 100644 index 000000000000..b1e846e788f6 --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/ExecuteStatementCommand.java @@ -0,0 +1,68 @@ +/* + * 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 java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.camel.Exchange; +import org.apache.camel.util.ObjectHelper; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.ExecuteStatementRequest; +import software.amazon.awssdk.services.dynamodb.model.ExecuteStatementResponse; + +public class ExecuteStatementCommand extends AbstractDdbCommand { + + public ExecuteStatementCommand(DynamoDbClient ddbClient, Ddb2Configuration configuration, Exchange exchange) { + super(ddbClient, configuration, exchange); + } + + @Override + public void execute() { + ExecuteStatementRequest.Builder builder = ExecuteStatementRequest.builder() + .statement(determineStatement()) + .consistentRead(determineConsistentRead()); + + List<AttributeValue> parameters = determineStatementParameters(); + if (ObjectHelper.isNotEmpty(parameters)) { + builder.parameters(parameters); + } + + String nextToken = exchange.getIn().getHeader(Ddb2Constants.NEXT_TOKEN, String.class); + if (ObjectHelper.isNotEmpty(nextToken)) { + builder.nextToken(nextToken); + } + + ExecuteStatementResponse result = ddbClient.executeStatement(builder.build()); + + Map<Object, Object> tmp = new HashMap<>(); + tmp.put(Ddb2Constants.EXECUTE_STATEMENT_ITEMS, result.items()); + tmp.put(Ddb2Constants.EXECUTE_STATEMENT_NEXT_TOKEN, result.nextToken()); + addToResults(tmp); + } + + private String determineStatement() { + return exchange.getIn().getHeader(Ddb2Constants.STATEMENT, String.class); + } + + @SuppressWarnings("unchecked") + private List<AttributeValue> determineStatementParameters() { + return exchange.getIn().getHeader(Ddb2Constants.STATEMENT_PARAMETERS, List.class); + } +} diff --git a/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/TransactGetItemsCommand.java b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/TransactGetItemsCommand.java new file mode 100644 index 000000000000..6d36cb333fcb --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/TransactGetItemsCommand.java @@ -0,0 +1,51 @@ +/* + * 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 java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.camel.Exchange; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.TransactGetItem; +import software.amazon.awssdk.services.dynamodb.model.TransactGetItemsRequest; +import software.amazon.awssdk.services.dynamodb.model.TransactGetItemsResponse; + +public class TransactGetItemsCommand extends AbstractDdbCommand { + + public TransactGetItemsCommand(DynamoDbClient ddbClient, Ddb2Configuration configuration, Exchange exchange) { + super(ddbClient, configuration, exchange); + } + + @Override + public void execute() { + TransactGetItemsResponse result = ddbClient.transactGetItems( + TransactGetItemsRequest.builder() + .transactItems(determineTransactGetItems()) + .build()); + + Map<Object, Object> tmp = new HashMap<>(); + tmp.put(Ddb2Constants.TRANSACT_GET_RESPONSE, result.responses()); + addToResults(tmp); + } + + @SuppressWarnings("unchecked") + private List<TransactGetItem> determineTransactGetItems() { + return exchange.getIn().getHeader(Ddb2Constants.TRANSACT_GET_ITEMS, List.class); + } +} diff --git a/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/TransactWriteItemsCommand.java b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/TransactWriteItemsCommand.java new file mode 100644 index 000000000000..a3304c6bfa6c --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/main/java/org/apache/camel/component/aws2/ddb/TransactWriteItemsCommand.java @@ -0,0 +1,50 @@ +/* + * 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 java.util.List; + +import org.apache.camel.Exchange; +import org.apache.camel.util.ObjectHelper; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.TransactWriteItem; +import software.amazon.awssdk.services.dynamodb.model.TransactWriteItemsRequest; + +public class TransactWriteItemsCommand extends AbstractDdbCommand { + + public TransactWriteItemsCommand(DynamoDbClient ddbClient, Ddb2Configuration configuration, Exchange exchange) { + super(ddbClient, configuration, exchange); + } + + @Override + public void execute() { + TransactWriteItemsRequest.Builder builder = TransactWriteItemsRequest.builder() + .transactItems(determineTransactWriteItems()); + + String clientRequestToken = exchange.getIn().getHeader(Ddb2Constants.TRANSACT_CLIENT_REQUEST_TOKEN, String.class); + if (ObjectHelper.isNotEmpty(clientRequestToken)) { + builder.clientRequestToken(clientRequestToken); + } + + ddbClient.transactWriteItems(builder.build()); + } + + @SuppressWarnings("unchecked") + private List<TransactWriteItem> determineTransactWriteItems() { + return exchange.getIn().getHeader(Ddb2Constants.TRANSACT_WRITE_ITEMS, List.class); + } +} diff --git a/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/AmazonDDBClientMock.java b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/AmazonDDBClientMock.java index 09dda06bdb13..ff224730ebd7 100644 --- a/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/AmazonDDBClientMock.java +++ b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/AmazonDDBClientMock.java @@ -27,8 +27,13 @@ import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.DynamoDbServiceClientConfiguration; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.BatchExecuteStatementRequest; +import software.amazon.awssdk.services.dynamodb.model.BatchExecuteStatementResponse; import software.amazon.awssdk.services.dynamodb.model.BatchGetItemRequest; import software.amazon.awssdk.services.dynamodb.model.BatchGetItemResponse; +import software.amazon.awssdk.services.dynamodb.model.BatchStatementResponse; +import software.amazon.awssdk.services.dynamodb.model.BatchWriteItemRequest; +import software.amazon.awssdk.services.dynamodb.model.BatchWriteItemResponse; import software.amazon.awssdk.services.dynamodb.model.ConsumedCapacity; import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; import software.amazon.awssdk.services.dynamodb.model.CreateTableResponse; @@ -38,8 +43,11 @@ import software.amazon.awssdk.services.dynamodb.model.DeleteTableRequest; import software.amazon.awssdk.services.dynamodb.model.DeleteTableResponse; import software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest; import software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse; +import software.amazon.awssdk.services.dynamodb.model.ExecuteStatementRequest; +import software.amazon.awssdk.services.dynamodb.model.ExecuteStatementResponse; import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; import software.amazon.awssdk.services.dynamodb.model.GetItemResponse; +import software.amazon.awssdk.services.dynamodb.model.ItemResponse; import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; import software.amazon.awssdk.services.dynamodb.model.KeysAndAttributes; import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughputDescription; @@ -51,10 +59,15 @@ import software.amazon.awssdk.services.dynamodb.model.ScanRequest; import software.amazon.awssdk.services.dynamodb.model.ScanResponse; import software.amazon.awssdk.services.dynamodb.model.TableDescription; import software.amazon.awssdk.services.dynamodb.model.TableStatus; +import software.amazon.awssdk.services.dynamodb.model.TransactGetItemsRequest; +import software.amazon.awssdk.services.dynamodb.model.TransactGetItemsResponse; +import software.amazon.awssdk.services.dynamodb.model.TransactWriteItemsRequest; +import software.amazon.awssdk.services.dynamodb.model.TransactWriteItemsResponse; import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse; import software.amazon.awssdk.services.dynamodb.model.UpdateTableRequest; import software.amazon.awssdk.services.dynamodb.model.UpdateTableResponse; +import software.amazon.awssdk.services.dynamodb.model.WriteRequest; public class AmazonDDBClientMock implements DynamoDbClient { public static final long NOW = 1327709390233L; @@ -67,8 +80,13 @@ public class AmazonDDBClientMock implements DynamoDbClient { DeleteItemRequest deleteItemRequest; GetItemRequest getItemRequest; BatchGetItemRequest batchGetItemRequest; + BatchWriteItemRequest batchWriteItemRequest; ScanRequest scanRequest; QueryRequest queryRequest; + ExecuteStatementRequest executeStatementRequest; + BatchExecuteStatementRequest batchExecuteStatementRequest; + TransactWriteItemsRequest transactWriteItemsRequest; + TransactGetItemsRequest transactGetItemsRequest; public AmazonDDBClientMock() { } @@ -203,6 +221,44 @@ public class AmazonDDBClientMock implements DynamoDbClient { .lastEvaluatedKey(lastEvaluatedKey).build(); } + @Override + public ExecuteStatementResponse executeStatement(ExecuteStatementRequest executeStatementRequest) { + this.executeStatementRequest = executeStatementRequest; + List<Map<String, AttributeValue>> items = new ArrayList<>(); + items.add(getAttributes()); + return ExecuteStatementResponse.builder().items(items).nextToken("nextToken123").build(); + } + + @Override + public BatchExecuteStatementResponse batchExecuteStatement( + BatchExecuteStatementRequest batchExecuteStatementRequest) { + this.batchExecuteStatementRequest = batchExecuteStatementRequest; + List<BatchStatementResponse> responses = new ArrayList<>(); + responses.add(BatchStatementResponse.builder().item(getAttributes()).build()); + return BatchExecuteStatementResponse.builder().responses(responses).build(); + } + + @Override + public TransactWriteItemsResponse transactWriteItems(TransactWriteItemsRequest transactWriteItemsRequest) { + this.transactWriteItemsRequest = transactWriteItemsRequest; + return TransactWriteItemsResponse.builder().build(); + } + + @Override + public TransactGetItemsResponse transactGetItems(TransactGetItemsRequest transactGetItemsRequest) { + this.transactGetItemsRequest = transactGetItemsRequest; + List<ItemResponse> responses = new ArrayList<>(); + responses.add(ItemResponse.builder().item(getAttributes()).build()); + return TransactGetItemsResponse.builder().responses(responses).build(); + } + + @Override + public BatchWriteItemResponse batchWriteItem(BatchWriteItemRequest batchWriteItemRequest) { + this.batchWriteItemRequest = batchWriteItemRequest; + Map<String, List<WriteRequest>> unprocessedItems = new HashMap<>(); + return BatchWriteItemResponse.builder().unprocessedItems(unprocessedItems).build(); + } + @Override public String serviceName() { // TODO Auto-generated method stub diff --git a/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/BatchExecuteStatementCommandTest.java b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/BatchExecuteStatementCommandTest.java new file mode 100644 index 000000000000..43d02e88be32 --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/BatchExecuteStatementCommandTest.java @@ -0,0 +1,70 @@ +/* + * 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 java.util.Arrays; +import java.util.List; + +import org.apache.camel.Exchange; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.support.DefaultExchange; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.BatchStatementRequest; +import software.amazon.awssdk.services.dynamodb.model.BatchStatementResponse; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class BatchExecuteStatementCommandTest { + + private BatchExecuteStatementCommand command; + private AmazonDDBClientMock ddbClient; + private Ddb2Configuration configuration; + private Exchange exchange; + + @BeforeEach + public void setUp() { + ddbClient = new AmazonDDBClientMock(); + configuration = new Ddb2Configuration(); + exchange = new DefaultExchange(new DefaultCamelContext()); + command = new BatchExecuteStatementCommand(ddbClient, configuration, exchange); + } + + @Test + public void execute() { + List<BatchStatementRequest> statements = Arrays.asList( + BatchStatementRequest.builder() + .statement("INSERT INTO \"DOMAIN1\" VALUE {'key': 'val1'}") + .build(), + BatchStatementRequest.builder() + .statement("INSERT INTO \"DOMAIN1\" VALUE {'key': 'val2'}") + .build()); + + exchange.getIn().setHeader(Ddb2Constants.BATCH_STATEMENTS, statements); + + command.execute(); + + assertEquals(statements, ddbClient.batchExecuteStatementRequest.statements()); + + @SuppressWarnings("unchecked") + List<BatchStatementResponse> responses + = exchange.getIn().getHeader(Ddb2Constants.BATCH_STATEMENT_RESPONSE, List.class); + assertNotNull(responses); + assertEquals(1, responses.size()); + } +} diff --git a/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/BatchWriteItemCommandTest.java b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/BatchWriteItemCommandTest.java new file mode 100644 index 000000000000..5adb876d7fb1 --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/BatchWriteItemCommandTest.java @@ -0,0 +1,77 @@ +/* + * 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 java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.camel.Exchange; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.support.DefaultExchange; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.PutRequest; +import software.amazon.awssdk.services.dynamodb.model.WriteRequest; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class BatchWriteItemCommandTest { + + private BatchWriteItemCommand command; + private AmazonDDBClientMock ddbClient; + private Ddb2Configuration configuration; + private Exchange exchange; + + @BeforeEach + public void setUp() { + ddbClient = new AmazonDDBClientMock(); + configuration = new Ddb2Configuration(); + exchange = new DefaultExchange(new DefaultCamelContext()); + command = new BatchWriteItemCommand(ddbClient, configuration, exchange); + } + + @SuppressWarnings("unchecked") + @Test + public void execute() { + Map<String, AttributeValue> item = new HashMap<>(); + item.put("key", AttributeValue.builder().s("val1").build()); + + WriteRequest writeRequest = WriteRequest.builder() + .putRequest(PutRequest.builder().item(item).build()) + .build(); + + Map<String, List<WriteRequest>> requestItems = new HashMap<>(); + requestItems.put("DOMAIN1", Arrays.asList(writeRequest)); + + exchange.getIn().setHeader(Ddb2Constants.BATCH_WRITE_ITEMS, requestItems); + + command.execute(); + + assertNotNull(ddbClient.batchWriteItemRequest); + assertEquals(requestItems, ddbClient.batchWriteItemRequest.requestItems()); + + Map<String, List<WriteRequest>> unprocessed + = exchange.getIn().getHeader(Ddb2Constants.BATCH_WRITE_UNPROCESSED_ITEMS, Map.class); + assertNotNull(unprocessed); + assertTrue(unprocessed.isEmpty()); + } +} diff --git a/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/ExecuteStatementCommandTest.java b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/ExecuteStatementCommandTest.java new file mode 100644 index 000000000000..4a38a7ac2d3d --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/ExecuteStatementCommandTest.java @@ -0,0 +1,84 @@ +/* + * 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 java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.apache.camel.Exchange; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.support.DefaultExchange; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class ExecuteStatementCommandTest { + + private ExecuteStatementCommand command; + private AmazonDDBClientMock ddbClient; + private Ddb2Configuration configuration; + private Exchange exchange; + + @BeforeEach + public void setUp() { + ddbClient = new AmazonDDBClientMock(); + configuration = new Ddb2Configuration(); + configuration.setTableName("DOMAIN1"); + exchange = new DefaultExchange(new DefaultCamelContext()); + command = new ExecuteStatementCommand(ddbClient, configuration, exchange); + } + + @Test + public void execute() { + String statement = "SELECT * FROM \"DOMAIN1\" WHERE \"key\" = ?"; + List<AttributeValue> parameters = Arrays.asList( + AttributeValue.builder().s("value1").build()); + + exchange.getIn().setHeader(Ddb2Constants.STATEMENT, statement); + exchange.getIn().setHeader(Ddb2Constants.STATEMENT_PARAMETERS, parameters); + exchange.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + + command.execute(); + + assertEquals(statement, ddbClient.executeStatementRequest.statement()); + assertEquals(parameters, ddbClient.executeStatementRequest.parameters()); + assertEquals(true, ddbClient.executeStatementRequest.consistentRead()); + + @SuppressWarnings("unchecked") + List<Map<String, AttributeValue>> items = exchange.getIn().getHeader(Ddb2Constants.EXECUTE_STATEMENT_ITEMS, List.class); + assertNotNull(items); + assertEquals(1, items.size()); + assertEquals(AttributeValue.builder().s("attrValue").build(), items.get(0).get("attrName")); + + assertEquals("nextToken123", exchange.getIn().getHeader(Ddb2Constants.EXECUTE_STATEMENT_NEXT_TOKEN, String.class)); + } + + @Test + public void executeWithoutParameters() { + String statement = "SELECT * FROM \"DOMAIN1\""; + exchange.getIn().setHeader(Ddb2Constants.STATEMENT, statement); + + command.execute(); + + assertEquals(statement, ddbClient.executeStatementRequest.statement()); + assertNotNull(exchange.getIn().getHeader(Ddb2Constants.EXECUTE_STATEMENT_ITEMS)); + } +} diff --git a/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/TransactGetItemsCommandTest.java b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/TransactGetItemsCommandTest.java new file mode 100644 index 000000000000..45ad69a06068 --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/TransactGetItemsCommandTest.java @@ -0,0 +1,75 @@ +/* + * 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 java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.camel.Exchange; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.support.DefaultExchange; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.Get; +import software.amazon.awssdk.services.dynamodb.model.ItemResponse; +import software.amazon.awssdk.services.dynamodb.model.TransactGetItem; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class TransactGetItemsCommandTest { + + private TransactGetItemsCommand command; + private AmazonDDBClientMock ddbClient; + private Ddb2Configuration configuration; + private Exchange exchange; + + @BeforeEach + public void setUp() { + ddbClient = new AmazonDDBClientMock(); + configuration = new Ddb2Configuration(); + exchange = new DefaultExchange(new DefaultCamelContext()); + command = new TransactGetItemsCommand(ddbClient, configuration, exchange); + } + + @Test + public void execute() { + Map<String, AttributeValue> key = new HashMap<>(); + key.put("key", AttributeValue.builder().s("val1").build()); + + List<TransactGetItem> transactItems = Arrays.asList( + TransactGetItem.builder() + .get(Get.builder().tableName("DOMAIN1").key(key).build()) + .build()); + + exchange.getIn().setHeader(Ddb2Constants.TRANSACT_GET_ITEMS, transactItems); + + command.execute(); + + assertNotNull(ddbClient.transactGetItemsRequest); + assertEquals(transactItems, ddbClient.transactGetItemsRequest.transactItems()); + + @SuppressWarnings("unchecked") + List<ItemResponse> responses = exchange.getIn().getHeader(Ddb2Constants.TRANSACT_GET_RESPONSE, List.class); + assertNotNull(responses); + assertEquals(1, responses.size()); + assertEquals(AttributeValue.builder().s("attrValue").build(), responses.get(0).item().get("attrName")); + } +} diff --git a/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/TransactWriteItemsCommandTest.java b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/TransactWriteItemsCommandTest.java new file mode 100644 index 000000000000..269e71857d40 --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/TransactWriteItemsCommandTest.java @@ -0,0 +1,87 @@ +/* + * 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 java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.camel.Exchange; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.support.DefaultExchange; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.Put; +import software.amazon.awssdk.services.dynamodb.model.TransactWriteItem; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class TransactWriteItemsCommandTest { + + private TransactWriteItemsCommand command; + private AmazonDDBClientMock ddbClient; + private Ddb2Configuration configuration; + private Exchange exchange; + + @BeforeEach + public void setUp() { + ddbClient = new AmazonDDBClientMock(); + configuration = new Ddb2Configuration(); + exchange = new DefaultExchange(new DefaultCamelContext()); + command = new TransactWriteItemsCommand(ddbClient, configuration, exchange); + } + + @Test + public void execute() { + Map<String, AttributeValue> item = new HashMap<>(); + item.put("key", AttributeValue.builder().s("val1").build()); + + List<TransactWriteItem> transactItems = Arrays.asList( + TransactWriteItem.builder() + .put(Put.builder().tableName("DOMAIN1").item(item).build()) + .build()); + + exchange.getIn().setHeader(Ddb2Constants.TRANSACT_WRITE_ITEMS, transactItems); + + command.execute(); + + assertNotNull(ddbClient.transactWriteItemsRequest); + assertEquals(transactItems, ddbClient.transactWriteItemsRequest.transactItems()); + } + + @Test + public void executeWithClientRequestToken() { + Map<String, AttributeValue> item = new HashMap<>(); + item.put("key", AttributeValue.builder().s("val1").build()); + + List<TransactWriteItem> transactItems = Arrays.asList( + TransactWriteItem.builder() + .put(Put.builder().tableName("DOMAIN1").item(item).build()) + .build()); + + exchange.getIn().setHeader(Ddb2Constants.TRANSACT_WRITE_ITEMS, transactItems); + exchange.getIn().setHeader(Ddb2Constants.TRANSACT_CLIENT_REQUEST_TOKEN, "idempotency-token-123"); + + command.execute(); + + assertNotNull(ddbClient.transactWriteItemsRequest); + assertEquals("idempotency-token-123", ddbClient.transactWriteItemsRequest.clientRequestToken()); + } +} diff --git a/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2BatchExecuteStatementRuleIT.java b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2BatchExecuteStatementRuleIT.java new file mode 100644 index 000000000000..cac17f459e0e --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2BatchExecuteStatementRuleIT.java @@ -0,0 +1,80 @@ +/* + * 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.localstack; + +import java.util.Arrays; +import java.util.List; + +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.ddb.Ddb2Constants; +import org.apache.camel.component.aws2.ddb.Ddb2Operations; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.BatchStatementRequest; +import software.amazon.awssdk.services.dynamodb.model.BatchStatementResponse; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class AWS2BatchExecuteStatementRuleIT extends Aws2DDBBase { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private final String attributeName = "clave"; + private final String tableName = "TestTableBatchPartiQL"; + + @Test + public void batchExecuteStatement() { + List<BatchStatementRequest> statements = Arrays.asList( + BatchStatementRequest.builder() + .statement("INSERT INTO \"" + tableName + "\" VALUE {'" + attributeName + "': 'key1', 'data': 'val1'}") + .build(), + BatchStatementRequest.builder() + .statement("INSERT INTO \"" + tableName + "\" VALUE {'" + attributeName + "': 'key2', 'data': 'val2'}") + .build()); + + Exchange result = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.BatchExecuteStatement); + exchange.getIn().setHeader(Ddb2Constants.BATCH_STATEMENTS, statements); + } + }); + + @SuppressWarnings("unchecked") + List<BatchStatementResponse> responses + = result.getIn().getHeader(Ddb2Constants.BATCH_STATEMENT_RESPONSE, List.class); + assertNotNull(responses); + } + + @Override + protected RouteBuilder createRouteBuilder() { + 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/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2BatchWriteItemRuleIT.java b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2BatchWriteItemRuleIT.java new file mode 100644 index 000000000000..798b5a3528c6 --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2BatchWriteItemRuleIT.java @@ -0,0 +1,87 @@ +/* + * 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.localstack; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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.ddb.Ddb2Constants; +import org.apache.camel.component.aws2.ddb.Ddb2Operations; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.PutRequest; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; +import software.amazon.awssdk.services.dynamodb.model.WriteRequest; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class AWS2BatchWriteItemRuleIT extends Aws2DDBBase { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private final String attributeName = "clave"; + private final String tableName = "TestTableBatchWrite"; + + @Test + public void batchWriteItem() { + Map<String, AttributeValue> item1 = new HashMap<>(); + item1.put(attributeName, AttributeValue.builder().s("batchKey1").build()); + item1.put("data", AttributeValue.builder().s("batchVal1").build()); + + Map<String, AttributeValue> item2 = new HashMap<>(); + item2.put(attributeName, AttributeValue.builder().s("batchKey2").build()); + item2.put("data", AttributeValue.builder().s("batchVal2").build()); + + Map<String, List<WriteRequest>> requestItems = new HashMap<>(); + requestItems.put(tableName, Arrays.asList( + WriteRequest.builder().putRequest(PutRequest.builder().item(item1).build()).build(), + WriteRequest.builder().putRequest(PutRequest.builder().item(item2).build()).build())); + + Exchange result = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.BatchWriteItem); + exchange.getIn().setHeader(Ddb2Constants.BATCH_WRITE_ITEMS, requestItems); + } + }); + + assertNull(result.getException()); + assertNotNull(result.getIn().getHeader(Ddb2Constants.BATCH_WRITE_UNPROCESSED_ITEMS)); + } + + @Override + protected RouteBuilder createRouteBuilder() { + 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/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2ExecuteStatementRuleIT.java b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2ExecuteStatementRuleIT.java new file mode 100644 index 000000000000..3065851a8f7f --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2ExecuteStatementRuleIT.java @@ -0,0 +1,89 @@ +/* + * 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.localstack; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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.ddb.Ddb2Constants; +import org.apache.camel.component.aws2.ddb.Ddb2Operations; +import org.junit.jupiter.api.Test; +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 static org.junit.jupiter.api.Assertions.assertNotNull; + +public class AWS2ExecuteStatementRuleIT extends Aws2DDBBase { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private final String attributeName = "clave"; + private final String tableName = "TestTablePartiQL"; + + @Test + public void executeStatement() { + // First put an item + final Map<String, AttributeValue> attributeMap = new HashMap<>(); + attributeMap.put(attributeName, AttributeValue.builder().s("hello").build()); + attributeMap.put("data", AttributeValue.builder().s("testValue").build()); + + template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.PutItem); + exchange.getIn().setHeader(Ddb2Constants.ITEM, attributeMap); + } + }); + + // Now query using PartiQL + Exchange result = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.ExecuteStatement); + exchange.getIn().setHeader(Ddb2Constants.STATEMENT, + "SELECT * FROM \"" + tableName + "\" WHERE \"" + attributeName + "\" = ?"); + exchange.getIn().setHeader(Ddb2Constants.STATEMENT_PARAMETERS, + Arrays.asList(AttributeValue.builder().s("hello").build())); + } + }); + + @SuppressWarnings("unchecked") + List<Map<String, AttributeValue>> items + = result.getIn().getHeader(Ddb2Constants.EXECUTE_STATEMENT_ITEMS, List.class); + assertNotNull(items); + } + + @Override + protected RouteBuilder createRouteBuilder() { + 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/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2NewOperationsRuleIT.java b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2NewOperationsRuleIT.java new file mode 100644 index 000000000000..aa96118510f1 --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2NewOperationsRuleIT.java @@ -0,0 +1,312 @@ +/* + * 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.localstack; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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.ddb.Ddb2Constants; +import org.apache.camel.component.aws2.ddb.Ddb2Operations; +import org.apache.camel.test.infra.aws2.clients.AWSSDKClientUtils; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.BatchStatementRequest; +import software.amazon.awssdk.services.dynamodb.model.BatchStatementResponse; +import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; +import software.amazon.awssdk.services.dynamodb.model.DeleteTableRequest; +import software.amazon.awssdk.services.dynamodb.model.Get; +import software.amazon.awssdk.services.dynamodb.model.ItemResponse; +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.Put; +import software.amazon.awssdk.services.dynamodb.model.PutRequest; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; +import software.amazon.awssdk.services.dynamodb.model.TransactGetItem; +import software.amazon.awssdk.services.dynamodb.model.TransactWriteItem; +import software.amazon.awssdk.services.dynamodb.model.WriteRequest; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Comprehensive integration test that exercises all new DynamoDB operations (PartiQL, transactions, batch write) in an + * end-to-end workflow against LocalStack. + */ +public class AWS2NewOperationsRuleIT extends Aws2DDBBase { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private static final String KEY_ATTR = "pk"; + private static final String TABLE_NAME = "TestNewOps"; + + @Override + protected void setupResources() throws Exception { + super.setupResources(); + ddbClient = AWSSDKClientUtils.newDynamoDBClient(); + CreateTableRequest createTableRequest = CreateTableRequest.builder() + .tableName(TABLE_NAME) + .keySchema( + KeySchemaElement.builder() + .attributeName(KEY_ATTR) + .keyType(KeyType.HASH) + .build()) + .attributeDefinitions( + AttributeDefinition.builder() + .attributeType(ScalarAttributeType.S) + .attributeName(KEY_ATTR) + .build()) + .provisionedThroughput(ProvisionedThroughput.builder() + .readCapacityUnits(5L) + .writeCapacityUnits(5L) + .build()) + .build(); + ddbClient.createTable(createTableRequest); + } + + @Override + protected void cleanupResources() throws Exception { + super.cleanupResources(); + DeleteTableRequest deleteTableRequest = DeleteTableRequest.builder() + .tableName(TABLE_NAME) + .build(); + ddbClient.deleteTable(deleteTableRequest); + } + + @Test + @SuppressWarnings("unchecked") + public void batchWriteAndPartiQLQuery() { + // Step 1: Use BatchWriteItem to insert multiple items + Map<String, AttributeValue> item1 = makeItem("bw-1", "Batch Write Item 1"); + Map<String, AttributeValue> item2 = makeItem("bw-2", "Batch Write Item 2"); + + Map<String, List<WriteRequest>> requestItems = new HashMap<>(); + requestItems.put(TABLE_NAME, Arrays.asList( + WriteRequest.builder().putRequest(PutRequest.builder().item(item1).build()).build(), + WriteRequest.builder().putRequest(PutRequest.builder().item(item2).build()).build())); + + Exchange batchWriteResult = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.BatchWriteItem); + e.getIn().setHeader(Ddb2Constants.BATCH_WRITE_ITEMS, requestItems); + }); + + assertNull(batchWriteResult.getException()); + Map<String, List<WriteRequest>> unprocessed + = batchWriteResult.getIn().getHeader(Ddb2Constants.BATCH_WRITE_UNPROCESSED_ITEMS, Map.class); + assertNotNull(unprocessed); + assertTrue(unprocessed.isEmpty(), "All items should have been processed"); + + // Step 2: Use ExecuteStatement (PartiQL) to read back one of the items + Exchange partiqlResult = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.ExecuteStatement); + e.getIn().setHeader(Ddb2Constants.STATEMENT, + "SELECT * FROM \"" + TABLE_NAME + "\" WHERE \"" + KEY_ATTR + "\" = ?"); + e.getIn().setHeader(Ddb2Constants.STATEMENT_PARAMETERS, + Arrays.asList(AttributeValue.builder().s("bw-1").build())); + e.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + }); + + assertNull(partiqlResult.getException()); + List<Map<String, AttributeValue>> items + = partiqlResult.getIn().getHeader(Ddb2Constants.EXECUTE_STATEMENT_ITEMS, List.class); + assertNotNull(items); + assertFalse(items.isEmpty(), "PartiQL SELECT should return the item inserted by BatchWriteItem"); + assertEquals("Batch Write Item 1", items.get(0).get("data").s()); + } + + @Test + @SuppressWarnings("unchecked") + public void batchExecuteStatementInsertAndSelect() { + // Step 1: Use BatchExecuteStatement to insert items via PartiQL + List<BatchStatementRequest> insertStatements = Arrays.asList( + BatchStatementRequest.builder() + .statement("INSERT INTO \"" + TABLE_NAME + "\" VALUE {'" + KEY_ATTR + + "': 'bps-1', 'data': 'Batch PartiQL 1'}") + .build(), + BatchStatementRequest.builder() + .statement("INSERT INTO \"" + TABLE_NAME + "\" VALUE {'" + KEY_ATTR + + "': 'bps-2', 'data': 'Batch PartiQL 2'}") + .build()); + + Exchange batchInsertResult = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.BatchExecuteStatement); + e.getIn().setHeader(Ddb2Constants.BATCH_STATEMENTS, insertStatements); + }); + + assertNull(batchInsertResult.getException()); + List<BatchStatementResponse> responses + = batchInsertResult.getIn().getHeader(Ddb2Constants.BATCH_STATEMENT_RESPONSE, List.class); + assertNotNull(responses); + assertEquals(2, responses.size()); + + // Step 2: Verify with PartiQL SELECT + Exchange selectResult = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.ExecuteStatement); + e.getIn().setHeader(Ddb2Constants.STATEMENT, + "SELECT * FROM \"" + TABLE_NAME + "\" WHERE \"" + KEY_ATTR + "\" = ?"); + e.getIn().setHeader(Ddb2Constants.STATEMENT_PARAMETERS, + Arrays.asList(AttributeValue.builder().s("bps-2").build())); + e.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + }); + + assertNull(selectResult.getException()); + List<Map<String, AttributeValue>> items + = selectResult.getIn().getHeader(Ddb2Constants.EXECUTE_STATEMENT_ITEMS, List.class); + assertNotNull(items); + assertFalse(items.isEmpty()); + assertEquals("Batch PartiQL 2", items.get(0).get("data").s()); + } + + @Test + @SuppressWarnings("unchecked") + public void transactWriteThenTransactGet() { + // Step 1: Use TransactWriteItems to atomically insert two items + Map<String, AttributeValue> txItem1 = makeItem("tx-1", "Transaction Item 1"); + Map<String, AttributeValue> txItem2 = makeItem("tx-2", "Transaction Item 2"); + + Exchange txWriteResult = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.TransactWriteItems); + e.getIn().setHeader(Ddb2Constants.TRANSACT_WRITE_ITEMS, Arrays.asList( + TransactWriteItem.builder() + .put(Put.builder().tableName(TABLE_NAME).item(txItem1).build()) + .build(), + TransactWriteItem.builder() + .put(Put.builder().tableName(TABLE_NAME).item(txItem2).build()) + .build())); + }); + + assertNull(txWriteResult.getException()); + + // Step 2: Use TransactGetItems to atomically read both items back + Map<String, AttributeValue> key1 = new HashMap<>(); + key1.put(KEY_ATTR, AttributeValue.builder().s("tx-1").build()); + Map<String, AttributeValue> key2 = new HashMap<>(); + key2.put(KEY_ATTR, AttributeValue.builder().s("tx-2").build()); + + Exchange txGetResult = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.TransactGetItems); + e.getIn().setHeader(Ddb2Constants.TRANSACT_GET_ITEMS, Arrays.asList( + TransactGetItem.builder() + .get(Get.builder().tableName(TABLE_NAME).key(key1).build()) + .build(), + TransactGetItem.builder() + .get(Get.builder().tableName(TABLE_NAME).key(key2).build()) + .build())); + }); + + assertNull(txGetResult.getException()); + List<ItemResponse> txResponses = txGetResult.getIn().getHeader(Ddb2Constants.TRANSACT_GET_RESPONSE, List.class); + assertNotNull(txResponses); + assertEquals(2, txResponses.size()); + assertEquals("Transaction Item 1", txResponses.get(0).item().get("data").s()); + assertEquals("Transaction Item 2", txResponses.get(1).item().get("data").s()); + } + + @Test + @SuppressWarnings("unchecked") + public void transactWriteWithIdempotencyToken() { + // Use TransactWriteItems with a client request token for idempotency + Map<String, AttributeValue> item = makeItem("tx-idem-1", "Idempotent Item"); + + for (int i = 0; i < 2; i++) { + Exchange result = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.TransactWriteItems); + e.getIn().setHeader(Ddb2Constants.TRANSACT_CLIENT_REQUEST_TOKEN, "unique-token-12345"); + e.getIn().setHeader(Ddb2Constants.TRANSACT_WRITE_ITEMS, Arrays.asList( + TransactWriteItem.builder() + .put(Put.builder().tableName(TABLE_NAME).item(item).build()) + .build())); + }); + assertNull(result.getException()); + } + + // Verify the item exists via PartiQL + Exchange selectResult = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.ExecuteStatement); + e.getIn().setHeader(Ddb2Constants.STATEMENT, + "SELECT * FROM \"" + TABLE_NAME + "\" WHERE \"" + KEY_ATTR + "\" = ?"); + e.getIn().setHeader(Ddb2Constants.STATEMENT_PARAMETERS, + Arrays.asList(AttributeValue.builder().s("tx-idem-1").build())); + e.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + }); + + List<Map<String, AttributeValue>> items + = selectResult.getIn().getHeader(Ddb2Constants.EXECUTE_STATEMENT_ITEMS, List.class); + assertNotNull(items); + assertEquals(1, items.size()); + assertEquals("Idempotent Item", items.get(0).get("data").s()); + } + + @Test + @SuppressWarnings("unchecked") + public void executeStatementWithPagination() { + // Insert multiple items via batch write + Map<String, List<WriteRequest>> requestItems = new HashMap<>(); + List<WriteRequest> writes = Arrays.asList( + WriteRequest.builder().putRequest(PutRequest.builder().item(makeItem("page-1", "Page 1")).build()).build(), + WriteRequest.builder().putRequest(PutRequest.builder().item(makeItem("page-2", "Page 2")).build()).build(), + WriteRequest.builder().putRequest(PutRequest.builder().item(makeItem("page-3", "Page 3")).build()).build()); + requestItems.put(TABLE_NAME, writes); + + template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.BatchWriteItem); + e.getIn().setHeader(Ddb2Constants.BATCH_WRITE_ITEMS, requestItems); + }); + + // Query with PartiQL (full table scan via PartiQL) + Exchange scanResult = template.send("direct:start", e -> { + e.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.ExecuteStatement); + e.getIn().setHeader(Ddb2Constants.STATEMENT, "SELECT * FROM \"" + TABLE_NAME + "\""); + e.getIn().setHeader(Ddb2Constants.CONSISTENT_READ, true); + }); + + assertNull(scanResult.getException()); + List<Map<String, AttributeValue>> items + = scanResult.getIn().getHeader(Ddb2Constants.EXECUTE_STATEMENT_ITEMS, List.class); + assertNotNull(items); + // Should return at least the 3 items we just inserted (may include others from other tests) + assertTrue(items.size() >= 3, "PartiQL scan should return at least 3 items"); + } + + private Map<String, AttributeValue> makeItem(String keyValue, String dataValue) { + Map<String, AttributeValue> item = new HashMap<>(); + item.put(KEY_ATTR, AttributeValue.builder().s(keyValue).build()); + item.put("data", AttributeValue.builder().s(dataValue).build()); + return item; + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start").to("aws2-ddb://" + TABLE_NAME); + } + }; + } +} diff --git a/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2TransactGetItemsRuleIT.java b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2TransactGetItemsRuleIT.java new file mode 100644 index 000000000000..643d214f6ffa --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2TransactGetItemsRuleIT.java @@ -0,0 +1,94 @@ +/* + * 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.localstack; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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.ddb.Ddb2Constants; +import org.apache.camel.component.aws2.ddb.Ddb2Operations; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.Get; +import software.amazon.awssdk.services.dynamodb.model.ItemResponse; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; +import software.amazon.awssdk.services.dynamodb.model.TransactGetItem; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class AWS2TransactGetItemsRuleIT extends Aws2DDBBase { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private final String attributeName = "clave"; + private final String tableName = "TestTableTransactGet"; + + @Test + public void transactGetItems() { + // First put an item + final Map<String, AttributeValue> attributeMap = new HashMap<>(); + attributeMap.put(attributeName, AttributeValue.builder().s("txGetKey1").build()); + attributeMap.put("data", AttributeValue.builder().s("txGetVal1").build()); + + template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.PutItem); + exchange.getIn().setHeader(Ddb2Constants.ITEM, attributeMap); + } + }); + + // Now transactionally get it + Map<String, AttributeValue> key = new HashMap<>(); + key.put(attributeName, AttributeValue.builder().s("txGetKey1").build()); + + Exchange result = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.TransactGetItems); + exchange.getIn().setHeader(Ddb2Constants.TRANSACT_GET_ITEMS, Arrays.asList( + TransactGetItem.builder() + .get(Get.builder().tableName(tableName).key(key).build()) + .build())); + } + }); + + @SuppressWarnings("unchecked") + List<ItemResponse> responses = result.getIn().getHeader(Ddb2Constants.TRANSACT_GET_RESPONSE, List.class); + assertNotNull(responses); + } + + @Override + protected RouteBuilder createRouteBuilder() { + 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/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2TransactWriteItemsRuleIT.java b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2TransactWriteItemsRuleIT.java new file mode 100644 index 000000000000..16e4bfee8d78 --- /dev/null +++ b/components/camel-aws/camel-aws2-ddb/src/test/java/org/apache/camel/component/aws2/ddb/localstack/AWS2TransactWriteItemsRuleIT.java @@ -0,0 +1,85 @@ +/* + * 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.localstack; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +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.ddb.Ddb2Constants; +import org.apache.camel.component.aws2.ddb.Ddb2Operations; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.Put; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; +import software.amazon.awssdk.services.dynamodb.model.TransactWriteItem; + +import static org.junit.jupiter.api.Assertions.assertNull; + +public class AWS2TransactWriteItemsRuleIT extends Aws2DDBBase { + + @EndpointInject("direct:start") + private ProducerTemplate template; + + private final String attributeName = "clave"; + private final String tableName = "TestTableTransactWrite"; + + @Test + public void transactWriteItems() { + Map<String, AttributeValue> item1 = new HashMap<>(); + item1.put(attributeName, AttributeValue.builder().s("txKey1").build()); + item1.put("data", AttributeValue.builder().s("txVal1").build()); + + Map<String, AttributeValue> item2 = new HashMap<>(); + item2.put(attributeName, AttributeValue.builder().s("txKey2").build()); + item2.put("data", AttributeValue.builder().s("txVal2").build()); + + Exchange result = template.send("direct:start", new Processor() { + public void process(Exchange exchange) { + exchange.getIn().setHeader(Ddb2Constants.OPERATION, Ddb2Operations.TransactWriteItems); + exchange.getIn().setHeader(Ddb2Constants.TRANSACT_WRITE_ITEMS, Arrays.asList( + TransactWriteItem.builder() + .put(Put.builder().tableName(tableName).item(item1).build()) + .build(), + TransactWriteItem.builder() + .put(Put.builder().tableName(tableName).item(item2).build()) + .build())); + } + }); + + assertNull(result.getException()); + } + + @Override + protected RouteBuilder createRouteBuilder() { + 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/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/Ddb2EndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/Ddb2EndpointBuilderFactory.java index f96a2a52bb1d..87a3c58cc15b 100644 --- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/Ddb2EndpointBuilderFactory.java +++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/Ddb2EndpointBuilderFactory.java @@ -1143,6 +1143,166 @@ public interface Ddb2EndpointBuilderFactory { public String awsDdbWriteCapacity() { return "CamelAwsDdbWriteCapacity"; } + /** + * A PartiQL statement that uses parameters. + * + * The option is a: {@code String} type. + * + * Group: ExecuteStatement BatchExecuteStatement + * + * @return the name of the header {@code AwsDdbStatement}. + */ + public String awsDdbStatement() { + return "CamelAwsDdbStatement"; + } + /** + * The parameters for the PartiQL statement, if any. + * + * The option is a: {@code + * java.util.List<software.amazon.awssdk.services.dynamodb.model.AttributeValue>} type. + * + * Group: ExecuteStatement BatchExecuteStatement + * + * @return the name of the header {@code AwsDdbStatementParameters}. + */ + public String awsDdbStatementParameters() { + return "CamelAwsDdbStatementParameters"; + } + /** + * The list of PartiQL statements representing the batch to run. + * + * The option is a: {@code + * java.util.List<software.amazon.awssdk.services.dynamodb.model.BatchStatementRequest>} type. + * + * Group: BatchExecuteStatement + * + * @return the name of the header {@code AwsDdbBatchStatements}. + */ + public String awsDdbBatchStatements() { + return "CamelAwsDdbBatchStatements"; + } + /** + * The response items from an ExecuteStatement operation. + * + * The option is a: {@code java.util.List<java.util.Map<String, + * software.amazon.awssdk.services.dynamodb.model.AttributeValue>>} + * type. + * + * Group: ExecuteStatement + * + * @return the name of the header {@code AwsDdbExecuteStatementItems}. + */ + public String awsDdbExecuteStatementItems() { + return "CamelAwsDdbExecuteStatementItems"; + } + /** + * The next token from an ExecuteStatement operation for pagination. + * + * The option is a: {@code String} type. + * + * Group: ExecuteStatement + * + * @return the name of the header {@code + * AwsDdbExecuteStatementNextToken}. + */ + public String awsDdbExecuteStatementNextToken() { + return "CamelAwsDdbExecuteStatementNextToken"; + } + /** + * The response to each PartiQL statement in the batch. + * + * The option is a: {@code + * java.util.List<software.amazon.awssdk.services.dynamodb.model.BatchStatementResponse>} type. + * + * Group: BatchExecuteStatement + * + * @return the name of the header {@code AwsDdbBatchStatementResponse}. + */ + public String awsDdbBatchStatementResponse() { + return "CamelAwsDdbBatchStatementResponse"; + } + /** + * The list of TransactWriteItem objects for a transactional write. + * + * The option is a: {@code + * java.util.List<software.amazon.awssdk.services.dynamodb.model.TransactWriteItem>} type. + * + * Group: TransactWriteItems + * + * @return the name of the header {@code AwsDdbTransactWriteItems}. + */ + public String awsDdbTransactWriteItems() { + return "CamelAwsDdbTransactWriteItems"; + } + /** + * A unique client request token for idempotent TransactWriteItems + * calls. + * + * The option is a: {@code String} type. + * + * Group: TransactWriteItems + * + * @return the name of the header {@code + * AwsDdbTransactClientRequestToken}. + */ + public String awsDdbTransactClientRequestToken() { + return "CamelAwsDdbTransactClientRequestToken"; + } + /** + * The list of TransactGetItem objects for a transactional read. + * + * The option is a: {@code + * java.util.List<software.amazon.awssdk.services.dynamodb.model.TransactGetItem>} type. + * + * Group: TransactGetItems + * + * @return the name of the header {@code AwsDdbTransactGetItems}. + */ + public String awsDdbTransactGetItems() { + return "CamelAwsDdbTransactGetItems"; + } + /** + * The response from a TransactGetItems operation. + * + * The option is a: {@code + * java.util.List<software.amazon.awssdk.services.dynamodb.model.ItemResponse>} type. + * + * Group: TransactGetItems + * + * @return the name of the header {@code AwsDdbTransactGetResponse}. + */ + public String awsDdbTransactGetResponse() { + return "CamelAwsDdbTransactGetResponse"; + } + /** + * A map of table names to lists of WriteRequest objects for batch + * writes. + * + * The option is a: {@code java.util.Map<String, + * java.util.List<software.amazon.awssdk.services.dynamodb.model.WriteRequest>>} type. + * + * Group: BatchWriteItem + * + * @return the name of the header {@code AwsDdbBatchWriteItems}. + */ + public String awsDdbBatchWriteItems() { + return "CamelAwsDdbBatchWriteItems"; + } + /** + * A map of tables and their respective unprocessed items after a + * BatchWriteItem operation. + * + * The option is a: {@code java.util.Map<String, + * java.util.List<software.amazon.awssdk.services.dynamodb.model.WriteRequest>>} type. + * + * Group: BatchWriteItem + * + * @return the name of the header {@code + * AwsDdbBatchWriteUnprocessedItems}. + */ + public String awsDdbBatchWriteUnprocessedItems() { + return "CamelAwsDdbBatchWriteUnprocessedItems"; + } /** * The Filter Expression. *
