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

commit ad0525e303cb1614fa3c395b2f1d7941c5959e68
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Oct 24 19:57:08 2026 +0200

    CAMEL-24961: Catalog body types for mina, mllp, grpc, thrift, avro, cometd, 
quickfix, jgroups and five more network components (#28413)
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../apache/camel/catalog/components/asterisk.json  |  5 ++
 .../org/apache/camel/catalog/components/avro.json  |  6 +++
 .../apache/camel/catalog/components/cometd.json    |  6 +++
 .../apache/camel/catalog/components/cometds.json   |  6 +++
 .../org/apache/camel/catalog/components/grpc.json  |  6 +++
 .../camel/catalog/components/jgroups-raft.json     |  5 ++
 .../apache/camel/catalog/components/jgroups.json   |  5 ++
 .../camel/catalog/components/lumberjack.json       |  3 ++
 .../apache/camel/catalog/components/mina-sftp.json |  5 ++
 .../org/apache/camel/catalog/components/mina.json  |  6 +++
 .../org/apache/camel/catalog/components/mllp.json  |  6 +++
 .../apache/camel/catalog/components/quickfix.json  |  6 +++
 .../apache/camel/catalog/components/thrift.json    |  6 +++
 .../apache/camel/catalog/docs/avro-component.adoc  |  6 +--
 .../apache/camel/catalog/docs/mllp-component.adoc  |  5 +-
 .../camel/catalog/docs/quickfix-component.adoc     |  8 +--
 .../apache/camel/component/asterisk/asterisk.json  |  5 ++
 .../camel/component/asterisk/AsteriskEndpoint.java | 16 ++++++
 .../org/apache/camel/component/avro/avro.json      |  6 +++
 .../src/main/docs/avro-component.adoc              |  6 +--
 .../apache/camel/component/avro/AvroEndpoint.java  | 22 ++++++++
 .../org/apache/camel/component/cometd/cometd.json  |  6 +++
 .../org/apache/camel/component/cometd/cometds.json |  6 +++
 .../camel/component/cometd/CometdEndpoint.java     | 18 +++++++
 .../org/apache/camel/component/grpc/grpc.json      |  6 +++
 .../apache/camel/component/grpc/GrpcEndpoint.java  | 36 ++++++++++++++
 .../camel/component/jgroups/raft/jgroups-raft.json |  5 ++
 .../jgroups/raft/JGroupsRaftEndpoint.java          | 16 ++++++
 .../apache/camel/component/jgroups/jgroups.json    |  5 ++
 .../camel/component/jgroups/JGroupsEndpoint.java   | 17 +++++++
 .../camel/component/lumberjack/lumberjack.json     |  3 ++
 .../component/lumberjack/LumberjackEndpoint.java   |  7 +++
 .../component/file/remote/mina/mina-sftp.json      |  5 ++
 .../file/remote/mina/MinaSftpEndpoint.java         | 17 +++++++
 .../org/apache/camel/component/mina/mina.json      |  6 +++
 .../apache/camel/component/mina/MinaEndpoint.java  | 58 ++++++++++++++++++++++
 .../org/apache/camel/component/mllp/mllp.json      |  6 +++
 .../camel-mllp/src/main/docs/mllp-component.adoc   |  5 +-
 .../apache/camel/component/mllp/MllpEndpoint.java  | 21 ++++++++
 .../apache/camel/component/quickfixj/quickfix.json |  6 +++
 .../src/main/docs/quickfix-component.adoc          |  8 +--
 .../component/quickfixj/QuickfixjEndpoint.java     | 21 ++++++++
 .../org/apache/camel/component/thrift/thrift.json  |  6 +++
 .../camel/component/thrift/ThriftEndpoint.java     | 22 ++++++++
 44 files changed, 435 insertions(+), 16 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/asterisk.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/asterisk.json
index bbfe2b935598..473fa1f31d1d 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/asterisk.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/asterisk.json
@@ -34,6 +34,11 @@
     "CamelAsteriskContext": { "index": 2, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The name of the context that contains 
the extension to query in case of an ExtensionStateAction.", "constantName": 
"org.apache.camel.component.asterisk.AsteriskConstants#CONTEXT" },
     "CamelAsteriskAction": { "index": 3, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"org.apache.camel.component.asterisk.AsteriskAction", "enum": [ "QUEUE_STATUS", 
"SIP_PEERS", "EXTENSION_STATE" ], "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The Asterisk action to 
do.", "constantName": 
"org.apache.camel.component.asterisk.AsteriskConstants#ACTION" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"org.asteriskjava.manager.event.ManagerEvent", "description": "The AMI event: a 
subclass of ManagerEvent such as NewChannelEvent or HangupEvent, with its 
simple class name in the CamelAsteriskEventName header. The ConnectEvent of the 
login comes first" },
+    "producerIn": { "carriers": [ "any" ], "description": "The body is not 
read: the action comes from the action option or the CamelAsteriskAction 
header, and the extension and context of EXTENSION_STATE from the 
CamelAsteriskExtension and CamelAsteriskContext headers" },
+    "producerOut": { "carriers": [ "pojo" ], "javaType": 
"org.asteriskjava.manager.response.ManagerResponse", "description": "The 
ManagerResponse of the action, such as an ExtensionStateResponse; a 
ManagerError when Asterisk answers with an error. QUEUE_STATUS and SIP_PEERS 
give only the first response, not the events of the list" }
+  },
   "properties": {
     "name": { "index": 0, "kind": "path", "displayName": "Name", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Name of component" },
     "hostname": { "index": 1, "kind": "parameter", "displayName": "Hostname", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The hostname of the asterisk server" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/avro.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/avro.json
index 0085a4f338e0..abbb70fea887 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/avro.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/avro.json
@@ -39,6 +39,12 @@
   "headers": {
     "CamelAvroMessageName": { "index": 0, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The name of the message to send. In consumer overrides 
message name from URI (if any)", "constantName": 
"org.apache.camel.component.avro.AvroConstants#AVRO_MESSAGE_NAME" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "list" ], "javaType": "java.lang.Object[]", 
"byOption": [ { "option": "singleParameter", "value": "true", "carriers": [ 
"unknown" ] } ], "description": "An Object array of the parameters of the 
called message, in the order of the protocol, with the message name in the 
CamelAvroMessageName header. With singleParameter the one parameter itself, 
such as a record" },
+    "consumerReply": { "carriers": [ "any" ], "description": "The response of 
the message, of its type in the protocol, such as the record class; it is not 
converted, so text or a Map fails for a record. Ignored for a message with a 
null response" },
+    "producerIn": { "carriers": [ "list", "pojo", "text", "value" ], 
"description": "An Object array of the parameters of the message, in the order 
of the protocol, or the one parameter itself, such as a record. A 
java.util.List is not unpacked and a Map is not a record: build the parameter 
types of the protocol. The message name comes from the CamelAvroMessageName 
header, or else from the endpoint" },
+    "producerOut": { "carriers": [ "unknown" ], "description": "The response 
of the message, of its type in the protocol, such as the record class; no body 
for a message with a null response" }
+  },
   "properties": {
     "transport": { "index": 0, "kind": "path", "displayName": "Transport", 
"group": "common", "label": "", "required": true, "type": "enum", "javaType": 
"org.apache.camel.component.avro.AvroTransport", "enum": [ "http", "netty" ], 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "configurationClass": 
"org.apache.camel.component.avro.AvroConfiguration", "configurationField": 
"configuration", "description": "Transport to use, can be either http or netty" 
},
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": true, "type": "integer", "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "configurationClass": 
"org.apache.camel.component.avro.AvroConfiguration", "configurationField": 
"configuration", "description": "Port number to use" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/cometd.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/cometd.json
index 03bfd0843d2e..063e7f61f736 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/cometd.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/cometd.json
@@ -40,6 +40,12 @@
     "CometdClientId": { "index": 0, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The clientId of the session", "constantName": 
"org.apache.camel.component.cometd.CometdBinding#COMETD_CLIENT_ID_HEADER_NAME" 
},
     "subscription": { "index": 1, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The subscription", "constantName": 
"org.apache.camel.component.cometd.CometdBinding#COMETD_SUBSCRIPTION_HEADER_NAME"
 }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "value", "map", "list", "null" ], 
"description": "The data of the Bayeux message, parsed from JSON: a String, a 
number or a boolean, a Map for an object, a List for an array, or null. From a 
cometd producer in the same JVM the body that producer sent, as is" },
+    "consumerReply": { "carriers": [ "text", "value", "map", "list" ], 
"description": "Only when the exchange is InOut (exchangePattern=InOut, or set 
in the route): the body the route ends with is sent back to the client that 
published, as JSON. Bytes become an array of numbers; a stream, a file or 
another object is sent as the text of its toString" },
+    "producerIn": { "carriers": [ "text", "value", "map", "list" ], 
"description": "The data published to the channel, sent as JSON to the 
subscribed clients: text, a number or a boolean, a Map or a List. Bytes become 
an array of numbers; a stream, a file or another object is sent as the text of 
its toString: convert it first. The headers go in the ext field of the message" 
},
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Hostname" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": true, "type": "integer", "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Host port number" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/cometds.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/cometds.json
index 2f5c6b83fed0..f45c80ef5ad4 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/cometds.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/cometds.json
@@ -40,6 +40,12 @@
     "CometdClientId": { "index": 0, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The clientId of the session", "constantName": 
"org.apache.camel.component.cometd.CometdBinding#COMETD_CLIENT_ID_HEADER_NAME" 
},
     "subscription": { "index": 1, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The subscription", "constantName": 
"org.apache.camel.component.cometd.CometdBinding#COMETD_SUBSCRIPTION_HEADER_NAME"
 }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "value", "map", "list", "null" ], 
"description": "The data of the Bayeux message, parsed from JSON: a String, a 
number or a boolean, a Map for an object, a List for an array, or null. From a 
cometd producer in the same JVM the body that producer sent, as is" },
+    "consumerReply": { "carriers": [ "text", "value", "map", "list" ], 
"description": "Only when the exchange is InOut (exchangePattern=InOut, or set 
in the route): the body the route ends with is sent back to the client that 
published, as JSON. Bytes become an array of numbers; a stream, a file or 
another object is sent as the text of its toString" },
+    "producerIn": { "carriers": [ "text", "value", "map", "list" ], 
"description": "The data published to the channel, sent as JSON to the 
subscribed clients: text, a number or a boolean, a Map or a List. Bytes become 
an array of numbers; a stream, a file or another object is sent as the text of 
its toString: convert it first. The headers go in the ext field of the message" 
},
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Hostname" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": true, "type": "integer", "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Host port number" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/grpc.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/grpc.json
index d237309749cb..4d235ea68662 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/grpc.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/grpc.json
@@ -34,6 +34,12 @@
     "CamelGrpcUserAgent": { "index": 1, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "If provided, the given agent will prepend the 
gRPC library's user agent information", "constantName": 
"org.apache.camel.component.grpc.GrpcConstants#GRPC_USER_AGENT_HEADER" },
     "CamelGrpcEventType": { "index": 2, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Received event type from the sent request. 
Possible values: onNext onCompleted onError", "constantName": 
"org.apache.camel.component.grpc.GrpcConstants#GRPC_EVENT_TYPE_HEADER" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "byOption": [ { "option": 
"consumerStrategy", "value": "AGGREGATION", "carriers": [ "pojo", "list" ] }, { 
"option": "forwardOnCompleted", "value": "true", "carriers": [ "pojo", "null" ] 
} ], "description": "The protobuf request message of the called method, with 
the method name in the CamelGrpcMethodName header. A streaming request gives 
one exchange per message, or with the AGGREGATION strategy a List of all its 
messages. forwardOnCompleted s [...]
+    "consumerReply": { "carriers": [ "pojo", "list", "null" ], "dependsOn": [ 
"routeControlledStreamObserver" ], "description": "The protobuf response 
message, or a List of them for a streaming response; no body sends an empty 
message. Text, bytes or a Map fail: build the message of the method. With 
routeControlledStreamObserver the route replies through a producer with 
toRouteControlledStreamObserver" },
+    "producerIn": { "carriers": [ "pojo", "list" ], "description": "The 
protobuf request message of the method, or a List of them for a streaming 
request. Text, bytes or a Map fail with an argument type mismatch: build the 
message first" },
+    "producerOut": { "carriers": [ "list" ], "byOption": [ { "option": 
"synchronous", "value": "true", "carriers": [ "pojo", "list" ] }, { "option": 
"producerStrategy", "value": "STREAMING", "carriers": [ "unchanged" ] }, { 
"option": "toRouteControlledStreamObserver", "value": "true", "carriers": [ 
"unchanged" ] } ], "description": "A List of the protobuf response messages. 
With synchronous=true the response message itself, or a List of them for a 
streaming response. With the STREAMING s [...]
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.grpc.GrpcConfiguration", "configurationField": 
"configuration", "description": "The gRPC server host name. This is localhost 
or 0.0.0.0 when being a consumer or remote server host name when using  [...]
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": true, "type": "integer", "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "configurationClass": 
"org.apache.camel.component.grpc.GrpcConfiguration", "configurationField": 
"configuration", "description": "The gRPC local or remote server port" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jgroups-raft.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jgroups-raft.json
index 9275faf86219..9ae0d9b25edf 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jgroups-raft.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jgroups-raft.json
@@ -46,6 +46,11 @@
     "CamelJGroupsRaftSetTimeout": { "index": 10, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Timeout to be used in set() 
operation.", "constantName": 
"org.apache.camel.component.jgroups.raft.JGroupsRaftConstants#HEADER_JGROUPSRAFT_SET_TIMEOUT"
 },
     "CamelJGroupsRaftSetTimeUnit": { "index": 11, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "java.util.concurrent.TimeUnit", "enum": [ "NANOSECONDS", 
"MICROSECONDS", "MILLISECONDS", "SECONDS", "MINUTES", "HOURS", "DAYS" ], 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Timeunit to be used in set() operation.", 
"constantName": "org.apache.camel.component.jgroups.raft.JGrou [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "null" ], "description": "No body: an event 
for each change of the role of this member (only with enableRoleChangeEvents), 
with LEADER or FOLLOWER in the CamelJGroupsRaftEventType header and the state 
of the raft in the other headers" },
+    "producerIn": { "carriers": [ "bytes", "text", "stream", "file" ], 
"description": "The bytes to set() in the replicated log: a byte array, or 
text, a stream or a file converted to bytes. A null body, a Map, a number or a 
POJO has no conversion to bytes and is skipped without an error: nothing is 
set" },
+    "producerOut": { "carriers": [ "bytes", "unchanged" ], "description": "The 
byte array the state machine returns for the set (an empty array with the 
default NopStateMachine), with the state of the raft in the headers. A body 
that was skipped is left as it was" }
+  },
   "properties": {
     "clusterName": { "index": 0, "kind": "path", "displayName": "Cluster 
Name", "group": "common", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The name of the 
JGroupsraft cluster the component should connect to." },
     "enableRoleChangeEvents": { "index": 1, "kind": "parameter", 
"displayName": "Enable Role Change Events", "group": "consumer", "label": 
"consumer", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "If set to true, the consumer endpoint will receive 
roleChange event as well (not just connecting and\/or using the state machine). 
By default it is set to false." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jgroups.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jgroups.json
index 5b19bbf465e0..79a55abbdfa9 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jgroups.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jgroups.json
@@ -39,6 +39,11 @@
     "CamelJGroupsSrc": { "index": 2, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": 
"org.jgroups.Address", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Consumer : The org.jgroups.Address 
instance extracted by org.jgroups.Message.getSrc() method of the consumed 
message. Producer: The custom source org.jgroups.Address of the message to be 
sent.", "constantName": "org.apache.camel.compon [...]
     "CamelJGroupsOriginalMessage": { "index": 3, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "org.jgroups.Message", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The original 
org.jgroups.Message instance from which the body of the consumed message has 
been extracted.", "constantName": 
"org.apache.camel.component.jgroups.JGroupsConstants#HEADER_JGROUPS_ORIGINAL_MESSAGE"
 }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "unknown" ], "dependsOn": [ 
"enableViewMessages" ], "description": "The object the sender put in the 
message, Java-deserialized: what a jgroups producer sent, such as a String, a 
byte array, a Map or a Serializable POJO, if the deserialization filter accepts 
its class. With enableViewMessages an org.jgroups.View also arrives on each 
change of the members of the cluster" },
+    "producerIn": { "carriers": [ "text", "bytes", "value", "map", "list", 
"file", "pojo" ], "description": "The body as is, Java-serialized into the 
message, so it must be Serializable: a stream or another object that is not 
fails with a NotSerializableException. A null body is not sent. The 
CamelJGroupsDest header sends it to one member instead of the cluster" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "clusterName": { "index": 0, "kind": "path", "displayName": "Cluster 
Name", "group": "common", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The name of the JGroups 
cluster the component should connect to." },
     "channelProperties": { "index": 1, "kind": "parameter", "displayName": 
"Channel Properties", "group": "common", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Specifies configuration 
properties of the JChannel used by the endpoint." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/lumberjack.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/lumberjack.json
index f2637d8720d5..654bbc210b4c 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/lumberjack.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/lumberjack.json
@@ -29,6 +29,9 @@
     "sslContextParameters": { "index": 2, "kind": "property", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the default SSL 
configuration to use for all the endpoints. You can also configure it directly 
at the endpoint level." },
     "useGlobalSslContextParameters": { "index": 3, "kind": "property", 
"displayName": "Use Global Ssl Context Parameters", "group": "security", 
"label": "security", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Enable usage of global SSL context 
parameters." }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "map", "list", "text", "value", "null" ], 
"description": "The log event: a Map of its fields, such as message, source and 
host, with the nested objects as Maps and the arrays as Lists. A JSON frame 
that is not an object gives a List, a String, a number, a boolean or null" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"consumer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Network interface on which to listen 
for Lumberjack" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"consumer", "label": "", "required": false, "type": "integer", "javaType": 
"int", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 5044, "description": "Network port on which to listen for 
Lumberjack" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mina-sftp.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mina-sftp.json
index 6cae8c76d1cb..813150fd16b4 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mina-sftp.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mina-sftp.json
@@ -49,6 +49,11 @@
     "CamelFtpReplyCode": { "index": 15, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "important": true, "description": "The FTP client reply code", 
"constantName": 
"org.apache.camel.component.file.remote.FtpConstants#FTP_REPLY_CODE" },
     "CamelFtpReplyString": { "index": 16, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "important": true, "description": "The FTP client reply string", 
"constantName": 
"org.apache.camel.component.file.remote.FtpConstants#FTP_REPLY_STRING" }
   },
+  "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, 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: text, bytes, a stream or a file. A Map or a List fails: 
marshal it first" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.file.remote.mina.MinaSftpConfiguration", 
"configurationField": "configuration", "description": "Hostname of the FTP 
server" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.file.remote.mina.MinaSftpConfiguration", 
"configurationField": "configuration", "description": "Port of the FTP server" 
},
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mina.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mina.json
index 2c014e2d5703..10b6c4d37ed4 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mina.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mina.json
@@ -61,6 +61,12 @@
     "CamelMinaLocalAddress": { "index": 2, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"java.net.SocketAddress", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The socket address of 
local machine that received the message.", "constantName": 
"org.apache.camel.component.mina.MinaConstants#MINA_LOCAL_ADDRESS" },
     "CamelMinaRemoteAddress": { "index": 3, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"java.net.SocketAddress", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The socket address of the 
remote machine that send the message.", "constantName": 
"org.apache.camel.component.mina.MinaConstants#MINA_REMOTE_ADDRESS" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"dependsOn": [ "codec", "objectCodecPattern", "transferExchange" ], "byOption": 
[ { "option": "protocol", "value": "udp", "carriers": [ "bytes" ], "javaType": 
"byte[]" }, { "option": "allowDefaultCodec", "value": "false", "carriers": [ 
"pojo" ], "javaType": "org.apache.mina.core.buffer.IoBuffer" } ], 
"description": "The data received as a String: one line with textline=true. The 
default object codec over TCP acc [...]
+    "consumerReply": { "carriers": [ "null", "text" ], "dependsOn": [ "codec", 
"transferExchange" ], "byOption": [ { "option": "protocol", "value": "udp", 
"carriers": [ "null", "text", "bytes", "stream", "file" ] }, { "option": 
"allowDefaultCodec", "value": "false", "carriers": [ "null", "pojo" ], 
"javaType": "org.apache.mina.core.buffer.IoBuffer" } ], "description": "The 
body the route ends with is written back to the caller, also with sync=false. 
Send a String: with textline=true other [...]
+    "producerIn": { "carriers": [ "null", "text" ], "dependsOn": [ "codec", 
"transferExchange" ], "byOption": [ { "option": "textline", "value": "true", 
"carriers": [ "any" ] }, { "option": "protocol", "value": "udp", "carriers": [ 
"null", "text", "bytes", "stream", "file" ] }, { "option": "allowDefaultCodec", 
"value": "false", "carriers": [ "null", "pojo" ], "javaType": 
"org.apache.mina.core.buffer.IoBuffer" } ], "description": "The data to send: a 
String. The default object codec over  [...]
+    "producerOut": { "carriers": [ "text", "null" ], "javaType": 
"java.lang.String", "dependsOn": [ "codec", "objectCodecPattern", 
"transferExchange" ], "byOption": [ { "option": "sync", "value": "false", 
"carriers": [ "unchanged", "null" ] }, { "option": "protocol", "value": "udp", 
"carriers": [ "bytes", "null" ], "javaType": "byte[]" }, { "option": 
"allowDefaultCodec", "value": "false", "carriers": [ "pojo", "null" ], 
"javaType": "org.apache.mina.core.buffer.IoBuffer" } ], "description [...]
+  },
   "properties": {
     "protocol": { "index": 0, "kind": "path", "displayName": "Protocol", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mina.MinaConfiguration", "configurationField": 
"configuration", "description": "Protocol to use" },
     "host": { "index": 1, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mina.MinaConfiguration", "configurationField": 
"configuration", "description": "Hostname to use. Use localhost or 0.0.0.0 for 
local server as consumer. For producer use the hostname or ip address  [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mllp.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mllp.json
index fe54a6d99450..43f0221ec6c1 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mllp.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mllp.json
@@ -85,6 +85,12 @@
     "CamelMllpVersionId": { "index": 21, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "MSH-12 value", "constantName": 
"org.apache.camel.component.mllp.MllpConstants#MLLP_VERSION_ID" },
     "CamelMllpCharset": { "index": 22, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "MSH-18 value", "constantName": 
"org.apache.camel.component.mllp.MllpConstants#MLLP_CHARSET" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"byOption": [ { "option": "stringPayload", "value": "false", "carriers": [ 
"bytes" ], "javaType": "byte[]" } ], "description": "The HL7 message without 
the MLLP envelope, as a String in the charset of MSH-18 or charsetName, or a 
byte array with stringPayload=false" },
+    "consumerReply": { "carriers": [ "any" ], "description": "The body is not 
sent back: the acknowledgement is the CamelMllpAcknowledgement or 
CamelMllpAcknowledgementString exchange property, or with autoAck an HL7 ACK 
(AA, or AE when the exchange failed)" },
+    "producerIn": { "carriers": [ "text", "bytes" ], "description": "The HL7 
message as a String or a byte array. No body fails; another body, such as a 
stream, is sent as an empty message: convert it to a String first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "The body is 
left as it was: with InOut the acknowledgement is in the 
CamelMllpAcknowledgement (byte array) and CamelMllpAcknowledgementString 
headers" }
+  },
   "properties": {
     "hostname": { "index": 0, "kind": "path", "displayName": "Hostname", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Hostname or IP for connection for the 
TCP connection. The default value is null, which means any local IP address" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": true, "type": "integer", "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Port number for the TCP connection" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/quickfix.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/quickfix.json
index eb9913659561..e4a007573f98 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/quickfix.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/quickfix.json
@@ -38,6 +38,12 @@
     "SessionID": { "index": 1, "kind": "header", "displayName": "", "group": 
"common", "label": "", "required": false, "javaType": "quickfix.SessionID", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The FIX message SessionID.", "constantName": 
"org.apache.camel.component.quickfixj.QuickfixjEndpoint#SESSION_ID_KEY" },
     "MessageType": { "index": 2, "kind": "header", "displayName": "", "group": 
"common", "label": "", "required": false, "javaType": "String", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "The FIX MsgType tag value.", "constantName": 
"org.apache.camel.component.quickfixj.QuickfixjEndpoint#MESSAGE_TYPE_KEY" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo", "null" ], "description": "The FIX 
message: a quickfix.Message, such as a quickfix.fix44.Email, with the kind of 
event in the EventCategory header and the MsgType in the MessageType header. 
SessionCreated, SessionLogon and SessionLogoff events have no body" },
+    "consumerReply": { "carriers": [ "pojo", "text", "bytes" ], "description": 
"With exchangePattern=InOut, the reply sent back on the session of the request: 
a quickfix.Message, or the FIX message as text or bytes. Every event is 
answered with the body the route ends with: a route that sets no reply sends 
back the message it received" },
+    "producerIn": { "carriers": [ "pojo", "text", "bytes" ], "description": 
"The FIX message to send: a quickfix.Message, or the FIX message as text or 
bytes, parsed with the DataDictionary exchange property or the data dictionary 
of the session. A stream, a Map or no body fails" },
+    "producerOut": { "carriers": [ "unchanged", "pojo" ], "description": "The 
body is left as it was. An InOut exchange waits for the reply that matches the 
CorrelationCriteria exchange property, and the reply quickfix.Message is the 
body" }
+  },
   "properties": {
     "configurationName": { "index": 0, "kind": "path", "displayName": 
"Configuration Name", "group": "common", "label": "", "required": true, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"supportFileReference": true, "description": "Path to the quickfix 
configuration file. You can prefix with: classpath, file, http, ref, or bean. 
classpath, file and http loads the configuration file using these protocol [...]
     "lazyCreateEngine": { "index": 1, "kind": "parameter", "displayName": 
"Lazy Create Engine", "group": "common", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "This option 
allows creating QuickFIX\/J engine on demand. Value true means the engine is 
started when first message is send or there's consumer configured in route 
definition. When false value is used, the  [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/thrift.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/thrift.json
index 0826fcc5dc0a..c5bcd0520b7d 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/thrift.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/thrift.json
@@ -32,6 +32,12 @@
   "headers": {
     "CamelThriftMethodName": { "index": 0, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Method name handled by the consumer service", 
"constantName": 
"org.apache.camel.component.thrift.ThriftConstants#THRIFT_METHOD_NAME_HEADER" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "list", "null" ], "byOption": [ { "option": 
"synchronous", "value": "true", "carriers": [ "list" ] } ], "description": "A 
List of the arguments of the called method, in the order of the IDL, with the 
method name in the CamelThriftMethodName header. A method without arguments 
gives no body, or an empty List with synchronous=true" },
+    "consumerReply": { "carriers": [ "any" ], "description": "The result of 
the method: the body is converted to its return type, so text works for an i32, 
and a struct result needs the Thrift struct. Ignored for a void method. A body 
that does not convert gives the client an error, or a null result from the 
asynchronous server" },
+    "producerIn": { "carriers": [ "list", "pojo", "text", "null" ], 
"description": "A List of the arguments of the method, in the order of the IDL; 
a body that is not a List is the one argument, no body calls a method without 
arguments. A binary argument is a ByteBuffer, not a byte array; a method whose 
one argument is a list needs it wrapped in a List" },
+    "producerOut": { "carriers": [ "unknown" ], "description": "The result of 
the method, of its return type in the IDL: a number, a boolean, a String, a 
ByteBuffer, a Thrift struct, or a List, Set or Map; no body for a void or 
oneway method" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.thrift.ThriftConfiguration", "configurationField": 
"configuration", "description": "The Thrift server host name. This is localhost 
or 0.0.0.0 (if not defined) when being a consumer or remote serve [...]
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": true, "type": "integer", "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "configurationClass": 
"org.apache.camel.component.thrift.ThriftConfiguration", "configurationField": 
"configuration", "description": "The Thrift server port" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/avro-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/avro-component.adoc
index 3372b143f5c2..373ff320112a 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/avro-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/avro-component.adoc
@@ -343,9 +343,9 @@ YAML::
 ====
 
 In the example above, get takes only one parameter, so `singleParameter`
-is used and `getProcessor` will receive Value class directly in body,
-while `putProcessor` will receive an array of size 2 with `String` key and
-`Value` value filled as array contents.
+is used and `getProcessor` will receive the `Key` directly in the body,
+while `putProcessor` will receive an array of size 2 with the `Key` and the
+`Value` as its contents.
 
 
 === Avro via HTTP SPI
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mllp-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mllp-component.adoc
index 0321f09b751f..383a40fc1504 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mllp-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mllp-component.adoc
@@ -30,8 +30,9 @@ The component supports the following:
 * A Camel consumer using a TCP Server
 * A Camel producer using a TCP Client
 
-The MLLP component use `byte[]` payloads, and relies on Camel type
-conversion to convert `byte[]` to other types.
+The MLLP consumer gives the HL7 payload as a `String` by default
+(`stringPayload=true`), or as a `byte[]` with `stringPayload=false`.
+The MLLP producer sends a `String` or a `byte[]` body.
 
 Maven users will need to add the following dependency to their pom.xml
 for this component:
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/quickfix-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/quickfix-component.adoc
index 241f122c6170..61d92dbca9fa 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/quickfix-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/quickfix-component.adoc
@@ -307,9 +307,11 @@ The correlation criteria is defined with a 
`MessagePredicate` object.
 The following example will treat
 a FIX `ExecutionReport` from the specified session where the transaction
 type is STATUS and the Order ID
-matches our request. The session ID should be for the __requestor__, the
-sender and target CompID fields
-will be reversed when looking for the reply.
+matches our request. The SenderCompID and TargetCompID of the session ID are
+matched as given against the header of the reply, so use the session ID as
+the __replier__ sees it: for a request sent on `FIX.4.2:TRADER->MARKET`, use
+`FIX.4.2:MARKET->TRADER`. The correlation criteria is required for an InOut
+exchange.
 
 ._Java-only: programmatic correlation criteria setup using QuickFIX/J API_
 [source,java]
diff --git 
a/components/camel-asterisk/src/generated/resources/META-INF/org/apache/camel/component/asterisk/asterisk.json
 
b/components/camel-asterisk/src/generated/resources/META-INF/org/apache/camel/component/asterisk/asterisk.json
index bbfe2b935598..473fa1f31d1d 100644
--- 
a/components/camel-asterisk/src/generated/resources/META-INF/org/apache/camel/component/asterisk/asterisk.json
+++ 
b/components/camel-asterisk/src/generated/resources/META-INF/org/apache/camel/component/asterisk/asterisk.json
@@ -34,6 +34,11 @@
     "CamelAsteriskContext": { "index": 2, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The name of the context that contains 
the extension to query in case of an ExtensionStateAction.", "constantName": 
"org.apache.camel.component.asterisk.AsteriskConstants#CONTEXT" },
     "CamelAsteriskAction": { "index": 3, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"org.apache.camel.component.asterisk.AsteriskAction", "enum": [ "QUEUE_STATUS", 
"SIP_PEERS", "EXTENSION_STATE" ], "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The Asterisk action to 
do.", "constantName": 
"org.apache.camel.component.asterisk.AsteriskConstants#ACTION" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"org.asteriskjava.manager.event.ManagerEvent", "description": "The AMI event: a 
subclass of ManagerEvent such as NewChannelEvent or HangupEvent, with its 
simple class name in the CamelAsteriskEventName header. The ConnectEvent of the 
login comes first" },
+    "producerIn": { "carriers": [ "any" ], "description": "The body is not 
read: the action comes from the action option or the CamelAsteriskAction 
header, and the extension and context of EXTENSION_STATE from the 
CamelAsteriskExtension and CamelAsteriskContext headers" },
+    "producerOut": { "carriers": [ "pojo" ], "javaType": 
"org.asteriskjava.manager.response.ManagerResponse", "description": "The 
ManagerResponse of the action, such as an ExtensionStateResponse; a 
ManagerError when Asterisk answers with an error. QUEUE_STATUS and SIP_PEERS 
give only the first response, not the events of the list" }
+  },
   "properties": {
     "name": { "index": 0, "kind": "path", "displayName": "Name", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Name of component" },
     "hostname": { "index": 1, "kind": "parameter", "displayName": "Hostname", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The hostname of the asterisk server" },
diff --git 
a/components/camel-asterisk/src/main/java/org/apache/camel/component/asterisk/AsteriskEndpoint.java
 
b/components/camel-asterisk/src/main/java/org/apache/camel/component/asterisk/AsteriskEndpoint.java
index fa8666cff371..88d35537b63d 100644
--- 
a/components/camel-asterisk/src/main/java/org/apache/camel/component/asterisk/AsteriskEndpoint.java
+++ 
b/components/camel-asterisk/src/main/java/org/apache/camel/component/asterisk/AsteriskEndpoint.java
@@ -22,6 +22,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.Metadata;
 import org.apache.camel.spi.UriEndpoint;
@@ -35,6 +38,19 @@ import org.apache.camel.util.ObjectHelper;
  */
 @UriEndpoint(firstVersion = "2.18.0", scheme = "asterisk", title = "Asterisk", 
syntax = "asterisk:name",
              category = { Category.MOBILE }, headersClass = 
AsteriskConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO, javaType = 
"org.asteriskjava.manager.event.ManagerEvent",
+                                   description = "The AMI event: a subclass of 
ManagerEvent such as NewChannelEvent or"
+                                                 + " HangupEvent, with its 
simple class name in the CamelAsteriskEventName"
+                                                 + " header. The ConnectEvent 
of the login comes first"),
+           producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "The body is not read: the 
action comes from the action option or the"
+                                                + " CamelAsteriskAction 
header, and the extension and context of"
+                                                + " EXTENSION_STATE from the 
CamelAsteriskExtension and"
+                                                + " CamelAsteriskContext 
headers"),
+           producerOut = @BodyType(value = Carrier.POJO, javaType = 
"org.asteriskjava.manager.response.ManagerResponse",
+                                   description = "The ManagerResponse of the 
action, such as an ExtensionStateResponse; a"
+                                                 + " ManagerError when 
Asterisk answers with an error. QUEUE_STATUS and"
+                                                 + " SIP_PEERS give only the 
first response, not the events of the list"))
 public class AsteriskEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
     @UriPath(description = "Name of component")
     @Metadata(required = true)
diff --git 
a/components/camel-avro-rpc/camel-avro-rpc-component/src/generated/resources/META-INF/org/apache/camel/component/avro/avro.json
 
b/components/camel-avro-rpc/camel-avro-rpc-component/src/generated/resources/META-INF/org/apache/camel/component/avro/avro.json
index 0085a4f338e0..abbb70fea887 100644
--- 
a/components/camel-avro-rpc/camel-avro-rpc-component/src/generated/resources/META-INF/org/apache/camel/component/avro/avro.json
+++ 
b/components/camel-avro-rpc/camel-avro-rpc-component/src/generated/resources/META-INF/org/apache/camel/component/avro/avro.json
@@ -39,6 +39,12 @@
   "headers": {
     "CamelAvroMessageName": { "index": 0, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The name of the message to send. In consumer overrides 
message name from URI (if any)", "constantName": 
"org.apache.camel.component.avro.AvroConstants#AVRO_MESSAGE_NAME" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "list" ], "javaType": "java.lang.Object[]", 
"byOption": [ { "option": "singleParameter", "value": "true", "carriers": [ 
"unknown" ] } ], "description": "An Object array of the parameters of the 
called message, in the order of the protocol, with the message name in the 
CamelAvroMessageName header. With singleParameter the one parameter itself, 
such as a record" },
+    "consumerReply": { "carriers": [ "any" ], "description": "The response of 
the message, of its type in the protocol, such as the record class; it is not 
converted, so text or a Map fails for a record. Ignored for a message with a 
null response" },
+    "producerIn": { "carriers": [ "list", "pojo", "text", "value" ], 
"description": "An Object array of the parameters of the message, in the order 
of the protocol, or the one parameter itself, such as a record. A 
java.util.List is not unpacked and a Map is not a record: build the parameter 
types of the protocol. The message name comes from the CamelAvroMessageName 
header, or else from the endpoint" },
+    "producerOut": { "carriers": [ "unknown" ], "description": "The response 
of the message, of its type in the protocol, such as the record class; no body 
for a message with a null response" }
+  },
   "properties": {
     "transport": { "index": 0, "kind": "path", "displayName": "Transport", 
"group": "common", "label": "", "required": true, "type": "enum", "javaType": 
"org.apache.camel.component.avro.AvroTransport", "enum": [ "http", "netty" ], 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "configurationClass": 
"org.apache.camel.component.avro.AvroConfiguration", "configurationField": 
"configuration", "description": "Transport to use, can be either http or netty" 
},
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": true, "type": "integer", "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "configurationClass": 
"org.apache.camel.component.avro.AvroConfiguration", "configurationField": 
"configuration", "description": "Port number to use" },
diff --git 
a/components/camel-avro-rpc/camel-avro-rpc-component/src/main/docs/avro-component.adoc
 
b/components/camel-avro-rpc/camel-avro-rpc-component/src/main/docs/avro-component.adoc
index 3372b143f5c2..373ff320112a 100644
--- 
a/components/camel-avro-rpc/camel-avro-rpc-component/src/main/docs/avro-component.adoc
+++ 
b/components/camel-avro-rpc/camel-avro-rpc-component/src/main/docs/avro-component.adoc
@@ -343,9 +343,9 @@ YAML::
 ====
 
 In the example above, get takes only one parameter, so `singleParameter`
-is used and `getProcessor` will receive Value class directly in body,
-while `putProcessor` will receive an array of size 2 with `String` key and
-`Value` value filled as array contents.
+is used and `getProcessor` will receive the `Key` directly in the body,
+while `putProcessor` will receive an array of size 2 with the `Key` and the
+`Value` as its contents.
 
 
 === Avro via HTTP SPI
diff --git 
a/components/camel-avro-rpc/camel-avro-rpc-component/src/main/java/org/apache/camel/component/avro/AvroEndpoint.java
 
b/components/camel-avro-rpc/camel-avro-rpc-component/src/main/java/org/apache/camel/component/avro/AvroEndpoint.java
index d5fde4529303..2dd1c4aefe54 100644
--- 
a/components/camel-avro-rpc/camel-avro-rpc-component/src/main/java/org/apache/camel/component/avro/AvroEndpoint.java
+++ 
b/components/camel-avro-rpc/camel-avro-rpc-component/src/main/java/org/apache/camel/component/avro/AvroEndpoint.java
@@ -28,6 +28,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.avro.support.AvroClassSecuritySupport;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.support.DefaultEndpoint;
@@ -37,6 +40,25 @@ import org.apache.camel.support.DefaultEndpoint;
  */
 @UriEndpoint(firstVersion = "2.10.0", scheme = "avro", title = "Avro RPC", 
syntax = "avro:transport:host:port/messageName",
              category = { Category.RPC }, headersClass = AvroConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.LIST, javaType = 
"java.lang.Object[]",
+                                   byOption = @BodyType.When(option = 
"singleParameter", value = "true",
+                                                             carriers = 
Carrier.UNKNOWN),
+                                   description = "An Object array of the 
parameters of the called message, in the order of"
+                                                 + " the protocol, with the 
message name in the CamelAvroMessageName header."
+                                                 + " With singleParameter the 
one parameter itself, such as a record"),
+           consumerReply = @BodyType(value = Carrier.ANY,
+                                     description = "The response of the 
message, of its type in the protocol, such as the"
+                                                   + " record class; it is not 
converted, so text or a Map fails for a record."
+                                                   + " Ignored for a message 
with a null response"),
+           producerIn = @BodyType(value = { Carrier.LIST, Carrier.POJO, 
Carrier.TEXT, Carrier.VALUE },
+                                  description = "An Object array of the 
parameters of the message, in the order of the"
+                                                + " protocol, or the one 
parameter itself, such as a record. A java.util.List"
+                                                + " is not unpacked and a Map 
is not a record: build the parameter types of"
+                                                + " the protocol. The message 
name comes from the CamelAvroMessageName header,"
+                                                + " or else from the 
endpoint"),
+           producerOut = @BodyType(value = Carrier.UNKNOWN,
+                                   description = "The response of the message, 
of its type in the protocol, such as the"
+                                                 + " record class; no body for 
a message with a null response"))
 public abstract class AvroEndpoint extends DefaultEndpoint implements 
AsyncEndpoint {
 
     @UriParam
diff --git 
a/components/camel-cometd/src/generated/resources/META-INF/org/apache/camel/component/cometd/cometd.json
 
b/components/camel-cometd/src/generated/resources/META-INF/org/apache/camel/component/cometd/cometd.json
index 03bfd0843d2e..063e7f61f736 100644
--- 
a/components/camel-cometd/src/generated/resources/META-INF/org/apache/camel/component/cometd/cometd.json
+++ 
b/components/camel-cometd/src/generated/resources/META-INF/org/apache/camel/component/cometd/cometd.json
@@ -40,6 +40,12 @@
     "CometdClientId": { "index": 0, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The clientId of the session", "constantName": 
"org.apache.camel.component.cometd.CometdBinding#COMETD_CLIENT_ID_HEADER_NAME" 
},
     "subscription": { "index": 1, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The subscription", "constantName": 
"org.apache.camel.component.cometd.CometdBinding#COMETD_SUBSCRIPTION_HEADER_NAME"
 }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "value", "map", "list", "null" ], 
"description": "The data of the Bayeux message, parsed from JSON: a String, a 
number or a boolean, a Map for an object, a List for an array, or null. From a 
cometd producer in the same JVM the body that producer sent, as is" },
+    "consumerReply": { "carriers": [ "text", "value", "map", "list" ], 
"description": "Only when the exchange is InOut (exchangePattern=InOut, or set 
in the route): the body the route ends with is sent back to the client that 
published, as JSON. Bytes become an array of numbers; a stream, a file or 
another object is sent as the text of its toString" },
+    "producerIn": { "carriers": [ "text", "value", "map", "list" ], 
"description": "The data published to the channel, sent as JSON to the 
subscribed clients: text, a number or a boolean, a Map or a List. Bytes become 
an array of numbers; a stream, a file or another object is sent as the text of 
its toString: convert it first. The headers go in the ext field of the message" 
},
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Hostname" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": true, "type": "integer", "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Host port number" },
diff --git 
a/components/camel-cometd/src/generated/resources/META-INF/org/apache/camel/component/cometd/cometds.json
 
b/components/camel-cometd/src/generated/resources/META-INF/org/apache/camel/component/cometd/cometds.json
index 2f5c6b83fed0..f45c80ef5ad4 100644
--- 
a/components/camel-cometd/src/generated/resources/META-INF/org/apache/camel/component/cometd/cometds.json
+++ 
b/components/camel-cometd/src/generated/resources/META-INF/org/apache/camel/component/cometd/cometds.json
@@ -40,6 +40,12 @@
     "CometdClientId": { "index": 0, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The clientId of the session", "constantName": 
"org.apache.camel.component.cometd.CometdBinding#COMETD_CLIENT_ID_HEADER_NAME" 
},
     "subscription": { "index": 1, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The subscription", "constantName": 
"org.apache.camel.component.cometd.CometdBinding#COMETD_SUBSCRIPTION_HEADER_NAME"
 }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text", "value", "map", "list", "null" ], 
"description": "The data of the Bayeux message, parsed from JSON: a String, a 
number or a boolean, a Map for an object, a List for an array, or null. From a 
cometd producer in the same JVM the body that producer sent, as is" },
+    "consumerReply": { "carriers": [ "text", "value", "map", "list" ], 
"description": "Only when the exchange is InOut (exchangePattern=InOut, or set 
in the route): the body the route ends with is sent back to the client that 
published, as JSON. Bytes become an array of numbers; a stream, a file or 
another object is sent as the text of its toString" },
+    "producerIn": { "carriers": [ "text", "value", "map", "list" ], 
"description": "The data published to the channel, sent as JSON to the 
subscribed clients: text, a number or a boolean, a Map or a List. Bytes become 
an array of numbers; a stream, a file or another object is sent as the text of 
its toString: convert it first. The headers go in the ext field of the message" 
},
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Hostname" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": true, "type": "integer", "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Host port number" },
diff --git 
a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdEndpoint.java
 
b/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdEndpoint.java
index 59c9d709cd63..8cbf8c62edb4 100644
--- 
a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdEndpoint.java
+++ 
b/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdEndpoint.java
@@ -23,6 +23,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.HeaderFilterStrategy;
 import org.apache.camel.spi.Metadata;
@@ -40,6 +43,21 @@ import org.apache.camel.util.ObjectHelper;
  */
 @UriEndpoint(firstVersion = "2.0.0", scheme = "cometd,cometds", title = 
"CometD", syntax = "cometd:host:port/channelName",
              category = { Category.NETWORKING, Category.MESSAGING }, 
headersClass = CometdBinding.class)
+@BodyTypes(consumerOut = @BodyType(value = { Carrier.TEXT, Carrier.VALUE, 
Carrier.MAP, Carrier.LIST, Carrier.NULL },
+                                   description = "The data of the Bayeux 
message, parsed from JSON: a String, a number or a"
+                                                 + " boolean, a Map for an 
object, a List for an array, or null. From a cometd"
+                                                 + " producer in the same JVM 
the body that producer sent, as is"),
+           consumerReply = @BodyType(value = { Carrier.TEXT, Carrier.VALUE, 
Carrier.MAP, Carrier.LIST },
+                                     description = "Only when the exchange is 
InOut (exchangePattern=InOut, or set in the"
+                                                   + " route): the body the 
route ends with is sent back to the client that"
+                                                   + " published, as JSON. 
Bytes become an array of numbers; a stream, a file"
+                                                   + " or another object is 
sent as the text of its toString"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.VALUE, 
Carrier.MAP, Carrier.LIST },
+                                  description = "The data published to the 
channel, sent as JSON to the subscribed clients:"
+                                                + " text, a number or a 
boolean, a Map or a List. Bytes become an array of"
+                                                + " numbers; a stream, a file 
or another object is sent as the text of its"
+                                                + " toString: convert it 
first. The headers go in the ext field of the message"),
+           producerOut = @BodyType(Carrier.UNCHANGED))
 public class CometdEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
 
     private CometdComponent component;
diff --git 
a/components/camel-grpc/src/generated/resources/META-INF/org/apache/camel/component/grpc/grpc.json
 
b/components/camel-grpc/src/generated/resources/META-INF/org/apache/camel/component/grpc/grpc.json
index d237309749cb..4d235ea68662 100644
--- 
a/components/camel-grpc/src/generated/resources/META-INF/org/apache/camel/component/grpc/grpc.json
+++ 
b/components/camel-grpc/src/generated/resources/META-INF/org/apache/camel/component/grpc/grpc.json
@@ -34,6 +34,12 @@
     "CamelGrpcUserAgent": { "index": 1, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "If provided, the given agent will prepend the 
gRPC library's user agent information", "constantName": 
"org.apache.camel.component.grpc.GrpcConstants#GRPC_USER_AGENT_HEADER" },
     "CamelGrpcEventType": { "index": 2, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Received event type from the sent request. 
Possible values: onNext onCompleted onError", "constantName": 
"org.apache.camel.component.grpc.GrpcConstants#GRPC_EVENT_TYPE_HEADER" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "byOption": [ { "option": 
"consumerStrategy", "value": "AGGREGATION", "carriers": [ "pojo", "list" ] }, { 
"option": "forwardOnCompleted", "value": "true", "carriers": [ "pojo", "null" ] 
} ], "description": "The protobuf request message of the called method, with 
the method name in the CamelGrpcMethodName header. A streaming request gives 
one exchange per message, or with the AGGREGATION strategy a List of all its 
messages. forwardOnCompleted s [...]
+    "consumerReply": { "carriers": [ "pojo", "list", "null" ], "dependsOn": [ 
"routeControlledStreamObserver" ], "description": "The protobuf response 
message, or a List of them for a streaming response; no body sends an empty 
message. Text, bytes or a Map fail: build the message of the method. With 
routeControlledStreamObserver the route replies through a producer with 
toRouteControlledStreamObserver" },
+    "producerIn": { "carriers": [ "pojo", "list" ], "description": "The 
protobuf request message of the method, or a List of them for a streaming 
request. Text, bytes or a Map fail with an argument type mismatch: build the 
message first" },
+    "producerOut": { "carriers": [ "list" ], "byOption": [ { "option": 
"synchronous", "value": "true", "carriers": [ "pojo", "list" ] }, { "option": 
"producerStrategy", "value": "STREAMING", "carriers": [ "unchanged" ] }, { 
"option": "toRouteControlledStreamObserver", "value": "true", "carriers": [ 
"unchanged" ] } ], "description": "A List of the protobuf response messages. 
With synchronous=true the response message itself, or a List of them for a 
streaming response. With the STREAMING s [...]
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.grpc.GrpcConfiguration", "configurationField": 
"configuration", "description": "The gRPC server host name. This is localhost 
or 0.0.0.0 when being a consumer or remote server host name when using  [...]
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": true, "type": "integer", "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "configurationClass": 
"org.apache.camel.component.grpc.GrpcConfiguration", "configurationField": 
"configuration", "description": "The gRPC local or remote server port" },
diff --git 
a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcEndpoint.java
 
b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcEndpoint.java
index cc262e828931..ec7ace7f6be5 100644
--- 
a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcEndpoint.java
+++ 
b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcEndpoint.java
@@ -20,6 +20,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.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -35,6 +38,39 @@ import org.apache.camel.util.ObjectHelper;
 @Metadata(annotations = {
         "protocol=http",
 })
+@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO,
+                                   byOption = {
+                                           @BodyType.When(option = 
"consumerStrategy", value = "AGGREGATION",
+                                                          carriers = { 
Carrier.POJO, Carrier.LIST }),
+                                           @BodyType.When(option = 
"forwardOnCompleted", value = "true",
+                                                          carriers = { 
Carrier.POJO, Carrier.NULL }) },
+                                   description = "The protobuf request message 
of the called method, with the method name in"
+                                                 + " the CamelGrpcMethodName 
header. A streaming request gives one exchange per"
+                                                 + " message, or with the 
AGGREGATION strategy a List of all its messages."
+                                                 + " forwardOnCompleted sends 
no body at the end of the stream, forwardOnError"
+                                                 + " the Throwable"),
+           consumerReply = @BodyType(value = { Carrier.POJO, Carrier.LIST, 
Carrier.NULL },
+                                     dependsOn = 
"routeControlledStreamObserver",
+                                     description = "The protobuf response 
message, or a List of them for a streaming response;"
+                                                   + " no body sends an empty 
message. Text, bytes or a Map fail: build the"
+                                                   + " message of the method. 
With routeControlledStreamObserver the route"
+                                                   + " replies through a 
producer with toRouteControlledStreamObserver"),
+           producerIn = @BodyType(value = { Carrier.POJO, Carrier.LIST },
+                                  description = "The protobuf request message 
of the method, or a List of them for a"
+                                                + " streaming request. Text, 
bytes or a Map fail with an argument type"
+                                                + " mismatch: build the 
message first"),
+           producerOut = @BodyType(value = Carrier.LIST,
+                                   byOption = {
+                                           @BodyType.When(option = 
"synchronous", value = "true",
+                                                          carriers = { 
Carrier.POJO, Carrier.LIST }),
+                                           @BodyType.When(option = 
"producerStrategy", value = "STREAMING",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"toRouteControlledStreamObserver", value = "true",
+                                                          carriers = 
Carrier.UNCHANGED) },
+                                   description = "A List of the protobuf 
response messages. With synchronous=true the"
+                                                 + " response message itself, 
or a List of them for a streaming response."
+                                                 + " With the STREAMING 
strategy the body is unchanged and each response goes"
+                                                 + " to the streamRepliesTo 
endpoint"))
 public class GrpcEndpoint extends DefaultEndpoint {
     @UriParam
     protected final GrpcConfiguration configuration;
diff --git 
a/components/camel-jgroups-raft/src/generated/resources/META-INF/org/apache/camel/component/jgroups/raft/jgroups-raft.json
 
b/components/camel-jgroups-raft/src/generated/resources/META-INF/org/apache/camel/component/jgroups/raft/jgroups-raft.json
index 9275faf86219..9ae0d9b25edf 100644
--- 
a/components/camel-jgroups-raft/src/generated/resources/META-INF/org/apache/camel/component/jgroups/raft/jgroups-raft.json
+++ 
b/components/camel-jgroups-raft/src/generated/resources/META-INF/org/apache/camel/component/jgroups/raft/jgroups-raft.json
@@ -46,6 +46,11 @@
     "CamelJGroupsRaftSetTimeout": { "index": 10, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Timeout to be used in set() 
operation.", "constantName": 
"org.apache.camel.component.jgroups.raft.JGroupsRaftConstants#HEADER_JGROUPSRAFT_SET_TIMEOUT"
 },
     "CamelJGroupsRaftSetTimeUnit": { "index": 11, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "java.util.concurrent.TimeUnit", "enum": [ "NANOSECONDS", 
"MICROSECONDS", "MILLISECONDS", "SECONDS", "MINUTES", "HOURS", "DAYS" ], 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Timeunit to be used in set() operation.", 
"constantName": "org.apache.camel.component.jgroups.raft.JGrou [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "null" ], "description": "No body: an event 
for each change of the role of this member (only with enableRoleChangeEvents), 
with LEADER or FOLLOWER in the CamelJGroupsRaftEventType header and the state 
of the raft in the other headers" },
+    "producerIn": { "carriers": [ "bytes", "text", "stream", "file" ], 
"description": "The bytes to set() in the replicated log: a byte array, or 
text, a stream or a file converted to bytes. A null body, a Map, a number or a 
POJO has no conversion to bytes and is skipped without an error: nothing is 
set" },
+    "producerOut": { "carriers": [ "bytes", "unchanged" ], "description": "The 
byte array the state machine returns for the set (an empty array with the 
default NopStateMachine), with the state of the raft in the headers. A body 
that was skipped is left as it was" }
+  },
   "properties": {
     "clusterName": { "index": 0, "kind": "path", "displayName": "Cluster 
Name", "group": "common", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The name of the 
JGroupsraft cluster the component should connect to." },
     "enableRoleChangeEvents": { "index": 1, "kind": "parameter", 
"displayName": "Enable Role Change Events", "group": "consumer", "label": 
"consumer", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "If set to true, the consumer endpoint will receive 
roleChange event as well (not just connecting and\/or using the state machine). 
By default it is set to false." },
diff --git 
a/components/camel-jgroups-raft/src/main/java/org/apache/camel/component/jgroups/raft/JGroupsRaftEndpoint.java
 
b/components/camel-jgroups-raft/src/main/java/org/apache/camel/component/jgroups/raft/JGroupsRaftEndpoint.java
index 4f0b69038410..b0d16e839aae 100644
--- 
a/components/camel-jgroups-raft/src/main/java/org/apache/camel/component/jgroups/raft/JGroupsRaftEndpoint.java
+++ 
b/components/camel-jgroups-raft/src/main/java/org/apache/camel/component/jgroups/raft/JGroupsRaftEndpoint.java
@@ -24,6 +24,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Exchange;
 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.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -40,6 +43,19 @@ import org.slf4j.LoggerFactory;
  */
 @UriEndpoint(firstVersion = "2.24.0", scheme = "jgroups-raft", title = 
"JGroups raft", syntax = "jgroup-raft:clusterName",
              category = { Category.CLUSTERING, Category.MESSAGING }, 
headersClass = JGroupsRaftConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.NULL,
+                                   description = "No body: an event for each 
change of the role of this member (only with"
+                                                 + " enableRoleChangeEvents), 
with LEADER or FOLLOWER in the"
+                                                 + " CamelJGroupsRaftEventType 
header and the state of the raft in the other"
+                                                 + " headers"),
+           producerIn = @BodyType(value = { Carrier.BYTES, Carrier.TEXT, 
Carrier.STREAM, Carrier.FILE },
+                                  description = "The bytes to set() in the 
replicated log: a byte array, or text, a stream or"
+                                                + " a file converted to bytes. 
A null body, a Map, a number or a POJO has no"
+                                                + " conversion to bytes and is 
skipped without an error: nothing is set"),
+           producerOut = @BodyType(value = { Carrier.BYTES, Carrier.UNCHANGED 
},
+                                   description = "The byte array the state 
machine returns for the set (an empty array with"
+                                                 + " the default 
NopStateMachine), with the state of the raft in the headers. A"
+                                                 + " body that was skipped is 
left as it was"))
 public class JGroupsRaftEndpoint extends DefaultEndpoint {
     private static final Logger LOG = 
LoggerFactory.getLogger(JGroupsRaftEndpoint.class);
 
diff --git 
a/components/camel-jgroups/src/generated/resources/META-INF/org/apache/camel/component/jgroups/jgroups.json
 
b/components/camel-jgroups/src/generated/resources/META-INF/org/apache/camel/component/jgroups/jgroups.json
index 5b19bbf465e0..79a55abbdfa9 100644
--- 
a/components/camel-jgroups/src/generated/resources/META-INF/org/apache/camel/component/jgroups/jgroups.json
+++ 
b/components/camel-jgroups/src/generated/resources/META-INF/org/apache/camel/component/jgroups/jgroups.json
@@ -39,6 +39,11 @@
     "CamelJGroupsSrc": { "index": 2, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": 
"org.jgroups.Address", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Consumer : The org.jgroups.Address 
instance extracted by org.jgroups.Message.getSrc() method of the consumed 
message. Producer: The custom source org.jgroups.Address of the message to be 
sent.", "constantName": "org.apache.camel.compon [...]
     "CamelJGroupsOriginalMessage": { "index": 3, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "org.jgroups.Message", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The original 
org.jgroups.Message instance from which the body of the consumed message has 
been extracted.", "constantName": 
"org.apache.camel.component.jgroups.JGroupsConstants#HEADER_JGROUPS_ORIGINAL_MESSAGE"
 }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "unknown" ], "dependsOn": [ 
"enableViewMessages" ], "description": "The object the sender put in the 
message, Java-deserialized: what a jgroups producer sent, such as a String, a 
byte array, a Map or a Serializable POJO, if the deserialization filter accepts 
its class. With enableViewMessages an org.jgroups.View also arrives on each 
change of the members of the cluster" },
+    "producerIn": { "carriers": [ "text", "bytes", "value", "map", "list", 
"file", "pojo" ], "description": "The body as is, Java-serialized into the 
message, so it must be Serializable: a stream or another object that is not 
fails with a NotSerializableException. A null body is not sent. The 
CamelJGroupsDest header sends it to one member instead of the cluster" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "clusterName": { "index": 0, "kind": "path", "displayName": "Cluster 
Name", "group": "common", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The name of the JGroups 
cluster the component should connect to." },
     "channelProperties": { "index": 1, "kind": "parameter", "displayName": 
"Channel Properties", "group": "common", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Specifies configuration 
properties of the JChannel used by the endpoint." },
diff --git 
a/components/camel-jgroups/src/main/java/org/apache/camel/component/jgroups/JGroupsEndpoint.java
 
b/components/camel-jgroups/src/main/java/org/apache/camel/component/jgroups/JGroupsEndpoint.java
index 9a88d432c277..eb5b1e42d3f1 100644
--- 
a/components/camel-jgroups/src/main/java/org/apache/camel/component/jgroups/JGroupsEndpoint.java
+++ 
b/components/camel-jgroups/src/main/java/org/apache/camel/component/jgroups/JGroupsEndpoint.java
@@ -26,6 +26,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Exchange;
 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.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -47,6 +50,20 @@ import org.slf4j.LoggerFactory;
  */
 @UriEndpoint(firstVersion = "2.13.0", scheme = "jgroups", title = "JGroups", 
syntax = "jgroups:clusterName",
              category = { Category.CLUSTERING, Category.MESSAGING }, 
headersClass = JGroupsConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.UNKNOWN, dependsOn = 
"enableViewMessages",
+                                   description = "The object the sender put in 
the message, Java-deserialized: what a jgroups"
+                                                 + " producer sent, such as a 
String, a byte array, a Map or a Serializable"
+                                                 + " POJO, if the 
deserialization filter accepts its class. With"
+                                                 + " enableViewMessages an 
org.jgroups.View also arrives on each change of the"
+                                                 + " members of the cluster"),
+           producerIn = @BodyType(value = {
+                   Carrier.TEXT, Carrier.BYTES, Carrier.VALUE, Carrier.MAP, 
Carrier.LIST,
+                   Carrier.FILE, Carrier.POJO },
+                                  description = "The body as is, 
Java-serialized into the message, so it must be"
+                                                + " Serializable: a stream or 
another object that is not fails with a"
+                                                + " NotSerializableException. 
A null body is not sent. The CamelJGroupsDest header"
+                                                + " sends it to one member 
instead of the cluster"),
+           producerOut = @BodyType(Carrier.UNCHANGED))
 public class JGroupsEndpoint extends DefaultEndpoint {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(JGroupsEndpoint.class);
diff --git 
a/components/camel-lumberjack/src/generated/resources/META-INF/org/apache/camel/component/lumberjack/lumberjack.json
 
b/components/camel-lumberjack/src/generated/resources/META-INF/org/apache/camel/component/lumberjack/lumberjack.json
index f2637d8720d5..654bbc210b4c 100644
--- 
a/components/camel-lumberjack/src/generated/resources/META-INF/org/apache/camel/component/lumberjack/lumberjack.json
+++ 
b/components/camel-lumberjack/src/generated/resources/META-INF/org/apache/camel/component/lumberjack/lumberjack.json
@@ -29,6 +29,9 @@
     "sslContextParameters": { "index": 2, "kind": "property", "displayName": 
"Ssl Context Parameters", "group": "security", "label": "security", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the default SSL 
configuration to use for all the endpoints. You can also configure it directly 
at the endpoint level." },
     "useGlobalSslContextParameters": { "index": 3, "kind": "property", 
"displayName": "Use Global Ssl Context Parameters", "group": "security", 
"label": "security", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Enable usage of global SSL context 
parameters." }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "map", "list", "text", "value", "null" ], 
"description": "The log event: a Map of its fields, such as message, source and 
host, with the nested objects as Maps and the arrays as Lists. A JSON frame 
that is not an object gives a List, a String, a number, a boolean or null" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"consumer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Network interface on which to listen 
for Lumberjack" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"consumer", "label": "", "required": false, "type": "integer", "javaType": 
"int", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 5044, "description": "Network port on which to listen for 
Lumberjack" },
diff --git 
a/components/camel-lumberjack/src/main/java/org/apache/camel/component/lumberjack/LumberjackEndpoint.java
 
b/components/camel-lumberjack/src/main/java/org/apache/camel/component/lumberjack/LumberjackEndpoint.java
index 98d0c0645e69..33c5b3a23ea6 100644
--- 
a/components/camel-lumberjack/src/main/java/org/apache/camel/component/lumberjack/LumberjackEndpoint.java
+++ 
b/components/camel-lumberjack/src/main/java/org/apache/camel/component/lumberjack/LumberjackEndpoint.java
@@ -24,6 +24,9 @@ import javax.net.ssl.SSLContext;
 import org.apache.camel.Category;
 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.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -36,6 +39,10 @@ import org.apache.camel.support.jsse.SSLContextParameters;
  */
 @UriEndpoint(firstVersion = "2.18.0", scheme = "lumberjack", title = 
"Lumberjack", syntax = "lumberjack:host:port",
              consumerOnly = true, category = { Category.MONITORING })
+@BodyTypes(consumerOut = @BodyType(value = { Carrier.MAP, Carrier.LIST, 
Carrier.TEXT, Carrier.VALUE, Carrier.NULL },
+                                   description = "The log event: a Map of its 
fields, such as message, source and host, with"
+                                                 + " the nested objects as 
Maps and the arrays as Lists. A JSON frame that is"
+                                                 + " not an object gives a 
List, a String, a number, a boolean or null"))
 public class LumberjackEndpoint extends DefaultEndpoint {
     @UriPath(description = "Network interface on which to listen for 
Lumberjack")
     @Metadata(required = true)
diff --git 
a/components/camel-mina-sftp/src/generated/resources/META-INF/org/apache/camel/component/file/remote/mina/mina-sftp.json
 
b/components/camel-mina-sftp/src/generated/resources/META-INF/org/apache/camel/component/file/remote/mina/mina-sftp.json
index 6cae8c76d1cb..813150fd16b4 100644
--- 
a/components/camel-mina-sftp/src/generated/resources/META-INF/org/apache/camel/component/file/remote/mina/mina-sftp.json
+++ 
b/components/camel-mina-sftp/src/generated/resources/META-INF/org/apache/camel/component/file/remote/mina/mina-sftp.json
@@ -49,6 +49,11 @@
     "CamelFtpReplyCode": { "index": 15, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "important": true, "description": "The FTP client reply code", 
"constantName": 
"org.apache.camel.component.file.remote.FtpConstants#FTP_REPLY_CODE" },
     "CamelFtpReplyString": { "index": 16, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "important": true, "description": "The FTP client reply string", 
"constantName": 
"org.apache.camel.component.file.remote.FtpConstants#FTP_REPLY_STRING" }
   },
+  "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, 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: text, bytes, a stream or a file. A Map or a List fails: 
marshal it first" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.file.remote.mina.MinaSftpConfiguration", 
"configurationField": "configuration", "description": "Hostname of the FTP 
server" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.file.remote.mina.MinaSftpConfiguration", 
"configurationField": "configuration", "description": "Port of the FTP server" 
},
diff --git 
a/components/camel-mina-sftp/src/main/java/org/apache/camel/component/file/remote/mina/MinaSftpEndpoint.java
 
b/components/camel-mina-sftp/src/main/java/org/apache/camel/component/file/remote/mina/MinaSftpEndpoint.java
index cee38caa334a..656757c1171f 100644
--- 
a/components/camel-mina-sftp/src/main/java/org/apache/camel/component/file/remote/mina/MinaSftpEndpoint.java
+++ 
b/components/camel-mina-sftp/src/main/java/org/apache/camel/component/file/remote/mina/MinaSftpEndpoint.java
@@ -29,6 +29,9 @@ import 
org.apache.camel.component.file.remote.SftpDefaultMoveExistingFileStrateg
 import org.apache.camel.component.file.remote.SftpRemoteFile;
 import 
org.apache.camel.component.file.remote.mina.strategy.MinaSftpProcessStrategyFactory;
 import org.apache.camel.component.file.strategy.FileMoveExistingStrategy;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -43,6 +46,20 @@ import org.apache.camel.util.ObjectHelper;
                               + 
"directoryMustExist,extendedAttributes,probeContentType,startingDirectoryMustExist,"
                               + 
"startingDirectoryMustHaveAccess,forceWrites,copyAndDeleteOnRenameFail,"
                               + "renameUsingCopy,synchronous")
+@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, 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: text, bytes, a stream or a file. A Map or"
+                                                + " a List fails: marshal it 
first"),
+           producerOut = @BodyType(Carrier.UNCHANGED))
 public class MinaSftpEndpoint extends RemoteFileEndpoint<SftpRemoteFile> {
 
     @UriParam
diff --git 
a/components/camel-mina/src/generated/resources/META-INF/org/apache/camel/component/mina/mina.json
 
b/components/camel-mina/src/generated/resources/META-INF/org/apache/camel/component/mina/mina.json
index 2c014e2d5703..10b6c4d37ed4 100644
--- 
a/components/camel-mina/src/generated/resources/META-INF/org/apache/camel/component/mina/mina.json
+++ 
b/components/camel-mina/src/generated/resources/META-INF/org/apache/camel/component/mina/mina.json
@@ -61,6 +61,12 @@
     "CamelMinaLocalAddress": { "index": 2, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"java.net.SocketAddress", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The socket address of 
local machine that received the message.", "constantName": 
"org.apache.camel.component.mina.MinaConstants#MINA_LOCAL_ADDRESS" },
     "CamelMinaRemoteAddress": { "index": 3, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"java.net.SocketAddress", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The socket address of the 
remote machine that send the message.", "constantName": 
"org.apache.camel.component.mina.MinaConstants#MINA_REMOTE_ADDRESS" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"dependsOn": [ "codec", "objectCodecPattern", "transferExchange" ], "byOption": 
[ { "option": "protocol", "value": "udp", "carriers": [ "bytes" ], "javaType": 
"byte[]" }, { "option": "allowDefaultCodec", "value": "false", "carriers": [ 
"pojo" ], "javaType": "org.apache.mina.core.buffer.IoBuffer" } ], 
"description": "The data received as a String: one line with textline=true. The 
default object codec over TCP acc [...]
+    "consumerReply": { "carriers": [ "null", "text" ], "dependsOn": [ "codec", 
"transferExchange" ], "byOption": [ { "option": "protocol", "value": "udp", 
"carriers": [ "null", "text", "bytes", "stream", "file" ] }, { "option": 
"allowDefaultCodec", "value": "false", "carriers": [ "null", "pojo" ], 
"javaType": "org.apache.mina.core.buffer.IoBuffer" } ], "description": "The 
body the route ends with is written back to the caller, also with sync=false. 
Send a String: with textline=true other [...]
+    "producerIn": { "carriers": [ "null", "text" ], "dependsOn": [ "codec", 
"transferExchange" ], "byOption": [ { "option": "textline", "value": "true", 
"carriers": [ "any" ] }, { "option": "protocol", "value": "udp", "carriers": [ 
"null", "text", "bytes", "stream", "file" ] }, { "option": "allowDefaultCodec", 
"value": "false", "carriers": [ "null", "pojo" ], "javaType": 
"org.apache.mina.core.buffer.IoBuffer" } ], "description": "The data to send: a 
String. The default object codec over  [...]
+    "producerOut": { "carriers": [ "text", "null" ], "javaType": 
"java.lang.String", "dependsOn": [ "codec", "objectCodecPattern", 
"transferExchange" ], "byOption": [ { "option": "sync", "value": "false", 
"carriers": [ "unchanged", "null" ] }, { "option": "protocol", "value": "udp", 
"carriers": [ "bytes", "null" ], "javaType": "byte[]" }, { "option": 
"allowDefaultCodec", "value": "false", "carriers": [ "pojo", "null" ], 
"javaType": "org.apache.mina.core.buffer.IoBuffer" } ], "description [...]
+  },
   "properties": {
     "protocol": { "index": 0, "kind": "path", "displayName": "Protocol", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mina.MinaConfiguration", "configurationField": 
"configuration", "description": "Protocol to use" },
     "host": { "index": 1, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.mina.MinaConfiguration", "configurationField": 
"configuration", "description": "Hostname to use. Use localhost or 0.0.0.0 for 
local server as consumer. For producer use the hostname or ip address  [...]
diff --git 
a/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaEndpoint.java
 
b/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaEndpoint.java
index 8290fd59380e..0ce86273caf5 100644
--- 
a/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaEndpoint.java
+++ 
b/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaEndpoint.java
@@ -22,6 +22,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.MultipleConsumersSupport;
 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;
@@ -33,6 +36,61 @@ import org.apache.camel.util.ObjectHelper;
  */
 @UriEndpoint(firstVersion = "2.10.0", scheme = "mina", title = "Mina", syntax 
= "mina:protocol:host:port",
              category = { Category.NETWORKING }, headersClass = 
MinaConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.TEXT, javaType = 
"java.lang.String",
+                                   dependsOn = { "codec", 
"objectCodecPattern", "transferExchange" },
+                                   byOption = {
+                                           @BodyType.When(option = "protocol", 
value = "udp", carriers = Carrier.BYTES,
+                                                          javaType = "byte[]"),
+                                           @BodyType.When(option = 
"allowDefaultCodec", value = "false",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"org.apache.mina.core.buffer.IoBuffer") },
+                                   description = "The data received as a 
String: one line with textline=true. The default"
+                                                 + " object codec over TCP 
accepts only a String unless objectCodecPattern"
+                                                 + " lists the classes to 
deserialize. Over UDP the datagram as a byte array"),
+           consumerReply = @BodyType(value = { Carrier.NULL, Carrier.TEXT },
+                                     dependsOn = { "codec", "transferExchange" 
},
+                                     byOption = {
+                                             @BodyType.When(option = 
"protocol", value = "udp",
+                                                            carriers = {
+                                                                    
Carrier.NULL, Carrier.TEXT, Carrier.BYTES,
+                                                                    
Carrier.STREAM, Carrier.FILE }),
+                                             @BodyType.When(option = 
"allowDefaultCodec", value = "false",
+                                                            carriers = { 
Carrier.NULL, Carrier.POJO },
+                                                            javaType = 
"org.apache.mina.core.buffer.IoBuffer") },
+                                     description = "The body the route ends 
with is written back to the caller, also with"
+                                                   + " sync=false. Send a 
String: with textline=true other bodies are"
+                                                   + " written with 
toString(), and the object codec writes any"
+                                                   + " Serializable object, 
which a Mina client accepts only when its"
+                                                   + " objectCodecPattern 
lists the class. No body sends nothing and closes"
+                                                   + " the connection"),
+           producerIn = @BodyType(value = { Carrier.NULL, Carrier.TEXT },
+                                  dependsOn = { "codec", "transferExchange" },
+                                  byOption = {
+                                          @BodyType.When(option = "textline", 
value = "true", carriers = Carrier.ANY),
+                                          @BodyType.When(option = "protocol", 
value = "udp",
+                                                         carriers = {
+                                                                 Carrier.NULL, 
Carrier.TEXT, Carrier.BYTES,
+                                                                 
Carrier.STREAM, Carrier.FILE }),
+                                          @BodyType.When(option = 
"allowDefaultCodec", value = "false",
+                                                         carriers = { 
Carrier.NULL, Carrier.POJO },
+                                                         javaType = 
"org.apache.mina.core.buffer.IoBuffer") },
+                                  description = "The data to send: a String. 
The default object codec over TCP serializes"
+                                                + " the body, but a Mina 
server accepts only a String unless its"
+                                                + " objectCodecPattern lists 
the class, and a stream fails; textline=true"
+                                                + " converts any body to a 
line of text. No body sends nothing"),
+           producerOut = @BodyType(value = { Carrier.TEXT, Carrier.NULL }, 
javaType = "java.lang.String",
+                                   dependsOn = { "codec", 
"objectCodecPattern", "transferExchange" },
+                                   byOption = {
+                                           @BodyType.When(option = "sync", 
value = "false",
+                                                          carriers = { 
Carrier.UNCHANGED, Carrier.NULL }),
+                                           @BodyType.When(option = "protocol", 
value = "udp",
+                                                          carriers = { 
Carrier.BYTES, Carrier.NULL }, javaType = "byte[]"),
+                                           @BodyType.When(option = 
"allowDefaultCodec", value = "false",
+                                                          carriers = { 
Carrier.POJO, Carrier.NULL },
+                                                          javaType = 
"org.apache.mina.core.buffer.IoBuffer") },
+                                   description = "With sync=true (the default) 
the reply of the server as a String, or a"
+                                                 + " byte array over UDP. No 
body is not sent and stays null. With"
+                                                 + " sync=false an InOut 
exchange ends with an empty message"))
 public class MinaEndpoint extends DefaultEndpoint implements 
MultipleConsumersSupport, EndpointServiceLocation {
 
     @UriParam
diff --git 
a/components/camel-mllp/src/generated/resources/META-INF/org/apache/camel/component/mllp/mllp.json
 
b/components/camel-mllp/src/generated/resources/META-INF/org/apache/camel/component/mllp/mllp.json
index fe54a6d99450..43f0221ec6c1 100644
--- 
a/components/camel-mllp/src/generated/resources/META-INF/org/apache/camel/component/mllp/mllp.json
+++ 
b/components/camel-mllp/src/generated/resources/META-INF/org/apache/camel/component/mllp/mllp.json
@@ -85,6 +85,12 @@
     "CamelMllpVersionId": { "index": 21, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "MSH-12 value", "constantName": 
"org.apache.camel.component.mllp.MllpConstants#MLLP_VERSION_ID" },
     "CamelMllpCharset": { "index": 22, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "MSH-18 value", "constantName": 
"org.apache.camel.component.mllp.MllpConstants#MLLP_CHARSET" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"byOption": [ { "option": "stringPayload", "value": "false", "carriers": [ 
"bytes" ], "javaType": "byte[]" } ], "description": "The HL7 message without 
the MLLP envelope, as a String in the charset of MSH-18 or charsetName, or a 
byte array with stringPayload=false" },
+    "consumerReply": { "carriers": [ "any" ], "description": "The body is not 
sent back: the acknowledgement is the CamelMllpAcknowledgement or 
CamelMllpAcknowledgementString exchange property, or with autoAck an HL7 ACK 
(AA, or AE when the exchange failed)" },
+    "producerIn": { "carriers": [ "text", "bytes" ], "description": "The HL7 
message as a String or a byte array. No body fails; another body, such as a 
stream, is sent as an empty message: convert it to a String first" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "The body is 
left as it was: with InOut the acknowledgement is in the 
CamelMllpAcknowledgement (byte array) and CamelMllpAcknowledgementString 
headers" }
+  },
   "properties": {
     "hostname": { "index": 0, "kind": "path", "displayName": "Hostname", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Hostname or IP for connection for the 
TCP connection. The default value is null, which means any local IP address" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": true, "type": "integer", "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Port number for the TCP connection" },
diff --git a/components/camel-mllp/src/main/docs/mllp-component.adoc 
b/components/camel-mllp/src/main/docs/mllp-component.adoc
index 0321f09b751f..383a40fc1504 100644
--- a/components/camel-mllp/src/main/docs/mllp-component.adoc
+++ b/components/camel-mllp/src/main/docs/mllp-component.adoc
@@ -30,8 +30,9 @@ The component supports the following:
 * A Camel consumer using a TCP Server
 * A Camel producer using a TCP Client
 
-The MLLP component use `byte[]` payloads, and relies on Camel type
-conversion to convert `byte[]` to other types.
+The MLLP consumer gives the HL7 payload as a `String` by default
+(`stringPayload=true`), or as a `byte[]` with `stringPayload=false`.
+The MLLP producer sends a `String` or a `byte[]` body.
 
 Maven users will need to add the following dependency to their pom.xml
 for this component:
diff --git 
a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpEndpoint.java
 
b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpEndpoint.java
index 736baea8551b..6b4ed87a1f59 100644
--- 
a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpEndpoint.java
+++ 
b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpEndpoint.java
@@ -30,6 +30,9 @@ import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.api.management.ManagedAttribute;
 import org.apache.camel.api.management.ManagedResource;
+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;
@@ -52,6 +55,24 @@ import org.slf4j.Logger;
 @UriEndpoint(scheme = "mllp", firstVersion = "2.17.0", title = "MLLP", syntax 
= "mllp:hostname:port",
              category = { Category.HEALTH }, generateConfigurer = true,
              headersClass = MllpConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.TEXT, javaType = 
"java.lang.String",
+                                   byOption = @BodyType.When(option = 
"stringPayload", value = "false",
+                                                             carriers = 
Carrier.BYTES, javaType = "byte[]"),
+                                   description = "The HL7 message without the 
MLLP envelope, as a String in the charset of"
+                                                 + " MSH-18 or charsetName, or 
a byte array with stringPayload=false"),
+           consumerReply = @BodyType(value = Carrier.ANY,
+                                     description = "The body is not sent back: 
the acknowledgement is the"
+                                                   + " 
CamelMllpAcknowledgement or CamelMllpAcknowledgementString exchange"
+                                                   + " property, or with 
autoAck an HL7 ACK (AA, or AE when the exchange"
+                                                   + " failed)"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES },
+                                  description = "The HL7 message as a String 
or a byte array. No body fails; another body,"
+                                                + " such as a stream, is sent 
as an empty message: convert it to a String"
+                                                + " first"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   description = "The body is left as it was: 
with InOut the acknowledgement is in the"
+                                                 + " CamelMllpAcknowledgement 
(byte array) and"
+                                                 + " 
CamelMllpAcknowledgementString headers"))
 public class MllpEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
 
     @UriPath
diff --git 
a/components/camel-quickfix/src/generated/resources/META-INF/org/apache/camel/component/quickfixj/quickfix.json
 
b/components/camel-quickfix/src/generated/resources/META-INF/org/apache/camel/component/quickfixj/quickfix.json
index eb9913659561..e4a007573f98 100644
--- 
a/components/camel-quickfix/src/generated/resources/META-INF/org/apache/camel/component/quickfixj/quickfix.json
+++ 
b/components/camel-quickfix/src/generated/resources/META-INF/org/apache/camel/component/quickfixj/quickfix.json
@@ -38,6 +38,12 @@
     "SessionID": { "index": 1, "kind": "header", "displayName": "", "group": 
"common", "label": "", "required": false, "javaType": "quickfix.SessionID", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The FIX message SessionID.", "constantName": 
"org.apache.camel.component.quickfixj.QuickfixjEndpoint#SESSION_ID_KEY" },
     "MessageType": { "index": 2, "kind": "header", "displayName": "", "group": 
"common", "label": "", "required": false, "javaType": "String", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "The FIX MsgType tag value.", "constantName": 
"org.apache.camel.component.quickfixj.QuickfixjEndpoint#MESSAGE_TYPE_KEY" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo", "null" ], "description": "The FIX 
message: a quickfix.Message, such as a quickfix.fix44.Email, with the kind of 
event in the EventCategory header and the MsgType in the MessageType header. 
SessionCreated, SessionLogon and SessionLogoff events have no body" },
+    "consumerReply": { "carriers": [ "pojo", "text", "bytes" ], "description": 
"With exchangePattern=InOut, the reply sent back on the session of the request: 
a quickfix.Message, or the FIX message as text or bytes. Every event is 
answered with the body the route ends with: a route that sets no reply sends 
back the message it received" },
+    "producerIn": { "carriers": [ "pojo", "text", "bytes" ], "description": 
"The FIX message to send: a quickfix.Message, or the FIX message as text or 
bytes, parsed with the DataDictionary exchange property or the data dictionary 
of the session. A stream, a Map or no body fails" },
+    "producerOut": { "carriers": [ "unchanged", "pojo" ], "description": "The 
body is left as it was. An InOut exchange waits for the reply that matches the 
CorrelationCriteria exchange property, and the reply quickfix.Message is the 
body" }
+  },
   "properties": {
     "configurationName": { "index": 0, "kind": "path", "displayName": 
"Configuration Name", "group": "common", "label": "", "required": true, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"supportFileReference": true, "description": "Path to the quickfix 
configuration file. You can prefix with: classpath, file, http, ref, or bean. 
classpath, file and http loads the configuration file using these protocol [...]
     "lazyCreateEngine": { "index": 1, "kind": "parameter", "displayName": 
"Lazy Create Engine", "group": "common", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "This option 
allows creating QuickFIX\/J engine on demand. Value true means the engine is 
started when first message is send or there's consumer configured in route 
definition. When false value is used, the  [...]
diff --git a/components/camel-quickfix/src/main/docs/quickfix-component.adoc 
b/components/camel-quickfix/src/main/docs/quickfix-component.adoc
index 241f122c6170..61d92dbca9fa 100644
--- a/components/camel-quickfix/src/main/docs/quickfix-component.adoc
+++ b/components/camel-quickfix/src/main/docs/quickfix-component.adoc
@@ -307,9 +307,11 @@ The correlation criteria is defined with a 
`MessagePredicate` object.
 The following example will treat
 a FIX `ExecutionReport` from the specified session where the transaction
 type is STATUS and the Order ID
-matches our request. The session ID should be for the __requestor__, the
-sender and target CompID fields
-will be reversed when looking for the reply.
+matches our request. The SenderCompID and TargetCompID of the session ID are
+matched as given against the header of the reply, so use the session ID as
+the __replier__ sees it: for a request sent on `FIX.4.2:TRADER->MARKET`, use
+`FIX.4.2:MARKET->TRADER`. The correlation criteria is required for an InOut
+exchange.
 
 ._Java-only: programmatic correlation criteria setup using QuickFIX/J API_
 [source,java]
diff --git 
a/components/camel-quickfix/src/main/java/org/apache/camel/component/quickfixj/QuickfixjEndpoint.java
 
b/components/camel-quickfix/src/main/java/org/apache/camel/component/quickfixj/QuickfixjEndpoint.java
index e9913b16ca16..0049fad2e67b 100644
--- 
a/components/camel-quickfix/src/main/java/org/apache/camel/component/quickfixj/QuickfixjEndpoint.java
+++ 
b/components/camel-quickfix/src/main/java/org/apache/camel/component/quickfixj/QuickfixjEndpoint.java
@@ -30,6 +30,9 @@ import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.ResolveEndpointFailedException;
 import org.apache.camel.component.quickfixj.converter.QuickfixjConverters;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -46,6 +49,24 @@ import quickfix.SessionID;
  */
 @UriEndpoint(firstVersion = "2.1.0", scheme = "quickfix", title = "QuickFix", 
syntax = "quickfix:configurationName",
              category = { Category.MESSAGING }, headersClass = 
QuickfixjEndpoint.class)
+@BodyTypes(consumerOut = @BodyType(value = { Carrier.POJO, Carrier.NULL },
+                                   description = "The FIX message: a 
quickfix.Message, such as a quickfix.fix44.Email, with"
+                                                 + " the kind of event in the 
EventCategory header and the MsgType in the"
+                                                 + " MessageType header. 
SessionCreated, SessionLogon and SessionLogoff"
+                                                 + " events have no body"),
+           consumerReply = @BodyType(value = { Carrier.POJO, Carrier.TEXT, 
Carrier.BYTES },
+                                     description = "With 
exchangePattern=InOut, the reply sent back on the session of the"
+                                                   + " request: a 
quickfix.Message, or the FIX message as text or bytes."
+                                                   + " Every event is answered 
with the body the route ends with: a route"
+                                                   + " that sets no reply 
sends back the message it received"),
+           producerIn = @BodyType(value = { Carrier.POJO, Carrier.TEXT, 
Carrier.BYTES },
+                                  description = "The FIX message to send: a 
quickfix.Message, or the FIX message as text or"
+                                                + " bytes, parsed with the 
DataDictionary exchange property or the data"
+                                                + " dictionary of the session. 
A stream, a Map or no body fails"),
+           producerOut = @BodyType(value = { Carrier.UNCHANGED, Carrier.POJO },
+                                   description = "The body is left as it was. 
An InOut exchange waits for the reply that"
+                                                 + " matches the 
CorrelationCriteria exchange property, and the reply"
+                                                 + " quickfix.Message is the 
body"))
 public class QuickfixjEndpoint extends DefaultEndpoint implements 
QuickfixjEventListener, MultipleConsumersSupport {
     @Metadata(description = "The event category.", javaType = 
"org.apache.camel.component.quickfixj.QuickfixjEventCategory")
     public static final String EVENT_CATEGORY_KEY = "EventCategory";
diff --git 
a/components/camel-thrift/src/generated/resources/META-INF/org/apache/camel/component/thrift/thrift.json
 
b/components/camel-thrift/src/generated/resources/META-INF/org/apache/camel/component/thrift/thrift.json
index 0826fcc5dc0a..c5bcd0520b7d 100644
--- 
a/components/camel-thrift/src/generated/resources/META-INF/org/apache/camel/component/thrift/thrift.json
+++ 
b/components/camel-thrift/src/generated/resources/META-INF/org/apache/camel/component/thrift/thrift.json
@@ -32,6 +32,12 @@
   "headers": {
     "CamelThriftMethodName": { "index": 0, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Method name handled by the consumer service", 
"constantName": 
"org.apache.camel.component.thrift.ThriftConstants#THRIFT_METHOD_NAME_HEADER" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "list", "null" ], "byOption": [ { "option": 
"synchronous", "value": "true", "carriers": [ "list" ] } ], "description": "A 
List of the arguments of the called method, in the order of the IDL, with the 
method name in the CamelThriftMethodName header. A method without arguments 
gives no body, or an empty List with synchronous=true" },
+    "consumerReply": { "carriers": [ "any" ], "description": "The result of 
the method: the body is converted to its return type, so text works for an i32, 
and a struct result needs the Thrift struct. Ignored for a void method. A body 
that does not convert gives the client an error, or a null result from the 
asynchronous server" },
+    "producerIn": { "carriers": [ "list", "pojo", "text", "null" ], 
"description": "A List of the arguments of the method, in the order of the IDL; 
a body that is not a List is the one argument, no body calls a method without 
arguments. A binary argument is a ByteBuffer, not a byte array; a method whose 
one argument is a list needs it wrapped in a List" },
+    "producerOut": { "carriers": [ "unknown" ], "description": "The result of 
the method, of its return type in the IDL: a number, a boolean, a String, a 
ByteBuffer, a Thrift struct, or a List, Set or Map; no body for a void or 
oneway method" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.thrift.ThriftConfiguration", "configurationField": 
"configuration", "description": "The Thrift server host name. This is localhost 
or 0.0.0.0 (if not defined) when being a consumer or remote serve [...]
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": true, "type": "integer", "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "configurationClass": 
"org.apache.camel.component.thrift.ThriftConfiguration", "configurationField": 
"configuration", "description": "The Thrift server port" },
diff --git 
a/components/camel-thrift/src/main/java/org/apache/camel/component/thrift/ThriftEndpoint.java
 
b/components/camel-thrift/src/main/java/org/apache/camel/component/thrift/ThriftEndpoint.java
index 0d8afaf8f0a3..ccce13c1a798 100644
--- 
a/components/camel-thrift/src/main/java/org/apache/camel/component/thrift/ThriftEndpoint.java
+++ 
b/components/camel-thrift/src/main/java/org/apache/camel/component/thrift/ThriftEndpoint.java
@@ -20,6 +20,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;
@@ -31,6 +34,25 @@ import org.apache.camel.support.SynchronousDelegateProducer;
  */
 @UriEndpoint(firstVersion = "2.20.0", scheme = "thrift", title = "Thrift", 
syntax = "thrift:host:port/service",
              category = { Category.RPC, Category.TRANSFORMATION }, 
headersClass = ThriftConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = { Carrier.LIST, Carrier.NULL },
+                                   byOption = @BodyType.When(option = 
"synchronous", value = "true", carriers = Carrier.LIST),
+                                   description = "A List of the arguments of 
the called method, in the order of the IDL, with"
+                                                 + " the method name in the 
CamelThriftMethodName header. A method without"
+                                                 + " arguments gives no body, 
or an empty List with synchronous=true"),
+           consumerReply = @BodyType(value = Carrier.ANY,
+                                     description = "The result of the method: 
the body is converted to its return type, so"
+                                                   + " text works for an i32, 
and a struct result needs the Thrift struct."
+                                                   + " Ignored for a void 
method. A body that does not convert gives the client an"
+                                                   + " error, or a null result 
from the asynchronous server"),
+           producerIn = @BodyType(value = { Carrier.LIST, Carrier.POJO, 
Carrier.TEXT, Carrier.NULL },
+                                  description = "A List of the arguments of 
the method, in the order of the IDL; a body that"
+                                                + " is not a List is the one 
argument, no body calls a method without"
+                                                + " arguments. A binary 
argument is a ByteBuffer, not a byte array; a method"
+                                                + " whose one argument is a 
list needs it wrapped in a List"),
+           producerOut = @BodyType(value = Carrier.UNKNOWN,
+                                   description = "The result of the method, of 
its return type in the IDL: a number, a"
+                                                 + " boolean, a String, a 
ByteBuffer, a Thrift struct, or a List, Set or Map;"
+                                                 + " no body for a void or 
oneway method"))
 public class ThriftEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
     @UriParam
     private ThriftConfiguration configuration;

Reply via email to