This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch feature/CAMEL-23789-wave1-multi-dsl-docs in repository https://gitbox.apache.org/repos/asf/camel.git
commit 6d67e193e5738220cebe4b7e7151faadbab45588 Author: Claus Ibsen <[email protected]> AuthorDate: Wed Jun 17 18:15:08 2026 +0200 CAMEL-23789: Make AWS S3 component docs multi-DSL friendly (Wave 1) Convert processor-based examples to declarative setHeader/setBody DSL, add XML and YAML tabs for all route examples, resolve AWS2S3Constants to string header values, add Java-only markers for programmatic config, and convert streaming upload timestamp grouping examples to multi-DSL. Co-Authored-By: Claude <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../src/main/docs/aws2-s3-component.adoc | 1426 +++++++++++++++----- 1 file changed, 1076 insertions(+), 350 deletions(-) diff --git a/components/camel-aws/camel-aws2-s3/src/main/docs/aws2-s3-component.adoc b/components/camel-aws/camel-aws2-s3/src/main/docs/aws2-s3-component.adoc index 0e02327ecb69..6b2a2c3ab60c 100644 --- a/components/camel-aws/camel-aws2-s3/src/main/docs/aws2-s3-component.adoc +++ b/components/camel-aws/camel-aws2-s3/src/main/docs/aws2-s3-component.adoc @@ -185,13 +185,54 @@ YAML:: To use AWS KMS to encrypt/decrypt data by using AWS infrastructure, you can use the options introduced in 2.21.x like in the following example +[tabs] +==== +Java:: ++ [source,java] ---- from("file:tmp/test?fileName=test.txt") - .setHeader(AWS2S3Constants.KEY, constant("testFile")) - .to("aws2-s3://mybucket?amazonS3Client=#client&useAwsKMS=true&awsKMSKeyId=3f0637ad-296a-3dfe-a796-e60654fb128c"); + .setHeader("CamelAwsS3Key", constant("testFile")) + .to("aws2-s3://mybucket?amazonS3Client=#client&useAwsKMS=true&awsKMSKeyId=3f0637ad-296a-3dfe-a796-e60654fb128c"); ---- +XML:: ++ +[source,xml] +---- +<route> + <from uri="file:tmp/test?fileName=test.txt"/> + <setHeader name="CamelAwsS3Key"> + <constant>testFile</constant> + </setHeader> + <to uri="aws2-s3://mybucket?amazonS3Client=#client&useAwsKMS=true&awsKMSKeyId=3f0637ad-296a-3dfe-a796-e60654fb128c"/> +</route> +---- + +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: file:tmp/test + parameters: + fileName: test.txt + steps: + - setHeader: + name: CamelAwsS3Key + constant: testFile + - to: + uri: aws2-s3://mybucket + parameters: + amazonS3Client: "#client" + useAwsKMS: true + awsKMSKeyId: "3f0637ad-296a-3dfe-a796-e60654fb128c" +---- +==== + +TIP: The Java example uses the string value `"CamelAwsS3Key"` directly. You can also use the Java constant `AWS2S3Constants.KEY`. + In this way, you'll ask S3 to use the KMS key 3f0637ad-296a-3dfe-a796-e60654fb128c, to encrypt the file test.txt. When you ask to download this file, the decryption will be done directly before the download. @@ -218,74 +259,213 @@ For more information about this you can look at https://docs.aws.amazon.com/sdk- - Single Upload: This operation will upload a file to S3 based on the body content +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3Key", constant("camel.txt")) + .setBody(constant("Camel rocks!")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camel.txt"); - exchange.getIn().setBody("Camel rocks!"); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>camel.txt</constant></setHeader> + <setBody><constant>Camel rocks!</constant></setBody> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "camel.txt" + - setBody: + constant: "Camel rocks!" + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + - to: + uri: mock:result +---- +==== + This operation will upload the file camel.txt with the content "Camel rocks!" in the _mycamelbucket_ bucket - Multipart Upload: This operation will perform a multipart upload of a file to S3 based on the body content +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3Key", constant("empty.txt")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&multiPartUpload=true&autoCreateBucket=true&partSize=1048576") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "empty.txt"); - exchange.getIn().setBody(new File("src/empty.txt")); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&multiPartUpload=true&autoCreateBucket=true&partSize=1048576") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>empty.txt</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&multiPartUpload=true&autoCreateBucket=true&partSize=1048576"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "empty.txt" + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + multiPartUpload: true + autoCreateBucket: true + partSize: 1048576 + - to: + uri: mock:result +---- +==== + This operation will perform a multipart upload of the file empty.txt with based on the content the file src/empty.txt in the _mycamelbucket_ bucket - CopyObject: this operation copies an object from one bucket to a different one +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3BucketDestinationName", constant("camelDestinationBucket")) + .setHeader("CamelAwsS3Key", constant("camelKey")) + .setHeader("CamelAwsS3DestinationKey", constant("camelDestinationKey")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=copyObject") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.BUCKET_DESTINATION_NAME, "camelDestinationBucket"); - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - exchange.getIn().setHeader(AWS2S3Constants.DESTINATION_KEY, "camelDestinationKey"); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=copyObject") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3BucketDestinationName"><constant>camelDestinationBucket</constant></setHeader> + <setHeader name="CamelAwsS3Key"><constant>camelKey</constant></setHeader> + <setHeader name="CamelAwsS3DestinationKey"><constant>camelDestinationKey</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=copyObject"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3BucketDestinationName + constant: "camelDestinationBucket" + - setHeader: + name: CamelAwsS3Key + constant: "camelKey" + - setHeader: + name: CamelAwsS3DestinationKey + constant: "camelDestinationKey" + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: copyObject + - to: + uri: mock:result +---- +==== + This operation will copy the object with the name expressed in the header camelDestinationKey to the camelDestinationBucket bucket, from the bucket _mycamelbucket_. - DeleteObject: this operation deletes an object from a bucket +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3Key", constant("camelKey")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=deleteObject") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=deleteObject") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>camelKey</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=deleteObject"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "camelKey" + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: deleteObject + - to: + uri: mock:result +---- +==== + This operation will delete the object camelKey from the bucket _mycamelbucket_. - ListBuckets: this operation lists the buckets for this account in this region @@ -422,55 +602,161 @@ This operation will list the objects in the _mycamelbucket_ bucket - GetObject: this operation gets a single object in a specific bucket +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3Key", constant("camelKey")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObject") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObject") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>camelKey</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObject"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "camelKey" + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: getObject + - to: + uri: mock:result +---- +==== + This operation will return an S3Object instance related to the camelKey object in _mycamelbucket_ bucket. - GetObjectRange: this operation gets a single object range in a specific bucket +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3Key", constant("camelKey")) + .setHeader("CamelAwsS3RangeStart", constant("0")) + .setHeader("CamelAwsS3RangeEnd", constant("9")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObjectRange") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - exchange.getIn().setHeader(AWS2S3Constants.RANGE_START, "0"); - exchange.getIn().setHeader(AWS2S3Constants.RANGE_END, "9"); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObjectRange") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>camelKey</constant></setHeader> + <setHeader name="CamelAwsS3RangeStart"><constant>0</constant></setHeader> + <setHeader name="CamelAwsS3RangeEnd"><constant>9</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObjectRange"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "camelKey" + - setHeader: + name: CamelAwsS3RangeStart + constant: "0" + - setHeader: + name: CamelAwsS3RangeEnd + constant: "9" + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: getObjectRange + - to: + uri: mock:result +---- +==== + This operation will return an S3Object instance related to the camelKey object in _mycamelbucket_ bucket, containing the bytes from 0 to 9. - CreateDownloadLink: this operation will return a download link through S3 Presigner +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3Key", constant("camelKey")) + .to("aws2-s3://mycamelbucket?accessKey=xxx&secretKey=yyy®ion=region&operation=createDownloadLink") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - } - }) - .to("aws2-s3://mycamelbucket?accessKey=xxx&secretKey=yyy®ion=region&operation=createDownloadLink") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>camelKey</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?accessKey=xxx&secretKey=yyy&region=region&operation=createDownloadLink"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "camelKey" + - to: + uri: aws2-s3://mycamelbucket + parameters: + accessKey: xxx + secretKey: yyy + region: region + operation: createDownloadLink + - to: + uri: mock:result +---- +==== + This operation will return a download link url for the file camel-key in the bucket _mycamelbucket_ and region _region_. Parameters (`accessKey`, `secretKey` and `region`) are mandatory for this operation, if S3 client is autowired from the registry. @@ -522,291 +808,468 @@ This operation will check if the bucket _mycamelbucket_ exists and is accessible - HeadObject: this operation retrieves metadata from an object without returning the object itself +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3Key", constant("camelKey")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=headObject") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=headObject") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>camelKey</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=headObject"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "camelKey" + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: headObject + - to: + uri: mock:result +---- +==== + This operation will return metadata about the object camelKey in the bucket _mycamelbucket_. - DeleteObjects: this operation deletes multiple objects from a bucket in a single request +NOTE: The `CamelAwsS3KeysToDelete` header requires a `List<String>` value, which must be set from a bean or processor. + +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .process(exchange -> { + List<String> keys = List.of("key1", "key2", "key3"); + exchange.getIn().setHeader("CamelAwsS3KeysToDelete", keys); + }) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=deleteObjects") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - List<String> keys = Arrays.asList("key1", "key2", "key3"); - exchange.getIn().setHeader(AWS2S3Constants.KEYS_TO_DELETE, keys); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=deleteObjects") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <process ref="deleteKeysProcessor"/> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=deleteObjects"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ [source,yaml] ---- -- from: - uri: direct:start - steps: - - process: - ref: myProcessor - - to: - uri: aws2-s3://mycamelbucket - parameters: - amazonS3Client: "#amazonS3Client" - operation: deleteObjects +- route: + from: + uri: direct:start + steps: + - process: + ref: deleteKeysProcessor + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: deleteObjects + - to: + uri: mock:result ---- +==== This operation will delete the objects with keys key1, key2, and key3 from the bucket _mycamelbucket_. - CreateUploadLink: this operation will return an upload link through S3 Presigner +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3Key", constant("camelKey")) + .to("aws2-s3://mycamelbucket?accessKey=xxx&secretKey=yyy®ion=region&operation=createUploadLink") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - } - }) - .to("aws2-s3://mycamelbucket?accessKey=xxx&secretKey=yyy®ion=region&operation=createUploadLink") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>camelKey</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?accessKey=xxx&secretKey=yyy&region=region&operation=createUploadLink"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ [source,yaml] ---- -- from: - uri: direct:start - steps: - - setHeader: - name: CamelAwsS3Key - constant: camelKey - - to: - uri: aws2-s3://mycamelbucket - parameters: - accessKey: xxx - secretKey: yyy - region: region - operation: createUploadLink +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "camelKey" + - to: + uri: aws2-s3://mycamelbucket + parameters: + accessKey: xxx + secretKey: yyy + region: region + operation: createUploadLink + - to: + uri: mock:result ---- +==== This operation will return an upload link url for uploading to the bucket _mycamelbucket_. - RestoreObject: this operation restores an archived object from Glacier storage +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3Key", constant("camelKey")) + .setHeader("CamelAwsS3RestoreDays", constant(1)) + .setHeader("CamelAwsS3RestoreTier", constant("Expedited")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=restoreObject") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - exchange.getIn().setHeader(AWS2S3Constants.RESTORE_DAYS, 1); - exchange.getIn().setHeader(AWS2S3Constants.RESTORE_TIER, "Expedited"); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=restoreObject") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>camelKey</constant></setHeader> + <setHeader name="CamelAwsS3RestoreDays"><constant>1</constant></setHeader> + <setHeader name="CamelAwsS3RestoreTier"><constant>Expedited</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=restoreObject"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ [source,yaml] ---- -- from: - uri: direct:start - steps: - - setHeader: - name: CamelAwsS3Key - constant: camelKey - - setHeader: - name: CamelAwsS3RestoreDays - constant: 1 - - setHeader: - name: CamelAwsS3RestoreTier - constant: Expedited - - to: - uri: aws2-s3://mycamelbucket - parameters: - amazonS3Client: "#amazonS3Client" - operation: restoreObject +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "camelKey" + - setHeader: + name: CamelAwsS3RestoreDays + constant: 1 + - setHeader: + name: CamelAwsS3RestoreTier + constant: "Expedited" + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: restoreObject + - to: + uri: mock:result ---- +==== This operation will restore the archived object camelKey from Glacier for 1 day using expedited retrieval. - GetObjectTagging: this operation retrieves the tags associated with an object +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3Key", constant("camelKey")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObjectTagging") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObjectTagging") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>camelKey</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObjectTagging"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ [source,yaml] ---- -- from: - uri: direct:start - steps: - - setHeader: - name: CamelAwsS3Key - constant: camelKey - - to: - uri: aws2-s3://mycamelbucket - parameters: - amazonS3Client: "#amazonS3Client" - operation: getObjectTagging +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "camelKey" + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: getObjectTagging + - to: + uri: mock:result ---- +==== This operation will return the tags for object camelKey in the bucket _mycamelbucket_. - PutObjectTagging: this operation sets tags on an object +NOTE: The `CamelAwsS3ObjectTags` header requires a `Map<String, String>` value, which must be set from a bean or processor. + +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { - - @Override - public void process(Exchange exchange) throws Exception { - Map<String, String> tags = new HashMap<>(); - tags.put("Environment", "Production"); - tags.put("Owner", "TeamA"); - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - exchange.getIn().setHeader(AWS2S3Constants.OBJECT_TAGS, tags); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putObjectTagging") - .to("mock:result"); +from("direct:start") + .process(exchange -> { + Map<String, String> tags = Map.of("Environment", "Production", "Owner", "TeamA"); + exchange.getIn().setHeader("CamelAwsS3Key", "camelKey"); + exchange.getIn().setHeader("CamelAwsS3ObjectTags", tags); + }) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putObjectTagging") + .to("mock:result"); +---- + +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <process ref="objectTagsProcessor"/> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putObjectTagging"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ [source,yaml] ---- -- from: - uri: direct:start - steps: - - process: - ref: myProcessor - - to: - uri: aws2-s3://mycamelbucket - parameters: - amazonS3Client: "#amazonS3Client" - operation: putObjectTagging +- route: + from: + uri: direct:start + steps: + - process: + ref: objectTagsProcessor + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: putObjectTagging + - to: + uri: mock:result ---- +==== This operation will set tags on the object camelKey in the bucket _mycamelbucket_. - DeleteObjectTagging: this operation deletes all tags from an object +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3Key", constant("camelKey")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=deleteObjectTagging") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=deleteObjectTagging") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>camelKey</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=deleteObjectTagging"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ [source,yaml] ---- -- from: - uri: direct:start - steps: - - setHeader: - name: CamelAwsS3Key - constant: camelKey - - to: - uri: aws2-s3://mycamelbucket - parameters: - amazonS3Client: "#amazonS3Client" - operation: deleteObjectTagging +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "camelKey" + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: deleteObjectTagging + - to: + uri: mock:result ---- +==== This operation will delete all tags from the object camelKey in the bucket _mycamelbucket_. - GetObjectAcl: this operation retrieves the access control list (ACL) for an object +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3Key", constant("camelKey")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObjectAcl") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObjectAcl") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>camelKey</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=getObjectAcl"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ [source,yaml] ---- -- from: - uri: direct:start - steps: - - setHeader: - name: CamelAwsS3Key - constant: camelKey - - to: - uri: aws2-s3://mycamelbucket - parameters: - amazonS3Client: "#amazonS3Client" - operation: getObjectAcl +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "camelKey" + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: getObjectAcl + - to: + uri: mock:result ---- +==== This operation will return the ACL for object camelKey in the bucket _mycamelbucket_. - PutObjectAcl: this operation sets the access control list (ACL) for an object +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { - - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.KEY, "camelKey"); - exchange.getIn().setHeader(AWS2S3Constants.CANNED_ACL, "PublicRead"); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putObjectAcl") - .to("mock:result"); +from("direct:start") + .setHeader("CamelAwsS3Key", constant("camelKey")) + .setHeader("CamelAwsS3CannedAcl", constant("PublicRead")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putObjectAcl") + .to("mock:result"); +---- + +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3Key"><constant>camelKey</constant></setHeader> + <setHeader name="CamelAwsS3CannedAcl"><constant>PublicRead</constant></setHeader> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putObjectAcl"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ [source,yaml] ---- -- from: - uri: direct:start - steps: - - setHeader: - name: CamelAwsS3Key - constant: camelKey - - setHeader: - name: CamelAwsS3CannedAcl - constant: PublicRead - - to: - uri: aws2-s3://mycamelbucket - parameters: - amazonS3Client: "#amazonS3Client" - operation: putObjectAcl +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3Key + constant: "camelKey" + - setHeader: + name: CamelAwsS3CannedAcl + constant: "PublicRead" + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: putObjectAcl + - to: + uri: mock:result ---- +==== This operation will set the ACL to public-read for object camelKey in the bucket _mycamelbucket_. @@ -900,35 +1363,54 @@ This operation will return the tags for the bucket _mycamelbucket_. - PutBucketTagging: this operation sets tags on a bucket +NOTE: The `CamelAwsS3BucketTags` header requires a `Map<String, String>` value, which must be set from a bean or processor. + +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { - - @Override - public void process(Exchange exchange) throws Exception { - Map<String, String> tags = new HashMap<>(); - tags.put("Project", "CamelIntegration"); - tags.put("CostCenter", "Engineering"); - exchange.getIn().setHeader(AWS2S3Constants.BUCKET_TAGS, tags); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putBucketTagging") - .to("mock:result"); +from("direct:start") + .process(exchange -> { + Map<String, String> tags = Map.of("Project", "CamelIntegration", "CostCenter", "Engineering"); + exchange.getIn().setHeader("CamelAwsS3BucketTags", tags); + }) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putBucketTagging") + .to("mock:result"); +---- + +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <process ref="bucketTagsProcessor"/> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putBucketTagging"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ [source,yaml] ---- -- from: - uri: direct:start - steps: - - process: - ref: myProcessor - - to: - uri: aws2-s3://mycamelbucket - parameters: - amazonS3Client: "#amazonS3Client" - operation: putBucketTagging +- route: + from: + uri: direct:start + steps: + - process: + ref: bucketTagsProcessor + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: putBucketTagging + - to: + uri: mock:result ---- +==== This operation will set tags on the bucket _mycamelbucket_. @@ -1022,33 +1504,52 @@ This operation will return the versioning configuration for the bucket _mycamelb - PutBucketVersioning: this operation sets the versioning configuration of a bucket +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { +from("direct:start") + .setHeader("CamelAwsS3VersioningStatus", constant("Enabled")) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putBucketVersioning") + .to("mock:result"); +---- - @Override - public void process(Exchange exchange) throws Exception { - exchange.getIn().setHeader(AWS2S3Constants.VERSIONING_STATUS, "Enabled"); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putBucketVersioning") - .to("mock:result"); +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <setHeader name="CamelAwsS3VersioningStatus"> + <constant>Enabled</constant> + </setHeader> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putBucketVersioning"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ [source,yaml] ---- -- from: - uri: direct:start - steps: - - setHeader: - name: CamelAwsS3VersioningStatus - constant: Enabled - - to: - uri: aws2-s3://mycamelbucket - parameters: - amazonS3Client: "#amazonS3Client" - operation: putBucketVersioning +- route: + from: + uri: direct:start + steps: + - setHeader: + name: CamelAwsS3VersioningStatus + constant: Enabled + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: putBucketVersioning + - to: + uri: mock:result ---- +==== This operation will enable versioning on the bucket _mycamelbucket_. @@ -1098,40 +1599,57 @@ This operation will return the bucket policy for _mycamelbucket_ as a JSON strin - PutBucketPolicy: this operation sets the policy on a bucket +NOTE: The `CamelAwsS3BucketPolicy` header requires a JSON policy string, which must be set from a bean or processor. + +[tabs] +==== +Java:: ++ [source,java] ---- - from("direct:start").process(new Processor() { - - @Override - public void process(Exchange exchange) throws Exception { - String policy = "{" - + "\"Version\": \"2012-10-17\"," - + "\"Statement\": [{" - + "\"Effect\": \"Allow\"," - + "\"Principal\": \"*\"," - + "\"Action\": \"s3:GetObject\"," - + "\"Resource\": \"arn:aws:s3:::mycamelbucket/*\"" - + "}]}"; - exchange.getIn().setHeader(AWS2S3Constants.BUCKET_POLICY, policy); - } - }) - .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putBucketPolicy") - .to("mock:result"); +from("direct:start") + .process(exchange -> { + String policy = """ + {"Version": "2012-10-17", "Statement": [{"Effect": "Allow", \ + "Principal": "*", "Action": "s3:GetObject", \ + "Resource": "arn:aws:s3:::mycamelbucket/*"}]}"""; + exchange.getIn().setHeader("CamelAwsS3BucketPolicy", policy); + }) + .to("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putBucketPolicy") + .to("mock:result"); +---- + +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:start"/> + <process ref="bucketPolicyProcessor"/> + <to uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&operation=putBucketPolicy"/> + <to uri="mock:result"/> +</route> ---- +YAML:: ++ [source,yaml] ---- -- from: - uri: direct:start - steps: - - process: - ref: myProcessor - - to: - uri: aws2-s3://mycamelbucket - parameters: - amazonS3Client: "#amazonS3Client" - operation: putBucketPolicy +- route: + from: + uri: direct:start + steps: + - process: + ref: bucketPolicyProcessor + - to: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + operation: putBucketPolicy + - to: + uri: mock:result ---- +==== This operation will set a bucket policy on _mycamelbucket_. @@ -1269,15 +1787,21 @@ Additionally, streaming upload mode supports timestamp-based file grouping, whic As an example: +._Java-only: Endpoint DSL builder style_ + [source,java] ---- from(kafka("topic1").brokers("localhost:9092")) .log("Kafka Message is: ${body}") - .to(aws2S3("camel-bucket").streamingUploadMode(true).batchMessageNumber(25).namingStrategy(AWS2S3EndpointBuilderFactory.AWSS3NamingStrategyEnum.progressive).keyName("{{kafkaTopic1}}/{{kafkaTopic1}}.txt")); + .to(aws2S3("camel-bucket").streamingUploadMode(true).batchMessageNumber(25) + .namingStrategy(AWS2S3EndpointBuilderFactory.AWSS3NamingStrategyEnum.progressive) + .keyName("{{kafkaTopic1}}/{{kafkaTopic1}}.txt")); from(kafka("topic2").brokers("localhost:9092")) .log("Kafka Message is: ${body}") - .to(aws2S3("camel-bucket").streamingUploadMode(true).batchMessageNumber(25).namingStrategy(AWS2S3EndpointBuilderFactory.AWSS3NamingStrategyEnum.random).keyName("{{kafkaTopic2}}/{{kafkaTopic2}}.txt")); + .to(aws2S3("camel-bucket").streamingUploadMode(true).batchMessageNumber(25) + .namingStrategy(AWS2S3EndpointBuilderFactory.AWSS3NamingStrategyEnum.random) + .keyName("{{kafkaTopic2}}/{{kafkaTopic2}}.txt")); ---- The default size for a batch is 1 Mb, but you can adjust it according to your requirements. @@ -1315,11 +1839,16 @@ In this way, the upload completion will be passed on three tiers: the timeout, t As an example: +._Java-only: Endpoint DSL builder style_ + [source,java] ---- from(kafka("topic1").brokers("localhost:9092")) .log("Kafka Message is: ${body}") - .to(aws2S3("camel-bucket").streamingUploadMode(true).batchMessageNumber(25).streamingUploadTimeout(10000).namingStrategy(AWS2S3EndpointBuilderFactory.AWSS3NamingStrategyEnum.progressive).keyName("{{kafkaTopic1}}/{{kafkaTopic1}}.txt")); + .to(aws2S3("camel-bucket").streamingUploadMode(true).batchMessageNumber(25) + .streamingUploadTimeout(10000) + .namingStrategy(AWS2S3EndpointBuilderFactory.AWSS3NamingStrategyEnum.progressive) + .keyName("{{kafkaTopic1}}/{{kafkaTopic1}}.txt")); ---- In this case, the upload will be completed after 10 seconds. @@ -1346,45 +1875,167 @@ Files are automatically named using a timestamp-based pattern that includes the Basic timestamp grouping with 5-minute windows: +[tabs] +==== +Java:: ++ [source,java] ---- from("timer:messages?period=10000") .setHeader(Exchange.MESSAGE_TIMESTAMP, simple("${date:now:timestamp}")) .setBody(constant("Message with timestamp")) - .to("aws2-s3://my-bucket?streamingUploadMode=true" - + "×tampGroupingEnabled=true" - + "×tampWindowSizeMillis=300000" - + "&keyName=grouped-messages.txt"); + .to("aws2-s3://my-bucket?streamingUploadMode=true×tampGroupingEnabled=true×tampWindowSizeMillis=300000&keyName=grouped-messages.txt"); +---- + +XML:: ++ +[source,xml] +---- +<route> + <from uri="timer:messages?period=10000"/> + <setHeader name="CamelMessageTimestamp"> + <simple>${date:now:timestamp}</simple> + </setHeader> + <setBody> + <constant>Message with timestamp</constant> + </setBody> + <to uri="aws2-s3://my-bucket?streamingUploadMode=true&timestampGroupingEnabled=true&timestampWindowSizeMillis=300000&keyName=grouped-messages.txt"/> +</route> +---- + +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: timer:messages + parameters: + period: 10000 + steps: + - setHeader: + name: CamelMessageTimestamp + simple: "${date:now:timestamp}" + - setBody: + constant: Message with timestamp + - to: + uri: aws2-s3://my-bucket + parameters: + streamingUploadMode: true + timestampGroupingEnabled: true + timestampWindowSizeMillis: 300000 + keyName: grouped-messages.txt ---- +==== Custom window size (1 minute) with custom header name: +[tabs] +==== +Java:: ++ [source,java] ---- from("direct:timestamped") .setHeader("MyTimestamp", simple("${date:now:timestamp}")) - .setBody("Custom timestamped message") - .to("aws2-s3://my-bucket?streamingUploadMode=true" - + "×tampGroupingEnabled=true" - + "×tampWindowSizeMillis=60000" - + "×tampHeaderName=MyTimestamp" - + "&keyName=custom-grouped.txt"); + .setBody(constant("Custom timestamped message")) + .to("aws2-s3://my-bucket?streamingUploadMode=true×tampGroupingEnabled=true×tampWindowSizeMillis=60000×tampHeaderName=MyTimestamp&keyName=custom-grouped.txt"); +---- + +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:timestamped"/> + <setHeader name="MyTimestamp"> + <simple>${date:now:timestamp}</simple> + </setHeader> + <setBody> + <constant>Custom timestamped message</constant> + </setBody> + <to uri="aws2-s3://my-bucket?streamingUploadMode=true&timestampGroupingEnabled=true&timestampWindowSizeMillis=60000&timestampHeaderName=MyTimestamp&keyName=custom-grouped.txt"/> +</route> +---- + +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: direct:timestamped + steps: + - setHeader: + name: MyTimestamp + simple: "${date:now:timestamp}" + - setBody: + constant: Custom timestamped message + - to: + uri: aws2-s3://my-bucket + parameters: + streamingUploadMode: true + timestampGroupingEnabled: true + timestampWindowSizeMillis: 60000 + timestampHeaderName: MyTimestamp + keyName: custom-grouped.txt ---- +==== Large files with multipart and timestamp grouping: +[tabs] +==== +Java:: ++ [source,java] ---- from("direct:large-timestamped") .setHeader(Exchange.MESSAGE_TIMESTAMP, simple("${date:now:timestamp}")) - .setBody("Large message content...") - .to("aws2-s3://my-bucket?streamingUploadMode=true" - + "×tampGroupingEnabled=true" - + "×tampWindowSizeMillis=1800000" // 30 minutes - + "&multiPartUpload=true" - + "&partSize=5242880" // 5MB parts - + "&keyName=large-grouped.txt"); + .setBody(constant("Large message content...")) + .to("aws2-s3://my-bucket?streamingUploadMode=true×tampGroupingEnabled=true×tampWindowSizeMillis=1800000&multiPartUpload=true&partSize=5242880&keyName=large-grouped.txt"); +---- + +XML:: ++ +[source,xml] +---- +<route> + <from uri="direct:large-timestamped"/> + <setHeader name="CamelMessageTimestamp"> + <simple>${date:now:timestamp}</simple> + </setHeader> + <setBody> + <constant>Large message content...</constant> + </setBody> + <to uri="aws2-s3://my-bucket?streamingUploadMode=true&timestampGroupingEnabled=true&timestampWindowSizeMillis=1800000&multiPartUpload=true&partSize=5242880&keyName=large-grouped.txt"/> +</route> +---- + +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: direct:large-timestamped + steps: + - setHeader: + name: CamelMessageTimestamp + simple: "${date:now:timestamp}" + - setBody: + constant: "Large message content..." + - to: + uri: aws2-s3://my-bucket + parameters: + streamingUploadMode: true + timestampGroupingEnabled: true + timestampWindowSizeMillis: 1800000 + multiPartUpload: true + partSize: 5242880 + keyName: large-grouped.txt ---- +==== ===== File Naming @@ -1485,26 +2136,87 @@ The options are `destinationBucketPrefix` and `destinationBucketSuffix`. Both options support the xref:languages:simple-language.adoc[Simple] expression language. Wrap an expression in `RAW()` to prevent the Camel URI parser from interpreting special characters: +[tabs] +==== +Java:: ++ [source,java] ---- - from("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&moveAfterRead=true" - + "&destinationBucket=myothercamelbucket" - + "&destinationBucketPrefix=RAW(pre-)&destinationBucketSuffix=RAW(-suff)") - .to("mock:result"); +from("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&moveAfterRead=true&destinationBucket=myothercamelbucket&destinationBucketPrefix=RAW(pre-)&destinationBucketSuffix=RAW(-suff)") + .to("mock:result"); +---- + +XML:: ++ +[source,xml] +---- +<route> + <from uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&moveAfterRead=true&destinationBucket=myothercamelbucket&destinationBucketPrefix=RAW(pre-)&destinationBucketSuffix=RAW(-suff)"/> + <to uri="mock:result"/> +</route> +---- + +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + moveAfterRead: true + destinationBucket: myothercamelbucket + destinationBucketPrefix: "RAW(pre-)" + destinationBucketSuffix: "RAW(-suff)" + steps: + - to: + uri: mock:result ---- +==== In this case, an object named `test` is moved to `myothercamelbucket` with the key `pre-test-suff`. Using a Simple expression, you can build dynamic paths at runtime. The following example organises moved objects by date: +[tabs] +==== +Java:: ++ [source,java] ---- - from("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&moveAfterRead=true" - + "&destinationBucket=myothercamelbucket" - + "&destinationBucketPrefix=RAW(${date:now:yyyy/MM/dd}/)") - .to("mock:result"); +from("aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&moveAfterRead=true&destinationBucket=myothercamelbucket&destinationBucketPrefix=RAW(${date:now:yyyy/MM/dd}/)") + .to("mock:result"); +---- + +XML:: ++ +[source,xml] +---- +<route> + <from uri="aws2-s3://mycamelbucket?amazonS3Client=#amazonS3Client&moveAfterRead=true&destinationBucket=myothercamelbucket&destinationBucketPrefix=RAW(${date:now:yyyy/MM/dd}/)"/> + <to uri="mock:result"/> +</route> +---- + +YAML:: ++ +[source,yaml] +---- +- route: + from: + uri: aws2-s3://mycamelbucket + parameters: + amazonS3Client: "#amazonS3Client" + moveAfterRead: true + destinationBucket: myothercamelbucket + destinationBucketPrefix: "RAW(${date:now:yyyy/MM/dd}/)" + steps: + - to: + uri: mock:result ---- +==== An object named `report.csv` consumed on 2026-05-19 is moved with the key `2026/05/19/report.csv`. Expressions are evaluated once per exchange, so each message can produce a different destination key. @@ -1687,6 +2399,8 @@ This consumer will only process files when a corresponding .done file exists in We introduced also the customer key support (an alternative of using KMS). The following code shows an example. +._Java-only: programmatic customer key encryption setup_ + [source,java] ---- String key = UUID.randomUUID().toString(); @@ -1697,7 +2411,7 @@ String b64KeyMd5 = Md5Utils.md5AsBase64(secretKey); String awsEndpoint = "aws2-s3://mycamel?autoCreateBucket=false&useCustomerKey=true&customerKeyId=RAW(" + b64Key + ")&customerKeyMD5=RAW(" + b64KeyMd5 + ")&customerAlgorithm=" + AES256.name(); from("direct:putObject") - .setHeader(AWS2S3Constants.KEY, constant("test.txt")) + .setHeader("CamelAwsS3Key", constant("test.txt")) .setBody(constant("Test")) .to(awsEndpoint); ---- @@ -1705,14 +2419,16 @@ from("direct:putObject") === Using a POJO as body Sometimes building an AWS Request can be complex because of multiple options. We introduce the possibility to use a POJO as the body. -In AWS S3 there are multiple operations you can submit, as an example for List brokers request, you can do something like: +In AWS S3 there are multiple operations you can submit, as an example for List objects request, you can do something like: + +._Java-only: POJO request requires building AWS SDK request objects_ [source,java] --------------------------- +---- from("direct:aws2-s3") -.setBody(ListObjectsV2Request.builder().bucket(bucketName).build()) - .to("aws2-s3://test?amazonS3Client=#amazonS3Client&operation=listObjects&pojoRequest=true") --------------------------- + .setBody(ListObjectsV2Request.builder().bucket(bucketName).build()) + .to("aws2-s3://test?amazonS3Client=#amazonS3Client&operation=listObjects&pojoRequest=true"); +---- In this way, you'll pass the request directly without the need of passing headers and options specifically related to this operation. @@ -1721,13 +2437,17 @@ In this way, you'll pass the request directly without the need of passing header Sometimes you would want to perform some advanced configuration using AWS2S3Configuration, which also allows to set the S3 client. You can create and set the S3 client in the component configuration as shown in the following example +._Java-only: programmatic S3 client creation_ + [source,java] ---- String awsBucketAccessKey = "your_access_key"; String awsBucketSecretKey = "your_secret_key"; -S3Client s3Client = S3Client.builder().credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(awsBucketAccessKey, awsBucketSecretKey))) - .region(Region.US_EAST_1).build(); +S3Client s3Client = S3Client.builder() + .credentialsProvider(StaticCredentialsProvider.create( + AwsBasicCredentials.create(awsBucketAccessKey, awsBucketSecretKey))) + .region(Region.US_EAST_1).build(); AWS2S3Configuration configuration = new AWS2S3Configuration(); configuration.setAmazonS3Client(s3Client); @@ -1739,6 +2459,8 @@ configuration.setRegion("us-east-1"); Now you can configure the S3 component (using the configuration object created above) and add it to the registry in the configure method before initialization of routes. +._Java-only: programmatic component registration_ + [source,java] ---- AWS2S3Component s3Component = new AWS2S3Component(getContext()); @@ -1751,15 +2473,19 @@ Now your component will be used for all the operations implemented in camel rout === Note about using this component for storing and retrieving objects from/to Dell ECS (Elastic Cloud Solutions) -For storing and retrieving objects from/to Dell ECS, both of the `forcePathStyle` and `overrideEndpoint` options need to be set to `true` and using the `uriEndpointOverride` you need to provide your own ECS endpoint. +For storing and retrieving objects from/to Dell ECS, both of the `forcePathStyle` and `overrideEndpoint` options need to be set to `true` and using the `uriEndpointOverride` you need to provide your own ECS endpoint. + +._Java-only: programmatic Dell ECS configuration_ [source,java] ---- String awsBucketAccessKey = "your_access_key"; String awsBucketSecretKey = "your_secret_key"; -S3Client s3Client = S3Client.builder().credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(awsBucketAccessKey, awsBucketSecretKey))) - .region(Region.US_EAST_1).build(); +S3Client s3Client = S3Client.builder() + .credentialsProvider(StaticCredentialsProvider.create( + AwsBasicCredentials.create(awsBucketAccessKey, awsBucketSecretKey))) + .region(Region.US_EAST_1).build(); AWS2S3Configuration configuration = new AWS2S3Configuration(); configuration.setForcePathStyle(true);
