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 b4a4e0e4af21529fd44c68dea190082ac197283a
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Oct 24 19:57:07 2026 +0200

    CAMEL-24961: Catalog body types for coap, milo, plc4x and tahu (#28411)
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../apache/camel/catalog/components/coap+tcp.json   |  6 ++++++
 .../org/apache/camel/catalog/components/coap.json   |  6 ++++++
 .../apache/camel/catalog/components/coaps+tcp.json  |  6 ++++++
 .../org/apache/camel/catalog/components/coaps.json  |  6 ++++++
 .../camel/catalog/components/milo-browse.json       |  4 ++++
 .../camel/catalog/components/milo-client.json       |  5 +++++
 .../camel/catalog/components/milo-server.json       |  5 +++++
 .../org/apache/camel/catalog/components/plc4x.json  |  5 +++++
 .../apache/camel/catalog/components/tahu-edge.json  |  4 ++++
 .../apache/camel/catalog/components/tahu-host.json  |  3 +++
 .../META-INF/org/apache/camel/coap/coap+tcp.json    |  6 ++++++
 .../META-INF/org/apache/camel/coap/coap.json        |  6 ++++++
 .../META-INF/org/apache/camel/coap/coaps+tcp.json   |  6 ++++++
 .../META-INF/org/apache/camel/coap/coaps.json       |  6 ++++++
 .../java/org/apache/camel/coap/CoAPEndpoint.java    | 21 +++++++++++++++++++++
 .../camel/component/milo/browse/milo-browse.json    |  4 ++++
 .../camel/component/milo/client/milo-client.json    |  5 +++++
 .../camel/component/milo/server/milo-server.json    |  5 +++++
 .../component/milo/browse/MiloBrowseEndpoint.java   | 10 ++++++++++
 .../component/milo/client/MiloClientEndpoint.java   | 21 +++++++++++++++++++++
 .../component/milo/server/MiloServerEndpoint.java   | 12 ++++++++++++
 .../org/apache/camel/component/plc4x/plc4x.json     |  5 +++++
 .../apache/camel/component/plc4x/Plc4XEndpoint.java | 13 +++++++++++++
 .../org/apache/camel/component/tahu/tahu-edge.json  |  4 ++++
 .../org/apache/camel/component/tahu/tahu-host.json  |  3 +++
 .../camel/component/tahu/TahuEdgeEndpoint.java      |  8 ++++++++
 .../camel/component/tahu/TahuHostEndpoint.java      |  7 +++++++
 27 files changed, 192 insertions(+)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coap+tcp.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coap+tcp.json
index 322e3ac0b329..9a6265a5f139 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coap+tcp.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coap+tcp.json
@@ -39,6 +39,12 @@
     "CamelCoapResponseCode": { "index": 3, "kind": "header", "displayName": 
"", "group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The CoAP response code sent by the external server. See 
RFC 7252 for details of what each code means.", "constantName": 
"org.apache.camel.coap.CoAPConstants#COAP_RESPONSE_CODE" },
     "Content-Type": { "index": 4, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The content type", "constantName": 
"org.apache.camel.coap.CoAPConstants#CONTENT_TYPE" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "The request payload as a byte array, empty for a request 
without a payload, such as a GET; with observe, the payload of each 
notification of the observed resource" },
+    "consumerReply": { "carriers": [ "null", "text", "bytes", "stream", "file" 
], "description": "The response payload: text, bytes, a stream, a file or no 
body. A Map, a POJO or a number is sent as an empty payload: convert or marshal 
it first" },
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"description": "The payload of a POST or a PUT: text, bytes, a stream or a 
file. A Map, a POJO or a number is sent as an empty payload: marshal it first. 
Without CamelCoapMethod, no body sends a GET and a body a POST" },
+    "producerOut": { "carriers": [ "bytes", "value" ], "byOption": [ { 
"option": "notify", "value": "true", "carriers": [ "unchanged" ] } ], 
"description": "The response payload as a byte array, empty for a response 
without a payload; a Boolean for a PING (CamelCoapMethod=PING). The response 
code is in the CamelCoapResponseCode header" }
+  },
   "properties": {
     "uri": { "index": 0, "kind": "path", "displayName": "Uri", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.net.URI", "deprecated": false, "autowired": false, "secret": false, 
"description": "The URI for the CoAP endpoint" },
     "coapMethodRestrict": { "index": 1, "kind": "parameter", "displayName": 
"Coap Method Restrict", "group": "consumer", "label": "consumer", "required": 
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "DELETE", 
"GET", "POST", "PUT" ], "multiEnum": true, "deprecated": false, "autowired": 
false, "secret": false, "description": "Comma separated list of methods that 
the CoAP consumer will bind to. The default is to bind to all methods (DELETE, 
GET, POST, PUT)." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coap.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coap.json
index 9c68f014aa82..88c4c89416d9 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coap.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coap.json
@@ -39,6 +39,12 @@
     "CamelCoapResponseCode": { "index": 3, "kind": "header", "displayName": 
"", "group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The CoAP response code sent by the external server. See 
RFC 7252 for details of what each code means.", "constantName": 
"org.apache.camel.coap.CoAPConstants#COAP_RESPONSE_CODE" },
     "Content-Type": { "index": 4, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The content type", "constantName": 
"org.apache.camel.coap.CoAPConstants#CONTENT_TYPE" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "The request payload as a byte array, empty for a request 
without a payload, such as a GET; with observe, the payload of each 
notification of the observed resource" },
+    "consumerReply": { "carriers": [ "null", "text", "bytes", "stream", "file" 
], "description": "The response payload: text, bytes, a stream, a file or no 
body. A Map, a POJO or a number is sent as an empty payload: convert or marshal 
it first" },
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"description": "The payload of a POST or a PUT: text, bytes, a stream or a 
file. A Map, a POJO or a number is sent as an empty payload: marshal it first. 
Without CamelCoapMethod, no body sends a GET and a body a POST" },
+    "producerOut": { "carriers": [ "bytes", "value" ], "byOption": [ { 
"option": "notify", "value": "true", "carriers": [ "unchanged" ] } ], 
"description": "The response payload as a byte array, empty for a response 
without a payload; a Boolean for a PING (CamelCoapMethod=PING). The response 
code is in the CamelCoapResponseCode header" }
+  },
   "properties": {
     "uri": { "index": 0, "kind": "path", "displayName": "Uri", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.net.URI", "deprecated": false, "autowired": false, "secret": false, 
"description": "The URI for the CoAP endpoint" },
     "coapMethodRestrict": { "index": 1, "kind": "parameter", "displayName": 
"Coap Method Restrict", "group": "consumer", "label": "consumer", "required": 
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "DELETE", 
"GET", "POST", "PUT" ], "multiEnum": true, "deprecated": false, "autowired": 
false, "secret": false, "description": "Comma separated list of methods that 
the CoAP consumer will bind to. The default is to bind to all methods (DELETE, 
GET, POST, PUT)." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coaps+tcp.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coaps+tcp.json
index 2d75470c488e..f69848818b02 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coaps+tcp.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coaps+tcp.json
@@ -39,6 +39,12 @@
     "CamelCoapResponseCode": { "index": 3, "kind": "header", "displayName": 
"", "group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The CoAP response code sent by the external server. See 
RFC 7252 for details of what each code means.", "constantName": 
"org.apache.camel.coap.CoAPConstants#COAP_RESPONSE_CODE" },
     "Content-Type": { "index": 4, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The content type", "constantName": 
"org.apache.camel.coap.CoAPConstants#CONTENT_TYPE" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "The request payload as a byte array, empty for a request 
without a payload, such as a GET; with observe, the payload of each 
notification of the observed resource" },
+    "consumerReply": { "carriers": [ "null", "text", "bytes", "stream", "file" 
], "description": "The response payload: text, bytes, a stream, a file or no 
body. A Map, a POJO or a number is sent as an empty payload: convert or marshal 
it first" },
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"description": "The payload of a POST or a PUT: text, bytes, a stream or a 
file. A Map, a POJO or a number is sent as an empty payload: marshal it first. 
Without CamelCoapMethod, no body sends a GET and a body a POST" },
+    "producerOut": { "carriers": [ "bytes", "value" ], "byOption": [ { 
"option": "notify", "value": "true", "carriers": [ "unchanged" ] } ], 
"description": "The response payload as a byte array, empty for a response 
without a payload; a Boolean for a PING (CamelCoapMethod=PING). The response 
code is in the CamelCoapResponseCode header" }
+  },
   "properties": {
     "uri": { "index": 0, "kind": "path", "displayName": "Uri", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.net.URI", "deprecated": false, "autowired": false, "secret": false, 
"description": "The URI for the CoAP endpoint" },
     "coapMethodRestrict": { "index": 1, "kind": "parameter", "displayName": 
"Coap Method Restrict", "group": "consumer", "label": "consumer", "required": 
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "DELETE", 
"GET", "POST", "PUT" ], "multiEnum": true, "deprecated": false, "autowired": 
false, "secret": false, "description": "Comma separated list of methods that 
the CoAP consumer will bind to. The default is to bind to all methods (DELETE, 
GET, POST, PUT)." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coaps.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coaps.json
index db85a2379c7f..be9883c933d2 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coaps.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/coaps.json
@@ -39,6 +39,12 @@
     "CamelCoapResponseCode": { "index": 3, "kind": "header", "displayName": 
"", "group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The CoAP response code sent by the external server. See 
RFC 7252 for details of what each code means.", "constantName": 
"org.apache.camel.coap.CoAPConstants#COAP_RESPONSE_CODE" },
     "Content-Type": { "index": 4, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The content type", "constantName": 
"org.apache.camel.coap.CoAPConstants#CONTENT_TYPE" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "The request payload as a byte array, empty for a request 
without a payload, such as a GET; with observe, the payload of each 
notification of the observed resource" },
+    "consumerReply": { "carriers": [ "null", "text", "bytes", "stream", "file" 
], "description": "The response payload: text, bytes, a stream, a file or no 
body. A Map, a POJO or a number is sent as an empty payload: convert or marshal 
it first" },
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"description": "The payload of a POST or a PUT: text, bytes, a stream or a 
file. A Map, a POJO or a number is sent as an empty payload: marshal it first. 
Without CamelCoapMethod, no body sends a GET and a body a POST" },
+    "producerOut": { "carriers": [ "bytes", "value" ], "byOption": [ { 
"option": "notify", "value": "true", "carriers": [ "unchanged" ] } ], 
"description": "The response payload as a byte array, empty for a response 
without a payload; a Boolean for a PING (CamelCoapMethod=PING). The response 
code is in the CamelCoapResponseCode header" }
+  },
   "properties": {
     "uri": { "index": 0, "kind": "path", "displayName": "Uri", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.net.URI", "deprecated": false, "autowired": false, "secret": false, 
"description": "The URI for the CoAP endpoint" },
     "coapMethodRestrict": { "index": 1, "kind": "parameter", "displayName": 
"Coap Method Restrict", "group": "consumer", "label": "consumer", "required": 
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "DELETE", 
"GET", "POST", "PUT" ], "multiEnum": true, "deprecated": false, "autowired": 
false, "secret": false, "description": "Comma separated list of methods that 
the CoAP consumer will bind to. The default is to bind to all methods (DELETE, 
GET, POST, PUT)." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-browse.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-browse.json
index cf30f028dc51..8a3c54e8be94 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-browse.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-browse.json
@@ -59,6 +59,10 @@
   "headers": {
     "CamelMiloNodeIds": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"List", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The node ids.", "constantName": 
"org.apache.camel.component.milo.MiloConstants#HEADER_NODE_IDS" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "The body is not 
read: the nodes to browse are the node IDs of the CamelMiloNodeIds header, or 
else the node option" },
+    "producerOut": { "carriers": [ "map" ], "description": "A Map of the 
browsed ExpandedNodeId to its Milo BrowseResult; the node IDs found are also in 
the CamelMiloNodeIds header, as a List of Strings for the milo-client producer" 
}
+  },
   "properties": {
     "endpointUri": { "index": 0, "kind": "path", "displayName": "Endpoint 
Uri", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The OPC UA server 
endpoint" },
     "clientId": { "index": 1, "kind": "parameter", "displayName": "Client Id", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "A virtual client id to 
force the creation of a new connection instance" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-client.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-client.json
index a4ecb41eb45e..d88fa10f1d74 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-client.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-client.json
@@ -62,6 +62,11 @@
     "CamelMiloAwait": { "index": 1, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The await setting for writes.", 
"constantName": "org.apache.camel.component.milo.MiloConstants#HEADER_AWAIT" },
     "CamelMiloNodeId": { "index": 2, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The node ID of the value, as configured in the 
node or nodes option. Not to be confused with CamelMiloNodeIds, the list of 
nodes that the producer reads.", "constantName": 
"org.apache.camel.component.milo.MiloConstants#HEADER_NODE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"org.eclipse.milo.opcua.stack.core.types.builtin.DataValue", "description": 
"The Milo DataValue of each change of a monitored node: its 
getValue().getValue() is the value, and the status code tells a good value from 
a lost connection. The node is in the CamelMiloNodeId header" },
+    "producerIn": { "carriers": [ "text", "bytes", "value", "pojo", "null" ], 
"description": "The value to write to the node, or the input arguments of the 
method: an OPC UA built-in value such as a String, a number, a boolean, a 
Variant or a DataValue. A stream, a file, a Map or a bean fails with 
Bad_EncodingError. With the CamelMiloNodeIds header the body is not read: the 
producer reads the values of those nodes" },
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"defaultAwaitWrites", "value": "true", "carriers": [ "pojo", "list" ] } ], 
"description": "The producer does not wait, unless the CamelMiloAwait header or 
defaultAwaitWrites says so; it then sets the result: the StatusCode of a write, 
the CallMethodResult of a method call, or a List of DataValue of the nodes 
read" }
+  },
   "properties": {
     "endpointUri": { "index": 0, "kind": "path", "displayName": "Endpoint 
Uri", "group": "common", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The OPC UA server 
endpoint" },
     "clientId": { "index": 1, "kind": "parameter", "displayName": "Client Id", 
"group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "A virtual client id to 
force the creation of a new connection instance" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-server.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-server.json
index c1cb7a71996b..17a52236abfe 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-server.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-server.json
@@ -45,6 +45,11 @@
     "userAuthenticationCredentials": { "index": 18, "kind": "property", 
"displayName": "User Authentication Credentials", "group": "security", "label": 
"security", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": true, 
"security": "secret", "description": "Set user password combinations in the 
form of user1:pwd1,user2:pwd2 Usernames and passwords will be URL decoded" },
     "usernameSecurityPolicyUri": { "index": 19, "kind": "property", 
"displayName": "Username Security Policy Uri", "group": "security", "label": 
"security", "required": false, "type": "enum", "javaType": 
"org.eclipse.milo.opcua.stack.core.security.SecurityPolicy", "enum": [ "None", 
"Basic128Rsa15", "Basic256", "Basic256Sha256", "Aes128_Sha256_RsaOaep", 
"Aes256_Sha256_RsaPss" ], "deprecated": false, "autowired": false, "secret": 
false, "description": "Set the UserTokenPolicy used when" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"org.eclipse.milo.opcua.stack.core.types.builtin.DataValue", "description": 
"The Milo DataValue an OPC UA client wrote to the item: its 
getValue().getValue() is the value" },
+    "producerIn": { "carriers": [ "text", "bytes", "value", "pojo", "null" ], 
"description": "The new value of the item: an OPC UA built-in value such as a 
String, a number, a boolean, a Variant or a DataValue. Another object, such as 
a Map or a stream, is accepted but clients cannot read it" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "itemId": { "index": 0, "kind": "path", "displayName": "Item Id", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "ID of the item" },
     "bridgeErrorHandler": { "index": 1, "kind": "parameter", "displayName": 
"Bridge Error Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions (if possible) occurred 
while the Camel consumer is trying to pickup incoming  [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/plc4x.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/plc4x.json
index 561923b977ae..0f88ab6c212f 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/plc4x.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/plc4x.json
@@ -28,6 +28,11 @@
     "lazyStartProducer": { "index": 1, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
     "autowiredEnabled": { "index": 2, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "map" ], "description": "A Map of the tag 
names and the values read from the PLC, such as an Integer or a String, as the 
driver reads them; the polling consumer and a trigger give the same Map" },
+    "producerIn": { "carriers": [ "map" ], "description": "A Map of the tag 
names, each to a Map of the address of the tag and the value to write, such as 
{temperature: {\"%DB1:DINT\": 21}}; another body fails" },
+    "producerOut": { "carriers": [ "pojo" ], "javaType": 
"org.apache.plc4x.java.api.messages.PlcWriteResponse", "description": "The 
write response of PLC4X, with the response code of each tag" }
+  },
   "properties": {
     "driver": { "index": 0, "kind": "path", "displayName": "Driver", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "PLC4X connection string for the 
connection to the target" },
     "autoReconnect": { "index": 1, "kind": "parameter", "displayName": "Auto 
Reconnect", "group": "common", "label": "", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to reconnect when no connection is present upon doing a request" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/tahu-edge.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/tahu-edge.json
index f5b4c03aafa7..ec3d1734e85b 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/tahu-edge.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/tahu-edge.json
@@ -45,6 +45,10 @@
     "CamelTahuMessageUUID": { "index": 3, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": 
"java.util.UUID", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The UUID of a Sparkplug message", 
"constantName": "org.apache.camel.component.tahu.TahuConstants#MESSAGE_UUID" },
     "CamelTahuMessageSequenceNumber": { "index": 4, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The sequence number of a Sparkplug 
message", "constantName": 
"org.apache.camel.component.tahu.TahuConstants#MESSAGE_SEQUENCE_NUMBER" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "pojo", "null" ], "description": "A Tahu 
SparkplugBPayload with the metrics to publish, or no body: the metrics are then 
made from the CamelTahuMetric.<name> headers. Text, bytes or another body 
fails, as it does not convert to a SparkplugBPayload" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "groupId": { "index": 0, "kind": "path", "displayName": "Group Id", 
"group": "producer", "label": "producer", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "ID of the group" },
     "edgeNode": { "index": 1, "kind": "path", "displayName": "Edge Node", 
"group": "producer", "label": "producer", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "ID of the edge node" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/tahu-host.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/tahu-host.json
index e4c543322b41..41bb0aaf40b2 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/tahu-host.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/tahu-host.json
@@ -44,6 +44,9 @@
     "CamelTahuMessageUUID": { "index": 3, "kind": "header", "displayName": "", 
"group": "consumer", "label": "", "required": false, "javaType": 
"java.util.UUID", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The UUID of a Sparkplug message", 
"constantName": "org.apache.camel.component.tahu.TahuConstants#MESSAGE_UUID" },
     "CamelTahuMessageSequenceNumber": { "index": 4, "kind": "header", 
"displayName": "", "group": "consumer", "label": "", "required": false, 
"javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The sequence number of a Sparkplug 
message", "constantName": 
"org.apache.camel.component.tahu.TahuConstants#MESSAGE_SEQUENCE_NUMBER" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "null", "bytes" ], "description": "The body 
of the Sparkplug payload as a byte array when it has one, else no body, as for 
most messages and for the exchange of each metric. The metrics are the 
CamelTahuMetric.<name> headers, each a Tahu Metric" }
+  },
   "properties": {
     "hostId": { "index": 0, "kind": "path", "displayName": "Host Id", "group": 
"consumer", "label": "consumer", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "ID for the host 
application" },
     "checkClientIdLength": { "index": 1, "kind": "parameter", "displayName": 
"Check Client Id Length", "group": "common", "label": "common", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.tahu.TahuConfiguration", "configurationField": 
"configuration", "description": "MQTT client ID length check enabled" },
diff --git 
a/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coap+tcp.json
 
b/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coap+tcp.json
index 322e3ac0b329..9a6265a5f139 100644
--- 
a/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coap+tcp.json
+++ 
b/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coap+tcp.json
@@ -39,6 +39,12 @@
     "CamelCoapResponseCode": { "index": 3, "kind": "header", "displayName": 
"", "group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The CoAP response code sent by the external server. See 
RFC 7252 for details of what each code means.", "constantName": 
"org.apache.camel.coap.CoAPConstants#COAP_RESPONSE_CODE" },
     "Content-Type": { "index": 4, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The content type", "constantName": 
"org.apache.camel.coap.CoAPConstants#CONTENT_TYPE" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "The request payload as a byte array, empty for a request 
without a payload, such as a GET; with observe, the payload of each 
notification of the observed resource" },
+    "consumerReply": { "carriers": [ "null", "text", "bytes", "stream", "file" 
], "description": "The response payload: text, bytes, a stream, a file or no 
body. A Map, a POJO or a number is sent as an empty payload: convert or marshal 
it first" },
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"description": "The payload of a POST or a PUT: text, bytes, a stream or a 
file. A Map, a POJO or a number is sent as an empty payload: marshal it first. 
Without CamelCoapMethod, no body sends a GET and a body a POST" },
+    "producerOut": { "carriers": [ "bytes", "value" ], "byOption": [ { 
"option": "notify", "value": "true", "carriers": [ "unchanged" ] } ], 
"description": "The response payload as a byte array, empty for a response 
without a payload; a Boolean for a PING (CamelCoapMethod=PING). The response 
code is in the CamelCoapResponseCode header" }
+  },
   "properties": {
     "uri": { "index": 0, "kind": "path", "displayName": "Uri", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.net.URI", "deprecated": false, "autowired": false, "secret": false, 
"description": "The URI for the CoAP endpoint" },
     "coapMethodRestrict": { "index": 1, "kind": "parameter", "displayName": 
"Coap Method Restrict", "group": "consumer", "label": "consumer", "required": 
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "DELETE", 
"GET", "POST", "PUT" ], "multiEnum": true, "deprecated": false, "autowired": 
false, "secret": false, "description": "Comma separated list of methods that 
the CoAP consumer will bind to. The default is to bind to all methods (DELETE, 
GET, POST, PUT)." },
diff --git 
a/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coap.json
 
b/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coap.json
index 9c68f014aa82..88c4c89416d9 100644
--- 
a/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coap.json
+++ 
b/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coap.json
@@ -39,6 +39,12 @@
     "CamelCoapResponseCode": { "index": 3, "kind": "header", "displayName": 
"", "group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The CoAP response code sent by the external server. See 
RFC 7252 for details of what each code means.", "constantName": 
"org.apache.camel.coap.CoAPConstants#COAP_RESPONSE_CODE" },
     "Content-Type": { "index": 4, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The content type", "constantName": 
"org.apache.camel.coap.CoAPConstants#CONTENT_TYPE" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "The request payload as a byte array, empty for a request 
without a payload, such as a GET; with observe, the payload of each 
notification of the observed resource" },
+    "consumerReply": { "carriers": [ "null", "text", "bytes", "stream", "file" 
], "description": "The response payload: text, bytes, a stream, a file or no 
body. A Map, a POJO or a number is sent as an empty payload: convert or marshal 
it first" },
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"description": "The payload of a POST or a PUT: text, bytes, a stream or a 
file. A Map, a POJO or a number is sent as an empty payload: marshal it first. 
Without CamelCoapMethod, no body sends a GET and a body a POST" },
+    "producerOut": { "carriers": [ "bytes", "value" ], "byOption": [ { 
"option": "notify", "value": "true", "carriers": [ "unchanged" ] } ], 
"description": "The response payload as a byte array, empty for a response 
without a payload; a Boolean for a PING (CamelCoapMethod=PING). The response 
code is in the CamelCoapResponseCode header" }
+  },
   "properties": {
     "uri": { "index": 0, "kind": "path", "displayName": "Uri", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.net.URI", "deprecated": false, "autowired": false, "secret": false, 
"description": "The URI for the CoAP endpoint" },
     "coapMethodRestrict": { "index": 1, "kind": "parameter", "displayName": 
"Coap Method Restrict", "group": "consumer", "label": "consumer", "required": 
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "DELETE", 
"GET", "POST", "PUT" ], "multiEnum": true, "deprecated": false, "autowired": 
false, "secret": false, "description": "Comma separated list of methods that 
the CoAP consumer will bind to. The default is to bind to all methods (DELETE, 
GET, POST, PUT)." },
diff --git 
a/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coaps+tcp.json
 
b/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coaps+tcp.json
index 2d75470c488e..f69848818b02 100644
--- 
a/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coaps+tcp.json
+++ 
b/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coaps+tcp.json
@@ -39,6 +39,12 @@
     "CamelCoapResponseCode": { "index": 3, "kind": "header", "displayName": 
"", "group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The CoAP response code sent by the external server. See 
RFC 7252 for details of what each code means.", "constantName": 
"org.apache.camel.coap.CoAPConstants#COAP_RESPONSE_CODE" },
     "Content-Type": { "index": 4, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The content type", "constantName": 
"org.apache.camel.coap.CoAPConstants#CONTENT_TYPE" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "The request payload as a byte array, empty for a request 
without a payload, such as a GET; with observe, the payload of each 
notification of the observed resource" },
+    "consumerReply": { "carriers": [ "null", "text", "bytes", "stream", "file" 
], "description": "The response payload: text, bytes, a stream, a file or no 
body. A Map, a POJO or a number is sent as an empty payload: convert or marshal 
it first" },
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"description": "The payload of a POST or a PUT: text, bytes, a stream or a 
file. A Map, a POJO or a number is sent as an empty payload: marshal it first. 
Without CamelCoapMethod, no body sends a GET and a body a POST" },
+    "producerOut": { "carriers": [ "bytes", "value" ], "byOption": [ { 
"option": "notify", "value": "true", "carriers": [ "unchanged" ] } ], 
"description": "The response payload as a byte array, empty for a response 
without a payload; a Boolean for a PING (CamelCoapMethod=PING). The response 
code is in the CamelCoapResponseCode header" }
+  },
   "properties": {
     "uri": { "index": 0, "kind": "path", "displayName": "Uri", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.net.URI", "deprecated": false, "autowired": false, "secret": false, 
"description": "The URI for the CoAP endpoint" },
     "coapMethodRestrict": { "index": 1, "kind": "parameter", "displayName": 
"Coap Method Restrict", "group": "consumer", "label": "consumer", "required": 
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "DELETE", 
"GET", "POST", "PUT" ], "multiEnum": true, "deprecated": false, "autowired": 
false, "secret": false, "description": "Comma separated list of methods that 
the CoAP consumer will bind to. The default is to bind to all methods (DELETE, 
GET, POST, PUT)." },
diff --git 
a/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coaps.json
 
b/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coaps.json
index db85a2379c7f..be9883c933d2 100644
--- 
a/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coaps.json
+++ 
b/components/camel-coap/src/generated/resources/META-INF/org/apache/camel/coap/coaps.json
@@ -39,6 +39,12 @@
     "CamelCoapResponseCode": { "index": 3, "kind": "header", "displayName": 
"", "group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The CoAP response code sent by the external server. See 
RFC 7252 for details of what each code means.", "constantName": 
"org.apache.camel.coap.CoAPConstants#COAP_RESPONSE_CODE" },
     "Content-Type": { "index": 4, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The content type", "constantName": 
"org.apache.camel.coap.CoAPConstants#CONTENT_TYPE" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "The request payload as a byte array, empty for a request 
without a payload, such as a GET; with observe, the payload of each 
notification of the observed resource" },
+    "consumerReply": { "carriers": [ "null", "text", "bytes", "stream", "file" 
], "description": "The response payload: text, bytes, a stream, a file or no 
body. A Map, a POJO or a number is sent as an empty payload: convert or marshal 
it first" },
+    "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], 
"description": "The payload of a POST or a PUT: text, bytes, a stream or a 
file. A Map, a POJO or a number is sent as an empty payload: marshal it first. 
Without CamelCoapMethod, no body sends a GET and a body a POST" },
+    "producerOut": { "carriers": [ "bytes", "value" ], "byOption": [ { 
"option": "notify", "value": "true", "carriers": [ "unchanged" ] } ], 
"description": "The response payload as a byte array, empty for a response 
without a payload; a Boolean for a PING (CamelCoapMethod=PING). The response 
code is in the CamelCoapResponseCode header" }
+  },
   "properties": {
     "uri": { "index": 0, "kind": "path", "displayName": "Uri", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.net.URI", "deprecated": false, "autowired": false, "secret": false, 
"description": "The URI for the CoAP endpoint" },
     "coapMethodRestrict": { "index": 1, "kind": "parameter", "displayName": 
"Coap Method Restrict", "group": "consumer", "label": "consumer", "required": 
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "DELETE", 
"GET", "POST", "PUT" ], "multiEnum": true, "deprecated": false, "autowired": 
false, "secret": false, "description": "Comma separated list of methods that 
the CoAP consumer will bind to. The default is to bind to all methods (DELETE, 
GET, POST, PUT)." },
diff --git 
a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java 
b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java
index 48f827a77af0..e94645a93ace 100644
--- 
a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java
+++ 
b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java
@@ -38,6 +38,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.HeaderFilterStrategyAware;
@@ -80,6 +83,24 @@ import static 
org.eclipse.californium.scandium.config.DtlsConfig.DTLS_RECOMMENDE
  */
 @UriEndpoint(firstVersion = "2.16.0", scheme = 
"coap,coaps,coap+tcp,coaps+tcp", title = "CoAP", syntax = "coap:uri",
              category = { Category.IOT }, headersClass = CoAPConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.BYTES, javaType = "byte[]",
+                                   description = "The request payload as a 
byte array, empty for a request without a"
+                                                 + " payload, such as a GET; 
with observe, the payload of each"
+                                                 + " notification of the 
observed resource"),
+           consumerReply = @BodyType(value = { Carrier.NULL, Carrier.TEXT, 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE },
+                                     description = "The response payload: 
text, bytes, a stream, a file or no body. A Map,"
+                                                   + " a POJO or a number is 
sent as an empty payload: convert or marshal"
+                                                   + " it first"),
+           producerIn = @BodyType(value = { Carrier.NULL, Carrier.TEXT, 
Carrier.BYTES, Carrier.STREAM, Carrier.FILE },
+                                  description = "The payload of a POST or a 
PUT: text, bytes, a stream or a file. A Map,"
+                                                + " a POJO or a number is sent 
as an empty payload: marshal it first."
+                                                + " Without CamelCoapMethod, 
no body sends a GET and a body a POST"),
+           producerOut = @BodyType(value = { Carrier.BYTES, Carrier.VALUE },
+                                   byOption = @BodyType.When(option = 
"notify", value = "true",
+                                                             carriers = 
Carrier.UNCHANGED),
+                                   description = "The response payload as a 
byte array, empty for a response without a"
+                                                 + " payload; a Boolean for a 
PING (CamelCoapMethod=PING). The response"
+                                                 + " code is in the 
CamelCoapResponseCode header"))
 public class CoAPEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation, HeaderFilterStrategyAware {
     final static Logger LOGGER = LoggerFactory.getLogger(CoAPEndpoint.class);
     @UriPath
diff --git 
a/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/browse/milo-browse.json
 
b/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/browse/milo-browse.json
index cf30f028dc51..8a3c54e8be94 100644
--- 
a/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/browse/milo-browse.json
+++ 
b/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/browse/milo-browse.json
@@ -59,6 +59,10 @@
   "headers": {
     "CamelMiloNodeIds": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"List", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The node ids.", "constantName": 
"org.apache.camel.component.milo.MiloConstants#HEADER_NODE_IDS" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "The body is not 
read: the nodes to browse are the node IDs of the CamelMiloNodeIds header, or 
else the node option" },
+    "producerOut": { "carriers": [ "map" ], "description": "A Map of the 
browsed ExpandedNodeId to its Milo BrowseResult; the node IDs found are also in 
the CamelMiloNodeIds header, as a List of Strings for the milo-client producer" 
}
+  },
   "properties": {
     "endpointUri": { "index": 0, "kind": "path", "displayName": "Endpoint 
Uri", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The OPC UA server 
endpoint" },
     "clientId": { "index": 1, "kind": "parameter", "displayName": "Client Id", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "A virtual client id to 
force the creation of a new connection instance" },
diff --git 
a/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/client/milo-client.json
 
b/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/client/milo-client.json
index a4ecb41eb45e..d88fa10f1d74 100644
--- 
a/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/client/milo-client.json
+++ 
b/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/client/milo-client.json
@@ -62,6 +62,11 @@
     "CamelMiloAwait": { "index": 1, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The await setting for writes.", 
"constantName": "org.apache.camel.component.milo.MiloConstants#HEADER_AWAIT" },
     "CamelMiloNodeId": { "index": 2, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The node ID of the value, as configured in the 
node or nodes option. Not to be confused with CamelMiloNodeIds, the list of 
nodes that the producer reads.", "constantName": 
"org.apache.camel.component.milo.MiloConstants#HEADER_NODE_ID" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"org.eclipse.milo.opcua.stack.core.types.builtin.DataValue", "description": 
"The Milo DataValue of each change of a monitored node: its 
getValue().getValue() is the value, and the status code tells a good value from 
a lost connection. The node is in the CamelMiloNodeId header" },
+    "producerIn": { "carriers": [ "text", "bytes", "value", "pojo", "null" ], 
"description": "The value to write to the node, or the input arguments of the 
method: an OPC UA built-in value such as a String, a number, a boolean, a 
Variant or a DataValue. A stream, a file, a Map or a bean fails with 
Bad_EncodingError. With the CamelMiloNodeIds header the body is not read: the 
producer reads the values of those nodes" },
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"defaultAwaitWrites", "value": "true", "carriers": [ "pojo", "list" ] } ], 
"description": "The producer does not wait, unless the CamelMiloAwait header or 
defaultAwaitWrites says so; it then sets the result: the StatusCode of a write, 
the CallMethodResult of a method call, or a List of DataValue of the nodes 
read" }
+  },
   "properties": {
     "endpointUri": { "index": 0, "kind": "path", "displayName": "Endpoint 
Uri", "group": "common", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The OPC UA server 
endpoint" },
     "clientId": { "index": 1, "kind": "parameter", "displayName": "Client Id", 
"group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "A virtual client id to 
force the creation of a new connection instance" },
diff --git 
a/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/server/milo-server.json
 
b/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/server/milo-server.json
index c1cb7a71996b..17a52236abfe 100644
--- 
a/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/server/milo-server.json
+++ 
b/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/server/milo-server.json
@@ -45,6 +45,11 @@
     "userAuthenticationCredentials": { "index": 18, "kind": "property", 
"displayName": "User Authentication Credentials", "group": "security", "label": 
"security", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": true, 
"security": "secret", "description": "Set user password combinations in the 
form of user1:pwd1,user2:pwd2 Usernames and passwords will be URL decoded" },
     "usernameSecurityPolicyUri": { "index": 19, "kind": "property", 
"displayName": "Username Security Policy Uri", "group": "security", "label": 
"security", "required": false, "type": "enum", "javaType": 
"org.eclipse.milo.opcua.stack.core.security.SecurityPolicy", "enum": [ "None", 
"Basic128Rsa15", "Basic256", "Basic256Sha256", "Aes128_Sha256_RsaOaep", 
"Aes256_Sha256_RsaPss" ], "deprecated": false, "autowired": false, "secret": 
false, "description": "Set the UserTokenPolicy used when" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"org.eclipse.milo.opcua.stack.core.types.builtin.DataValue", "description": 
"The Milo DataValue an OPC UA client wrote to the item: its 
getValue().getValue() is the value" },
+    "producerIn": { "carriers": [ "text", "bytes", "value", "pojo", "null" ], 
"description": "The new value of the item: an OPC UA built-in value such as a 
String, a number, a boolean, a Variant or a DataValue. Another object, such as 
a Map or a stream, is accepted but clients cannot read it" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "itemId": { "index": 0, "kind": "path", "displayName": "Item Id", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "ID of the item" },
     "bridgeErrorHandler": { "index": 1, "kind": "parameter", "displayName": 
"Bridge Error Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions (if possible) occurred 
while the Camel consumer is trying to pickup incoming  [...]
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/browse/MiloBrowseEndpoint.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/browse/MiloBrowseEndpoint.java
index 7d0354d26738..386ff66286e1 100644
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/browse/MiloBrowseEndpoint.java
+++ 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/browse/MiloBrowseEndpoint.java
@@ -26,6 +26,9 @@ import org.apache.camel.component.milo.MiloConstants;
 import org.apache.camel.component.milo.client.MiloClientConfiguration;
 import org.apache.camel.component.milo.client.MiloClientConnection;
 import org.apache.camel.component.milo.client.MiloClientConnectionManager;
+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;
@@ -45,6 +48,13 @@ import static 
org.apache.camel.component.milo.MiloConstants.SCHEME_BROWSE;
  */
 @UriEndpoint(firstVersion = "3.15.0", scheme = SCHEME_BROWSE, syntax = 
"milo-browse:endpointUri", title = "OPC UA Browser",
              category = { Category.IOT }, producerOnly = true, headersClass = 
MiloConstants.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "The body is not read: the 
nodes to browse are the node IDs of the"
+                                                + " CamelMiloNodeIds header, 
or else the node option"),
+           producerOut = @BodyType(value = Carrier.MAP,
+                                   description = "A Map of the browsed 
ExpandedNodeId to its Milo BrowseResult; the node IDs"
+                                                 + " found are also in the 
CamelMiloNodeIds header, as a List of Strings for"
+                                                 + " the milo-client 
producer"))
 public class MiloBrowseEndpoint extends DefaultEndpoint {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(MiloBrowseEndpoint.class);
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientEndpoint.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientEndpoint.java
index 254b612f2f6b..a56cc0b70a9a 100644
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientEndpoint.java
+++ 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientEndpoint.java
@@ -23,6 +23,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.component.milo.MiloConstants;
+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;
@@ -37,6 +40,24 @@ import static 
org.apache.camel.component.milo.MiloConstants.SCHEME_CLIENT;
  */
 @UriEndpoint(firstVersion = "2.19.0", scheme = SCHEME_CLIENT, syntax = 
"milo-client:endpointUri", title = "OPC UA Client",
              category = { Category.IOT }, headersClass = MiloConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO,
+                                   javaType = 
"org.eclipse.milo.opcua.stack.core.types.builtin.DataValue",
+                                   description = "The Milo DataValue of each 
change of a monitored node: its"
+                                                 + " getValue().getValue() is 
the value, and the status code tells a good"
+                                                 + " value from a lost 
connection. The node is in the CamelMiloNodeId header"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.VALUE, Carrier.POJO, Carrier.NULL },
+                                  description = "The value to write to the 
node, or the input arguments of the method: an"
+                                                + " OPC UA built-in value such 
as a String, a number, a boolean, a Variant"
+                                                + " or a DataValue. A stream, 
a file, a Map or a bean fails with"
+                                                + " Bad_EncodingError. With 
the CamelMiloNodeIds header the body is not read:"
+                                                + " the producer reads the 
values of those nodes"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   byOption = @BodyType.When(option = 
"defaultAwaitWrites", value = "true",
+                                                             carriers = { 
Carrier.POJO, Carrier.LIST }),
+                                   description = "The producer does not wait, 
unless the CamelMiloAwait header or"
+                                                 + " defaultAwaitWrites says 
so; it then sets the result: the StatusCode"
+                                                 + " of a write, the 
CallMethodResult of a method call, or a List of"
+                                                 + " DataValue of the nodes 
read"))
 public class MiloClientEndpoint extends DefaultEndpoint {
 
     private final MiloClientConnectionManager connectionManager;
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/MiloServerEndpoint.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/MiloServerEndpoint.java
index 5a37426b1a23..9be1570c3465 100644
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/MiloServerEndpoint.java
+++ 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/MiloServerEndpoint.java
@@ -22,6 +22,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.component.milo.server.internal.CamelServerItem;
+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.UriPath;
@@ -34,6 +37,15 @@ import static 
org.apache.camel.component.milo.MiloConstants.SCHEME_SERVER;
  */
 @UriEndpoint(firstVersion = "2.19.0", scheme = SCHEME_SERVER, syntax = 
"milo-server:itemId", title = "OPC UA Server",
              category = { Category.IOT })
+@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO,
+                                   javaType = 
"org.eclipse.milo.opcua.stack.core.types.builtin.DataValue",
+                                   description = "The Milo DataValue an OPC UA 
client wrote to the item: its"
+                                                 + " getValue().getValue() is 
the value"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.VALUE, Carrier.POJO, Carrier.NULL },
+                                  description = "The new value of the item: an 
OPC UA built-in value such as a String, a"
+                                                + " number, a boolean, a 
Variant or a DataValue. Another object, such as a"
+                                                + " Map or a stream, is 
accepted but clients cannot read it"),
+           producerOut = @BodyType(Carrier.UNCHANGED))
 public class MiloServerEndpoint extends DefaultEndpoint {
 
     private volatile CamelServerItem item;
diff --git 
a/components/camel-plc4x/src/generated/resources/META-INF/org/apache/camel/component/plc4x/plc4x.json
 
b/components/camel-plc4x/src/generated/resources/META-INF/org/apache/camel/component/plc4x/plc4x.json
index 561923b977ae..0f88ab6c212f 100644
--- 
a/components/camel-plc4x/src/generated/resources/META-INF/org/apache/camel/component/plc4x/plc4x.json
+++ 
b/components/camel-plc4x/src/generated/resources/META-INF/org/apache/camel/component/plc4x/plc4x.json
@@ -28,6 +28,11 @@
     "lazyStartProducer": { "index": 1, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
     "autowiredEnabled": { "index": 2, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "map" ], "description": "A Map of the tag 
names and the values read from the PLC, such as an Integer or a String, as the 
driver reads them; the polling consumer and a trigger give the same Map" },
+    "producerIn": { "carriers": [ "map" ], "description": "A Map of the tag 
names, each to a Map of the address of the tag and the value to write, such as 
{temperature: {\"%DB1:DINT\": 21}}; another body fails" },
+    "producerOut": { "carriers": [ "pojo" ], "javaType": 
"org.apache.plc4x.java.api.messages.PlcWriteResponse", "description": "The 
write response of PLC4X, with the response code of each tag" }
+  },
   "properties": {
     "driver": { "index": 0, "kind": "path", "displayName": "Driver", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "PLC4X connection string for the 
connection to the target" },
     "autoReconnect": { "index": 1, "kind": "parameter", "displayName": "Auto 
Reconnect", "group": "common", "label": "", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to reconnect when no connection is present upon doing a request" },
diff --git 
a/components/camel-plc4x/src/main/java/org/apache/camel/component/plc4x/Plc4XEndpoint.java
 
b/components/camel-plc4x/src/main/java/org/apache/camel/component/plc4x/Plc4XEndpoint.java
index 9850533cd4ed..55fd8e923881 100644
--- 
a/components/camel-plc4x/src/main/java/org/apache/camel/component/plc4x/Plc4XEndpoint.java
+++ 
b/components/camel-plc4x/src/main/java/org/apache/camel/component/plc4x/Plc4XEndpoint.java
@@ -24,6 +24,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.PollingConsumer;
 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;
@@ -45,6 +48,16 @@ import org.slf4j.LoggerFactory;
  */
 @UriEndpoint(scheme = "plc4x", firstVersion = "3.20.0", title = "PLC4X",
              lenientProperties = true, syntax = "plc4x:driver", category = 
Category.IOT)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.MAP,
+                                   description = "A Map of the tag names and 
the values read from the PLC, such as an"
+                                                 + " Integer or a String, as 
the driver reads them; the polling consumer"
+                                                 + " and a trigger give the 
same Map"),
+           producerIn = @BodyType(value = Carrier.MAP,
+                                  description = "A Map of the tag names, each 
to a Map of the address of the tag and the"
+                                                + " value to write, such as 
{temperature: {\"%DB1:DINT\": 21}}; another body"
+                                                + " fails"),
+           producerOut = @BodyType(value = Carrier.POJO, javaType = 
"org.apache.plc4x.java.api.messages.PlcWriteResponse",
+                                   description = "The write response of PLC4X, 
with the response code of each tag"))
 public class Plc4XEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(Plc4XEndpoint.class);
 
diff --git 
a/components/camel-tahu/src/generated/resources/META-INF/org/apache/camel/component/tahu/tahu-edge.json
 
b/components/camel-tahu/src/generated/resources/META-INF/org/apache/camel/component/tahu/tahu-edge.json
index f5b4c03aafa7..ec3d1734e85b 100644
--- 
a/components/camel-tahu/src/generated/resources/META-INF/org/apache/camel/component/tahu/tahu-edge.json
+++ 
b/components/camel-tahu/src/generated/resources/META-INF/org/apache/camel/component/tahu/tahu-edge.json
@@ -45,6 +45,10 @@
     "CamelTahuMessageUUID": { "index": 3, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": 
"java.util.UUID", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The UUID of a Sparkplug message", 
"constantName": "org.apache.camel.component.tahu.TahuConstants#MESSAGE_UUID" },
     "CamelTahuMessageSequenceNumber": { "index": 4, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The sequence number of a Sparkplug 
message", "constantName": 
"org.apache.camel.component.tahu.TahuConstants#MESSAGE_SEQUENCE_NUMBER" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "pojo", "null" ], "description": "A Tahu 
SparkplugBPayload with the metrics to publish, or no body: the metrics are then 
made from the CamelTahuMetric.<name> headers. Text, bytes or another body 
fails, as it does not convert to a SparkplugBPayload" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "groupId": { "index": 0, "kind": "path", "displayName": "Group Id", 
"group": "producer", "label": "producer", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "ID of the group" },
     "edgeNode": { "index": 1, "kind": "path", "displayName": "Edge Node", 
"group": "producer", "label": "producer", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "ID of the edge node" },
diff --git 
a/components/camel-tahu/src/generated/resources/META-INF/org/apache/camel/component/tahu/tahu-host.json
 
b/components/camel-tahu/src/generated/resources/META-INF/org/apache/camel/component/tahu/tahu-host.json
index e4c543322b41..41bb0aaf40b2 100644
--- 
a/components/camel-tahu/src/generated/resources/META-INF/org/apache/camel/component/tahu/tahu-host.json
+++ 
b/components/camel-tahu/src/generated/resources/META-INF/org/apache/camel/component/tahu/tahu-host.json
@@ -44,6 +44,9 @@
     "CamelTahuMessageUUID": { "index": 3, "kind": "header", "displayName": "", 
"group": "consumer", "label": "", "required": false, "javaType": 
"java.util.UUID", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The UUID of a Sparkplug message", 
"constantName": "org.apache.camel.component.tahu.TahuConstants#MESSAGE_UUID" },
     "CamelTahuMessageSequenceNumber": { "index": 4, "kind": "header", 
"displayName": "", "group": "consumer", "label": "", "required": false, 
"javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The sequence number of a Sparkplug 
message", "constantName": 
"org.apache.camel.component.tahu.TahuConstants#MESSAGE_SEQUENCE_NUMBER" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "null", "bytes" ], "description": "The body 
of the Sparkplug payload as a byte array when it has one, else no body, as for 
most messages and for the exchange of each metric. The metrics are the 
CamelTahuMetric.<name> headers, each a Tahu Metric" }
+  },
   "properties": {
     "hostId": { "index": 0, "kind": "path", "displayName": "Host Id", "group": 
"consumer", "label": "consumer", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "ID for the host 
application" },
     "checkClientIdLength": { "index": 1, "kind": "parameter", "displayName": 
"Check Client Id Length", "group": "common", "label": "common", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.tahu.TahuConfiguration", "configurationField": 
"configuration", "description": "MQTT client ID length check enabled" },
diff --git 
a/components/camel-tahu/src/main/java/org/apache/camel/component/tahu/TahuEdgeEndpoint.java
 
b/components/camel-tahu/src/main/java/org/apache/camel/component/tahu/TahuEdgeEndpoint.java
index 96f5487a7fda..e7fa9bacdfef 100644
--- 
a/components/camel-tahu/src/main/java/org/apache/camel/component/tahu/TahuEdgeEndpoint.java
+++ 
b/components/camel-tahu/src/main/java/org/apache/camel/component/tahu/TahuEdgeEndpoint.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.HeaderFilterStrategy;
 import org.apache.camel.spi.HeaderFilterStrategyAware;
 import org.apache.camel.spi.Metadata;
@@ -47,6 +50,11 @@ import org.eclipse.tahu.message.model.SparkplugBPayloadMap;
              producerOnly = true,
              category = { Category.MESSAGING, Category.IOT, 
Category.MONITORING },
              headersClass = TahuConstants.class)
+@BodyTypes(producerIn = @BodyType(value = { Carrier.POJO, Carrier.NULL },
+                                  description = "A Tahu SparkplugBPayload with 
the metrics to publish, or no body: the"
+                                                + " metrics are then made from 
the CamelTahuMetric.<name> headers. Text, bytes"
+                                                + " or another body fails, as 
it does not convert to a SparkplugBPayload"),
+           producerOut = @BodyType(Carrier.UNCHANGED))
 public class TahuEdgeEndpoint extends TahuDefaultEndpoint implements 
HeaderFilterStrategyAware {
 
     @UriPath(label = "producer", description = "ID of the group")
diff --git 
a/components/camel-tahu/src/main/java/org/apache/camel/component/tahu/TahuHostEndpoint.java
 
b/components/camel-tahu/src/main/java/org/apache/camel/component/tahu/TahuHostEndpoint.java
index 4f0dcc5f2655..711da519f38e 100644
--- 
a/components/camel-tahu/src/main/java/org/apache/camel/component/tahu/TahuHostEndpoint.java
+++ 
b/components/camel-tahu/src/main/java/org/apache/camel/component/tahu/TahuHostEndpoint.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.UriPath;
@@ -35,6 +38,10 @@ import org.apache.camel.util.ObjectHelper;
              consumerOnly = true,
              category = { Category.MESSAGING, Category.IOT, 
Category.MONITORING },
              headersClass = TahuConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = { Carrier.NULL, Carrier.BYTES },
+                                   description = "The body of the Sparkplug 
payload as a byte array when it has one, else"
+                                                 + " no body, as for most 
messages and for the exchange of each metric. The"
+                                                 + " metrics are the 
CamelTahuMetric.<name> headers, each a Tahu Metric"))
 public class TahuHostEndpoint extends TahuDefaultEndpoint {
 
     @UriPath(label = "consumer", description = "ID for the host application")

Reply via email to