You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/10/23 10:04:25 UTC

[camel] branch main updated: CAMEL-19707: camel-aws-s3 - Upload small / zero length files in single operation instead of multi-part (#11806)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 2a14217619d CAMEL-19707: camel-aws-s3 - Upload small / zero length files in single operation instead of multi-part (#11806)
2a14217619d is described below

commit 2a14217619d4f6f4d3063b0264b8e11fa4048ee8
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Oct 23 12:04:19 2023 +0200

    CAMEL-19707: camel-aws-s3 - Upload small / zero length files in single operation instead of multi-part (#11806)
---
 .../apache/camel/catalog/components/aws2-s3.json   |  8 +++----
 .../apache/camel/component/aws2/s3/aws2-s3.json    |  8 +++----
 .../component/aws2/s3/AWS2S3Configuration.java     | 11 ++++++---
 .../camel/component/aws2/s3/AWS2S3Producer.java    | 18 ++++++++++-----
 .../integration/S3MultipartUploadOperationIT.java  | 20 +++++++++++++++++
 .../dsl/Aws2S3ComponentBuilderFactory.java         | 13 +++++++----
 .../endpoint/dsl/AWS2S3EndpointBuilderFactory.java | 26 +++++++++++++++-------
 7 files changed, 76 insertions(+), 28 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 39ff469be5a..05398c8d8d7 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
@@ -53,10 +53,10 @@
     "deleteAfterWrite": { "index": 28, "kind": "property", "displayName": "Delete After Write", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Delete file object after the S3 file has been uploaded" },
     "keyName": { "index": 29, "kind": "property", "displayName": "Key Name", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Setting the key name for an element in the bucket through endpoint parameter" },
     "lazyStartProducer": { "index": 30, "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 fai [...]
-    "multiPartUpload": { "index": 31, "kind": "property", "displayName": "Multi Part Upload", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "If it is true, camel will upload the file with multi part format, the part size [...]
+    "multiPartUpload": { "index": 31, "kind": "property", "displayName": "Multi Part Upload", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "If it is true, camel will upload the file with multi-part format, the part size [...]
     "namingStrategy": { "index": 32, "kind": "property", "displayName": "Naming Strategy", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.s3.stream.AWSS3NamingStrategyEnum", "enum": [ "progressive", "random" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "progressive", "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuratio [...]
     "operation": { "index": 33, "kind": "property", "displayName": "Operation", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.s3.AWS2S3Operations", "enum": [ "copyObject", "listObjects", "deleteObject", "deleteBucket", "listBuckets", "getObject", "getObjectRange", "createDownloadLink" ], "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Con [...]
-    "partSize": { "index": 34, "kind": "property", "displayName": "Part Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 26214400, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Setup the partSize which is used in multi part upload, the default size is 25M." },
+    "partSize": { "index": 34, "kind": "property", "displayName": "Part Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 26214400, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Setup the partSize which is used in multi-part upload, the default size is 25M. Camel will onl [...]
     "restartingPolicy": { "index": 35, "kind": "property", "displayName": "Restarting Policy", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.s3.stream.AWSS3RestartingPolicyEnum", "enum": [ "override", "lastPart" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "override", "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configurat [...]
     "storageClass": { "index": 36, "kind": "property", "displayName": "Storage Class", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "The storage class to set in the com.amazonaws.services.s3.model.PutObjectRequest request." },
     "streamingUploadMode": { "index": 37, "kind": "property", "displayName": "Streaming Upload Mode", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "When stream mode is true the upload to bucket will be done in streaming" },
@@ -149,10 +149,10 @@
     "bufferSize": { "index": 33, "kind": "parameter", "displayName": "Buffer Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 1000000, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "The buffer size (in bytes) in streaming upload mode" },
     "deleteAfterWrite": { "index": 34, "kind": "parameter", "displayName": "Delete After Write", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Delete file object after the S3 file has been uploaded" },
     "keyName": { "index": 35, "kind": "parameter", "displayName": "Key Name", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Setting the key name for an element in the bucket through endpoint parameter" },
-    "multiPartUpload": { "index": 36, "kind": "parameter", "displayName": "Multi Part Upload", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "If it is true, camel will upload the file with multi part format, the part siz [...]
+    "multiPartUpload": { "index": 36, "kind": "parameter", "displayName": "Multi Part Upload", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "If it is true, camel will upload the file with multi-part format, the part siz [...]
     "namingStrategy": { "index": 37, "kind": "parameter", "displayName": "Naming Strategy", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.s3.stream.AWSS3NamingStrategyEnum", "enum": [ "progressive", "random" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "progressive", "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configurati [...]
     "operation": { "index": 38, "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.s3.AWS2S3Operations", "enum": [ "copyObject", "listObjects", "deleteObject", "deleteBucket", "listBuckets", "getObject", "getObjectRange", "createDownloadLink" ], "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Co [...]
-    "partSize": { "index": 39, "kind": "parameter", "displayName": "Part Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 26214400, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Setup the partSize which is used in multi part upload, the default size is 25M." },
+    "partSize": { "index": 39, "kind": "parameter", "displayName": "Part Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 26214400, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Setup the partSize which is used in multi-part upload, the default size is 25M. Camel will on [...]
     "restartingPolicy": { "index": 40, "kind": "parameter", "displayName": "Restarting Policy", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.s3.stream.AWSS3RestartingPolicyEnum", "enum": [ "override", "lastPart" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "override", "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configura [...]
     "storageClass": { "index": 41, "kind": "parameter", "displayName": "Storage Class", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "The storage class to set in the com.amazonaws.services.s3.model.PutObjectRequest request." },
     "streamingUploadMode": { "index": 42, "kind": "parameter", "displayName": "Streaming Upload Mode", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "When stream mode is true the upload to bucket will be done in streaming" },
diff --git a/components/camel-aws/camel-aws2-s3/src/generated/resources/org/apache/camel/component/aws2/s3/aws2-s3.json b/components/camel-aws/camel-aws2-s3/src/generated/resources/org/apache/camel/component/aws2/s3/aws2-s3.json
index 39ff469be5a..05398c8d8d7 100644
--- a/components/camel-aws/camel-aws2-s3/src/generated/resources/org/apache/camel/component/aws2/s3/aws2-s3.json
+++ b/components/camel-aws/camel-aws2-s3/src/generated/resources/org/apache/camel/component/aws2/s3/aws2-s3.json
@@ -53,10 +53,10 @@
     "deleteAfterWrite": { "index": 28, "kind": "property", "displayName": "Delete After Write", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Delete file object after the S3 file has been uploaded" },
     "keyName": { "index": 29, "kind": "property", "displayName": "Key Name", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Setting the key name for an element in the bucket through endpoint parameter" },
     "lazyStartProducer": { "index": 30, "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 fai [...]
-    "multiPartUpload": { "index": 31, "kind": "property", "displayName": "Multi Part Upload", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "If it is true, camel will upload the file with multi part format, the part size [...]
+    "multiPartUpload": { "index": 31, "kind": "property", "displayName": "Multi Part Upload", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "If it is true, camel will upload the file with multi-part format, the part size [...]
     "namingStrategy": { "index": 32, "kind": "property", "displayName": "Naming Strategy", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.s3.stream.AWSS3NamingStrategyEnum", "enum": [ "progressive", "random" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "progressive", "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuratio [...]
     "operation": { "index": 33, "kind": "property", "displayName": "Operation", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.s3.AWS2S3Operations", "enum": [ "copyObject", "listObjects", "deleteObject", "deleteBucket", "listBuckets", "getObject", "getObjectRange", "createDownloadLink" ], "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Con [...]
-    "partSize": { "index": 34, "kind": "property", "displayName": "Part Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 26214400, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Setup the partSize which is used in multi part upload, the default size is 25M." },
+    "partSize": { "index": 34, "kind": "property", "displayName": "Part Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 26214400, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Setup the partSize which is used in multi-part upload, the default size is 25M. Camel will onl [...]
     "restartingPolicy": { "index": 35, "kind": "property", "displayName": "Restarting Policy", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.s3.stream.AWSS3RestartingPolicyEnum", "enum": [ "override", "lastPart" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "override", "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configurat [...]
     "storageClass": { "index": 36, "kind": "property", "displayName": "Storage Class", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "The storage class to set in the com.amazonaws.services.s3.model.PutObjectRequest request." },
     "streamingUploadMode": { "index": 37, "kind": "property", "displayName": "Streaming Upload Mode", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "When stream mode is true the upload to bucket will be done in streaming" },
@@ -149,10 +149,10 @@
     "bufferSize": { "index": 33, "kind": "parameter", "displayName": "Buffer Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 1000000, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "The buffer size (in bytes) in streaming upload mode" },
     "deleteAfterWrite": { "index": 34, "kind": "parameter", "displayName": "Delete After Write", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Delete file object after the S3 file has been uploaded" },
     "keyName": { "index": 35, "kind": "parameter", "displayName": "Key Name", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Setting the key name for an element in the bucket through endpoint parameter" },
-    "multiPartUpload": { "index": 36, "kind": "parameter", "displayName": "Multi Part Upload", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "If it is true, camel will upload the file with multi part format, the part siz [...]
+    "multiPartUpload": { "index": 36, "kind": "parameter", "displayName": "Multi Part Upload", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "If it is true, camel will upload the file with multi-part format, the part siz [...]
     "namingStrategy": { "index": 37, "kind": "parameter", "displayName": "Naming Strategy", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.s3.stream.AWSS3NamingStrategyEnum", "enum": [ "progressive", "random" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "progressive", "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configurati [...]
     "operation": { "index": 38, "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.s3.AWS2S3Operations", "enum": [ "copyObject", "listObjects", "deleteObject", "deleteBucket", "listBuckets", "getObject", "getObjectRange", "createDownloadLink" ], "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Co [...]
-    "partSize": { "index": 39, "kind": "parameter", "displayName": "Part Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 26214400, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Setup the partSize which is used in multi part upload, the default size is 25M." },
+    "partSize": { "index": 39, "kind": "parameter", "displayName": "Part Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 26214400, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "Setup the partSize which is used in multi-part upload, the default size is 25M. Camel will on [...]
     "restartingPolicy": { "index": 40, "kind": "parameter", "displayName": "Restarting Policy", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.aws2.s3.stream.AWSS3RestartingPolicyEnum", "enum": [ "override", "lastPart" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "override", "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configura [...]
     "storageClass": { "index": 41, "kind": "parameter", "displayName": "Storage Class", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "The storage class to set in the com.amazonaws.services.s3.model.PutObjectRequest request." },
     "streamingUploadMode": { "index": 42, "kind": "parameter", "displayName": "Streaming Upload Mode", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.aws2.s3.AWS2S3Configuration", "configurationField": "configuration", "description": "When stream mode is true the upload to bucket will be done in streaming" },
diff --git a/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Configuration.java b/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Configuration.java
index 9e8bdb848b7..1a9a18bcc6f 100644
--- a/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Configuration.java
+++ b/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Configuration.java
@@ -142,7 +142,10 @@ public class AWS2S3Configuration implements Cloneable {
     }
 
     /**
-     * Setup the partSize which is used in multi part upload, the default size is 25M.
+     * Setup the partSize which is used in multi-part upload, the default size is 25M.
+     *
+     * Camel will only do multi-part uploads for files that are larger than the part-size thresholds.
+     * Files that are smaller will be uploaded in a single operation.
      */
     public void setPartSize(long partSize) {
         this.partSize = partSize;
@@ -153,8 +156,10 @@ public class AWS2S3Configuration implements Cloneable {
     }
 
     /**
-     * If it is true, camel will upload the file with multi part format, the part size is decided by the option of
-     * `partSize`
+     * If it is true, camel will upload the file with multi-part format, the part size is decided by the partSize option.
+     *
+     * Camel will only do multi-part uploads for files that are larger than the part-size thresholds.
+     * Files that are smaller will be uploaded in a single operation.
      */
     public void setMultiPartUpload(boolean multiPartUpload) {
         this.multiPartUpload = multiPartUpload;
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 b80fea74376..899c4cc81cb 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
@@ -129,7 +129,7 @@ public class AWS2S3Producer extends DefaultProducer {
     }
 
     public void processMultiPart(final Exchange exchange) throws Exception {
-        File filePayload = null;
+        File filePayload;
         Object obj = exchange.getIn().getMandatoryBody();
         // Need to check if the message body is WrappedFile
         if (obj instanceof WrappedFile) {
@@ -147,6 +147,17 @@ public class AWS2S3Producer extends DefaultProducer {
         if (contentLength == null || contentLength == 0) {
             contentLength = filePayload.length();
         }
+
+        long partSize = getConfiguration().getPartSize();
+        if (contentLength == 0 && contentLength < partSize) {
+            // optimize to do a single op if content length is known and < part size
+            LOG.debug("File size < partSize. Uploading file in single operation: {}", filePayload);
+            processSingleOp(exchange);
+            return;
+        }
+
+        LOG.debug("File size >= partSize. Uploading file using multi-part operation: {}", filePayload);
+
         objectMetadata.put("Content-Length", contentLength.toString());
 
         final String keyName = AWS2S3Utils.determineKey(exchange, getConfiguration());
@@ -198,13 +209,10 @@ public class AWS2S3Producer extends DefaultProducer {
 
         CreateMultipartUploadResponse initResponse
                 = getEndpoint().getS3Client().createMultipartUpload(createMultipartUploadRequest.build());
-        //final long contentLength = Long.parseLong(objectMetadata.get("Content-Length"));
         List<CompletedPart> completedParts = new ArrayList<CompletedPart>();
-        long partSize = getConfiguration().getPartSize();
-        CompleteMultipartUploadResponse uploadResult = null;
+        CompleteMultipartUploadResponse uploadResult;
 
         long filePosition = 0;
-
         try {
             for (int part = 1; filePosition < contentLength; part++) {
                 partSize = Math.min(partSize, contentLength - filePosition);
diff --git a/components/camel-aws/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/integration/S3MultipartUploadOperationIT.java b/components/camel-aws/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/integration/S3MultipartUploadOperationIT.java
index bdc64dc2a86..be6df3ead16 100644
--- a/components/camel-aws/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/integration/S3MultipartUploadOperationIT.java
+++ b/components/camel-aws/camel-aws2-s3/src/test/java/org/apache/camel/component/aws2/s3/integration/S3MultipartUploadOperationIT.java
@@ -26,6 +26,7 @@ import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.aws2.s3.AWS2S3Constants;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.test.infra.aws2.clients.AWSSDKClientUtils;
+import org.apache.camel.util.IOHelper;
 import org.junit.jupiter.api.Test;
 import software.amazon.awssdk.core.ResponseInputStream;
 import software.amazon.awssdk.services.s3.S3Client;
@@ -78,6 +79,25 @@ public class S3MultipartUploadOperationIT extends Aws2S3Base {
         assertEquals("application/text", response.response().contentType());
     }
 
+    @Test
+    public void sendZeroLength() throws Exception {
+        result.expectedMessageCount(1);
+
+        File zero = new File("target/zero.txt");
+        IOHelper.writeText("", zero);
+
+        template.send("direct:putObject", new Processor() {
+
+            @Override
+            public void process(Exchange exchange) {
+                exchange.getIn().setHeader(AWS2S3Constants.KEY, "zero.txt");
+                exchange.getIn().setBody(zero);
+            }
+        });
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() {
         return new RouteBuilder() {
diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/Aws2S3ComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/Aws2S3ComponentBuilderFactory.java
index 206b2bb2384..32dfd6b2d89 100644
--- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/Aws2S3ComponentBuilderFactory.java
+++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/Aws2S3ComponentBuilderFactory.java
@@ -578,8 +578,11 @@ public interface Aws2S3ComponentBuilderFactory {
             return this;
         }
         /**
-         * If it is true, camel will upload the file with multi part format, the
-         * part size is decided by the option of partSize.
+         * If it is true, camel will upload the file with multi-part format, the
+         * part size is decided by the partSize option. Camel will only do
+         * multi-part uploads for files that are larger than the part-size
+         * thresholds. Files that are smaller will be uploaded in a single
+         * operation.
          * 
          * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
          * 
@@ -627,8 +630,10 @@ public interface Aws2S3ComponentBuilderFactory {
             return this;
         }
         /**
-         * Setup the partSize which is used in multi part upload, the default
-         * size is 25M.
+         * Setup the partSize which is used in multi-part upload, the default
+         * size is 25M. Camel will only do multi-part uploads for files that are
+         * larger than the part-size thresholds. Files that are smaller will be
+         * uploaded in a single operation.
          * 
          * The option is a: &lt;code&gt;long&lt;/code&gt; type.
          * 
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 a046827c6c4..4e1561914c6 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
@@ -2052,8 +2052,11 @@ public interface AWS2S3EndpointBuilderFactory {
             return this;
         }
         /**
-         * If it is true, camel will upload the file with multi part format, the
-         * part size is decided by the option of partSize.
+         * If it is true, camel will upload the file with multi-part format, the
+         * part size is decided by the partSize option. Camel will only do
+         * multi-part uploads for files that are larger than the part-size
+         * thresholds. Files that are smaller will be uploaded in a single
+         * operation.
          * 
          * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
          * 
@@ -2069,8 +2072,11 @@ public interface AWS2S3EndpointBuilderFactory {
             return this;
         }
         /**
-         * If it is true, camel will upload the file with multi part format, the
-         * part size is decided by the option of partSize.
+         * If it is true, camel will upload the file with multi-part format, the
+         * part size is decided by the partSize option. Camel will only do
+         * multi-part uploads for files that are larger than the part-size
+         * thresholds. Files that are smaller will be uploaded in a single
+         * operation.
          * 
          * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
          * type.
@@ -2152,8 +2158,10 @@ public interface AWS2S3EndpointBuilderFactory {
             return this;
         }
         /**
-         * Setup the partSize which is used in multi part upload, the default
-         * size is 25M.
+         * Setup the partSize which is used in multi-part upload, the default
+         * size is 25M. Camel will only do multi-part uploads for files that are
+         * larger than the part-size thresholds. Files that are smaller will be
+         * uploaded in a single operation.
          * 
          * The option is a: &lt;code&gt;long&lt;/code&gt; type.
          * 
@@ -2168,8 +2176,10 @@ public interface AWS2S3EndpointBuilderFactory {
             return this;
         }
         /**
-         * Setup the partSize which is used in multi part upload, the default
-         * size is 25M.
+         * Setup the partSize which is used in multi-part upload, the default
+         * size is 25M. Camel will only do multi-part uploads for files that are
+         * larger than the part-size thresholds. Files that are smaller will be
+         * uploaded in a single operation.
          * 
          * The option will be converted to a &lt;code&gt;long&lt;/code&gt; type.
          *