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 6646255bde54 CAMEL-24961: Catalog body types for object storage 
(#28251)
6646255bde54 is described below

commit 6646255bde54715cb0befe4cfc3d24f8373623b5
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Oct 24 09:04:11 2026 +0200

    CAMEL-24961: Catalog body types for object storage (#28251)
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
---
 .../apache/camel/catalog/components/aws2-s3.json   |   5 +
 .../camel/catalog/components/azure-files.json      |   5 +
 .../catalog/components/azure-storage-blob.json     |   5 +
 .../apache/camel/catalog/components/dropbox.json   |   5 +
 .../camel/catalog/components/google-storage.json   |   5 +
 .../apache/camel/catalog/components/ibm-cos.json   |   5 +
 .../org/apache/camel/catalog/components/minio.json |   5 +
 .../camel/catalog/docs/aws2-s3-component.adoc      |   4 +-
 .../catalog/docs/aws2-s3-consumer-examples.adoc    |   2 +-
 .../catalog/docs/aws2-s3-producer-operations.adoc  |   2 +-
 .../catalog/docs/google-storage-component.adoc     |   2 +-
 .../apache/camel/catalog/docs/minio-component.adoc |   8 +-
 .../apache/camel/component/aws2/s3/aws2-s3.json    |   5 +
 .../src/main/docs/aws2-s3-component.adoc           |   4 +-
 .../src/main/docs/aws2-s3-consumer-examples.adoc   |   2 +-
 .../src/main/docs/aws2-s3-producer-operations.adoc |   2 +-
 .../camel/component/aws2/s3/AWS2S3Endpoint.java    |  91 ++++++++++++++++++
 .../camel/component/file/azure/azure-files.json    |   5 +
 .../camel/component/file/azure/FilesEndpoint.java  |  18 ++++
 .../azure/storage/blob/azure-storage-blob.json     |   5 +
 .../component/azure/storage/blob/BlobEndpoint.java | 106 +++++++++++++++++++++
 .../apache/camel/component/dropbox/dropbox.json    |   5 +
 .../camel/component/dropbox/DropboxEndpoint.java   |  34 +++++++
 .../component/google/storage/google-storage.json   |   5 +
 .../src/main/docs/google-storage-component.adoc    |   2 +-
 .../google/storage/GoogleCloudStorageEndpoint.java |  39 ++++++++
 .../apache/camel/component/ibm/cos/ibm-cos.json    |   5 +
 .../camel/component/ibm/cos/IBMCOSEndpoint.java    |  34 +++++++
 .../org/apache/camel/component/minio/minio.json    |   5 +
 .../camel-minio/src/main/docs/minio-component.adoc |   8 +-
 .../camel/component/minio/MinioEndpoint.java       |  44 +++++++++
 .../camel/dsl/yaml/validator/CatalogBodyTypes.java |   7 +-
 .../camel/dsl/yaml/validator/TextBodyFlow.java     |   2 +-
 .../camel/dsl/yaml/validator/TextBodyFlowTest.java |  53 +++++++++++
 34 files changed, 513 insertions(+), 21 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 a99e76777b8b..e2d95e2159cc 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
@@ -145,6 +145,11 @@
     "CamelAwsS3UploadLinkHttpRequestHeaders": { "index": 52, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Map<String, List<String>>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
headers that are needed by the service for upload (not needed when 
BrowserCompatible is true)", "constantName": 
"org.apache.camel.component.aws2.s3.AWS2S3Constants#UPLOAD_LINK_HTTP_REQUEST_HE 
[...]
     "CamelAwsS3UploadLinkSignedPayload": { "index": 53, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The request payload that is needed by 
the service for upload (not needed when BrowserCompatible is true)", 
"constantName": 
"org.apache.camel.component.aws2.s3.AWS2S3Constants#UPLOAD_LINK_SIGNED_PAYLOAD" 
}
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"byOption": [ { "option": "includeBody", "value": "false", "carriers": [ 
"stream" ] }, { "option": "ignoreBody", "value": "true", "carriers": [ "null" ] 
} ], "description": "The content of the object as a byte array, one message per 
object, with its key and metadata in headers. With includeBody=false the stream 
of the object, and with ignoreBody=true no body" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "operation", "pojoRequest" ], "description": "The content to 
upload, when no operation is set: text, bytes, a stream or a file. A Map or a 
List fails: marshal it first. The operations take their input from headers, or 
with pojoRequest=true from the request of the AWS SDK in the body, such as a 
GetObjectRequest" },
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "getObject", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "getObjectRange", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "listObjects", "carriers": [ "list" ], "javaType": 
"java.util.List<software.amazon.awssdk.services.s3.model.S3Object>" }, { 
"option": "operation", "value": "listBuckets", "carriers": [ "list" ], 
"javaType": "java.util.List<software.amazon. [...]
+  },
   "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" },
     "autoCreateBucket": { "index": 1, "kind": "parameter", "displayName": 
"Auto Create Bucket", "group": "common", "label": "common", "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": "Setting the autocreation of the S3 bucket 
bucketName. This will apply also in cas [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-files.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-files.json
index 231fb1308104..47b35f5d38ff 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-files.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-files.json
@@ -47,6 +47,11 @@
     "CamelFileLocalWorkPath": { "index": 13, "kind": "header", "displayName": 
"", "group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Path to the local work file, if local work directory is 
used.", "constantName": 
"org.apache.camel.component.file.azure.FilesConstants#FILE_LOCAL_WORK_PATH" },
     "CamelFileHost": { "index": 14, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The remote hostname.", "constantName": 
"org.apache.camel.component.file.azure.FilesConstants#FILE_HOST" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "file" ], "dependsOn": [ "preMove" ], 
"byOption": [ { "option": "streamDownload", "value": "true", "carriers": [ 
"stream" ] }, { "option": "download", "value": "false", "carriers": [ "null" ] 
} ], "description": "The file as read: a RemoteFile with its content loaded as 
bytes, which converts to text, bytes or a stream; a stream with streamDownload; 
with preMove its content, a byte array" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"byOption": [ { "option": "allowNullBody", "value": "true", "carriers": [ 
"null", "text", "bytes", "stream", "file" ] } ], "description": "What converts 
to an InputStream or a byte array: text, bytes, a stream or a file. A Map or a 
List fails: marshal it first" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "account": { "index": 0, "kind": "path", "displayName": "Account", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.file.azure.FilesConfiguration", 
"configurationField": "configuration", "description": "The account to use" },
     "share": { "index": 1, "kind": "path", "displayName": "Share", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.file.azure.FilesConfiguration", 
"configurationField": "configuration", "description": "The share to use" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-storage-blob.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-storage-blob.json
index 677b93044d53..c69e7afe81dd 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-storage-blob.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-storage-blob.json
@@ -157,6 +157,11 @@
     "CamelAzureStorageBlobImmutabilityPolicyMode": { "index": 77, "kind": 
"header", "displayName": "", "group": "producer", "label": "producer", 
"required": false, "javaType": 
"com.azure.storage.blob.models.BlobImmutabilityPolicyMode", "enum": [ 
"Mutable", "Unlocked", "Locked" ], "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": 
"(setBlobImmutabilityPolicy) The mode of the immutability policy: UNLOCKED 
(default, can be modified or deleted), L [...]
     "CamelAzureStorageBlobRehydratePriority": { "index": 78, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "com.azure.storage.blob.models.RehydratePriority", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "(setBlobTier) The rehydrate priority used when rehydrating a 
blob from the archive tier: Standard or High. Ignored when changing tier 
between non-archive tiers.", "constantN [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "stream", "file" ], "description": "The 
content of the blob, one message per blob: a stream that reads it, or with 
fileDir the java.io.File it is downloaded to" },
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": 
"operation", "value": "uploadBlockBlob", "carriers": [ "text", "bytes", 
"stream", "file" ] }, { "option": "operation", "value": "commitAppendBlob", 
"carriers": [ "text", "bytes", "stream", "file" ] }, { "option": "operation", 
"value": "uploadPageBlob", "carriers": [ "text", "bytes", "stream", "file" ] }, 
{ "option": "operation", "value": "stageBlockBlobList", "carriers": [ "list", 
"pojo" ] }, { "option": "operation", "v [...]
+    "producerOut": { "carriers": [ "list" ], "byOption": [ { "option": 
"operation", "value": "getBlob", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "downloadBlobToFile", "carriers": [ "file" ], "javaType": 
"java.io.File" }, { "option": "operation", "value": "getBlobTags", "carriers": 
[ "map" ], "javaType": "java.util.Map<String, String>" }, { "option": 
"operation", "value": "getPageBlobRanges", "carriers": [ "iterator" ], 
"javaType": "com.azure.core.http.rest.PagedItera [...]
+  },
   "properties": {
     "accountName": { "index": 0, "kind": "path", "displayName": "Account 
Name", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "Azure account name to be 
used for authentication with azure blob services" },
     "containerName": { "index": 1, "kind": "path", "displayName": "Container 
Name", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "The blob container name" 
},
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dropbox.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dropbox.json
index 7233ac519422..f5be463c68e9 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dropbox.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dropbox.json
@@ -43,6 +43,11 @@
     "DELETED_PATH": { "index": 11, "kind": "header", "displayName": "", 
"group": "del", "label": "del", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Name of the path deleted on dropbox", "constantName": 
"org.apache.camel.component.dropbox.util.DropboxConstants#DELETED_PATH" },
     "MOVED_PATH": { "index": 12, "kind": "header", "displayName": "", "group": 
"move", "label": "move", "required": false, "javaType": "String", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "Name of the path moved on dropbox", "constantName": 
"org.apache.camel.component.dropbox.util.DropboxConstants#MOVED_PATH" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"operation", "value": "get", "carriers": [ "stream", "bytes", "map" ] }, { 
"option": "operation", "value": "search", "carriers": [ "list" ], "javaType": 
"java.util.List<com.dropbox.core.v2.files.SearchMatchV2>" } ], "description": 
"One message per poll. get: the content of the file in remotePath as a stream 
cache (a byte array when stream caching is off), or for a folder a Map of the 
path to the content of each fil [...]
+    "producerIn": { "carriers": [ "any" ], "description": "Only put reads the 
body, unless localPath or the CamelDropboxLocalPath header names a local file 
or folder to upload: the content to upload, as text, bytes, a stream or a file. 
A Map or a List is not uploaded, and the result is KO without an error: marshal 
it first" },
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"operation", "value": "put", "carriers": [ "value", "map" ] }, { "option": 
"operation", "value": "get", "carriers": [ "stream", "bytes", "map" ] }, { 
"option": "operation", "value": "del", "carriers": [ "text" ], "javaType": 
"java.lang.String" }, { "option": "operation", "value": "move", "carriers": [ 
"text" ], "javaType": "java.lang.String" }, { "option": "operation", "value": 
"search", "carriers": [ "list" ], "ja [...]
+  },
   "properties": {
     "operation": { "index": 0, "kind": "path", "displayName": "Operation", 
"group": "common", "label": "", "required": true, "type": "enum", "javaType": 
"org.apache.camel.component.dropbox.util.DropboxOperation", "enum": [ "put", 
"del", "search", "get", "move" ], "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.dropbox.DropboxConfiguration", 
"configurationField": "configuration", "description": "The specifi [...]
     "clientIdentifier": { "index": 1, "kind": "parameter", "displayName": 
"Client Identifier", "group": "common", "label": "common", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.dropbox.DropboxConfiguration", 
"configurationField": "configuration", "description": "Name of the app 
registered to make API requests" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/google-storage.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/google-storage.json
index c074a07ef91b..669344fe5b62 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/google-storage.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/google-storage.json
@@ -79,6 +79,11 @@
     "CamelGoogleCloudStorageLastUpdate": { "index": 26, "kind": "header", 
"displayName": "", "group": "consumer", "label": "consumer", "required": false, 
"javaType": "Date", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The last update of the object", 
"constantName": 
"org.apache.camel.component.google.storage.GoogleCloudStorageConstants#METADATA_LAST_UPDATE"
 },
     "CamelGoogleCloudStorageOverrideBucketName": { "index": 27, "kind": 
"header", "displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The bucket Name to override which this 
object will be stored or which will be used for the current operation or in 
which this object is contained.", "constantName": 
"org.apache.camel.component.google.storage.GoogleCloudSt [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "stream", "bytes", "file" ], "byOption": [ 
{ "option": "includeBody", "value": "false", "carriers": [ "pojo" ], 
"javaType": "com.google.cloud.storage.Blob" } ], "description": "The content of 
the object, one message per object, with its metadata in headers: a stream 
cache, or a byte array when stream caching is off. With downloadFileName the 
java.io.File it is downloaded to, and with includeBody=false the Blob, which 
has the metadata and not the content" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "operation" ], "description": "The content to upload, when no 
operation is set: text, bytes, a stream or a file. A Map, a List or no body 
fails: marshal it first. The operations take their input from options and 
headers" },
+    "producerOut": { "carriers": [ "pojo" ], "javaType": 
"com.google.cloud.storage.Blob", "byOption": [ { "option": "operation", 
"value": "getObject", "carriers": [ "bytes" ], "javaType": "byte[]" }, { 
"option": "operation", "value": "listObjects", "carriers": [ "list" ], 
"javaType": "java.util.List<com.google.cloud.storage.Blob>" }, { "option": 
"operation", "value": "listBuckets", "carriers": [ "list" ], "javaType": 
"java.util.List<com.google.cloud.storage.Bucket>" }, { "option": "opera [...]
+  },
   "properties": {
     "bucketName": { "index": 0, "kind": "path", "displayName": "Bucket Name", 
"group": "common", "label": "common", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.google.storage.GoogleCloudStorageConfiguration", 
"configurationField": "configuration", "description": "Bucket name or ARN" },
     "autoCreateBucket": { "index": 1, "kind": "parameter", "displayName": 
"Auto Create Bucket", "group": "common", "label": "common", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.google.storage.GoogleCloudStorageConfiguration", 
"configurationField": "configuration", "description": "Setting the autocreation 
of the bucket bucketName." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ibm-cos.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ibm-cos.json
index 3158ed8eac8c..02e6f53e8496 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ibm-cos.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ibm-cos.json
@@ -77,6 +77,11 @@
     "CamelIBMCOSRangeEnd": { "index": 19, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"Long", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The range end position for partial object 
retrieval", "constantName": 
"org.apache.camel.component.ibm.cos.IBMCOSConstants#RANGE_END" },
     "CamelIBMCOSBucketExists": { "index": 20, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Whether the bucket exists or not", 
"constantName": 
"org.apache.camel.component.ibm.cos.IBMCOSConstants#BUCKET_EXISTS" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "stream" ], "byOption": [ { "option": 
"includeBody", "value": "false", "carriers": [ "null" ] } ], "description": 
"The content of the object as a stream, one message per object, with its key 
and metadata in headers. No body with includeBody=false" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "operation" ], "byOption": [ { "option": "operation", "value": 
"putObject", "carriers": [ "text", "bytes", "stream", "file" ] } ], 
"description": "The content to upload with putObject, the default: text, bytes, 
a stream or a file. A Map, a List or no body fails: marshal it first. The other 
operations take their input from headers" },
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "getObject", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "getObjectRange", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "listObjects", "carriers": [ "list" ], "javaType": 
"java.util.List<com.ibm.cloud.objectstorage.services.s3.model.S3ObjectSummary>" 
}, { "option": "operation", "value": "listBuckets", "carriers": [ "list" ], 
"javaType": "java.util.List<com. [...]
+  },
   "properties": {
     "bucketName": { "index": 0, "kind": "path", "displayName": "Bucket Name", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Bucket name" },
     "autoCreateBucket": { "index": 1, "kind": "parameter", "displayName": 
"Auto Create Bucket", "group": "common", "label": "common", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.ibm.cos.IBMCOSConfiguration", "configurationField": 
"configuration", "description": "Automatically create the bucket if it doesn't 
exist" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/minio.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/minio.json
index 317451362eb3..6ef423af1683 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/minio.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/minio.json
@@ -99,6 +99,11 @@
     "CamelMinioPresignedURLExpirationTime": { "index": 21, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Expiration of minio presigned url in 
Seconds", "constantName": 
"org.apache.camel.component.minio.MinioConstants#PRESIGNED_URL_EXPIRATION_TIME" 
},
     "CamelMinioOverrideBucketName": { "index": 22, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The bucket Name to override which this 
object will be stored or which will be used for the current operation or in 
which this object is contained.", "constantName": 
"org.apache.camel.component.minio.MinioConstants#OVERRIDE_BUCKET_NAME" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"byOption": [ { "option": "includeBody", "value": "false", "carriers": [ "null" 
] } ], "description": "The content of the object as a byte array, one message 
per object, with its metadata in headers. No body with includeBody=false" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "operation", "pojoRequest" ], "description": "The content to 
upload, when no operation is set: text, bytes, a stream or a file. A Map, a 
List or no body fails: marshal it first. The operations take their input from 
headers, or with pojoRequest=true from the builder of the request of the Minio 
SDK in the body, such as a GetObjectArgs.Builder; deleteObjects works only so" 
},
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "getObject", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "getObjectRange", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "listObjects", "carriers": [ "iterator" ], "javaType": 
"java.lang.Iterable<io.minio.Result<io.minio.messages.Item>>" }, { "option": 
"operation", "value": "listBuckets", "carriers": [ "iterator" ], "javaType": 
"java.util.Iterator<io.minio.m [...]
+  },
   "properties": {
     "bucketName": { "index": 0, "kind": "path", "displayName": "Bucket Name", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.minio.MinioConfiguration", "configurationField": 
"configuration", "description": "Bucket name" },
     "autoCreateBucket": { "index": 1, "kind": "parameter", "displayName": 
"Auto Create Bucket", "group": "common", "label": "common", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.minio.MinioConfiguration", "configurationField": 
"configuration", "description": "Setting the autocreation of the bucket if 
bucket name not exist." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-s3-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-s3-component.adoc
index ed3923fa2caf..56423c115d56 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-s3-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-s3-component.adoc
@@ -69,8 +69,8 @@ Camel-AWS2-S3 component provides the following operation on 
the producer side:
 - listBuckets
 - deleteBucket
 - listObjects
-- getObject (this will return an S3Object instance)
-- getObjectRange (this will return an S3Object instance)
+- getObject (this will return the content of the object as a stream)
+- getObjectRange (this will return the range of the content as a stream)
 - createDownloadLink
 - createUploadLink
 - headBucket
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-s3-consumer-examples.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-s3-consumer-examples.adoc
index f86b54a59b31..5e584818cb81 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-s3-consumer-examples.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-s3-consumer-examples.adoc
@@ -225,7 +225,7 @@ YAML::
 ----
 ====
 
-This consumer polls every 60 seconds, processes up to 5 objects per poll, and 
doesn't include the object body in the message (only metadata).
+This consumer polls every 60 seconds, processes up to 5 objects per poll, and 
puts the stream of the object in the body instead of reading it into a byte 
array. Use `ignoreBody: true` to get only the metadata.
 
 == Consumer with file filtering and no deletion
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-s3-producer-operations.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-s3-producer-operations.adoc
index f7782ee6cf28..64415177080a 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-s3-producer-operations.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-s3-producer-operations.adoc
@@ -83,7 +83,7 @@ don't require a key header — just set the `operation` 
parameter.
 |
 
 | `getObject`
-| Get a single object. Returns an `S3Object` instance.
+| Get a single object. Returns its content as a stream.
 |
 
 | `getObjectRange`
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-storage-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-storage-component.adoc
index e088354e966a..4678ee29f9a0 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-storage-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-storage-component.adoc
@@ -544,7 +544,7 @@ YAML::
 ----
 ====
 
-This operation will return a Blob object instance related to the `OBJECT_NAME` 
object in `myCamelBucket` bucket.
+This operation will return the content of the `OBJECT_NAME` object in 
`myCamelBucket` bucket as a byte array, with its metadata in headers.
 
 - `CreateDownloadLink`: this operation will return a download link
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/minio-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/minio-component.adoc
index a0e2de922b1a..49889d3f5b57 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/minio-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/minio-component.adoc
@@ -103,8 +103,8 @@ Camel-Minio component provides the following operation on 
the producer side:
 - `listBuckets`
 - `deleteBucket`
 - `listObjects`
-- `getObject` (this will return a `MinioObject instance)
-- `getObjectRange` (this will return a `MinioObject instance)
+- `getObject` (this will return the content of the object as a stream)
+- `getObjectRange` (this will return the range of the content as a stream)
 - `createDownloadLink` (this will return a Presigned download Url)
 - `createUploadLink` (this will return a Presigned upload url)
 
@@ -450,7 +450,7 @@ YAML::
 ----
 ====
 
-This operation will return a MinioObject instance related to the camelKey 
object in `mycamelbucket` bucket.
+This operation will return the content of the camelKey object in 
`mycamelbucket` bucket as a stream.
 
 - `GetObjectRange`: this operation gets a single object range in a specific 
bucket
 
@@ -514,7 +514,7 @@ YAML::
             uri: mock:result
 ----
 ====
-This operation will return a MinioObject instance related to the camelKey 
object in `mycamelbucket` bucket, containing bytes from 0 to 9.
+This operation will return the bytes from 0 to 9 of the camelKey object in 
`mycamelbucket` bucket as a stream.
 
 - `createDownloadLink`: this operation will return a presigned url through 
which a file can be downloaded using GET method
 
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 a99e76777b8b..e2d95e2159cc 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
@@ -145,6 +145,11 @@
     "CamelAwsS3UploadLinkHttpRequestHeaders": { "index": 52, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Map<String, List<String>>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
headers that are needed by the service for upload (not needed when 
BrowserCompatible is true)", "constantName": 
"org.apache.camel.component.aws2.s3.AWS2S3Constants#UPLOAD_LINK_HTTP_REQUEST_HE 
[...]
     "CamelAwsS3UploadLinkSignedPayload": { "index": 53, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The request payload that is needed by 
the service for upload (not needed when BrowserCompatible is true)", 
"constantName": 
"org.apache.camel.component.aws2.s3.AWS2S3Constants#UPLOAD_LINK_SIGNED_PAYLOAD" 
}
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"byOption": [ { "option": "includeBody", "value": "false", "carriers": [ 
"stream" ] }, { "option": "ignoreBody", "value": "true", "carriers": [ "null" ] 
} ], "description": "The content of the object as a byte array, one message per 
object, with its key and metadata in headers. With includeBody=false the stream 
of the object, and with ignoreBody=true no body" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "operation", "pojoRequest" ], "description": "The content to 
upload, when no operation is set: text, bytes, a stream or a file. A Map or a 
List fails: marshal it first. The operations take their input from headers, or 
with pojoRequest=true from the request of the AWS SDK in the body, such as a 
GetObjectRequest" },
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "getObject", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "getObjectRange", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "listObjects", "carriers": [ "list" ], "javaType": 
"java.util.List<software.amazon.awssdk.services.s3.model.S3Object>" }, { 
"option": "operation", "value": "listBuckets", "carriers": [ "list" ], 
"javaType": "java.util.List<software.amazon. [...]
+  },
   "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" },
     "autoCreateBucket": { "index": 1, "kind": "parameter", "displayName": 
"Auto Create Bucket", "group": "common", "label": "common", "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": "Setting the autocreation of the S3 bucket 
bucketName. This will apply also in cas [...]
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 ed3923fa2caf..56423c115d56 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
@@ -69,8 +69,8 @@ Camel-AWS2-S3 component provides the following operation on 
the producer side:
 - listBuckets
 - deleteBucket
 - listObjects
-- getObject (this will return an S3Object instance)
-- getObjectRange (this will return an S3Object instance)
+- getObject (this will return the content of the object as a stream)
+- getObjectRange (this will return the range of the content as a stream)
 - createDownloadLink
 - createUploadLink
 - headBucket
diff --git 
a/components/camel-aws/camel-aws2-s3/src/main/docs/aws2-s3-consumer-examples.adoc
 
b/components/camel-aws/camel-aws2-s3/src/main/docs/aws2-s3-consumer-examples.adoc
index f86b54a59b31..5e584818cb81 100644
--- 
a/components/camel-aws/camel-aws2-s3/src/main/docs/aws2-s3-consumer-examples.adoc
+++ 
b/components/camel-aws/camel-aws2-s3/src/main/docs/aws2-s3-consumer-examples.adoc
@@ -225,7 +225,7 @@ YAML::
 ----
 ====
 
-This consumer polls every 60 seconds, processes up to 5 objects per poll, and 
doesn't include the object body in the message (only metadata).
+This consumer polls every 60 seconds, processes up to 5 objects per poll, and 
puts the stream of the object in the body instead of reading it into a byte 
array. Use `ignoreBody: true` to get only the metadata.
 
 == Consumer with file filtering and no deletion
 
diff --git 
a/components/camel-aws/camel-aws2-s3/src/main/docs/aws2-s3-producer-operations.adoc
 
b/components/camel-aws/camel-aws2-s3/src/main/docs/aws2-s3-producer-operations.adoc
index f7782ee6cf28..64415177080a 100644
--- 
a/components/camel-aws/camel-aws2-s3/src/main/docs/aws2-s3-producer-operations.adoc
+++ 
b/components/camel-aws/camel-aws2-s3/src/main/docs/aws2-s3-producer-operations.adoc
@@ -83,7 +83,7 @@ don't require a key header — just set the `operation` 
parameter.
 |
 
 | `getObject`
-| Get a single object. Returns an `S3Object` instance.
+| Get a single object. Returns its content as a stream.
 |
 
 | `getObjectRange`
diff --git 
a/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Endpoint.java
 
b/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Endpoint.java
index 7350a7bebd8f..2ff11c29cc66 100644
--- 
a/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Endpoint.java
+++ 
b/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Endpoint.java
@@ -25,6 +25,9 @@ import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.component.aws2.s3.client.AWS2S3ClientFactory;
 import org.apache.camel.component.aws2.s3.stream.AWS2S3StreamUploadProducer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.IdempotentRepository;
 import org.apache.camel.spi.Metadata;
@@ -49,6 +52,94 @@ import 
software.amazon.awssdk.services.s3.model.PutBucketPolicyRequest;
 @UriEndpoint(firstVersion = "3.2.0", scheme = "aws2-s3", title = "AWS S3 
Storage Service",
              syntax = "aws2-s3://bucketNameOrArn", category = { 
Category.CLOUD, Category.FILE },
              headersClass = AWS2S3Constants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.BYTES, javaType = "byte[]",
+                                   byOption = {
+                                           @BodyType.When(option = 
"includeBody", value = "false", carriers = Carrier.STREAM),
+                                           @BodyType.When(option = 
"ignoreBody", value = "true", carriers = Carrier.NULL) },
+                                   description = "The content of the object as 
a byte array, one message per object, with its"
+                                                 + " key and metadata in 
headers. With includeBody=false the stream of the"
+                                                 + " object, and with 
ignoreBody=true no body"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  dependsOn = { "operation", "pojoRequest" },
+                                  description = "The content to upload, when 
no operation is set: text, bytes, a stream or a"
+                                                + " file. A Map or a List 
fails: marshal it first. The operations take their"
+                                                + " input from headers, or 
with pojoRequest=true from the request of the AWS SDK"
+                                                + " in the body, such as a 
GetObjectRequest"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   byOption = {
+                                           @BodyType.When(option = 
"operation", value = "getObject", carriers = Carrier.STREAM),
+                                           @BodyType.When(option = 
"operation", value = "getObjectRange",
+                                                          carriers = 
Carrier.STREAM),
+                                           @BodyType.When(option = 
"operation", value = "listObjects", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<software.amazon.awssdk.services.s3.model.S3Object>"),
+                                           @BodyType.When(option = 
"operation", value = "listBuckets", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<software.amazon.awssdk.services.s3.model.Bucket>"),
+                                           @BodyType.When(option = 
"operation", value = "getObjectTagging",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<software.amazon.awssdk.services.s3.model.Tag>"),
+                                           @BodyType.When(option = 
"operation", value = "getBucketTagging",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<software.amazon.awssdk.services.s3.model.Tag>"),
+                                           @BodyType.When(option = 
"operation", value = "createDownloadLink",
+                                                          carriers = 
Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "createUploadLink",
+                                                          carriers = 
Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getBucketPolicy",
+                                                          carriers = 
Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "deleteObject",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "headBucket",
+                                                          carriers = { 
Carrier.POJO, Carrier.UNCHANGED }),
+                                           @BodyType.When(option = 
"operation", value = "headObject", carriers = Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.HeadObjectResponse"),
+                                           @BodyType.When(option = 
"operation", value = "deleteObjects",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.DeleteObjectsResponse"),
+                                           @BodyType.When(option = 
"operation", value = "deleteBucket", carriers = Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.DeleteBucketResponse"),
+                                           @BodyType.When(option = 
"operation", value = "createBucket", carriers = Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.CreateBucketResponse"),
+                                           @BodyType.When(option = 
"operation", value = "restoreObject",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.RestoreObjectResponse"),
+                                           @BodyType.When(option = 
"operation", value = "putObjectTagging",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.PutObjectTaggingResponse"),
+                                           @BodyType.When(option = 
"operation", value = "deleteObjectTagging",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.DeleteObjectTaggingResponse"),
+                                           @BodyType.When(option = 
"operation", value = "getObjectAcl", carriers = Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.GetObjectAclResponse"),
+                                           @BodyType.When(option = 
"operation", value = "putObjectAcl", carriers = Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.PutObjectAclResponse"),
+                                           @BodyType.When(option = 
"operation", value = "putBucketTagging",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.PutBucketTaggingResponse"),
+                                           @BodyType.When(option = 
"operation", value = "deleteBucketTagging",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.DeleteBucketTaggingResponse"),
+                                           @BodyType.When(option = 
"operation", value = "getBucketVersioning",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.GetBucketVersioningResponse"),
+                                           @BodyType.When(option = 
"operation", value = "putBucketVersioning",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.PutBucketVersioningResponse"),
+                                           @BodyType.When(option = 
"operation", value = "putBucketPolicy",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.PutBucketPolicyResponse"),
+                                           @BodyType.When(option = 
"operation", value = "deleteBucketPolicy",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"software.amazon.awssdk.services.s3.model.DeleteBucketPolicyResponse") },
+                                   description = "Unchanged after an upload 
and a copyObject, with the ETag in a header. By the"
+                                                 + " operation: the stream of 
the object for getObject and getObjectRange, a"
+                                                 + " List for the lists and 
the tagging gets, the URL as text for the links, the"
+                                                 + " policy JSON for 
getBucketPolicy, true for deleteObject, and the response of"
+                                                 + " the AWS SDK for the 
others. getObject with ignoreBody=true, headBucket for a"
+                                                 + " bucket that does not 
exist and streamingUploadMode keep the body"))
 public class AWS2S3Endpoint extends ScheduledPollEndpoint implements 
EndpointServiceLocation {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(AWS2S3Endpoint.class);
diff --git 
a/components/camel-azure/camel-azure-files/src/generated/resources/META-INF/org/apache/camel/component/file/azure/azure-files.json
 
b/components/camel-azure/camel-azure-files/src/generated/resources/META-INF/org/apache/camel/component/file/azure/azure-files.json
index 231fb1308104..47b35f5d38ff 100644
--- 
a/components/camel-azure/camel-azure-files/src/generated/resources/META-INF/org/apache/camel/component/file/azure/azure-files.json
+++ 
b/components/camel-azure/camel-azure-files/src/generated/resources/META-INF/org/apache/camel/component/file/azure/azure-files.json
@@ -47,6 +47,11 @@
     "CamelFileLocalWorkPath": { "index": 13, "kind": "header", "displayName": 
"", "group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Path to the local work file, if local work directory is 
used.", "constantName": 
"org.apache.camel.component.file.azure.FilesConstants#FILE_LOCAL_WORK_PATH" },
     "CamelFileHost": { "index": 14, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The remote hostname.", "constantName": 
"org.apache.camel.component.file.azure.FilesConstants#FILE_HOST" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "file" ], "dependsOn": [ "preMove" ], 
"byOption": [ { "option": "streamDownload", "value": "true", "carriers": [ 
"stream" ] }, { "option": "download", "value": "false", "carriers": [ "null" ] 
} ], "description": "The file as read: a RemoteFile with its content loaded as 
bytes, which converts to text, bytes or a stream; a stream with streamDownload; 
with preMove its content, a byte array" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"byOption": [ { "option": "allowNullBody", "value": "true", "carriers": [ 
"null", "text", "bytes", "stream", "file" ] } ], "description": "What converts 
to an InputStream or a byte array: text, bytes, a stream or a file. A Map or a 
List fails: marshal it first" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "account": { "index": 0, "kind": "path", "displayName": "Account", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.file.azure.FilesConfiguration", 
"configurationField": "configuration", "description": "The account to use" },
     "share": { "index": 1, "kind": "path", "displayName": "Share", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.file.azure.FilesConfiguration", 
"configurationField": "configuration", "description": "The share to use" },
diff --git 
a/components/camel-azure/camel-azure-files/src/main/java/org/apache/camel/component/file/azure/FilesEndpoint.java
 
b/components/camel-azure/camel-azure-files/src/main/java/org/apache/camel/component/file/azure/FilesEndpoint.java
index ccbce1eaba6a..692d67aaae7b 100644
--- 
a/components/camel-azure/camel-azure-files/src/main/java/org/apache/camel/component/file/azure/FilesEndpoint.java
+++ 
b/components/camel-azure/camel-azure-files/src/main/java/org/apache/camel/component/file/azure/FilesEndpoint.java
@@ -30,6 +30,9 @@ import 
org.apache.camel.component.file.GenericFileProcessStrategy;
 import 
org.apache.camel.component.file.azure.strategy.FilesProcessStrategyFactory;
 import org.apache.camel.component.file.remote.RemoteFileConsumer;
 import org.apache.camel.component.file.remote.RemoteFileEndpoint;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
@@ -51,6 +54,21 @@ import org.apache.camel.util.ObjectHelper;
                               + 
"siteCommand,fastExistsCheck,soTimeout,separator,sendNoop,ignoreFileNotFoundOrPermissionError,"
                               + "bufferSize,moveExisting,username,host")
 @ManagedResource(description = "Camel Azure Files endpoint")
+@BodyTypes(consumerOut = @BodyType(value = Carrier.FILE, dependsOn = "preMove",
+                                   byOption = {
+                                           @BodyType.When(option = 
"streamDownload", value = "true", carriers = Carrier.STREAM),
+                                           @BodyType.When(option = "download", 
value = "false", carriers = Carrier.NULL) },
+                                   description = "The file as read: a 
RemoteFile with its content loaded as bytes, which converts"
+                                                 + " to text, bytes or a 
stream; a stream with streamDownload; with preMove its"
+                                                 + " content, a byte array"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  byOption = @BodyType.When(option = 
"allowNullBody", value = "true",
+                                                            carriers = {
+                                                                    
Carrier.NULL, Carrier.TEXT, Carrier.BYTES,
+                                                                    
Carrier.STREAM, Carrier.FILE }),
+                                  description = "What converts to an 
InputStream or a byte array: text, bytes, a stream or a"
+                                                + " file. A Map or a List 
fails: marshal it first"),
+           producerOut = @BodyType(Carrier.UNCHANGED))
 public class FilesEndpoint extends RemoteFileEndpoint<ShareFileItem> 
implements EndpointServiceLocation {
 
     // without hiding configuration field from type 
GenericFileEndpoint<ShareFileItem>
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
 
b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
index 677b93044d53..c69e7afe81dd 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
@@ -157,6 +157,11 @@
     "CamelAzureStorageBlobImmutabilityPolicyMode": { "index": 77, "kind": 
"header", "displayName": "", "group": "producer", "label": "producer", 
"required": false, "javaType": 
"com.azure.storage.blob.models.BlobImmutabilityPolicyMode", "enum": [ 
"Mutable", "Unlocked", "Locked" ], "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": 
"(setBlobImmutabilityPolicy) The mode of the immutability policy: UNLOCKED 
(default, can be modified or deleted), L [...]
     "CamelAzureStorageBlobRehydratePriority": { "index": 78, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "com.azure.storage.blob.models.RehydratePriority", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "(setBlobTier) The rehydrate priority used when rehydrating a 
blob from the archive tier: Standard or High. Ignored when changing tier 
between non-archive tiers.", "constantN [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "stream", "file" ], "description": "The 
content of the blob, one message per blob: a stream that reads it, or with 
fileDir the java.io.File it is downloaded to" },
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": 
"operation", "value": "uploadBlockBlob", "carriers": [ "text", "bytes", 
"stream", "file" ] }, { "option": "operation", "value": "commitAppendBlob", 
"carriers": [ "text", "bytes", "stream", "file" ] }, { "option": "operation", 
"value": "uploadPageBlob", "carriers": [ "text", "bytes", "stream", "file" ] }, 
{ "option": "operation", "value": "stageBlockBlobList", "carriers": [ "list", 
"pojo" ] }, { "option": "operation", "v [...]
+    "producerOut": { "carriers": [ "list" ], "byOption": [ { "option": 
"operation", "value": "getBlob", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "downloadBlobToFile", "carriers": [ "file" ], "javaType": 
"java.io.File" }, { "option": "operation", "value": "getBlobTags", "carriers": 
[ "map" ], "javaType": "java.util.Map<String, String>" }, { "option": 
"operation", "value": "getPageBlobRanges", "carriers": [ "iterator" ], 
"javaType": "com.azure.core.http.rest.PagedItera [...]
+  },
   "properties": {
     "accountName": { "index": 0, "kind": "path", "displayName": "Account 
Name", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "Azure account name to be 
used for authentication with azure blob services" },
     "containerName": { "index": 1, "kind": "path", "displayName": "Container 
Name", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "The blob container name" 
},
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobEndpoint.java
 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobEndpoint.java
index e06f9e8c8231..41283e68f2d1 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobEndpoint.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobEndpoint.java
@@ -30,6 +30,9 @@ import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.component.azure.storage.blob.client.BlobClientFactory;
 import 
org.apache.camel.component.azure.storage.blob.operations.BlobOperationResponse;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -42,6 +45,109 @@ import org.apache.camel.util.ObjectHelper;
 @UriEndpoint(firstVersion = "3.3.0", scheme = "azure-storage-blob", title = 
"Azure Storage Blob Service",
              syntax = "azure-storage-blob:accountName/containerName", category 
= { Category.CLOUD, Category.FILE },
              headersClass = BlobConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = { Carrier.STREAM, Carrier.FILE },
+                                   description = "The content of the blob, one 
message per blob: a stream that reads it, or"
+                                                 + " with fileDir the 
java.io.File it is downloaded to"),
+           producerIn = @BodyType(value = Carrier.ANY,
+                                  byOption = {
+                                          @BodyType.When(option = "operation", 
value = "uploadBlockBlob",
+                                                         carriers = {
+                                                                 Carrier.TEXT, 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE }),
+                                          @BodyType.When(option = "operation", 
value = "commitAppendBlob",
+                                                         carriers = {
+                                                                 Carrier.TEXT, 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE }),
+                                          @BodyType.When(option = "operation", 
value = "uploadPageBlob",
+                                                         carriers = {
+                                                                 Carrier.TEXT, 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE }),
+                                          @BodyType.When(option = "operation", 
value = "stageBlockBlobList",
+                                                         carriers = { 
Carrier.LIST, Carrier.POJO }),
+                                          @BodyType.When(option = "operation", 
value = "commitBlobBlockList",
+                                                         carriers = { 
Carrier.LIST, Carrier.POJO }) },
+                                  description = "The content to upload for 
uploadBlockBlob, commitAppendBlob and uploadPageBlob:"
+                                                + " text, bytes, a stream or a 
file; a Map or a List fails: marshal it first. A"
+                                                + " List of BlobBlock for 
stageBlockBlobList, and of Block for"
+                                                + " commitBlobBlockList. 
getBlob writes into an OutputStream body. The other"
+                                                + " operations do not use the 
body, or take their value from a header first: the"
+                                                + " file of 
uploadBlockBlobChunked, the tags, the tag filter, the legal hold, the"
+                                                + " tier and the policy"),
+           producerOut = @BodyType(value = Carrier.LIST,
+                                   byOption = {
+                                           @BodyType.When(option = 
"operation", value = "getBlob", carriers = Carrier.STREAM),
+                                           @BodyType.When(option = 
"operation", value = "downloadBlobToFile",
+                                                          carriers = 
Carrier.FILE,
+                                                          javaType = 
"java.io.File"),
+                                           @BodyType.When(option = 
"operation", value = "getBlobTags", carriers = Carrier.MAP,
+                                                          javaType = 
"java.util.Map<String, String>"),
+                                           @BodyType.When(option = 
"operation", value = "getPageBlobRanges",
+                                                          carriers = 
Carrier.ITERATOR,
+                                                          javaType = 
"com.azure.core.http.rest.PagedIterable<com.azure.storage.blob.models.PageRangeItem>"),
+                                           @BodyType.When(option = 
"operation", value = "getBlobBlockList",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"com.azure.storage.blob.models.BlockList"),
+                                           @BodyType.When(option = 
"operation", value = "setBlobImmutabilityPolicy",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"com.azure.storage.blob.models.BlobImmutabilityPolicy"),
+                                           @BodyType.When(option = 
"operation", value = "setBlobTier", carriers = Carrier.POJO,
+                                                          javaType = 
"com.azure.storage.blob.models.AccessTier"),
+                                           @BodyType.When(option = 
"operation", value = "copyBlob", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "createBlobSnapshot",
+                                                          carriers = 
Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "setBlobLegalHold",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "createBlobContainer",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "deleteBlobContainer",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "deleteBlob", carriers = Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "downloadLink",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "uploadBlockBlob",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "uploadBlockBlobChunked",
+                                                          carriers = 
Carrier.VALUE, javaType = "java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "stageBlockBlobList",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "commitBlobBlockList",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "createAppendBlob",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "commitAppendBlob",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "createPageBlob",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "uploadPageBlob",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "resizePageBlob",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "clearPageBlob",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "setBlobTags", carriers = Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "undeleteBlob",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean") },
+                                   description = "A List of the items of the 
SDK for listBlobContainers, the default,"
+                                                 + " findBlobsByTags, 
listBlobs, listBlobVersions and getChangeFeed. A stream of"
+                                                 + " the content for getBlob, 
or the OutputStream body it wrote into; the"
+                                                 + " java.io.File for 
downloadBlobToFile; true for the operations that create,"
+                                                 + " upload, set or delete, 
with their results in headers, such as the link of"
+                                                 + " downloadLink"))
 public class BlobEndpoint extends ScheduledPollEndpoint implements 
EndpointServiceLocation {
 
     @UriParam
diff --git 
a/components/camel-dropbox/src/generated/resources/META-INF/org/apache/camel/component/dropbox/dropbox.json
 
b/components/camel-dropbox/src/generated/resources/META-INF/org/apache/camel/component/dropbox/dropbox.json
index 7233ac519422..f5be463c68e9 100644
--- 
a/components/camel-dropbox/src/generated/resources/META-INF/org/apache/camel/component/dropbox/dropbox.json
+++ 
b/components/camel-dropbox/src/generated/resources/META-INF/org/apache/camel/component/dropbox/dropbox.json
@@ -43,6 +43,11 @@
     "DELETED_PATH": { "index": 11, "kind": "header", "displayName": "", 
"group": "del", "label": "del", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Name of the path deleted on dropbox", "constantName": 
"org.apache.camel.component.dropbox.util.DropboxConstants#DELETED_PATH" },
     "MOVED_PATH": { "index": 12, "kind": "header", "displayName": "", "group": 
"move", "label": "move", "required": false, "javaType": "String", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "Name of the path moved on dropbox", "constantName": 
"org.apache.camel.component.dropbox.util.DropboxConstants#MOVED_PATH" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"operation", "value": "get", "carriers": [ "stream", "bytes", "map" ] }, { 
"option": "operation", "value": "search", "carriers": [ "list" ], "javaType": 
"java.util.List<com.dropbox.core.v2.files.SearchMatchV2>" } ], "description": 
"One message per poll. get: the content of the file in remotePath as a stream 
cache (a byte array when stream caching is off), or for a folder a Map of the 
path to the content of each fil [...]
+    "producerIn": { "carriers": [ "any" ], "description": "Only put reads the 
body, unless localPath or the CamelDropboxLocalPath header names a local file 
or folder to upload: the content to upload, as text, bytes, a stream or a file. 
A Map or a List is not uploaded, and the result is KO without an error: marshal 
it first" },
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"operation", "value": "put", "carriers": [ "value", "map" ] }, { "option": 
"operation", "value": "get", "carriers": [ "stream", "bytes", "map" ] }, { 
"option": "operation", "value": "del", "carriers": [ "text" ], "javaType": 
"java.lang.String" }, { "option": "operation", "value": "move", "carriers": [ 
"text" ], "javaType": "java.lang.String" }, { "option": "operation", "value": 
"search", "carriers": [ "list" ], "ja [...]
+  },
   "properties": {
     "operation": { "index": 0, "kind": "path", "displayName": "Operation", 
"group": "common", "label": "", "required": true, "type": "enum", "javaType": 
"org.apache.camel.component.dropbox.util.DropboxOperation", "enum": [ "put", 
"del", "search", "get", "move" ], "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.dropbox.DropboxConfiguration", 
"configurationField": "configuration", "description": "The specifi [...]
     "clientIdentifier": { "index": 1, "kind": "parameter", "displayName": 
"Client Identifier", "group": "common", "label": "common", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.dropbox.DropboxConfiguration", 
"configurationField": "configuration", "description": "Name of the app 
registered to make API requests" },
diff --git 
a/components/camel-dropbox/src/main/java/org/apache/camel/component/dropbox/DropboxEndpoint.java
 
b/components/camel-dropbox/src/main/java/org/apache/camel/component/dropbox/DropboxEndpoint.java
index 4755b343859f..489ee82cd698 100644
--- 
a/components/camel-dropbox/src/main/java/org/apache/camel/component/dropbox/DropboxEndpoint.java
+++ 
b/components/camel-dropbox/src/main/java/org/apache/camel/component/dropbox/DropboxEndpoint.java
@@ -31,6 +31,9 @@ import 
org.apache.camel.component.dropbox.integration.producer.DropboxSearchProd
 import org.apache.camel.component.dropbox.util.DropboxConstants;
 import org.apache.camel.component.dropbox.util.DropboxException;
 import org.apache.camel.component.dropbox.util.DropboxOperation;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -43,6 +46,37 @@ import org.slf4j.LoggerFactory;
  */
 @UriEndpoint(firstVersion = "2.14.0", scheme = "dropbox", title = "Dropbox", 
syntax = "dropbox:operation",
              category = { Category.CLOUD, Category.FILE, Category.API }, 
headersClass = DropboxConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.UNKNOWN,
+                                   byOption = {
+                                           @BodyType.When(option = 
"operation", value = "get",
+                                                          carriers = { 
Carrier.STREAM, Carrier.BYTES, Carrier.MAP }),
+                                           @BodyType.When(option = 
"operation", value = "search", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<com.dropbox.core.v2.files.SearchMatchV2>") },
+                                   description = "One message per poll. get: 
the content of the file in remotePath as a stream"
+                                                 + " cache (a byte array when 
stream caching is off), or for a folder a Map of"
+                                                 + " the path to the content 
of each file. search: a List of SearchMatchV2"),
+           producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "Only put reads the body, 
unless localPath or the CamelDropboxLocalPath header"
+                                                + " names a local file or 
folder to upload: the content to upload, as text,"
+                                                + " bytes, a stream or a file. 
A Map or a List is not uploaded, and the result"
+                                                + " is KO without an error: 
marshal it first"),
+           producerOut = @BodyType(value = Carrier.UNKNOWN,
+                                   byOption = {
+                                           @BodyType.When(option = 
"operation", value = "put",
+                                                          carriers = { 
Carrier.VALUE, Carrier.MAP }),
+                                           @BodyType.When(option = 
"operation", value = "get",
+                                                          carriers = { 
Carrier.STREAM, Carrier.BYTES, Carrier.MAP }),
+                                           @BodyType.When(option = 
"operation", value = "del", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "move", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "search", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<com.dropbox.core.v2.files.SearchMatchV2>") },
+                                   description = "put: OK or KO, a 
DropboxResultCode, or for a local folder of several files a"
+                                                 + " Map of each remote path 
to its result. get: the content of the file as a"
+                                                 + " stream cache (a byte 
array when stream caching is off), or a Map of the path"
+                                                 + " to the content of each 
file of a folder. del: the path deleted. move: the new"
+                                                 + " path. search: a List of 
SearchMatchV2"))
 public class DropboxEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(DropboxEndpoint.class);
diff --git 
a/components/camel-google/camel-google-storage/src/generated/resources/META-INF/org/apache/camel/component/google/storage/google-storage.json
 
b/components/camel-google/camel-google-storage/src/generated/resources/META-INF/org/apache/camel/component/google/storage/google-storage.json
index c074a07ef91b..669344fe5b62 100644
--- 
a/components/camel-google/camel-google-storage/src/generated/resources/META-INF/org/apache/camel/component/google/storage/google-storage.json
+++ 
b/components/camel-google/camel-google-storage/src/generated/resources/META-INF/org/apache/camel/component/google/storage/google-storage.json
@@ -79,6 +79,11 @@
     "CamelGoogleCloudStorageLastUpdate": { "index": 26, "kind": "header", 
"displayName": "", "group": "consumer", "label": "consumer", "required": false, 
"javaType": "Date", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The last update of the object", 
"constantName": 
"org.apache.camel.component.google.storage.GoogleCloudStorageConstants#METADATA_LAST_UPDATE"
 },
     "CamelGoogleCloudStorageOverrideBucketName": { "index": 27, "kind": 
"header", "displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The bucket Name to override which this 
object will be stored or which will be used for the current operation or in 
which this object is contained.", "constantName": 
"org.apache.camel.component.google.storage.GoogleCloudSt [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "stream", "bytes", "file" ], "byOption": [ 
{ "option": "includeBody", "value": "false", "carriers": [ "pojo" ], 
"javaType": "com.google.cloud.storage.Blob" } ], "description": "The content of 
the object, one message per object, with its metadata in headers: a stream 
cache, or a byte array when stream caching is off. With downloadFileName the 
java.io.File it is downloaded to, and with includeBody=false the Blob, which 
has the metadata and not the content" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "operation" ], "description": "The content to upload, when no 
operation is set: text, bytes, a stream or a file. A Map, a List or no body 
fails: marshal it first. The operations take their input from options and 
headers" },
+    "producerOut": { "carriers": [ "pojo" ], "javaType": 
"com.google.cloud.storage.Blob", "byOption": [ { "option": "operation", 
"value": "getObject", "carriers": [ "bytes" ], "javaType": "byte[]" }, { 
"option": "operation", "value": "listObjects", "carriers": [ "list" ], 
"javaType": "java.util.List<com.google.cloud.storage.Blob>" }, { "option": 
"operation", "value": "listBuckets", "carriers": [ "list" ], "javaType": 
"java.util.List<com.google.cloud.storage.Bucket>" }, { "option": "opera [...]
+  },
   "properties": {
     "bucketName": { "index": 0, "kind": "path", "displayName": "Bucket Name", 
"group": "common", "label": "common", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.google.storage.GoogleCloudStorageConfiguration", 
"configurationField": "configuration", "description": "Bucket name or ARN" },
     "autoCreateBucket": { "index": 1, "kind": "parameter", "displayName": 
"Auto Create Bucket", "group": "common", "label": "common", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.google.storage.GoogleCloudStorageConfiguration", 
"configurationField": "configuration", "description": "Setting the autocreation 
of the bucket bucketName." },
diff --git 
a/components/camel-google/camel-google-storage/src/main/docs/google-storage-component.adoc
 
b/components/camel-google/camel-google-storage/src/main/docs/google-storage-component.adoc
index e088354e966a..4678ee29f9a0 100644
--- 
a/components/camel-google/camel-google-storage/src/main/docs/google-storage-component.adoc
+++ 
b/components/camel-google/camel-google-storage/src/main/docs/google-storage-component.adoc
@@ -544,7 +544,7 @@ YAML::
 ----
 ====
 
-This operation will return a Blob object instance related to the `OBJECT_NAME` 
object in `myCamelBucket` bucket.
+This operation will return the content of the `OBJECT_NAME` object in 
`myCamelBucket` bucket as a byte array, with its metadata in headers.
 
 - `CreateDownloadLink`: this operation will return a download link
 
diff --git 
a/components/camel-google/camel-google-storage/src/main/java/org/apache/camel/component/google/storage/GoogleCloudStorageEndpoint.java
 
b/components/camel-google/camel-google-storage/src/main/java/org/apache/camel/component/google/storage/GoogleCloudStorageEndpoint.java
index a0ee328b685d..0e9a495e2dc9 100644
--- 
a/components/camel-google/camel-google-storage/src/main/java/org/apache/camel/component/google/storage/GoogleCloudStorageEndpoint.java
+++ 
b/components/camel-google/camel-google-storage/src/main/java/org/apache/camel/component/google/storage/GoogleCloudStorageEndpoint.java
@@ -27,6 +27,9 @@ import org.apache.camel.Category;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -43,6 +46,42 @@ import org.slf4j.LoggerFactory;
  */
 @UriEndpoint(firstVersion = "3.9.0", scheme = "google-storage", title = 
"Google Storage", syntax = "google-storage:bucketName",
              category = { Category.CLOUD }, headersClass = 
GoogleCloudStorageConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = { Carrier.STREAM, Carrier.BYTES, 
Carrier.FILE },
+                                   byOption = @BodyType.When(option = 
"includeBody", value = "false", carriers = Carrier.POJO,
+                                                             javaType = 
"com.google.cloud.storage.Blob"),
+                                   description = "The content of the object, 
one message per object, with its metadata in"
+                                                 + " headers: a stream cache, 
or a byte array when stream caching is off. With"
+                                                 + " downloadFileName the 
java.io.File it is downloaded to, and with"
+                                                 + " includeBody=false the 
Blob, which has the metadata and not the content"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  dependsOn = "operation",
+                                  description = "The content to upload, when 
no operation is set: text, bytes, a stream or a"
+                                                + " file. A Map, a List or no 
body fails: marshal it first. The operations take"
+                                                + " their input from options 
and headers"),
+           producerOut = @BodyType(value = Carrier.POJO, javaType = 
"com.google.cloud.storage.Blob",
+                                   byOption = {
+                                           @BodyType.When(option = 
"operation", value = "getObject", carriers = Carrier.BYTES,
+                                                          javaType = "byte[]"),
+                                           @BodyType.When(option = 
"operation", value = "listObjects", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<com.google.cloud.storage.Blob>"),
+                                           @BodyType.When(option = 
"operation", value = "listBuckets", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<com.google.cloud.storage.Bucket>"),
+                                           @BodyType.When(option = 
"operation", value = "copyObject", carriers = Carrier.POJO,
+                                                          javaType = 
"com.google.cloud.storage.CopyWriter"),
+                                           @BodyType.When(option = 
"operation", value = "deleteObject",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "deleteBucket",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "createDownloadLink",
+                                                          carriers = 
Carrier.TEXT,
+                                                          javaType = 
"java.lang.String") },
+                                   description = "The Blob of the uploaded 
object. By the operation: the content as a byte array"
+                                                 + " for getObject, with its 
metadata in headers, a List of Blob or Bucket for the"
+                                                 + " lists, the CopyWriter for 
copyObject, whose getResult() gives the Blob of the"
+                                                 + " copy, true or false for 
the deletes and the signed URL as text for"
+                                                 + " createDownloadLink"))
 public class GoogleCloudStorageEndpoint extends ScheduledPollEndpoint 
implements EndpointServiceLocation {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(GoogleCloudStorageEndpoint.class);
diff --git 
a/components/camel-ibm/camel-ibm-cos/src/generated/resources/META-INF/org/apache/camel/component/ibm/cos/ibm-cos.json
 
b/components/camel-ibm/camel-ibm-cos/src/generated/resources/META-INF/org/apache/camel/component/ibm/cos/ibm-cos.json
index 3158ed8eac8c..02e6f53e8496 100644
--- 
a/components/camel-ibm/camel-ibm-cos/src/generated/resources/META-INF/org/apache/camel/component/ibm/cos/ibm-cos.json
+++ 
b/components/camel-ibm/camel-ibm-cos/src/generated/resources/META-INF/org/apache/camel/component/ibm/cos/ibm-cos.json
@@ -77,6 +77,11 @@
     "CamelIBMCOSRangeEnd": { "index": 19, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"Long", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The range end position for partial object 
retrieval", "constantName": 
"org.apache.camel.component.ibm.cos.IBMCOSConstants#RANGE_END" },
     "CamelIBMCOSBucketExists": { "index": 20, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Whether the bucket exists or not", 
"constantName": 
"org.apache.camel.component.ibm.cos.IBMCOSConstants#BUCKET_EXISTS" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "stream" ], "byOption": [ { "option": 
"includeBody", "value": "false", "carriers": [ "null" ] } ], "description": 
"The content of the object as a stream, one message per object, with its key 
and metadata in headers. No body with includeBody=false" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "operation" ], "byOption": [ { "option": "operation", "value": 
"putObject", "carriers": [ "text", "bytes", "stream", "file" ] } ], 
"description": "The content to upload with putObject, the default: text, bytes, 
a stream or a file. A Map, a List or no body fails: marshal it first. The other 
operations take their input from headers" },
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "getObject", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "getObjectRange", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "listObjects", "carriers": [ "list" ], "javaType": 
"java.util.List<com.ibm.cloud.objectstorage.services.s3.model.S3ObjectSummary>" 
}, { "option": "operation", "value": "listBuckets", "carriers": [ "list" ], 
"javaType": "java.util.List<com. [...]
+  },
   "properties": {
     "bucketName": { "index": 0, "kind": "path", "displayName": "Bucket Name", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Bucket name" },
     "autoCreateBucket": { "index": 1, "kind": "parameter", "displayName": 
"Auto Create Bucket", "group": "common", "label": "common", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.ibm.cos.IBMCOSConfiguration", "configurationField": 
"configuration", "description": "Automatically create the bucket if it doesn't 
exist" },
diff --git 
a/components/camel-ibm/camel-ibm-cos/src/main/java/org/apache/camel/component/ibm/cos/IBMCOSEndpoint.java
 
b/components/camel-ibm/camel-ibm-cos/src/main/java/org/apache/camel/component/ibm/cos/IBMCOSEndpoint.java
index dcbafcfd3dc9..4b0a82ec9a95 100644
--- 
a/components/camel-ibm/camel-ibm-cos/src/main/java/org/apache/camel/component/ibm/cos/IBMCOSEndpoint.java
+++ 
b/components/camel-ibm/camel-ibm-cos/src/main/java/org/apache/camel/component/ibm/cos/IBMCOSEndpoint.java
@@ -30,6 +30,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.IdempotentRepository;
 import org.apache.camel.spi.Metadata;
@@ -49,6 +52,37 @@ import org.slf4j.LoggerFactory;
 @UriEndpoint(firstVersion = "4.16.0", scheme = "ibm-cos", title = "IBM Cloud 
Object Storage",
              syntax = "ibm-cos:bucketName", category = { Category.CLOUD, 
Category.FILE },
              headersClass = IBMCOSConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.STREAM,
+                                   byOption = @BodyType.When(option = 
"includeBody", value = "false", carriers = Carrier.NULL),
+                                   description = "The content of the object as 
a stream, one message per object, with its key"
+                                                 + " and metadata in headers. 
No body with includeBody=false"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  dependsOn = "operation",
+                                  byOption = @BodyType.When(option = 
"operation", value = "putObject",
+                                                            carriers = {
+                                                                    
Carrier.TEXT, Carrier.BYTES, Carrier.STREAM,
+                                                                    
Carrier.FILE }),
+                                  description = "The content to upload with 
putObject, the default: text, bytes, a stream or a"
+                                                + " file. A Map, a List or no 
body fails: marshal it first. The other"
+                                                + " operations take their 
input from headers"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   byOption = {
+                                           @BodyType.When(option = 
"operation", value = "getObject", carriers = Carrier.STREAM),
+                                           @BodyType.When(option = 
"operation", value = "getObjectRange",
+                                                          carriers = 
Carrier.STREAM),
+                                           @BodyType.When(option = 
"operation", value = "listObjects", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<com.ibm.cloud.objectstorage.services.s3.model.S3ObjectSummary>"),
+                                           @BodyType.When(option = 
"operation", value = "listBuckets", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<com.ibm.cloud.objectstorage.services.s3.model.Bucket>"),
+                                           @BodyType.When(option = 
"operation", value = "deleteObjects",
+                                                          carriers = 
Carrier.LIST),
+                                           @BodyType.When(option = 
"operation", value = "headBucket", carriers = Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean") },
+                                   description = "Unchanged after putObject 
(with the ETag in a header), copyObject,"
+                                                 + " deleteObject, 
createBucket and deleteBucket. getObject and getObjectRange"
+                                                 + " give the content as a 
stream, listObjects a List of the first page of"
+                                                 + " objects, listBuckets a 
List of Bucket, deleteObjects a List of the deleted"
+                                                 + " objects and headBucket 
whether the bucket exists"))
 public class IBMCOSEndpoint extends ScheduledPollEndpoint implements 
EndpointServiceLocation {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(IBMCOSEndpoint.class);
diff --git 
a/components/camel-minio/src/generated/resources/META-INF/org/apache/camel/component/minio/minio.json
 
b/components/camel-minio/src/generated/resources/META-INF/org/apache/camel/component/minio/minio.json
index 317451362eb3..6ef423af1683 100644
--- 
a/components/camel-minio/src/generated/resources/META-INF/org/apache/camel/component/minio/minio.json
+++ 
b/components/camel-minio/src/generated/resources/META-INF/org/apache/camel/component/minio/minio.json
@@ -99,6 +99,11 @@
     "CamelMinioPresignedURLExpirationTime": { "index": 21, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Expiration of minio presigned url in 
Seconds", "constantName": 
"org.apache.camel.component.minio.MinioConstants#PRESIGNED_URL_EXPIRATION_TIME" 
},
     "CamelMinioOverrideBucketName": { "index": 22, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The bucket Name to override which this 
object will be stored or which will be used for the current operation or in 
which this object is contained.", "constantName": 
"org.apache.camel.component.minio.MinioConstants#OVERRIDE_BUCKET_NAME" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"byOption": [ { "option": "includeBody", "value": "false", "carriers": [ "null" 
] } ], "description": "The content of the object as a byte array, one message 
per object, with its metadata in headers. No body with includeBody=false" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "operation", "pojoRequest" ], "description": "The content to 
upload, when no operation is set: text, bytes, a stream or a file. A Map, a 
List or no body fails: marshal it first. The operations take their input from 
headers, or with pojoRequest=true from the builder of the request of the Minio 
SDK in the body, such as a GetObjectArgs.Builder; deleteObjects works only so" 
},
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "getObject", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "getObjectRange", "carriers": [ "stream" ] }, { "option": 
"operation", "value": "listObjects", "carriers": [ "iterator" ], "javaType": 
"java.lang.Iterable<io.minio.Result<io.minio.messages.Item>>" }, { "option": 
"operation", "value": "listBuckets", "carriers": [ "iterator" ], "javaType": 
"java.util.Iterator<io.minio.m [...]
+  },
   "properties": {
     "bucketName": { "index": 0, "kind": "path", "displayName": "Bucket Name", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.minio.MinioConfiguration", "configurationField": 
"configuration", "description": "Bucket name" },
     "autoCreateBucket": { "index": 1, "kind": "parameter", "displayName": 
"Auto Create Bucket", "group": "common", "label": "common", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.minio.MinioConfiguration", "configurationField": 
"configuration", "description": "Setting the autocreation of the bucket if 
bucket name not exist." },
diff --git a/components/camel-minio/src/main/docs/minio-component.adoc 
b/components/camel-minio/src/main/docs/minio-component.adoc
index a0e2de922b1a..49889d3f5b57 100644
--- a/components/camel-minio/src/main/docs/minio-component.adoc
+++ b/components/camel-minio/src/main/docs/minio-component.adoc
@@ -103,8 +103,8 @@ Camel-Minio component provides the following operation on 
the producer side:
 - `listBuckets`
 - `deleteBucket`
 - `listObjects`
-- `getObject` (this will return a `MinioObject instance)
-- `getObjectRange` (this will return a `MinioObject instance)
+- `getObject` (this will return the content of the object as a stream)
+- `getObjectRange` (this will return the range of the content as a stream)
 - `createDownloadLink` (this will return a Presigned download Url)
 - `createUploadLink` (this will return a Presigned upload url)
 
@@ -450,7 +450,7 @@ YAML::
 ----
 ====
 
-This operation will return a MinioObject instance related to the camelKey 
object in `mycamelbucket` bucket.
+This operation will return the content of the camelKey object in 
`mycamelbucket` bucket as a stream.
 
 - `GetObjectRange`: this operation gets a single object range in a specific 
bucket
 
@@ -514,7 +514,7 @@ YAML::
             uri: mock:result
 ----
 ====
-This operation will return a MinioObject instance related to the camelKey 
object in `mycamelbucket` bucket, containing bytes from 0 to 9.
+This operation will return the bytes from 0 to 9 of the camelKey object in 
`mycamelbucket` bucket as a stream.
 
 - `createDownloadLink`: this operation will return a presigned url through 
which a file can be downloaded using GET method
 
diff --git 
a/components/camel-minio/src/main/java/org/apache/camel/component/minio/MinioEndpoint.java
 
b/components/camel-minio/src/main/java/org/apache/camel/component/minio/MinioEndpoint.java
index 5a9fc6a3f0f7..7461d32599e8 100644
--- 
a/components/camel-minio/src/main/java/org/apache/camel/component/minio/MinioEndpoint.java
+++ 
b/components/camel-minio/src/main/java/org/apache/camel/component/minio/MinioEndpoint.java
@@ -28,6 +28,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Message;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -42,6 +45,47 @@ import static org.apache.camel.util.ObjectHelper.isNotEmpty;
  */
 @UriEndpoint(firstVersion = "3.5.0", scheme = "minio", title = "Minio", syntax 
= "minio:bucketName",
              category = { Category.CLOUD, Category.FILE }, headersClass = 
MinioConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.BYTES, javaType = "byte[]",
+                                   byOption = @BodyType.When(option = 
"includeBody", value = "false", carriers = Carrier.NULL),
+                                   description = "The content of the object as 
a byte array, one message per object, with its"
+                                                 + " metadata in headers. No 
body with includeBody=false"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  dependsOn = { "operation", "pojoRequest" },
+                                  description = "The content to upload, when 
no operation is set: text, bytes, a stream or a"
+                                                + " file. A Map, a List or no 
body fails: marshal it first. The operations take"
+                                                + " their input from headers, 
or with pojoRequest=true from the builder of the"
+                                                + " request of the Minio SDK 
in the body, such as a GetObjectArgs.Builder;"
+                                                + " deleteObjects works only 
so"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   byOption = {
+                                           @BodyType.When(option = 
"operation", value = "getObject", carriers = Carrier.STREAM),
+                                           @BodyType.When(option = 
"operation", value = "getObjectRange",
+                                                          carriers = 
Carrier.STREAM),
+                                           @BodyType.When(option = 
"operation", value = "listObjects",
+                                                          carriers = 
Carrier.ITERATOR,
+                                                          javaType = 
"java.lang.Iterable<io.minio.Result<io.minio.messages.Item>>"),
+                                           @BodyType.When(option = 
"operation", value = "listBuckets",
+                                                          carriers = 
Carrier.ITERATOR,
+                                                          javaType = 
"java.util.Iterator<io.minio.messages.ListAllMyBucketsResult.Bucket>"),
+                                           @BodyType.When(option = 
"operation", value = "deleteObject",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "deleteObjects",
+                                                          carriers = 
Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"operation", value = "deleteBucket", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "createDownloadLink",
+                                                          carriers = 
Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "createUploadLink",
+                                                          carriers = 
Carrier.TEXT,
+                                                          javaType = 
"java.lang.String") },
+                                   description = "Unchanged after an upload 
and a copyObject, with the ETag in a header. By the"
+                                                 + " operation: the stream of 
the object for getObject and getObjectRange, a"
+                                                 + " lazy Iterable of Result 
for listObjects, whose get() gives the Item, an"
+                                                 + " Iterator of Bucket for 
listBuckets, true for the deletes, ok for"
+                                                 + " deleteBucket and the URL 
as text for the links"))
 @Deprecated(since = "4.23")
 public class MinioEndpoint extends ScheduledPollEndpoint implements 
EndpointServiceLocation {
 
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/CatalogBodyTypes.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/CatalogBodyTypes.java
index 897532a0a271..e3640b1b2253 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/CatalogBodyTypes.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/CatalogBodyTypes.java
@@ -100,9 +100,12 @@ final class CatalogBodyTypes {
             return carriers.equals(List.of("unchanged"));
         }
 
-        /** The file as read. */
+        /**
+         * The file as read, such as the GenericFile of the file consumer: the 
file is the only carrier. A blob that is
+         * a stream or a downloaded file is a payload like any other.
+         */
         boolean file() {
-            return carriers.contains("file");
+            return carriers.equals(List.of("file"));
         }
 
         /** The data format of the format, as an unmarshal or a marshal names 
it: json, jacksonXml, csv or yaml. */
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/TextBodyFlow.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/TextBodyFlow.java
index feb84871f8b0..b29bc22a7100 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/TextBodyFlow.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/TextBodyFlow.java
@@ -280,7 +280,7 @@ final class TextBodyFlow {
         if (out.payload()) {
             // the file as read has the format of the files it reads
             return out.file()
-                    ? new Text(consumer + (out.carriers().size() > 1 ? " as " 
+ out.inWords() : ""), fileFormat(from), true)
+                    ? new Text(consumer, fileFormat(from), true)
                     : new Text(consumer + " as " + out.inWords(), 
out.dataFormat());
         }
         return out.data() ? new Parsed(consumer + " as " + out.inWords(), 
out.dataFormat()) : null;
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java
index 0c2af877367d..2422508a73f5 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java
@@ -1081,6 +1081,59 @@ public class TextBodyFlowTest {
                 .contains("to: openai:chat-completion returns it as text: 
unmarshal it first"));
     }
 
+    @Test
+    public void testTheBodyOfObjectStorage() {
+        // getObject gives the stream of the object and the blob consumer the 
stream or the file of the blob, so a field
+        // read needs an unmarshal; an upload names no operation, which the 
component may set, and dropbox search gives a
+        // List
+        String yaml = """
+                - route:
+                    id: get
+                    from:
+                      uri: timer:tick
+                      steps:
+                        - to: aws2-s3:reports?operation=getObject
+                        - setHeader:
+                            name: name
+                            simple: ${body[name]}
+                - route:
+                    id: upload
+                    from:
+                      uri: timer:tick
+                      steps:
+                        - setBody:
+                            constant: '{"name": "Camel"}'
+                        - to: aws2-s3:reports
+                        - setHeader:
+                            name: name
+                            simple: ${body[name]}
+                - route:
+                    id: blob
+                    from:
+                      uri: azure-storage-blob:account/reports
+                      steps:
+                        - setHeader:
+                            name: name
+                            simple: ${body[name]}
+                - route:
+                    id: search
+                    from:
+                      uri: timer:tick
+                      steps:
+                        - to: dropbox:search?query=camel
+                        - setHeader:
+                            name: first
+                            simple: ${body[0]}
+                """;
+        assertThat(lines(yaml)).hasSize(2).anySatisfy(m -> assertThat(m)
+                .contains("route get: simple reads a field of the body 
(${body[name]})")
+                .contains("to: aws2-s3:reports returns it as a stream: 
unmarshal it first"))
+                .anySatisfy(m -> assertThat(m)
+                        .contains("route blob: simple reads a field of the 
body (${body[name]})")
+                        .contains("the body here is still text, not parsed 
data")
+                        .contains("the azure-storage-blob consumer gives it as 
a stream or a file: unmarshal it first"));
+    }
+
     @Test
     public void testOneReportForAStepThatFails() {
         // the first write fails at runtime, so the second does not run with 
this body

Reply via email to