This is an automated email from the ASF dual-hosted git repository.
acosentino pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new c2f4266dbd5 CAMEL-21251 - Camel-AWS2-S3: Support Conditional Reads on
producer operations (#15691)
c2f4266dbd5 is described below
commit c2f4266dbd55bdc39c5e07219c11fb632738a3af
Author: Andrea Cosentino <[email protected]>
AuthorDate: Wed Sep 25 11:50:29 2024 +0200
CAMEL-21251 - Camel-AWS2-S3: Support Conditional Reads on producer
operations (#15691)
* CAMEL-21251 - Camel-AWS2-S3: Support Conditional Reads on producer
operations - GetObject
Signed-off-by: Andrea Cosentino <[email protected]>
* CAMEL-21251 - Camel-AWS2-S3: Support Conditional Reads on producer
operations - CopyObject
Signed-off-by: Andrea Cosentino <[email protected]>
---------
Signed-off-by: Andrea Cosentino <[email protected]>
---
.../apache/camel/catalog/components/aws2-s3.json | 6 ++-
.../apache/camel/component/aws2/s3/aws2-s3.json | 6 ++-
.../camel/component/aws2/s3/AWS2S3Constants.java | 12 +++++
.../camel/component/aws2/s3/AWS2S3Producer.java | 39 ++++++++++++++++
.../endpoint/dsl/AWS2S3EndpointBuilderFactory.java | 53 ++++++++++++++++++++++
5 files changed, 114 insertions(+), 2 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws2-s3.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws2-s3.json
index df28d3a336d..d94c1646ba1 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws2-s3.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws2-s3.json
@@ -117,7 +117,11 @@
"CamelAwsS3Metadata": { "index": 28, "kind": "header", "displayName": "",
"group": "common", "label": "", "required": false, "javaType": "Map<String,
String>", "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "description": "A map of metadata to be stored or stored with
the object in S3. More details about metadata
https:\/\/docs.aws.amazon.com\/AmazonS3\/latest\/userguide\/UsingMetadata.htmlhere.",
"constantName": "org.apache.camel.component.aws2.s3.A [...]
"CamelMessageTimestamp": { "index": 29, "kind": "header", "displayName":
"", "group": "consumer", "label": "consumer", "required": false, "javaType":
"long", "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "description": "The timestamp of the message", "constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#MESSAGE_TIMESTAMP" },
"CamelAwsS3Prefix": { "index": 30, "kind": "header", "displayName": "",
"group": "common", "label": "", "required": false, "javaType": "",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The prefix which is used in the
com.amazonaws.services.s3.model.ListObjectsRequest to only list objects we are
interested in", "constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#PREFIX" },
- "CamelAwsS3Delimiter": { "index": 31, "kind": "header", "displayName": "",
"group": "common", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The delimiter which is used in the
com.amazonaws.services.s3.model.ListObjectsRequest to only list objects we are
interested in", "constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#DELIMITER" }
+ "CamelAwsS3Delimiter": { "index": 31, "kind": "header", "displayName": "",
"group": "common", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The delimiter which is used in the
com.amazonaws.services.s3.model.ListObjectsRequest to only list objects we are
interested in", "constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#DELIMITER" },
+ "CamelAwsS3IfMatchCondition": { "index": 32, "kind": "header",
"displayName": "", "group": "common", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Return\/copy the object only if its
entity tag (ETag) is the same as the one specified in this header.",
"constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#IF_MATCH_CONDITION" },
+ "CamelAwsS3IfModifiedSinceCondition": { "index": 33, "kind": "header",
"displayName": "", "group": "common", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Return\/copy the object only if it has
been modified since the specified time; otherwise, return a 304 Not Modified
error.", "constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#IF_MODIFIED_SINCE_CONDITION"
},
+ "CamelAwsS3IfNoneMatchCondition": { "index": 34, "kind": "header",
"displayName": "", "group": "common", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Return\/copy the object only if its
entity tag (ETag) is different from the one specified in this header.",
"constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#IF_NONE_MATCH_CONDITION" },
+ "CamelAwsS3IfUnmodifiedSinceCondition": { "index": 35, "kind": "header",
"displayName": "", "group": "common", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Return\/copy the object only if it has
not been modified since the specified time.", "constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#IF_UNMODIFIED_SINCE_CONDITION"
}
},
"properties": {
"bucketNameOrArn": { "index": 0, "kind": "path", "displayName": "Bucket
Name Or Arn", "group": "common", "label": "", "required": true, "type":
"string", "javaType": "java.lang.String", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false, "description":
"Bucket name or ARN" },
diff --git
a/components/camel-aws/camel-aws2-s3/src/generated/resources/META-INF/org/apache/camel/component/aws2/s3/aws2-s3.json
b/components/camel-aws/camel-aws2-s3/src/generated/resources/META-INF/org/apache/camel/component/aws2/s3/aws2-s3.json
index df28d3a336d..d94c1646ba1 100644
---
a/components/camel-aws/camel-aws2-s3/src/generated/resources/META-INF/org/apache/camel/component/aws2/s3/aws2-s3.json
+++
b/components/camel-aws/camel-aws2-s3/src/generated/resources/META-INF/org/apache/camel/component/aws2/s3/aws2-s3.json
@@ -117,7 +117,11 @@
"CamelAwsS3Metadata": { "index": 28, "kind": "header", "displayName": "",
"group": "common", "label": "", "required": false, "javaType": "Map<String,
String>", "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "description": "A map of metadata to be stored or stored with
the object in S3. More details about metadata
https:\/\/docs.aws.amazon.com\/AmazonS3\/latest\/userguide\/UsingMetadata.htmlhere.",
"constantName": "org.apache.camel.component.aws2.s3.A [...]
"CamelMessageTimestamp": { "index": 29, "kind": "header", "displayName":
"", "group": "consumer", "label": "consumer", "required": false, "javaType":
"long", "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "description": "The timestamp of the message", "constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#MESSAGE_TIMESTAMP" },
"CamelAwsS3Prefix": { "index": 30, "kind": "header", "displayName": "",
"group": "common", "label": "", "required": false, "javaType": "",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The prefix which is used in the
com.amazonaws.services.s3.model.ListObjectsRequest to only list objects we are
interested in", "constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#PREFIX" },
- "CamelAwsS3Delimiter": { "index": 31, "kind": "header", "displayName": "",
"group": "common", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The delimiter which is used in the
com.amazonaws.services.s3.model.ListObjectsRequest to only list objects we are
interested in", "constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#DELIMITER" }
+ "CamelAwsS3Delimiter": { "index": 31, "kind": "header", "displayName": "",
"group": "common", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The delimiter which is used in the
com.amazonaws.services.s3.model.ListObjectsRequest to only list objects we are
interested in", "constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#DELIMITER" },
+ "CamelAwsS3IfMatchCondition": { "index": 32, "kind": "header",
"displayName": "", "group": "common", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Return\/copy the object only if its
entity tag (ETag) is the same as the one specified in this header.",
"constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#IF_MATCH_CONDITION" },
+ "CamelAwsS3IfModifiedSinceCondition": { "index": 33, "kind": "header",
"displayName": "", "group": "common", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Return\/copy the object only if it has
been modified since the specified time; otherwise, return a 304 Not Modified
error.", "constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#IF_MODIFIED_SINCE_CONDITION"
},
+ "CamelAwsS3IfNoneMatchCondition": { "index": 34, "kind": "header",
"displayName": "", "group": "common", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Return\/copy the object only if its
entity tag (ETag) is different from the one specified in this header.",
"constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#IF_NONE_MATCH_CONDITION" },
+ "CamelAwsS3IfUnmodifiedSinceCondition": { "index": 35, "kind": "header",
"displayName": "", "group": "common", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "Return\/copy the object only if it has
not been modified since the specified time.", "constantName":
"org.apache.camel.component.aws2.s3.AWS2S3Constants#IF_UNMODIFIED_SINCE_CONDITION"
}
},
"properties": {
"bucketNameOrArn": { "index": 0, "kind": "path", "displayName": "Bucket
Name Or Arn", "group": "common", "label": "", "required": true, "type":
"string", "javaType": "java.lang.String", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false, "description":
"Bucket name or ARN" },
diff --git
a/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Constants.java
b/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Constants.java
index 5248cff744d..c7a916e5bee 100644
---
a/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Constants.java
+++
b/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Constants.java
@@ -142,4 +142,16 @@ public interface AWS2S3Constants {
@Metadata(description = "The delimiter which is used in the
com.amazonaws.services.s3.model.ListObjectsRequest to only list objects we are
interested in",
javaType = "String")
String DELIMITER = "CamelAwsS3Delimiter";
+ @Metadata(description = "Return/copy the object only if its entity tag
(ETag) is the same as the one specified in this header.",
+ javaType = "String")
+ String IF_MATCH_CONDITION = "CamelAwsS3IfMatchCondition";
+ @Metadata(description = "Return/copy the object only if it has been
modified since the specified time; otherwise, return a 304 Not Modified error.",
+ javaType = "String")
+ String IF_MODIFIED_SINCE_CONDITION = "CamelAwsS3IfModifiedSinceCondition";
+ @Metadata(description = "Return/copy the object only if its entity tag
(ETag) is different from the one specified in this header.",
+ javaType = "String")
+ String IF_NONE_MATCH_CONDITION = "CamelAwsS3IfNoneMatchCondition";
+ @Metadata(description = "Return/copy the object only if it has not been
modified since the specified time.",
+ javaType = "String")
+ String IF_UNMODIFIED_SINCE_CONDITION =
"CamelAwsS3IfUnmodifiedSinceCondition";
}
diff --git
a/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Producer.java
b/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Producer.java
index 3d1de35a387..368875fb0f3 100644
---
a/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Producer.java
+++
b/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Producer.java
@@ -23,6 +23,7 @@ import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URI;
import java.time.Duration;
+import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -466,6 +467,25 @@ public class AWS2S3Producer extends DefaultProducer {
copyObjectRequest.sseCustomerAlgorithm(getConfiguration().getCustomerAlgorithm());
}
}
+ final String ifMatchCondition =
exchange.getMessage().getHeader(AWS2S3Constants.IF_MATCH_CONDITION,
String.class);
+ final Instant ifModifiedSinceCondition
+ =
exchange.getMessage().getHeader(AWS2S3Constants.IF_MODIFIED_SINCE_CONDITION,
Instant.class);
+ final String ifNoneMatchCondition
+ =
exchange.getMessage().getHeader(AWS2S3Constants.IF_NONE_MATCH_CONDITION,
String.class);
+ final Instant ifUnmodifiedSince
+ =
exchange.getMessage().getHeader(AWS2S3Constants.IF_UNMODIFIED_SINCE_CONDITION,
Instant.class);
+ if (ObjectHelper.isNotEmpty(ifMatchCondition)) {
+ copyObjectRequest.copySourceIfMatch(ifMatchCondition);
+ }
+ if (ObjectHelper.isNotEmpty(ifModifiedSinceCondition)) {
+
copyObjectRequest.copySourceIfModifiedSince(ifModifiedSinceCondition);
+ }
+ if (ObjectHelper.isNotEmpty(ifNoneMatchCondition)) {
+ copyObjectRequest.copySourceIfNoneMatch(ifNoneMatchCondition);
+ }
+ if (ObjectHelper.isNotEmpty(ifUnmodifiedSince)) {
+
copyObjectRequest.copySourceIfUnmodifiedSince(ifUnmodifiedSince);
+ }
CopyObjectResponse copyObjectResult =
s3Client.copyObject(copyObjectRequest.build());
@@ -541,7 +561,26 @@ public class AWS2S3Producer extends DefaultProducer {
} else {
final String bucketName =
AWS2S3Utils.determineBucketName(exchange, getConfiguration());
final String keyName = AWS2S3Utils.determineKey(exchange,
getConfiguration());
+ final String ifMatchCondition =
exchange.getMessage().getHeader(AWS2S3Constants.IF_MATCH_CONDITION,
String.class);
+ final Instant ifModifiedSinceCondition
+ =
exchange.getMessage().getHeader(AWS2S3Constants.IF_MODIFIED_SINCE_CONDITION,
Instant.class);
+ final String ifNoneMatchCondition
+ =
exchange.getMessage().getHeader(AWS2S3Constants.IF_NONE_MATCH_CONDITION,
String.class);
+ final Instant ifUnmodifiedSince
+ =
exchange.getMessage().getHeader(AWS2S3Constants.IF_UNMODIFIED_SINCE_CONDITION,
Instant.class);
GetObjectRequest.Builder req =
GetObjectRequest.builder().bucket(bucketName).key(keyName);
+ if (ObjectHelper.isNotEmpty(ifMatchCondition)) {
+ req.ifMatch(ifMatchCondition);
+ }
+ if (ObjectHelper.isNotEmpty(ifModifiedSinceCondition)) {
+ req.ifModifiedSince(ifModifiedSinceCondition);
+ }
+ if (ObjectHelper.isNotEmpty(ifNoneMatchCondition)) {
+ req.ifNoneMatch(ifNoneMatchCondition);
+ }
+ if (ObjectHelper.isNotEmpty(ifUnmodifiedSince)) {
+ req.ifUnmodifiedSince(ifUnmodifiedSince);
+ }
ResponseInputStream<GetObjectResponse> res =
s3Client.getObject(req.build(), ResponseTransformer.toInputStream());
Message message = getMessageForResponse(exchange);
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AWS2S3EndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AWS2S3EndpointBuilderFactory.java
index 5cb462a783d..4d21a4f9e58 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AWS2S3EndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/AWS2S3EndpointBuilderFactory.java
@@ -4017,6 +4017,59 @@ public interface AWS2S3EndpointBuilderFactory {
public String awsS3Delimiter() {
return "CamelAwsS3Delimiter";
}
+ /**
+ * Return/copy the object only if its entity tag (ETag) is the same as
+ * the one specified in this header.
+ *
+ * The option is a: {@code String} type.
+ *
+ * Group: common
+ *
+ * @return the name of the header {@code AwsS3IfMatchCondition}.
+ */
+ public String awsS3IfMatchCondition() {
+ return "CamelAwsS3IfMatchCondition";
+ }
+ /**
+ * Return/copy the object only if it has been modified since the
+ * specified time; otherwise, return a 304 Not Modified error.
+ *
+ * The option is a: {@code String} type.
+ *
+ * Group: common
+ *
+ * @return the name of the header {@code
AwsS3IfModifiedSinceCondition}.
+ */
+ public String awsS3IfModifiedSinceCondition() {
+ return "CamelAwsS3IfModifiedSinceCondition";
+ }
+ /**
+ * Return/copy the object only if its entity tag (ETag) is different
+ * from the one specified in this header.
+ *
+ * The option is a: {@code String} type.
+ *
+ * Group: common
+ *
+ * @return the name of the header {@code AwsS3IfNoneMatchCondition}.
+ */
+ public String awsS3IfNoneMatchCondition() {
+ return "CamelAwsS3IfNoneMatchCondition";
+ }
+ /**
+ * Return/copy the object only if it has not been modified since the
+ * specified time.
+ *
+ * The option is a: {@code String} type.
+ *
+ * Group: common
+ *
+ * @return the name of the header {@code
+ * AwsS3IfUnmodifiedSinceCondition}.
+ */
+ public String awsS3IfUnmodifiedSinceCondition() {
+ return "CamelAwsS3IfUnmodifiedSinceCondition";
+ }
}
static AWS2S3EndpointBuilder endpointBuilder(String componentName, String
path) {
class AWS2S3EndpointBuilderImpl extends AbstractEndpointBuilder
implements AWS2S3EndpointBuilder, AdvancedAWS2S3EndpointBuilder {