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

    CAMEL-24961: Catalog body types for keycloak, ldap, spring-ldap, ldif, 
spiffe, openfga, opa, openfeature, crypto and xmlsecurity (#28416)
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../apache/camel/catalog/components/crypto.json    |   4 +
 .../apache/camel/catalog/components/keycloak.json  |   5 +
 .../org/apache/camel/catalog/components/ldap.json  |   4 +
 .../org/apache/camel/catalog/components/ldif.json  |   4 +
 .../org/apache/camel/catalog/components/opa.json   |   4 +
 .../camel/catalog/components/openfeature.json      |   4 +
 .../apache/camel/catalog/components/openfga.json   |   4 +
 .../apache/camel/catalog/components/spiffe.json    |   4 +
 .../camel/catalog/components/spring-ldap.json      |   4 +
 .../camel/catalog/components/xmlsecurity-sign.json |   4 +
 .../catalog/components/xmlsecurity-verify.json     |   4 +
 .../camel/catalog/docs/openfga-component.adoc      |   6 +-
 .../camel/catalog/docs/spring-ldap-component.adoc  |   4 +-
 .../org/apache/camel/component/crypto/crypto.json  |   4 +
 .../component/crypto/DigitalSignatureEndpoint.java |  12 +
 .../apache/camel/component/keycloak/keycloak.json  |   5 +
 .../camel/component/keycloak/KeycloakEndpoint.java | 268 +++++++++++++++++++++
 .../org/apache/camel/component/ldap/ldap.json      |   4 +
 .../apache/camel/component/ldap/LdapEndpoint.java  |  10 +
 .../org/apache/camel/component/ldif/ldif.json      |   4 +
 .../apache/camel/component/ldif/LdifEndpoint.java  |  10 +
 .../org/apache/camel/component/opa/opa.json        |   4 +
 .../apache/camel/component/opa/OpaEndpoint.java    |  13 +
 .../camel/component/openfeature/openfeature.json   |   4 +
 .../component/openfeature/OpenFeatureEndpoint.java |  21 ++
 .../apache/camel/component/openfga/openfga.json    |   4 +
 .../src/main/docs/openfga-component.adoc           |   6 +-
 .../camel/component/openfga/OpenFgaEndpoint.java   |  51 ++++
 .../org/apache/camel/component/spiffe/spiffe.json  |   4 +
 .../camel/component/spiffe/SpiffeEndpoint.java     |  23 ++
 .../camel/component/springldap/spring-ldap.json    |   4 +
 .../src/main/docs/spring-ldap-component.adoc       |   4 +-
 .../component/springldap/SpringLdapEndpoint.java   |  19 ++
 .../component/xmlsecurity/xmlsecurity-sign.json    |   4 +
 .../component/xmlsecurity/xmlsecurity-verify.json  |   4 +
 .../component/xmlsecurity/XmlSignerEndpoint.java   |  17 ++
 .../component/xmlsecurity/XmlVerifierEndpoint.java |  14 ++
 .../jbang/core/commands/ai/CatalogDocsTest.java    |   8 +-
 38 files changed, 562 insertions(+), 14 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/crypto.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/crypto.json
index 78094572f0c4..c490e9e89045 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/crypto.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/crypto.json
@@ -53,6 +53,10 @@
     "CamelSignatureKeyStoreAlias": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The alias used to query the KeyStore 
for keys and Certificates to be used in signing and verifying exchanges", 
"constantName": 
"org.apache.camel.component.crypto.DigitalSignatureConstants#KEYSTORE_ALIAS" },
     "CamelSignatureKeyStorePassword": { "index": 4, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "char[]", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The password used to access an aliased 
PrivateKey in the KeyStore.", "constantName": 
"org.apache.camel.component.crypto.DigitalSignatureConstants#KEYSTORE_PASSWORD" 
}
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file", "null" ], 
"description": "The payload to sign or verify, read as a stream: text, bytes, a 
stream or a file; no body is an empty payload. A Map, a POJO or a number fails: 
marshal it first. Without stream caching a stream body is used up. The 
signature is not in the body: sign sets it, Base64 encoded, in the 
CamelDigitalSignature header (signatureHeaderName), which verify reads" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "The body is 
unchanged: a signature that does not verify fails the exchange with a 
SignatureException" }
+  },
   "properties": {
     "cryptoOperation": { "index": 0, "kind": "path", "displayName": "Crypto 
Operation", "group": "producer", "label": "", "required": true, "type": "enum", 
"javaType": "org.apache.camel.component.crypto.CryptoOperation", "enum": [ 
"sign", "verify" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.crypto.DigitalSignatureConfiguration", 
"configurationField": "configuration", "description": "Set the Crypto o [...]
     "name": { "index": 1, "kind": "path", "displayName": "Name", "group": 
"producer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.crypto.DigitalSignatureConfiguration", 
"configurationField": "configuration", "description": "The logical name of this 
operation." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/keycloak.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/keycloak.json
index 91c717d8cfab..3c9bd12bf19d 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/keycloak.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/keycloak.json
@@ -127,6 +127,11 @@
     "CamelKeycloakFederatedUserId": { "index": 65, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The user id at the external identity 
provider", "constantName": 
"org.apache.camel.component.keycloak.KeycloakConstants#FEDERATED_USER_ID" },
     "CamelKeycloakFederatedUsername": { "index": 66, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The username at the external identity 
provider", "constantName": 
"org.apache.camel.component.keycloak.KeycloakConstants#FEDERATED_USERNAME" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"org.keycloak.representations.idm.EventRepresentation", "byOption": [ { 
"option": "eventType", "value": "admin-events", "carriers": [ "pojo" ], 
"javaType": "org.keycloak.representations.idm.AdminEventRepresentation" } ], 
"description": "One message per event: the EventRepresentation of a user event 
such as a login, or the AdminEventRepresentation with eventType=admin-events. 
The CamelKeycloakEventType header says event or admin-event" },
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": 
"pojoRequest", "value": "true", "carriers": [ "pojo" ] } ], "description": 
"Mostly not read: the operations take their input from headers, such as 
CamelKeycloakRealmName and CamelKeycloakUserId. With pojoRequest=true the 
create and update operations take the Keycloak representation, such as a 
UserRepresentation for createUser; a body of another type does nothing and 
keeps the body. The bulk operations take a List when t [...]
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"operation", "value": "createRealm", "carriers": [ "text" ], "javaType": 
"java.lang.String" }, { "option": "operation", "value": "deleteRealm", 
"carriers": [ "text" ], "javaType": "java.lang.String" }, { "option": 
"operation", "value": "getRealm", "carriers": [ "pojo" ], "javaType": 
"org.keycloak.representations.idm.RealmRepresentation" }, { "option": 
"operation", "value": "updateRealm", "carriers": [ "text" ], "ja [...]
+  },
   "properties": {
     "label": { "index": 0, "kind": "path", "displayName": "Label", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.keycloak.KeycloakConfiguration", 
"configurationField": "configuration", "description": "Logical name" },
     "accessToken": { "index": 1, "kind": "parameter", "displayName": "Access 
Token", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.keycloak.KeycloakConfiguration", 
"configurationField": "configuration", "description": "Pre-obtained access 
token for authentication. When provided, this token will be used dire [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ldap.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ldap.json
index 40f40de475b9..9511ea5f92bd 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ldap.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ldap.json
@@ -27,6 +27,10 @@
     "lazyStartProducer": { "index": 0, "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": 1, "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": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"description": "The LDAP search filter, such as (objectClass=person), as text, 
or bytes, a stream or a file of it. A Map or a POJO is read as its toString(), 
which is not a filter, and no body fails as an empty filter" },
+    "producerOut": { "carriers": [ "list" ], "javaType": 
"java.util.List<javax.naming.directory.SearchResult>", "description": "The 
entries found under the base DN: a List of SearchResult, empty when none match, 
all the pages of them with pageSize" }
+  },
   "properties": {
     "dirContextName": { "index": 0, "kind": "path", "displayName": "Dir 
Context Name", "group": "producer", "label": "", "required": true, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Name of either a javax.naming.directory.DirContext, or java.util.Hashtable, or 
Map bean to lookup in the registry. If the bean is either a Hashtable or Map 
then a new javax.naming.directory.DirContext insta [...]
     "base": { "index": 1, "kind": "parameter", "displayName": "Base", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "ou=system", "description": "The base DN for searches." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ldif.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ldif.json
index 5a63cb4ed51c..0f9640e447c8 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ldif.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ldif.json
@@ -27,6 +27,10 @@
     "lazyStartProducer": { "index": 0, "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": 1, "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": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"description": "The LDIF text, starting with version: 1, or bytes, a stream or 
a file of it. With allowUrlBody, a text that is not LDIF is read as the URL of 
the LDIF file; otherwise it fails, as does a Map or a POJO" },
+    "producerOut": { "carriers": [ "list", "null" ], "description": "A List of 
one status String per LDIF entry: success, or the error message from the 
server, which can be empty. No body or an empty body gives null" }
+  },
   "properties": {
     "ldapConnectionName": { "index": 0, "kind": "path", "displayName": "Ldap 
Connection Name", "group": "producer", "label": "", "required": true, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
name of the LdapConnection bean to pull from the registry. Note that this must 
be of scope prototype to avoid it being shared among threads or using a 
connection that has timed out." },
     "lazyStartProducer": { "index": 1, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "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 produc [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opa.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opa.json
index 7ce60ba344d6..2191ee4824eb 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opa.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/opa.json
@@ -55,6 +55,10 @@
     "CamelOpaDecisionFailedOpen": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Set to true only when the exchange 
proceeded because failOpen is enabled and the policy could not be evaluated - 
nothing authorized it. Absent on every decision an actual policy made, so a 
route or an audit trail can tell the  [...]
     "CamelOpaBatchDecision": { "index": 4, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"java.util.List<Boolean>", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The per-element 
allow\/deny verdicts of a batch evaluation (batch=true), as a List of Boolean 
parallel to the List body. Always overwritten by the component. An element 
whose evaluation could not be reached is denie [...]
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": "batch", 
"value": "true", "carriers": [ "list" ] } ], "description": "Not read unless 
includeBody=true: then a String, number, boolean, Map or List goes into the 
input document as it is, and another body as its string form (a POJO as its 
toString). With batch=true a List, one input document per element: another body 
fails" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "The body is 
kept: the verdict is in the CamelOpaDecisionAllow header and the decision 
document in CamelOpaDecision, or with batch=true a List of Boolean per element 
in CamelOpaBatchDecision" }
+  },
   "properties": {
     "policyPath": { "index": 0, "kind": "path", "displayName": "Policy Path", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Path of the Rego rule head 
to evaluate, relative to the OPA data document. For a rule named allow in a 
policy declaring package authz.orders, this is authz\/orders\/allow. The path 
is taken from the endpoint only: i [...]
     "allowKey": { "index": 1, "kind": "parameter", "displayName": "Allow Key", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "allow", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The key to read the allow\/deny verdict from 
when the policy returns an object rather than a plain  [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openfeature.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openfeature.json
index 5d69ffb5a8b3..a7aaf376c5be 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openfeature.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openfeature.json
@@ -50,6 +50,10 @@
     "CamelOpenFeatureReason": { "index": 5, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The reason string returned by the provider for this 
evaluation.", "constantName": 
"org.apache.camel.component.openfeature.OpenFeatureConstants#EVALUATION_REASON" 
},
     "CamelOpenFeatureErrorCode": { "index": 6, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The error code when the evaluation 
failed (e.g. FLAG_NOT_FOUND, TYPE_MISMATCH).", "constantName": 
"org.apache.camel.component.openfeature.OpenFeatureConstants#EVALUATION_ERROR_CODE"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "Not read: the flag 
key, the targeting key and the context come from the options and the 
CamelOpenFeature headers. With contextFromBody, a Map body is the evaluation 
context, and any other body is ignored" },
+    "producerOut": { "carriers": [ "value", "text" ], "dependsOn": [ 
"resultProperty" ], "byOption": [ { "option": "evaluationType", "value": 
"boolean", "carriers": [ "value" ], "javaType": "java.lang.Boolean" }, { 
"option": "evaluationType", "value": "isEnabled", "carriers": [ "value" ], 
"javaType": "java.lang.Boolean" }, { "option": "evaluationType", "value": 
"variant", "carriers": [ "text" ], "javaType": "java.lang.String" } ], 
"description": "The value of the flag: a Boolean for a bo [...]
+  },
   "properties": {
     "domain": { "index": 0, "kind": "path", "displayName": "Domain", "group": 
"producer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The OpenFeature domain to bind the 
provider to." },
     "evaluationType": { "index": 1, "kind": "path", "displayName": "Evaluation 
Type", "group": "producer", "label": "", "required": false, "type": "enum", 
"javaType": "java.lang.String", "enum": [ "boolean", "variant", "isEnabled" ], 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
evaluation type. 'boolean' and 'isEnabled' use boolean evaluation 
(getBooleanValue). 'variant' uses string evaluation (getStringValue). When not 
set, the type is inferred from defa [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openfga.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openfga.json
index be93cd5d098c..fc618a885c5f 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openfga.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openfga.json
@@ -71,6 +71,10 @@
     "CamelOpenFgaWrittenTuples": { "index": 8, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "How many relationship tuples the 
writeTuples operation wrote.", "constantName": 
"org.apache.camel.component.openfga.OpenFgaConstants#WRITTEN_TUPLES" },
     "CamelOpenFgaDeletedTuples": { "index": 9, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "How many relationship tuples the 
deleteTuples operation deleted.", "constantName": 
"org.apache.camel.component.openfga.OpenFgaConstants#DELETED_TUPLES" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "dependsOn": [ "object" ], 
"byOption": [ { "option": "operation", "value": "batchCheck", "carriers": [ 
"list", "text", "bytes", "stream", "file" ] }, { "option": "operation", 
"value": "writeTuples", "carriers": [ "map", "list", "pojo" ] }, { "option": 
"operation", "value": "deleteTuples", "carriers": [ "map", "list", "pojo" ] } 
], "description": "batchCheck: the objects to check, as a List or 
comma-separated text. writeTuples and deleteTuples: a [...]
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"operation", "value": "check", "carriers": [ "unchanged" ] }, { "option": 
"operation", "value": "batchCheck", "carriers": [ "list" ], "javaType": 
"java.util.List<java.lang.String>" }, { "option": "operation", "value": 
"listObjects", "carriers": [ "list" ], "javaType": 
"java.util.List<java.lang.String>" }, { "option": "operation", "value": 
"listRelations", "carriers": [ "list" ], "javaType": "java.util.List<java.lan 
[...]
+  },
   "properties": {
     "operation": { "index": 0, "kind": "path", "displayName": "Operation", 
"group": "producer", "label": "", "required": true, "type": "enum", "javaType": 
"org.apache.camel.component.openfga.OpenFgaOperation", "enum": [ "check", 
"batchCheck", "listObjects", "listRelations", "listUsers", "readTuples", 
"readChanges", "expand", "writeTuples", "deleteTuples" ], "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
operation to perform. The opera [...]
     "apiUrl": { "index": 1, "kind": "parameter", "displayName": "Api Url", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "http:\/\/localhost:8080", 
"configurationClass": 
"org.apache.camel.component.openfga.OpenFgaConfiguration", 
"configurationField": "configuration", "description": "The base URL of the 
OpenFGA HTTP API, without a trailing path. The default as [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spiffe.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spiffe.json
index 1c3dbda49cc6..a6f4c170bc82 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spiffe.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spiffe.json
@@ -41,6 +41,10 @@
     "CamelSpiffeSpiffeId": { "index": 3, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The SPIFFE ID of the returned SVID.", 
"constantName": "org.apache.camel.component.spiffe.SpiffeConstants#SPIFFE_ID" },
     "CamelSpiffeExpiry": { "index": 4, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"java.util.Date", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The expiry of the returned SVID: the 
token expiry for fetchJwtSvid, or the leaf certificate's notAfter for 
fetchX509Svid.", "constantName": 
"org.apache.camel.component.spiffe.SpiffeConstants#EXPIRY" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "Only 
validateJwtSvid reads the body: the token as text, when neither the 
CamelSpiffeToken header nor an Authorization: Bearer header carries it. The 
fetch operations ignore the body" },
+    "producerOut": { "carriers": [ "list" ], "javaType": 
"java.util.List<java.security.cert.X509Certificate>", "dependsOn": [ 
"allowOperationHeader" ], "byOption": [ { "option": "x509Response", "value": 
"svid", "carriers": [ "pojo" ], "javaType": "io.spiffe.svid.x509svid.X509Svid" 
}, { "option": "x509Response", "value": "id", "carriers": [ "unchanged" ] }, { 
"option": "operation", "value": "fetchJwtSvid", "carriers": [ "text" ], 
"javaType": "java.lang.String" }, { "option": "operation",  [...]
+  },
   "properties": {
     "label": { "index": 0, "kind": "path", "displayName": "Label", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Logical name of the endpoint" },
     "audience": { "index": 1, "kind": "parameter", "displayName": "Audience", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "The comma-separated audience(s) to request for 
a JWT-SVID (fetchJwtSvid) or to validate against (validateJwtSvid). fetc [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ldap.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ldap.json
index bfeb9f96566f..9cff0ad27e32 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ldap.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-ldap.json
@@ -27,6 +27,10 @@
     "lazyStartProducer": { "index": 0, "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": 1, "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": {
+    "producerIn": { "carriers": [ "map" ], "description": "A Map of the 
parameters of the operation: dn (not needed when the context source has a base 
DN), filter for search and authenticate, attributes (an Attributes) for bind, 
password for authenticate, modificationItems (a ModificationItem array) for 
modify_attributes, and function and request for function_driven. Another body, 
such as a JSON text, fails" },
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "SEARCH", "carriers": [ "list" ], "javaType": 
"java.util.List<javax.naming.directory.Attributes>" }, { "option": "operation", 
"value": "FUNCTION_DRIVEN", "carriers": [ "unknown" ] } ], "description": 
"bind, unbind, authenticate and modify_attributes leave the Map as it was; a 
failed authenticate throws an exception. search gives a List of the Attributes 
of the entries found, function_driven  [...]
+  },
   "properties": {
     "templateName": { "index": 0, "kind": "path", "displayName": "Template 
Name", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Name of the Spring LDAP 
Template bean" },
     "operation": { "index": 1, "kind": "parameter", "displayName": 
"Operation", "group": "producer", "label": "", "required": true, "type": 
"enum", "javaType": "org.apache.camel.component.springldap.LdapOperation", 
"enum": [ "SEARCH", "BIND", "UNBIND", "AUTHENTICATE", "MODIFY_ATTRIBUTES", 
"FUNCTION_DRIVEN" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The LDAP operation to be performed." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xmlsecurity-sign.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xmlsecurity-sign.json
index 962310279ef6..0b01985daa26 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xmlsecurity-sign.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xmlsecurity-sign.json
@@ -71,6 +71,10 @@
     "CamelXmlSignatureXAdESPrefix": { "index": 13, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "overwrites the XAdES prefix parameter 
value", "constantName": 
"org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants#HEADER_XADES_PREFIX"
 },
     "CamelCharsetName": { "index": 14, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The name of the charset", "constantName": 
"org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants#CHARSET_NAME" 
}
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file", "pojo" ], 
"format": "xml", "byOption": [ { "option": "plainText", "value": "true", 
"carriers": [ "text", "bytes", "stream", "file" ] } ], "description": "The XML 
document to sign: text, bytes, a stream, a file or a DOM Document. A Map, a 
POJO that is not XML or no body fails: marshal it first. With plainText (or the 
CamelXmlSignatureMessageIsPlainText header) the body is any text, which an 
enveloping signature wraps" },
+    "producerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", "format": 
"xml", "description": "The signed XML document as bytes, in the 
outputXmlEncoding when set: the document with the signature for enveloped and 
detached, or the Signature element with the payload inside for enveloping" }
+  },
   "properties": {
     "name": { "index": 0, "kind": "path", "displayName": "Name", "group": 
"producer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The name part in the URI can be chosen 
by the user to distinguish between different signer endpoints within the camel 
context." },
     "addKeyInfoReference": { "index": 1, "kind": "parameter", "displayName": 
"Add Key Info Reference", "group": "producer", "label": "", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, 
"configurationClass": 
"org.apache.camel.component.xmlsecurity.processor.XmlSignerConfiguration", 
"configurationField": "configuration", "description": "In order to protect the 
KeyInfo element from tamperi [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xmlsecurity-verify.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xmlsecurity-verify.json
index b624742dc4e5..cdd98c50bf1d 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xmlsecurity-verify.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xmlsecurity-verify.json
@@ -56,6 +56,10 @@
     "CamelXmlSignatureXAdESPrefix": { "index": 8, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "overwrites the XAdES prefix parameter 
value", "constantName": 
"org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants#HEADER_XADES_PREFIX"
 },
     "CamelCharsetName": { "index": 9, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The name of the charset", "constantName": 
"org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants#CHARSET_NAME" 
}
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file", "pojo" ], 
"format": "xml", "description": "The signed XML document: text, bytes, a 
stream, a file or a DOM Document. A document without a Signature element, a 
body that is not XML or no body fails" },
+    "producerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"dependsOn": [ "xmlSignature2Message" ], "description": "The verified content 
as bytes, in the outputXmlEncoding when set: by default the document without 
its Signature for an enveloped or detached signature, and the content of the 
Object for an enveloping one, which is the plain text when it was signed with 
plainText; outputNodeSearchType picks another node. A signature that does not 
verify fails the exchange" }
+  },
   "properties": {
     "name": { "index": 0, "kind": "path", "displayName": "Name", "group": 
"producer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The name part in the URI can be chosen 
by the user to distinguish between different verify endpoints within the camel 
context." },
     "baseUri": { "index": 1, "kind": "parameter", "displayName": "Base Uri", 
"group": "producer", "label": "producer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.xmlsecurity.processor.XmlVerifierConfiguration", 
"configurationField": "configuration", "description": "You can set a base URI 
which is used in the URI dereferencing. Relative URIs are then concat [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openfga-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openfga-component.adoc
index 73de540a0070..517718a756ad 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openfga-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openfga-component.adoc
@@ -288,9 +288,9 @@ with it. Both replace the body with a `List<String>`.
 
 === Granting and revoking access
 
-A route that creates a resource usually has to grant access to it too. 
`writeTuples` takes its tuples from the
-body, and falls back to the endpoint's `user`/`relation`/`object` when the 
body carries none — which is the shape
-that reads best right after a resource was created:
+A route that creates a resource usually has to grant access to it too. 
`writeTuples` takes its tuple from the
+endpoint's `user`/`relation`/`object` when they are configured, and from the 
body only when none of them is — the
+configured tuple is the shape that reads best right after a resource was 
created:
 
 [tabs]
 ====
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-ldap-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-ldap-component.adoc
index 67f3103b5cf0..f312ebf4d1c9 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-ldap-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/spring-ldap-component.adoc
@@ -59,8 +59,8 @@ this map must contain at least an entry with the key *`dn`* 
(not needed for func
 specifies the root node for the LDAP operation to be performed. Other
 entries of the map are operation-specific (see below).
 
-The body of the message remains unchanged for the `bind` and `unbind`
-operations. For the `search` and `function_driven` operations, the body is set 
to the result of
+The body of the message remains unchanged for the `bind`, `unbind`, 
`authenticate`
+and `modify_attributes` operations. For the `search` and `function_driven` 
operations, the body is set to the result of
 the search, see
 
http://static.springsource.org/spring-ldap/site/apidocs/org/springframework/ldap/core/LdapTemplate.html#search%28java.lang.String,%20java.lang.String,%20int,%20org.springframework.ldap.core.AttributesMapper%29[http://static.springsource.org/spring-ldap/site/apidocs/org/springframework/ldap/core/LdapTemplate.html#search%28java.lang.String,%20java.lang.String,%20int,%20org.springframework.ldap.core.AttributesMapper%29].
 
diff --git 
a/components/camel-crypto/src/generated/resources/META-INF/org/apache/camel/component/crypto/crypto.json
 
b/components/camel-crypto/src/generated/resources/META-INF/org/apache/camel/component/crypto/crypto.json
index 78094572f0c4..c490e9e89045 100644
--- 
a/components/camel-crypto/src/generated/resources/META-INF/org/apache/camel/component/crypto/crypto.json
+++ 
b/components/camel-crypto/src/generated/resources/META-INF/org/apache/camel/component/crypto/crypto.json
@@ -53,6 +53,10 @@
     "CamelSignatureKeyStoreAlias": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The alias used to query the KeyStore 
for keys and Certificates to be used in signing and verifying exchanges", 
"constantName": 
"org.apache.camel.component.crypto.DigitalSignatureConstants#KEYSTORE_ALIAS" },
     "CamelSignatureKeyStorePassword": { "index": 4, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "char[]", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The password used to access an aliased 
PrivateKey in the KeyStore.", "constantName": 
"org.apache.camel.component.crypto.DigitalSignatureConstants#KEYSTORE_PASSWORD" 
}
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file", "null" ], 
"description": "The payload to sign or verify, read as a stream: text, bytes, a 
stream or a file; no body is an empty payload. A Map, a POJO or a number fails: 
marshal it first. Without stream caching a stream body is used up. The 
signature is not in the body: sign sets it, Base64 encoded, in the 
CamelDigitalSignature header (signatureHeaderName), which verify reads" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "The body is 
unchanged: a signature that does not verify fails the exchange with a 
SignatureException" }
+  },
   "properties": {
     "cryptoOperation": { "index": 0, "kind": "path", "displayName": "Crypto 
Operation", "group": "producer", "label": "", "required": true, "type": "enum", 
"javaType": "org.apache.camel.component.crypto.CryptoOperation", "enum": [ 
"sign", "verify" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.crypto.DigitalSignatureConfiguration", 
"configurationField": "configuration", "description": "Set the Crypto o [...]
     "name": { "index": 1, "kind": "path", "displayName": "Name", "group": 
"producer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.crypto.DigitalSignatureConfiguration", 
"configurationField": "configuration", "description": "The logical name of this 
operation." },
diff --git 
a/components/camel-crypto/src/main/java/org/apache/camel/component/crypto/DigitalSignatureEndpoint.java
 
b/components/camel-crypto/src/main/java/org/apache/camel/component/crypto/DigitalSignatureEndpoint.java
index a4e85340ba83..9ea33ce2ce24 100644
--- 
a/components/camel-crypto/src/main/java/org/apache/camel/component/crypto/DigitalSignatureEndpoint.java
+++ 
b/components/camel-crypto/src/main/java/org/apache/camel/component/crypto/DigitalSignatureEndpoint.java
@@ -28,6 +28,9 @@ import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.component.crypto.processor.SigningProcessor;
 import org.apache.camel.component.crypto.processor.VerifyingProcessor;
+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;
@@ -38,6 +41,15 @@ import org.apache.camel.support.DefaultEndpoint;
 @UriEndpoint(firstVersion = "2.3.0", scheme = "crypto", title = "Crypto 
(JCE)", syntax = "crypto:cryptoOperation:name",
              remote = false, producerOnly = true, category = { 
Category.SECURITY, Category.TRANSFORMATION },
              headersClass = DigitalSignatureConstants.class)
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE, Carrier.NULL },
+                                  description = "The payload to sign or 
verify, read as a stream: text, bytes, a stream or a"
+                                                + " file; no body is an empty 
payload. A Map, a POJO or a number fails: marshal"
+                                                + " it first. Without stream 
caching a stream body is used up. The signature"
+                                                + " is not in the body: sign 
sets it, Base64 encoded, in the"
+                                                + " CamelDigitalSignature 
header (signatureHeaderName), which verify reads"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   description = "The body is unchanged: a 
signature that does not verify fails the exchange"
+                                                 + " with a 
SignatureException"))
 public class DigitalSignatureEndpoint extends DefaultEndpoint {
     @UriParam
     private DigitalSignatureConfiguration configuration;
diff --git 
a/components/camel-keycloak/src/generated/resources/META-INF/org/apache/camel/component/keycloak/keycloak.json
 
b/components/camel-keycloak/src/generated/resources/META-INF/org/apache/camel/component/keycloak/keycloak.json
index 91c717d8cfab..3c9bd12bf19d 100644
--- 
a/components/camel-keycloak/src/generated/resources/META-INF/org/apache/camel/component/keycloak/keycloak.json
+++ 
b/components/camel-keycloak/src/generated/resources/META-INF/org/apache/camel/component/keycloak/keycloak.json
@@ -127,6 +127,11 @@
     "CamelKeycloakFederatedUserId": { "index": 65, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The user id at the external identity 
provider", "constantName": 
"org.apache.camel.component.keycloak.KeycloakConstants#FEDERATED_USER_ID" },
     "CamelKeycloakFederatedUsername": { "index": 66, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The username at the external identity 
provider", "constantName": 
"org.apache.camel.component.keycloak.KeycloakConstants#FEDERATED_USERNAME" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"org.keycloak.representations.idm.EventRepresentation", "byOption": [ { 
"option": "eventType", "value": "admin-events", "carriers": [ "pojo" ], 
"javaType": "org.keycloak.representations.idm.AdminEventRepresentation" } ], 
"description": "One message per event: the EventRepresentation of a user event 
such as a login, or the AdminEventRepresentation with eventType=admin-events. 
The CamelKeycloakEventType header says event or admin-event" },
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": 
"pojoRequest", "value": "true", "carriers": [ "pojo" ] } ], "description": 
"Mostly not read: the operations take their input from headers, such as 
CamelKeycloakRealmName and CamelKeycloakUserId. With pojoRequest=true the 
create and update operations take the Keycloak representation, such as a 
UserRepresentation for createUser; a body of another type does nothing and 
keeps the body. The bulk operations take a List when t [...]
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"operation", "value": "createRealm", "carriers": [ "text" ], "javaType": 
"java.lang.String" }, { "option": "operation", "value": "deleteRealm", 
"carriers": [ "text" ], "javaType": "java.lang.String" }, { "option": 
"operation", "value": "getRealm", "carriers": [ "pojo" ], "javaType": 
"org.keycloak.representations.idm.RealmRepresentation" }, { "option": 
"operation", "value": "updateRealm", "carriers": [ "text" ], "ja [...]
+  },
   "properties": {
     "label": { "index": 0, "kind": "path", "displayName": "Label", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.keycloak.KeycloakConfiguration", 
"configurationField": "configuration", "description": "Logical name" },
     "accessToken": { "index": 1, "kind": "parameter", "displayName": "Access 
Token", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.keycloak.KeycloakConfiguration", 
"configurationField": "configuration", "description": "Pre-obtained access 
token for authentication. When provided, this token will be used dire [...]
diff --git 
a/components/camel-keycloak/src/main/java/org/apache/camel/component/keycloak/KeycloakEndpoint.java
 
b/components/camel-keycloak/src/main/java/org/apache/camel/component/keycloak/KeycloakEndpoint.java
index f5ba8add5b19..a85258706031 100644
--- 
a/components/camel-keycloak/src/main/java/org/apache/camel/component/keycloak/KeycloakEndpoint.java
+++ 
b/components/camel-keycloak/src/main/java/org/apache/camel/component/keycloak/KeycloakEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -35,6 +38,271 @@ import org.keycloak.admin.client.KeycloakBuilder;
 @UriEndpoint(firstVersion = "4.15.0", scheme = "keycloak", title = "Keycloak",
              syntax = "keycloak:label", category = { Category.SECURITY, 
Category.MANAGEMENT },
              headersClass = KeycloakConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO, javaType = 
"org.keycloak.representations.idm.EventRepresentation",
+                                   byOption = @BodyType.When(option = 
"eventType", value = "admin-events",
+                                                             carriers = 
Carrier.POJO,
+                                                             javaType = 
"org.keycloak.representations.idm.AdminEventRepresentation"),
+                                   description = "One message per event: the 
EventRepresentation of a user event such as a"
+                                                 + " login, or the 
AdminEventRepresentation with eventType=admin-events. The"
+                                                 + " CamelKeycloakEventType 
header says event or admin-event"),
+           producerIn = @BodyType(value = Carrier.ANY,
+                                  byOption = @BodyType.When(option = 
"pojoRequest", value = "true", carriers = Carrier.POJO),
+                                  description = "Mostly not read: the 
operations take their input from headers, such as"
+                                                + " CamelKeycloakRealmName and 
CamelKeycloakUserId. With pojoRequest=true the"
+                                                + " create and update 
operations take the Keycloak representation, such as a"
+                                                + " UserRepresentation for 
createUser; a body of another type does nothing"
+                                                + " and keeps the body. The 
bulk operations take a List when"
+                                                + " the header is not set: of 
UserRepresentation for bulkCreateUsers and"
+                                                + " bulkUpdateUsers, of String 
ids or role names for the others."
+                                                + " introspectToken, 
revokeAccessToken and revokeRefreshToken take the token"
+                                                + " as text when the 
CamelKeycloakToken header is not set"),
+           producerOut = @BodyType(value = Carrier.UNKNOWN,
+                                   byOption = {
+                                           @BodyType.When(option = 
"operation", value = "createRealm", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "deleteRealm", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getRealm", carriers = Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.RealmRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "updateRealm", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "createUser", carriers = Carrier.POJO,
+                                                          javaType = 
"jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "deleteUser", carriers = Carrier.POJO,
+                                                          javaType = 
"jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "getUser", carriers = Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.UserRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "updateUser", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listUsers", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.UserRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "searchUsers", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.UserRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "createRole", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "deleteRole", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getRole", carriers = Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.RoleRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "updateRole", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listRoles", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.RoleRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "assignRoleToUser",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "removeRoleFromUser",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getUserRoles", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.RoleRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "createGroup", carriers = Carrier.POJO,
+                                                          javaType = 
"jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "deleteGroup", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getGroup", carriers = Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.GroupRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "updateGroup", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listGroups", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.GroupRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "addUserToGroup",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "removeUserFromGroup",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listUserGroups",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.GroupRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "createClient", carriers = Carrier.POJO,
+                                                          javaType = 
"jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "deleteClient", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getClient", carriers = Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.ClientRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "updateClient", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listClients", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.ClientRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "resetUserPassword",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "createClientRole",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "deleteClientRole",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getClientRole",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.RoleRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "updateClientRole",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listClientRoles",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.RoleRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "assignClientRoleToUser",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "removeClientRoleFromUser",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listUserSessions",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.UserSessionRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "logoutUser", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "logoutAllUsers",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "revokeAccessToken",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "revokeRefreshToken",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "introspectToken",
+                                                          carriers = 
Carrier.MAP,
+                                                          javaType = 
"java.util.Map<java.lang.String, java.lang.Object>"),
+                                           @BodyType.When(option = 
"operation", value = "pushNotBefore",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "createClientScope",
+                                                          carriers = 
Carrier.POJO, javaType = "jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "deleteClientScope",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getClientScope",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.ClientScopeRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "updateClientScope",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listClientScopes",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.ClientScopeRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "createIdentityProvider",
+                                                          carriers = 
Carrier.POJO, javaType = "jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "deleteIdentityProvider",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getIdentityProvider",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.IdentityProviderRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "updateIdentityProvider",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listIdentityProviders",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.IdentityProviderRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "createResource",
+                                                          carriers = 
Carrier.POJO, javaType = "jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "deleteResource",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getResource", carriers = Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.authorization.ResourceRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "updateResource",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listResources",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.authorization.ResourceRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "createResourcePolicy",
+                                                          carriers = 
Carrier.POJO, javaType = "jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "deleteResourcePolicy",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getResourcePolicy",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.authorization.PolicyRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "updateResourcePolicy",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listResourcePolicies",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.authorization.PolicyRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "createResourcePermission",
+                                                          carriers = 
Carrier.POJO, javaType = "jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "deleteResourcePermission",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getResourcePermission",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.authorization.PolicyRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "updateResourcePermission",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listResourcePermissions",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.authorization.PolicyRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "evaluatePermission",
+                                                          carriers = 
Carrier.MAP,
+                                                          javaType = 
"java.util.Map<java.lang.String, java.lang.Object>"),
+                                           @BodyType.When(option = 
"operation", value = "getUserAttributes",
+                                                          carriers = 
Carrier.MAP,
+                                                          javaType = 
"java.util.Map<java.lang.String, java.util.List<java.lang.String>>"),
+                                           @BodyType.When(option = 
"operation", value = "setUserAttribute",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "deleteUserAttribute",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getUserCredentials",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.CredentialRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "deleteUserCredential",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "sendVerifyEmail",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "sendPasswordResetEmail",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "addRequiredAction",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "removeRequiredAction",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "executeActionsEmail",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getClientSecret",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.CredentialRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "regenerateClientSecret",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.CredentialRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "bulkCreateUsers",
+                                                          carriers = 
Carrier.MAP,
+                                                          javaType = 
"java.util.Map<java.lang.String, java.lang.Object>"),
+                                           @BodyType.When(option = 
"operation", value = "bulkDeleteUsers",
+                                                          carriers = 
Carrier.MAP,
+                                                          javaType = 
"java.util.Map<java.lang.String, java.lang.Object>"),
+                                           @BodyType.When(option = 
"operation", value = "bulkAssignRolesToUser",
+                                                          carriers = 
Carrier.MAP,
+                                                          javaType = 
"java.util.Map<java.lang.String, java.lang.Object>"),
+                                           @BodyType.When(option = 
"operation", value = "bulkAssignRoleToUsers",
+                                                          carriers = 
Carrier.MAP,
+                                                          javaType = 
"java.util.Map<java.lang.String, java.lang.Object>"),
+                                           @BodyType.When(option = 
"operation", value = "bulkUpdateUsers",
+                                                          carriers = 
Carrier.MAP,
+                                                          javaType = 
"java.util.Map<java.lang.String, java.lang.Object>"),
+                                           @BodyType.When(option = 
"operation", value = "createOrganization",
+                                                          carriers = 
Carrier.POJO, javaType = "jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "updateOrganization",
+                                                          carriers = 
Carrier.POJO, javaType = "jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "deleteOrganization",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getOrganization",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"org.keycloak.representations.idm.OrganizationRepresentation"),
+                                           @BodyType.When(option = 
"operation", value = "listOrganizations",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.OrganizationRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "searchOrganizations",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.OrganizationRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "addOrganizationMember",
+                                                          carriers = 
Carrier.POJO, javaType = "jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "removeOrganizationMember",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listOrganizationMembers",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.MemberRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "linkOrganizationIdentityProvider",
+                                                          carriers = 
Carrier.POJO, javaType = "jakarta.ws.rs.core.Response"),
+                                           @BodyType.When(option = 
"operation", value = "unlinkOrganizationIdentityProvider",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "listOrganizationIdentityProviders",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.IdentityProviderRepresentation>"),
+                                           @BodyType.When(option = 
"operation", value = "addFederatedIdentity",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "removeFederatedIdentity",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "getFederatedIdentities",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<org.keycloak.representations.idm.FederatedIdentityRepresentation>")
 },
+                                   description = "Depends on the operation, 
which the CamelKeycloakOperation header can set:"
+                                                 + " get gives the Keycloak 
representation, such as a UserRepresentation, and"
+                                                 + " list and search a List of 
them. Most create operations, deleteUser and"
+                                                 + " some organization 
operations give the JAX-RS Response, whose status says"
+                                                 + " whether it worked (a 409 
or 404 is no error); the others"
+                                                 + " a confirmation text such 
as Realm deleted successfully. The bulk"
+                                                 + " operations give a Map 
with total, success, failed and results"))
 public class KeycloakEndpoint extends ScheduledPollEndpoint implements 
EndpointServiceLocation {
 
     private Keycloak keycloakClient;
diff --git 
a/components/camel-ldap/src/generated/resources/META-INF/org/apache/camel/component/ldap/ldap.json
 
b/components/camel-ldap/src/generated/resources/META-INF/org/apache/camel/component/ldap/ldap.json
index 40f40de475b9..9511ea5f92bd 100644
--- 
a/components/camel-ldap/src/generated/resources/META-INF/org/apache/camel/component/ldap/ldap.json
+++ 
b/components/camel-ldap/src/generated/resources/META-INF/org/apache/camel/component/ldap/ldap.json
@@ -27,6 +27,10 @@
     "lazyStartProducer": { "index": 0, "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": 1, "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": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"description": "The LDAP search filter, such as (objectClass=person), as text, 
or bytes, a stream or a file of it. A Map or a POJO is read as its toString(), 
which is not a filter, and no body fails as an empty filter" },
+    "producerOut": { "carriers": [ "list" ], "javaType": 
"java.util.List<javax.naming.directory.SearchResult>", "description": "The 
entries found under the base DN: a List of SearchResult, empty when none match, 
all the pages of them with pageSize" }
+  },
   "properties": {
     "dirContextName": { "index": 0, "kind": "path", "displayName": "Dir 
Context Name", "group": "producer", "label": "", "required": true, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Name of either a javax.naming.directory.DirContext, or java.util.Hashtable, or 
Map bean to lookup in the registry. If the bean is either a Hashtable or Map 
then a new javax.naming.directory.DirContext insta [...]
     "base": { "index": 1, "kind": "parameter", "displayName": "Base", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "ou=system", "description": "The base DN for searches." },
diff --git 
a/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapEndpoint.java
 
b/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapEndpoint.java
index 8633ae0b817e..9c41bef75c94 100644
--- 
a/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapEndpoint.java
+++ 
b/components/camel-ldap/src/main/java/org/apache/camel/component/ldap/LdapEndpoint.java
@@ -25,6 +25,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.RuntimeCamelException;
+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,13 @@ import org.apache.camel.support.DefaultEndpoint;
  */
 @UriEndpoint(firstVersion = "1.5.0", scheme = "ldap", title = "LDAP", syntax = 
"ldap:dirContextName", producerOnly = true,
              category = { Category.DATABASE, Category.SECURITY })
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  description = "The LDAP search filter, such 
as (objectClass=person), as text, or bytes, a"
+                                                + " stream or a file of it. A 
Map or a POJO is read as its toString(), which is"
+                                                + " not a filter, and no body 
fails as an empty filter"),
+           producerOut = @BodyType(value = Carrier.LIST, javaType = 
"java.util.List<javax.naming.directory.SearchResult>",
+                                   description = "The entries found under the 
base DN: a List of SearchResult, empty when"
+                                                 + " none match, all the pages 
of them with pageSize"))
 public class LdapEndpoint extends DefaultEndpoint {
     public static final String SYSTEM_DN = "ou=system";
     public static final String OBJECT_SCOPE = "object";
diff --git 
a/components/camel-ldif/src/generated/resources/META-INF/org/apache/camel/component/ldif/ldif.json
 
b/components/camel-ldif/src/generated/resources/META-INF/org/apache/camel/component/ldif/ldif.json
index 5a63cb4ed51c..0f9640e447c8 100644
--- 
a/components/camel-ldif/src/generated/resources/META-INF/org/apache/camel/component/ldif/ldif.json
+++ 
b/components/camel-ldif/src/generated/resources/META-INF/org/apache/camel/component/ldif/ldif.json
@@ -27,6 +27,10 @@
     "lazyStartProducer": { "index": 0, "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": 1, "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": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"description": "The LDIF text, starting with version: 1, or bytes, a stream or 
a file of it. With allowUrlBody, a text that is not LDIF is read as the URL of 
the LDIF file; otherwise it fails, as does a Map or a POJO" },
+    "producerOut": { "carriers": [ "list", "null" ], "description": "A List of 
one status String per LDIF entry: success, or the error message from the 
server, which can be empty. No body or an empty body gives null" }
+  },
   "properties": {
     "ldapConnectionName": { "index": 0, "kind": "path", "displayName": "Ldap 
Connection Name", "group": "producer", "label": "", "required": true, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
name of the LdapConnection bean to pull from the registry. Note that this must 
be of scope prototype to avoid it being shared among threads or using a 
connection that has timed out." },
     "lazyStartProducer": { "index": 1, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "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 produc [...]
diff --git 
a/components/camel-ldif/src/main/java/org/apache/camel/component/ldif/LdifEndpoint.java
 
b/components/camel-ldif/src/main/java/org/apache/camel/component/ldif/LdifEndpoint.java
index fda73cbb5fa0..190174b34fbd 100644
--- 
a/components/camel-ldif/src/main/java/org/apache/camel/component/ldif/LdifEndpoint.java
+++ 
b/components/camel-ldif/src/main/java/org/apache/camel/component/ldif/LdifEndpoint.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;
@@ -31,6 +34,13 @@ import org.apache.camel.support.DefaultEndpoint;
  */
 @UriEndpoint(firstVersion = "2.20.0", scheme = "ldif", title = "LDIF", syntax 
= "ldif:ldapConnectionName", producerOnly = true,
              category = { Category.DATABASE, Category.SECURITY })
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  description = "The LDIF text, starting with 
version: 1, or bytes, a stream or a file of it."
+                                                + " With allowUrlBody, a text 
that is not LDIF is read as the URL of the LDIF"
+                                                + " file; otherwise it fails, 
as does a Map or a POJO"),
+           producerOut = @BodyType(value = { Carrier.LIST, Carrier.NULL },
+                                   description = "A List of one status String 
per LDIF entry: success, or the error message from"
+                                                 + " the server, which can be 
empty. No body or an empty body gives null"))
 public class LdifEndpoint extends DefaultEndpoint {
     @UriPath
     @Metadata(required = true)
diff --git 
a/components/camel-opa/src/generated/resources/META-INF/org/apache/camel/component/opa/opa.json
 
b/components/camel-opa/src/generated/resources/META-INF/org/apache/camel/component/opa/opa.json
index 7ce60ba344d6..2191ee4824eb 100644
--- 
a/components/camel-opa/src/generated/resources/META-INF/org/apache/camel/component/opa/opa.json
+++ 
b/components/camel-opa/src/generated/resources/META-INF/org/apache/camel/component/opa/opa.json
@@ -55,6 +55,10 @@
     "CamelOpaDecisionFailedOpen": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Set to true only when the exchange 
proceeded because failOpen is enabled and the policy could not be evaluated - 
nothing authorized it. Absent on every decision an actual policy made, so a 
route or an audit trail can tell the  [...]
     "CamelOpaBatchDecision": { "index": 4, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"java.util.List<Boolean>", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The per-element 
allow\/deny verdicts of a batch evaluation (batch=true), as a List of Boolean 
parallel to the List body. Always overwritten by the component. An element 
whose evaluation could not be reached is denie [...]
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": "batch", 
"value": "true", "carriers": [ "list" ] } ], "description": "Not read unless 
includeBody=true: then a String, number, boolean, Map or List goes into the 
input document as it is, and another body as its string form (a POJO as its 
toString). With batch=true a List, one input document per element: another body 
fails" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "The body is 
kept: the verdict is in the CamelOpaDecisionAllow header and the decision 
document in CamelOpaDecision, or with batch=true a List of Boolean per element 
in CamelOpaBatchDecision" }
+  },
   "properties": {
     "policyPath": { "index": 0, "kind": "path", "displayName": "Policy Path", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Path of the Rego rule head 
to evaluate, relative to the OPA data document. For a rule named allow in a 
policy declaring package authz.orders, this is authz\/orders\/allow. The path 
is taken from the endpoint only: i [...]
     "allowKey": { "index": 1, "kind": "parameter", "displayName": "Allow Key", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "allow", "configurationClass": 
"org.apache.camel.component.opa.OpaConfiguration", "configurationField": 
"configuration", "description": "The key to read the allow\/deny verdict from 
when the policy returns an object rather than a plain  [...]
diff --git 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaEndpoint.java
 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaEndpoint.java
index f605b2280572..434e6473899d 100644
--- 
a/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaEndpoint.java
+++ 
b/components/camel-opa/src/main/java/org/apache/camel/component/opa/OpaEndpoint.java
@@ -24,6 +24,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -40,6 +43,16 @@ import org.slf4j.LoggerFactory;
 @UriEndpoint(firstVersion = "4.23.0", scheme = "opa", title = "OPA",
              syntax = "opa:policyPath", producerOnly = true, category = { 
Category.SECURITY },
              headersClass = OpaConstants.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  byOption = @BodyType.When(option = "batch", 
value = "true", carriers = Carrier.LIST),
+                                  description = "Not read unless 
includeBody=true: then a String, number, boolean, Map or"
+                                                + " List goes into the input 
document as it is, and another body as its"
+                                                + " string form (a POJO as its 
toString). With batch=true a List, one input"
+                                                + " document per element: 
another body fails"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   description = "The body is kept: the 
verdict is in the CamelOpaDecisionAllow header and"
+                                                 + " the decision document in 
CamelOpaDecision, or with batch=true a List"
+                                                 + " of Boolean per element in 
CamelOpaBatchDecision"))
 public class OpaEndpoint extends DefaultEndpoint {
 
     static final String WASM_MODE = "wasm";
diff --git 
a/components/camel-openfeature/src/generated/resources/META-INF/org/apache/camel/component/openfeature/openfeature.json
 
b/components/camel-openfeature/src/generated/resources/META-INF/org/apache/camel/component/openfeature/openfeature.json
index 5d69ffb5a8b3..a7aaf376c5be 100644
--- 
a/components/camel-openfeature/src/generated/resources/META-INF/org/apache/camel/component/openfeature/openfeature.json
+++ 
b/components/camel-openfeature/src/generated/resources/META-INF/org/apache/camel/component/openfeature/openfeature.json
@@ -50,6 +50,10 @@
     "CamelOpenFeatureReason": { "index": 5, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The reason string returned by the provider for this 
evaluation.", "constantName": 
"org.apache.camel.component.openfeature.OpenFeatureConstants#EVALUATION_REASON" 
},
     "CamelOpenFeatureErrorCode": { "index": 6, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The error code when the evaluation 
failed (e.g. FLAG_NOT_FOUND, TYPE_MISMATCH).", "constantName": 
"org.apache.camel.component.openfeature.OpenFeatureConstants#EVALUATION_ERROR_CODE"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "Not read: the flag 
key, the targeting key and the context come from the options and the 
CamelOpenFeature headers. With contextFromBody, a Map body is the evaluation 
context, and any other body is ignored" },
+    "producerOut": { "carriers": [ "value", "text" ], "dependsOn": [ 
"resultProperty" ], "byOption": [ { "option": "evaluationType", "value": 
"boolean", "carriers": [ "value" ], "javaType": "java.lang.Boolean" }, { 
"option": "evaluationType", "value": "isEnabled", "carriers": [ "value" ], 
"javaType": "java.lang.Boolean" }, { "option": "evaluationType", "value": 
"variant", "carriers": [ "text" ], "javaType": "java.lang.String" } ], 
"description": "The value of the flag: a Boolean for a bo [...]
+  },
   "properties": {
     "domain": { "index": 0, "kind": "path", "displayName": "Domain", "group": 
"producer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The OpenFeature domain to bind the 
provider to." },
     "evaluationType": { "index": 1, "kind": "path", "displayName": "Evaluation 
Type", "group": "producer", "label": "", "required": false, "type": "enum", 
"javaType": "java.lang.String", "enum": [ "boolean", "variant", "isEnabled" ], 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
evaluation type. 'boolean' and 'isEnabled' use boolean evaluation 
(getBooleanValue). 'variant' uses string evaluation (getStringValue). When not 
set, the type is inferred from defa [...]
diff --git 
a/components/camel-openfeature/src/main/java/org/apache/camel/component/openfeature/OpenFeatureEndpoint.java
 
b/components/camel-openfeature/src/main/java/org/apache/camel/component/openfeature/OpenFeatureEndpoint.java
index 9cdcf57dcb86..b44fd2b62bc1 100644
--- 
a/components/camel-openfeature/src/main/java/org/apache/camel/component/openfeature/OpenFeatureEndpoint.java
+++ 
b/components/camel-openfeature/src/main/java/org/apache/camel/component/openfeature/OpenFeatureEndpoint.java
@@ -41,6 +41,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;
@@ -54,6 +57,24 @@ import org.slf4j.LoggerFactory;
 @UriEndpoint(firstVersion = "4.23.0", scheme = "openfeature", title = 
"OpenFeature",
              syntax = "openfeature:domain/evaluationType",
              producerOnly = true, category = { Category.CLOUD }, headersClass 
= OpenFeatureConstants.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "Not read: the flag key, the 
targeting key and the context come from the"
+                                                + " options and the 
CamelOpenFeature headers. With contextFromBody, a Map body"
+                                                + " is the evaluation context, 
and any other body is ignored"),
+           producerOut = @BodyType(value = { Carrier.VALUE, Carrier.TEXT }, 
dependsOn = "resultProperty",
+                                   byOption = {
+                                           @BodyType.When(option = 
"evaluationType", value = "boolean",
+                                                          carriers = 
Carrier.VALUE, javaType = "java.lang.Boolean"),
+                                           @BodyType.When(option = 
"evaluationType", value = "isEnabled",
+                                                          carriers = 
Carrier.VALUE, javaType = "java.lang.Boolean"),
+                                           @BodyType.When(option = 
"evaluationType", value = "variant",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String") },
+                                   description = "The value of the flag: a 
Boolean for a boolean evaluation, which is the"
+                                                 + " default when defaultValue 
is true or false, or else a String; the"
+                                                 + " defaultValue when the 
flag is missing or of another type. The"
+                                                 + " 
CamelOpenFeatureEvaluationType header overrides the evaluation type. With"
+                                                 + " resultProperty the value 
goes to that exchange property and the body is"
+                                                 + " unchanged"))
 public class OpenFeatureEndpoint extends DefaultEndpoint {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(OpenFeatureEndpoint.class);
diff --git 
a/components/camel-openfga/src/generated/resources/META-INF/org/apache/camel/component/openfga/openfga.json
 
b/components/camel-openfga/src/generated/resources/META-INF/org/apache/camel/component/openfga/openfga.json
index be93cd5d098c..fc618a885c5f 100644
--- 
a/components/camel-openfga/src/generated/resources/META-INF/org/apache/camel/component/openfga/openfga.json
+++ 
b/components/camel-openfga/src/generated/resources/META-INF/org/apache/camel/component/openfga/openfga.json
@@ -71,6 +71,10 @@
     "CamelOpenFgaWrittenTuples": { "index": 8, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "How many relationship tuples the 
writeTuples operation wrote.", "constantName": 
"org.apache.camel.component.openfga.OpenFgaConstants#WRITTEN_TUPLES" },
     "CamelOpenFgaDeletedTuples": { "index": 9, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "How many relationship tuples the 
deleteTuples operation deleted.", "constantName": 
"org.apache.camel.component.openfga.OpenFgaConstants#DELETED_TUPLES" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "dependsOn": [ "object" ], 
"byOption": [ { "option": "operation", "value": "batchCheck", "carriers": [ 
"list", "text", "bytes", "stream", "file" ] }, { "option": "operation", 
"value": "writeTuples", "carriers": [ "map", "list", "pojo" ] }, { "option": 
"operation", "value": "deleteTuples", "carriers": [ "map", "list", "pojo" ] } 
], "description": "batchCheck: the objects to check, as a List or 
comma-separated text. writeTuples and deleteTuples: a [...]
+    "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": 
"operation", "value": "check", "carriers": [ "unchanged" ] }, { "option": 
"operation", "value": "batchCheck", "carriers": [ "list" ], "javaType": 
"java.util.List<java.lang.String>" }, { "option": "operation", "value": 
"listObjects", "carriers": [ "list" ], "javaType": 
"java.util.List<java.lang.String>" }, { "option": "operation", "value": 
"listRelations", "carriers": [ "list" ], "javaType": "java.util.List<java.lan 
[...]
+  },
   "properties": {
     "operation": { "index": 0, "kind": "path", "displayName": "Operation", 
"group": "producer", "label": "", "required": true, "type": "enum", "javaType": 
"org.apache.camel.component.openfga.OpenFgaOperation", "enum": [ "check", 
"batchCheck", "listObjects", "listRelations", "listUsers", "readTuples", 
"readChanges", "expand", "writeTuples", "deleteTuples" ], "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
operation to perform. The opera [...]
     "apiUrl": { "index": 1, "kind": "parameter", "displayName": "Api Url", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "http:\/\/localhost:8080", 
"configurationClass": 
"org.apache.camel.component.openfga.OpenFgaConfiguration", 
"configurationField": "configuration", "description": "The base URL of the 
OpenFGA HTTP API, without a trailing path. The default as [...]
diff --git a/components/camel-openfga/src/main/docs/openfga-component.adoc 
b/components/camel-openfga/src/main/docs/openfga-component.adoc
index 73de540a0070..517718a756ad 100644
--- a/components/camel-openfga/src/main/docs/openfga-component.adoc
+++ b/components/camel-openfga/src/main/docs/openfga-component.adoc
@@ -288,9 +288,9 @@ with it. Both replace the body with a `List<String>`.
 
 === Granting and revoking access
 
-A route that creates a resource usually has to grant access to it too. 
`writeTuples` takes its tuples from the
-body, and falls back to the endpoint's `user`/`relation`/`object` when the 
body carries none — which is the shape
-that reads best right after a resource was created:
+A route that creates a resource usually has to grant access to it too. 
`writeTuples` takes its tuple from the
+endpoint's `user`/`relation`/`object` when they are configured, and from the 
body only when none of them is — the
+configured tuple is the shape that reads best right after a resource was 
created:
 
 [tabs]
 ====
diff --git 
a/components/camel-openfga/src/main/java/org/apache/camel/component/openfga/OpenFgaEndpoint.java
 
b/components/camel-openfga/src/main/java/org/apache/camel/component/openfga/OpenFgaEndpoint.java
index 9d8238c54501..89a47e4452c2 100644
--- 
a/components/camel-openfga/src/main/java/org/apache/camel/component/openfga/OpenFgaEndpoint.java
+++ 
b/components/camel-openfga/src/main/java/org/apache/camel/component/openfga/OpenFgaEndpoint.java
@@ -27,6 +27,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -44,6 +47,54 @@ import org.slf4j.LoggerFactory;
 @UriEndpoint(firstVersion = "4.23.0", scheme = "openfga", title = "OpenFGA",
              syntax = "openfga:operation", producerOnly = true, category = { 
Category.SECURITY },
              headersClass = OpenFgaConstants.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY, dependsOn = "object",
+                                  byOption = {
+                                          @BodyType.When(option = "operation", 
value = "batchCheck",
+                                                         carriers = {
+                                                                 Carrier.LIST, 
Carrier.TEXT, Carrier.BYTES, Carrier.STREAM,
+                                                                 Carrier.FILE 
}),
+                                          @BodyType.When(option = "operation", 
value = "writeTuples",
+                                                         carriers = { 
Carrier.MAP, Carrier.LIST, Carrier.POJO }),
+                                          @BodyType.When(option = "operation", 
value = "deleteTuples",
+                                                         carriers = { 
Carrier.MAP, Carrier.LIST, Carrier.POJO }) },
+                                  description = "batchCheck: the objects to 
check, as a List or comma-separated text."
+                                                + " writeTuples and 
deleteTuples: a Map with user, relation and object, a"
+                                                + " ClientTupleKey, or a List 
of them, used only when none of user,"
+                                                + " relation and object is 
configured; text fails, unmarshal JSON first. The"
+                                                + " other operations do not 
read the body"),
+           producerOut = @BodyType(value = Carrier.UNKNOWN,
+                                   byOption = {
+                                           @BodyType.When(option = 
"operation", value = "check",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"operation", value = "batchCheck", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<java.lang.String>"),
+                                           @BodyType.When(option = 
"operation", value = "listObjects",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<java.lang.String>"),
+                                           @BodyType.When(option = 
"operation", value = "listRelations",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<java.lang.String>"),
+                                           @BodyType.When(option = 
"operation", value = "listUsers", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<java.lang.String>"),
+                                           @BodyType.When(option = 
"operation", value = "readTuples",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<java.util.Map<java.lang.String, java.lang.Object>>"),
+                                           @BodyType.When(option = 
"operation", value = "readChanges",
+                                                          carriers = 
Carrier.LIST,
+                                                          javaType = 
"java.util.List<java.util.Map<java.lang.String, java.lang.Object>>"),
+                                           @BodyType.When(option = 
"operation", value = "expand",
+                                                          carriers = { 
Carrier.POJO, Carrier.NULL }),
+                                           @BodyType.When(option = 
"operation", value = "writeTuples",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"operation", value = "deleteTuples",
+                                                          carriers = 
Carrier.UNCHANGED) },
+                                   description = "check, writeTuples and 
deleteTuples keep the body: the verdict is in the"
+                                                 + " CamelOpenFgaAllowed 
header, the count in CamelOpenFgaWrittenTuples or"
+                                                 + " 
CamelOpenFgaDeletedTuples. batchCheck: the allowed objects of the body;"
+                                                 + " the list operations: a 
List of String identifiers; readTuples and"
+                                                 + " readChanges: a List of 
Maps with user, relation, object and timestamp"
+                                                 + " (and operation for a 
change); expand: the UsersetTree, or null when the"
+                                                 + " object or relation does 
not resolve"))
 public class OpenFgaEndpoint extends DefaultEndpoint {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(OpenFgaEndpoint.class);
diff --git 
a/components/camel-spiffe/src/generated/resources/META-INF/org/apache/camel/component/spiffe/spiffe.json
 
b/components/camel-spiffe/src/generated/resources/META-INF/org/apache/camel/component/spiffe/spiffe.json
index 1c3dbda49cc6..a6f4c170bc82 100644
--- 
a/components/camel-spiffe/src/generated/resources/META-INF/org/apache/camel/component/spiffe/spiffe.json
+++ 
b/components/camel-spiffe/src/generated/resources/META-INF/org/apache/camel/component/spiffe/spiffe.json
@@ -41,6 +41,10 @@
     "CamelSpiffeSpiffeId": { "index": 3, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The SPIFFE ID of the returned SVID.", 
"constantName": "org.apache.camel.component.spiffe.SpiffeConstants#SPIFFE_ID" },
     "CamelSpiffeExpiry": { "index": 4, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"java.util.Date", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The expiry of the returned SVID: the 
token expiry for fetchJwtSvid, or the leaf certificate's notAfter for 
fetchX509Svid.", "constantName": 
"org.apache.camel.component.spiffe.SpiffeConstants#EXPIRY" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "Only 
validateJwtSvid reads the body: the token as text, when neither the 
CamelSpiffeToken header nor an Authorization: Bearer header carries it. The 
fetch operations ignore the body" },
+    "producerOut": { "carriers": [ "list" ], "javaType": 
"java.util.List<java.security.cert.X509Certificate>", "dependsOn": [ 
"allowOperationHeader" ], "byOption": [ { "option": "x509Response", "value": 
"svid", "carriers": [ "pojo" ], "javaType": "io.spiffe.svid.x509svid.X509Svid" 
}, { "option": "x509Response", "value": "id", "carriers": [ "unchanged" ] }, { 
"option": "operation", "value": "fetchJwtSvid", "carriers": [ "text" ], 
"javaType": "java.lang.String" }, { "option": "operation",  [...]
+  },
   "properties": {
     "label": { "index": 0, "kind": "path", "displayName": "Label", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Logical name of the endpoint" },
     "audience": { "index": 1, "kind": "parameter", "displayName": "Audience", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.spiffe.SpiffeConfiguration", "configurationField": 
"configuration", "description": "The comma-separated audience(s) to request for 
a JWT-SVID (fetchJwtSvid) or to validate against (validateJwtSvid). fetc [...]
diff --git 
a/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeEndpoint.java
 
b/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeEndpoint.java
index 03b3f3aed9a9..660c4e73c8e5 100644
--- 
a/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeEndpoint.java
+++ 
b/components/camel-spiffe/src/main/java/org/apache/camel/component/spiffe/SpiffeEndpoint.java
@@ -23,6 +23,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -36,6 +39,26 @@ import org.apache.camel.util.ObjectHelper;
 @UriEndpoint(firstVersion = "4.23.0", scheme = "spiffe", title = "SPIFFE",
              syntax = "spiffe:label", producerOnly = true, category = { 
Category.SECURITY },
              headersClass = SpiffeConstants.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "Only validateJwtSvid reads 
the body: the token as text, when neither the"
+                                                + " CamelSpiffeToken header 
nor an Authorization: Bearer header carries it."
+                                                + " The fetch operations 
ignore the body"),
+           producerOut = @BodyType(value = Carrier.LIST, javaType = 
"java.util.List<java.security.cert.X509Certificate>",
+                                   dependsOn = "allowOperationHeader",
+                                   byOption = {
+                                           @BodyType.When(option = 
"x509Response", value = "svid", carriers = Carrier.POJO,
+                                                          javaType = 
"io.spiffe.svid.x509svid.X509Svid"),
+                                           @BodyType.When(option = 
"x509Response", value = "id",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"operation", value = "fetchJwtSvid",
+                                                          carriers = 
Carrier.TEXT, javaType = "java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "validateJwtSvid",
+                                                          carriers = 
Carrier.POJO,
+                                                          javaType = 
"io.spiffe.svid.jwtsvid.JwtSvid") },
+                                   description = "fetchX509Svid: the 
certificate chain without the private key; the X509Svid"
+                                                 + " with its private key with 
x509Response=svid, or the body kept with"
+                                                 + " x509Response=id. 
fetchJwtSvid: the token. validateJwtSvid: the validated"
+                                                 + " JwtSvid. The SPIFFE ID is 
in the CamelSpiffeSpiffeId header"))
 public class SpiffeEndpoint extends DefaultEndpoint {
 
     @UriPath(description = "Logical name of the endpoint")
diff --git 
a/components/camel-spring-parent/camel-spring-ldap/src/generated/resources/META-INF/org/apache/camel/component/springldap/spring-ldap.json
 
b/components/camel-spring-parent/camel-spring-ldap/src/generated/resources/META-INF/org/apache/camel/component/springldap/spring-ldap.json
index bfeb9f96566f..9cff0ad27e32 100644
--- 
a/components/camel-spring-parent/camel-spring-ldap/src/generated/resources/META-INF/org/apache/camel/component/springldap/spring-ldap.json
+++ 
b/components/camel-spring-parent/camel-spring-ldap/src/generated/resources/META-INF/org/apache/camel/component/springldap/spring-ldap.json
@@ -27,6 +27,10 @@
     "lazyStartProducer": { "index": 0, "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": 1, "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": {
+    "producerIn": { "carriers": [ "map" ], "description": "A Map of the 
parameters of the operation: dn (not needed when the context source has a base 
DN), filter for search and authenticate, attributes (an Attributes) for bind, 
password for authenticate, modificationItems (a ModificationItem array) for 
modify_attributes, and function and request for function_driven. Another body, 
such as a JSON text, fails" },
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "SEARCH", "carriers": [ "list" ], "javaType": 
"java.util.List<javax.naming.directory.Attributes>" }, { "option": "operation", 
"value": "FUNCTION_DRIVEN", "carriers": [ "unknown" ] } ], "description": 
"bind, unbind, authenticate and modify_attributes leave the Map as it was; a 
failed authenticate throws an exception. search gives a List of the Attributes 
of the entries found, function_driven  [...]
+  },
   "properties": {
     "templateName": { "index": 0, "kind": "path", "displayName": "Template 
Name", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Name of the Spring LDAP 
Template bean" },
     "operation": { "index": 1, "kind": "parameter", "displayName": 
"Operation", "group": "producer", "label": "", "required": true, "type": 
"enum", "javaType": "org.apache.camel.component.springldap.LdapOperation", 
"enum": [ "SEARCH", "BIND", "UNBIND", "AUTHENTICATE", "MODIFY_ATTRIBUTES", 
"FUNCTION_DRIVEN" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The LDAP operation to be performed." },
diff --git 
a/components/camel-spring-parent/camel-spring-ldap/src/main/docs/spring-ldap-component.adoc
 
b/components/camel-spring-parent/camel-spring-ldap/src/main/docs/spring-ldap-component.adoc
index 67f3103b5cf0..f312ebf4d1c9 100644
--- 
a/components/camel-spring-parent/camel-spring-ldap/src/main/docs/spring-ldap-component.adoc
+++ 
b/components/camel-spring-parent/camel-spring-ldap/src/main/docs/spring-ldap-component.adoc
@@ -59,8 +59,8 @@ this map must contain at least an entry with the key *`dn`* 
(not needed for func
 specifies the root node for the LDAP operation to be performed. Other
 entries of the map are operation-specific (see below).
 
-The body of the message remains unchanged for the `bind` and `unbind`
-operations. For the `search` and `function_driven` operations, the body is set 
to the result of
+The body of the message remains unchanged for the `bind`, `unbind`, 
`authenticate`
+and `modify_attributes` operations. For the `search` and `function_driven` 
operations, the body is set to the result of
 the search, see
 
http://static.springsource.org/spring-ldap/site/apidocs/org/springframework/ldap/core/LdapTemplate.html#search%28java.lang.String,%20java.lang.String,%20int,%20org.springframework.ldap.core.AttributesMapper%29[http://static.springsource.org/spring-ldap/site/apidocs/org/springframework/ldap/core/LdapTemplate.html#search%28java.lang.String,%20java.lang.String,%20int,%20org.springframework.ldap.core.AttributesMapper%29].
 
diff --git 
a/components/camel-spring-parent/camel-spring-ldap/src/main/java/org/apache/camel/component/springldap/SpringLdapEndpoint.java
 
b/components/camel-spring-parent/camel-spring-ldap/src/main/java/org/apache/camel/component/springldap/SpringLdapEndpoint.java
index c0b36cd4f3cb..09e68df3bf0e 100644
--- 
a/components/camel-spring-parent/camel-spring-ldap/src/main/java/org/apache/camel/component/springldap/SpringLdapEndpoint.java
+++ 
b/components/camel-spring-parent/camel-spring-ldap/src/main/java/org/apache/camel/component/springldap/SpringLdapEndpoint.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.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -34,6 +37,22 @@ import org.springframework.ldap.core.LdapTemplate;
  */
 @UriEndpoint(firstVersion = "2.11.0", scheme = "spring-ldap", title = "Spring 
LDAP", syntax = "spring-ldap:templateName",
              producerOnly = true, category = { Category.SECURITY })
+@BodyTypes(producerIn = @BodyType(value = Carrier.MAP,
+                                  description = "A Map of the parameters of 
the operation: dn (not needed when the context"
+                                                + " source has a base DN), 
filter for search and authenticate, attributes (an"
+                                                + " Attributes) for bind, 
password for authenticate, modificationItems (a"
+                                                + " ModificationItem array) 
for modify_attributes, and function and request for"
+                                                + " function_driven. Another 
body, such as a JSON text, fails"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   byOption = {
+                                           @BodyType.When(option = 
"operation", value = "SEARCH", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<javax.naming.directory.Attributes>"),
+                                           @BodyType.When(option = 
"operation", value = "FUNCTION_DRIVEN",
+                                                          carriers = 
Carrier.UNKNOWN) },
+                                   description = "bind, unbind, authenticate 
and modify_attributes leave the Map as it was;"
+                                                 + " a failed authenticate 
throws an exception. search gives a List of the"
+                                                 + " Attributes of the entries 
found, function_driven what the function"
+                                                 + " returns"))
 public class SpringLdapEndpoint extends DefaultEndpoint {
 
     private static final String OBJECT_SCOPE_NAME = "object";
diff --git 
a/components/camel-xmlsecurity/src/generated/resources/META-INF/org/apache/camel/component/xmlsecurity/xmlsecurity-sign.json
 
b/components/camel-xmlsecurity/src/generated/resources/META-INF/org/apache/camel/component/xmlsecurity/xmlsecurity-sign.json
index 962310279ef6..0b01985daa26 100644
--- 
a/components/camel-xmlsecurity/src/generated/resources/META-INF/org/apache/camel/component/xmlsecurity/xmlsecurity-sign.json
+++ 
b/components/camel-xmlsecurity/src/generated/resources/META-INF/org/apache/camel/component/xmlsecurity/xmlsecurity-sign.json
@@ -71,6 +71,10 @@
     "CamelXmlSignatureXAdESPrefix": { "index": 13, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "overwrites the XAdES prefix parameter 
value", "constantName": 
"org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants#HEADER_XADES_PREFIX"
 },
     "CamelCharsetName": { "index": 14, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The name of the charset", "constantName": 
"org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants#CHARSET_NAME" 
}
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file", "pojo" ], 
"format": "xml", "byOption": [ { "option": "plainText", "value": "true", 
"carriers": [ "text", "bytes", "stream", "file" ] } ], "description": "The XML 
document to sign: text, bytes, a stream, a file or a DOM Document. A Map, a 
POJO that is not XML or no body fails: marshal it first. With plainText (or the 
CamelXmlSignatureMessageIsPlainText header) the body is any text, which an 
enveloping signature wraps" },
+    "producerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", "format": 
"xml", "description": "The signed XML document as bytes, in the 
outputXmlEncoding when set: the document with the signature for enveloped and 
detached, or the Signature element with the payload inside for enveloping" }
+  },
   "properties": {
     "name": { "index": 0, "kind": "path", "displayName": "Name", "group": 
"producer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The name part in the URI can be chosen 
by the user to distinguish between different signer endpoints within the camel 
context." },
     "addKeyInfoReference": { "index": 1, "kind": "parameter", "displayName": 
"Add Key Info Reference", "group": "producer", "label": "", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, 
"configurationClass": 
"org.apache.camel.component.xmlsecurity.processor.XmlSignerConfiguration", 
"configurationField": "configuration", "description": "In order to protect the 
KeyInfo element from tamperi [...]
diff --git 
a/components/camel-xmlsecurity/src/generated/resources/META-INF/org/apache/camel/component/xmlsecurity/xmlsecurity-verify.json
 
b/components/camel-xmlsecurity/src/generated/resources/META-INF/org/apache/camel/component/xmlsecurity/xmlsecurity-verify.json
index b624742dc4e5..cdd98c50bf1d 100644
--- 
a/components/camel-xmlsecurity/src/generated/resources/META-INF/org/apache/camel/component/xmlsecurity/xmlsecurity-verify.json
+++ 
b/components/camel-xmlsecurity/src/generated/resources/META-INF/org/apache/camel/component/xmlsecurity/xmlsecurity-verify.json
@@ -56,6 +56,10 @@
     "CamelXmlSignatureXAdESPrefix": { "index": 8, "kind": "header", 
"displayName": "", "group": "producer", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "overwrites the XAdES prefix parameter 
value", "constantName": 
"org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants#HEADER_XADES_PREFIX"
 },
     "CamelCharsetName": { "index": 9, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The name of the charset", "constantName": 
"org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants#CHARSET_NAME" 
}
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file", "pojo" ], 
"format": "xml", "description": "The signed XML document: text, bytes, a 
stream, a file or a DOM Document. A document without a Signature element, a 
body that is not XML or no body fails" },
+    "producerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"dependsOn": [ "xmlSignature2Message" ], "description": "The verified content 
as bytes, in the outputXmlEncoding when set: by default the document without 
its Signature for an enveloped or detached signature, and the content of the 
Object for an enveloping one, which is the plain text when it was signed with 
plainText; outputNodeSearchType picks another node. A signature that does not 
verify fails the exchange" }
+  },
   "properties": {
     "name": { "index": 0, "kind": "path", "displayName": "Name", "group": 
"producer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The name part in the URI can be chosen 
by the user to distinguish between different verify endpoints within the camel 
context." },
     "baseUri": { "index": 1, "kind": "parameter", "displayName": "Base Uri", 
"group": "producer", "label": "producer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.xmlsecurity.processor.XmlVerifierConfiguration", 
"configurationField": "configuration", "description": "You can set a base URI 
which is used in the URI dereferencing. Relative URIs are then concat [...]
diff --git 
a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignerEndpoint.java
 
b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignerEndpoint.java
index 7a50bbc149cf..d0382c7d4194 100644
--- 
a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignerEndpoint.java
+++ 
b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlSignerEndpoint.java
@@ -23,6 +23,9 @@ import org.apache.camel.Producer;
 import org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants;
 import org.apache.camel.component.xmlsecurity.processor.XmlSignerConfiguration;
 import org.apache.camel.component.xmlsecurity.processor.XmlSignerProcessor;
+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,20 @@ import static 
org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants.S
 @UriEndpoint(firstVersion = "2.12.0", scheme = SCHEME_SIGN, title = "XML 
Security Sign",
              syntax = "xmlsecurity-sign:name", producerOnly = true, category = 
{ Category.SECURITY, Category.TRANSFORMATION },
              remote = false, headersClass = XmlSignatureConstants.class)
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE, Carrier.POJO },
+                                  format = "xml",
+                                  byOption = @BodyType.When(option = 
"plainText", value = "true",
+                                                            carriers = {
+                                                                    
Carrier.TEXT, Carrier.BYTES, Carrier.STREAM,
+                                                                    
Carrier.FILE }),
+                                  description = "The XML document to sign: 
text, bytes, a stream, a file or a DOM Document."
+                                                + " A Map, a POJO that is not 
XML or no body fails: marshal it first. With"
+                                                + " plainText (or the 
CamelXmlSignatureMessageIsPlainText header) the body is"
+                                                + " any text, which an 
enveloping signature wraps"),
+           producerOut = @BodyType(value = Carrier.BYTES, javaType = "byte[]", 
format = "xml",
+                                   description = "The signed XML document as 
bytes, in the outputXmlEncoding when set: the"
+                                                 + " document with the 
signature for enveloped and detached, or the Signature"
+                                                 + " element with the payload 
inside for enveloping"))
 public class XmlSignerEndpoint extends DefaultEndpoint {
 
     @UriPath
diff --git 
a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java
 
b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java
index 2014da924aaa..119ce0bec928 100644
--- 
a/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java
+++ 
b/components/camel-xmlsecurity/src/main/java/org/apache/camel/component/xmlsecurity/XmlVerifierEndpoint.java
@@ -23,6 +23,9 @@ import org.apache.camel.Producer;
 import org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants;
 import 
org.apache.camel.component.xmlsecurity.processor.XmlVerifierConfiguration;
 import org.apache.camel.component.xmlsecurity.processor.XmlVerifierProcessor;
+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,17 @@ import static 
org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants.S
 @UriEndpoint(firstVersion = "2.12.0", scheme = SCHEME_VERIFIER, title = "XML 
Security Verify",
              syntax = "xmlsecurity-verify:name", producerOnly = true, category 
= { Category.SECURITY, Category.TRANSFORMATION },
              remote = false, headersClass = XmlSignatureConstants.class)
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE, Carrier.POJO },
+                                  format = "xml",
+                                  description = "The signed XML document: 
text, bytes, a stream, a file or a DOM Document. A"
+                                                + " document without a 
Signature element, a body that is not XML or no body"
+                                                + " fails"),
+           producerOut = @BodyType(value = Carrier.BYTES, javaType = "byte[]", 
dependsOn = "xmlSignature2Message",
+                                   description = "The verified content as 
bytes, in the outputXmlEncoding when set: by"
+                                                 + " default the document 
without its Signature for an enveloped or detached"
+                                                 + " signature, and the 
content of the Object for an enveloping one, which is"
+                                                 + " the plain text when it 
was signed with plainText; outputNodeSearchType"
+                                                 + " picks another node. A 
signature that does not verify fails the exchange"))
 public class XmlVerifierEndpoint extends DefaultEndpoint {
 
     @UriPath
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocsTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocsTest.java
index 188d02562dca..8ef59dc6d6e4 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocsTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocsTest.java
@@ -160,10 +160,10 @@ class CatalogDocsTest {
         assertTrue(((JsonObject) 
xpath.get("bodyTypes")).getString("expressionOut")
                 .startsWith("pojo (org.w3c.dom.NodeList). The nodes the 
expression selects. With resultQName=STRING: text"));
 
-        // a component that does not declare them has none, rather than a guess
-        JsonObject ldif = catalogDoc(Map.of("name", "ldif", "kind", 
"component", "includeOptions", false));
-        assertNull(ldif.get("bodyTypes"));
-        assertNull(ldif.get("bodyTypesHint"));
+        // a model that does not declare them, such as an EIP, has none, 
rather than a guess
+        JsonObject split = catalogDoc(Map.of("name", "split", "kind", "eip", 
"includeOptions", false));
+        assertNull(split.get("bodyTypes"));
+        assertNull(split.get("bodyTypesHint"));
     }
 
     @Test

Reply via email to