You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2024/01/02 11:05:50 UTC

(camel) branch convert-variable created (now b7bc92f21aa)

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

davsclaus pushed a change to branch convert-variable
in repository https://gitbox.apache.org/repos/asf/camel.git


      at b7bc92f21aa CAMEL-19749: Add variables as concept to Camel

This branch includes the following new commits:

     new b7bc92f21aa CAMEL-19749: Add variables as concept to Camel

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(camel) 01/01: CAMEL-19749: Add variables as concept to Camel

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b7bc92f21aa3d287e969f36430081fb14819eff7
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Jan 2 12:05:33 2024 +0100

    CAMEL-19749: Add variables as concept to Camel
---
 .../org/apache/camel/catalog/models.properties     |   1 +
 .../org/apache/camel/catalog/models/aggregate.json |   2 +-
 .../camel/catalog/models/circuitBreaker.json       |   2 +-
 .../camel/catalog/models/convertVariableTo.json    |  23 ++
 .../org/apache/camel/catalog/models/doCatch.json   |   2 +-
 .../org/apache/camel/catalog/models/doFinally.json |   2 +-
 .../org/apache/camel/catalog/models/doTry.json     |   2 +-
 .../org/apache/camel/catalog/models/filter.json    |   2 +-
 .../camel/catalog/models/idempotentConsumer.json   |   2 +-
 .../org/apache/camel/catalog/models/intercept.json |   2 +-
 .../apache/camel/catalog/models/interceptFrom.json |   2 +-
 .../catalog/models/interceptSendToEndpoint.json    |   2 +-
 .../org/apache/camel/catalog/models/kamelet.json   |   2 +-
 .../apache/camel/catalog/models/loadBalance.json   |   2 +-
 .../org/apache/camel/catalog/models/loop.json      |   2 +-
 .../org/apache/camel/catalog/models/multicast.json |   2 +-
 .../apache/camel/catalog/models/onCompletion.json  |   2 +-
 .../apache/camel/catalog/models/onException.json   |   2 +-
 .../apache/camel/catalog/models/onFallback.json    |   2 +-
 .../org/apache/camel/catalog/models/otherwise.json |   2 +-
 .../org/apache/camel/catalog/models/pipeline.json  |   2 +-
 .../apache/camel/catalog/models/resequence.json    |   2 +-
 .../org/apache/camel/catalog/models/route.json     |   2 +-
 .../org/apache/camel/catalog/models/saga.json      |   2 +-
 .../org/apache/camel/catalog/models/split.json     |   2 +-
 .../org/apache/camel/catalog/models/step.json      |   2 +-
 .../org/apache/camel/catalog/models/when.json      |   2 +-
 .../catalog/models/whenSkipSendToEndpoint.json     |   2 +-
 .../apache/camel/catalog/schemas/camel-spring.xsd  |  81 ++++++++
 .../mock/MockExpressionClauseSupport.java          |  14 ++
 .../camel/NoSuchHeaderOrPropertyException.java     |   2 +-
 .../org/apache/camel/NoSuchVariableException.java  |  50 +++++
 .../eips/examples/json/convertVariableTo.json      |   1 +
 .../src/main/docs/modules/eips/nav.adoc            |   1 +
 .../modules/eips/pages/convertVariableTo-eip.adoc  | 109 ++++++++++
 .../services/org/apache/camel/model.properties     |   1 +
 .../org/apache/camel/model/aggregate.json          |   2 +-
 .../org/apache/camel/model/circuitBreaker.json     |   2 +-
 .../org/apache/camel/model/convertVariableTo.json  |  23 ++
 .../resources/org/apache/camel/model/doCatch.json  |   2 +-
 .../org/apache/camel/model/doFinally.json          |   2 +-
 .../resources/org/apache/camel/model/doTry.json    |   2 +-
 .../resources/org/apache/camel/model/filter.json   |   2 +-
 .../org/apache/camel/model/idempotentConsumer.json |   2 +-
 .../org/apache/camel/model/intercept.json          |   2 +-
 .../org/apache/camel/model/interceptFrom.json      |   2 +-
 .../camel/model/interceptSendToEndpoint.json       |   2 +-
 .../resources/org/apache/camel/model/jaxb.index    |   1 +
 .../resources/org/apache/camel/model/kamelet.json  |   2 +-
 .../org/apache/camel/model/loadBalance.json        |   2 +-
 .../resources/org/apache/camel/model/loop.json     |   2 +-
 .../org/apache/camel/model/multicast.json          |   2 +-
 .../org/apache/camel/model/onCompletion.json       |   2 +-
 .../org/apache/camel/model/onException.json        |   2 +-
 .../org/apache/camel/model/onFallback.json         |   2 +-
 .../org/apache/camel/model/otherwise.json          |   2 +-
 .../resources/org/apache/camel/model/pipeline.json |   2 +-
 .../org/apache/camel/model/resequence.json         |   2 +-
 .../resources/org/apache/camel/model/route.json    |   2 +-
 .../resources/org/apache/camel/model/saga.json     |   2 +-
 .../resources/org/apache/camel/model/split.json    |   2 +-
 .../resources/org/apache/camel/model/step.json     |   2 +-
 .../resources/org/apache/camel/model/when.json     |   2 +-
 .../apache/camel/model/whenSkipSendToEndpoint.json |   2 +-
 .../camel/model/ConvertHeaderDefinition.java       |   2 +-
 ...inition.java => ConvertVariableDefinition.java} |  24 +--
 .../apache/camel/model/ProcessorDefinition.java    |  38 ++++
 .../camel/reifier/ConvertVariableReifier.java      |  65 ++++++
 .../org/apache/camel/reifier/ProcessorReifier.java |   3 +
 .../java/org/apache/camel/model/XmlParseTest.java  |   9 +
 .../processor/converter/ConvertVariableTest.java   | 231 +++++++++++++++++++++
 .../org/apache/camel/model/convertVariable.xml     |  25 +++
 .../mbean/ManagedConvertVariableMBean.java         |  32 +++
 .../DefaultManagementObjectStrategy.java           |   4 +
 .../management/mbean/ManagedConvertVariable.java   |  48 +++++
 .../processor/ConvertVariableProcessor.java        | 191 +++++++++++++++++
 .../java/org/apache/camel/xml/in/ModelParser.java  |  13 ++
 .../java/org/apache/camel/xml/out/ModelWriter.java |  19 ++
 .../org/apache/camel/yaml/out/ModelWriter.java     |  19 ++
 docs/user-manual/modules/ROOT/pages/variables.adoc |   2 +-
 .../dsl/yaml/deserializers/ModelDeserializers.java |  85 ++++++++
 .../deserializers/ModelDeserializersResolver.java  |   3 +
 .../generated/resources/schema/camelYamlDsl.json   |  47 +++++
 .../camel/dsl/yaml/ConvertVariableTest.groovy      |  88 ++++++++
 84 files changed, 1292 insertions(+), 67 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
index 6302c86936d..4c1e0b75d21 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
@@ -22,6 +22,7 @@ consulServiceDiscovery
 contextScan
 convertBodyTo
 convertHeaderTo
+convertVariableTo
 crypto
 csimple
 csv
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/aggregate.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/aggregate.json
index 6411c8b6422..2a5e8a5d0f4 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/aggregate.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/aggregate.json
@@ -42,6 +42,6 @@
     "discardOnAggregationFailure": { "index": 27, "kind": "attribute", "displayName": "Discard On Aggregation Failure", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Discards the aggregated message when aggregation failed (an exception was thrown from AggregationStrategy . This means the partly aggregated message is dropped and not sent out of the [...]
     "forceCompletionOnStop": { "index": 28, "kind": "attribute", "displayName": "Force Completion On Stop", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Indicates to complete all current aggregated exchanges when the context is stopped" },
     "completeAllOnStop": { "index": 29, "kind": "attribute", "displayName": "Complete All On Stop", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Indicates to wait to complete all current and partial (pending) aggregated exchanges when the context is stopped. This also means that we will wait for all pending exchanges which are stored in the aggre [...]
-    "outputs": { "index": 30, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "on [...]
+    "outputs": { "index": 30, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast" [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/circuitBreaker.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/circuitBreaker.json
index 9cd6e592cfc..e34dd61ff59 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/circuitBreaker.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/circuitBreaker.json
@@ -19,6 +19,6 @@
     "resilience4jConfiguration": { "index": 4, "kind": "element", "displayName": "Resilience4j Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.model.Resilience4jConfigurationDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Configures the circuit breaker to use Resilience4j with the given configuration." },
     "faultToleranceConfiguration": { "index": 5, "kind": "element", "displayName": "Fault Tolerance Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.model.FaultToleranceConfigurationDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Configures the circuit breaker to use MicroProfile Fault Tolerance with the given configuration." },
     "onFallback": { "index": 6, "kind": "element", "displayName": "On Fallback", "required": false, "type": "object", "javaType": "org.apache.camel.model.OnFallbackDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "The fallback route path to execute that does not go over the network. This should be a static or cached result that can immediately be returned upon failure. If the fallback requires network connection then use onFallbackViaNetwork() ." },
-    "outputs": { "index": 7, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 7, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/convertVariableTo.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/convertVariableTo.json
new file mode 100644
index 00000000000..ffb99653c99
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/convertVariableTo.json
@@ -0,0 +1,23 @@
+{
+  "model": {
+    "kind": "model",
+    "name": "convertVariableTo",
+    "title": "Convert Variable To",
+    "description": "Converts the variable to another type",
+    "deprecated": false,
+    "label": "eip,transformation",
+    "javaType": "org.apache.camel.model.ConvertVariableDefinition",
+    "abstract": false,
+    "input": true,
+    "output": false
+  },
+  "properties": {
+    "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
+    "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
+    "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
+    "name": { "index": 3, "kind": "attribute", "displayName": "Name", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of variable to convert its value The simple language can be used to define a dynamic evaluated header name to be used. Otherwise a constant name will be used." },
+    "type": { "index": 4, "kind": "attribute", "displayName": "Type", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The java type to convert to" },
+    "mandatory": { "index": 5, "kind": "attribute", "displayName": "Mandatory", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "When mandatory then the conversion must return a value (cannot be null), if this is not possible then NoTypeConversionAvailableException is thrown. Setting this to false could mean conversion is not possible and the value is [...]
+    "charset": { "index": 6, "kind": "attribute", "displayName": "Charset", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a specific charset when converting" }
+  }
+}
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doCatch.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doCatch.json
index adb84178cff..66b0c0eadb9 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doCatch.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doCatch.json
@@ -17,6 +17,6 @@
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "exception": { "index": 3, "kind": "element", "displayName": "Exception", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "The exception(s) to catch." },
     "onWhen": { "index": 4, "kind": "element", "displayName": "On When", "required": false, "type": "object", "javaType": "org.apache.camel.model.WhenDefinition", "deprecated": false, "autowired": false, "secret": false, "asPredicate": true, "description": "Sets an additional predicate that should be true before the onCatch is triggered. To be used for fine grained controlling whether a thrown exception should be intercepted by this exception type or not." },
-    "outputs": { "index": 5, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 5, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doFinally.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doFinally.json
index 6eef88af181..4a89b16f38d 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doFinally.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doFinally.json
@@ -15,6 +15,6 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doTry.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doTry.json
index 8ac3754360d..067e33d0ee7 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doTry.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doTry.json
@@ -15,6 +15,6 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/filter.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/filter.json
index 13eb266ab0d..208e188fee3 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/filter.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/filter.json
@@ -17,6 +17,6 @@
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "expression": { "index": 3, "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "sec [...]
     "statusPropertyName": { "index": 4, "kind": "attribute", "displayName": "Status Property Name", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of exchange property to use for storing the status of the filtering. Setting this allows to know if the filter predicate evaluated as true or false." },
-    "outputs": { "index": 5, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance [...]
+    "outputs": { "index": 5, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "k [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/idempotentConsumer.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/idempotentConsumer.json
index 149004e15b2..b6925b0a6a9 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/idempotentConsumer.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/idempotentConsumer.json
@@ -21,6 +21,6 @@
     "completionEager": { "index": 6, "kind": "attribute", "displayName": "Completion Eager", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether to complete the idempotent consumer eager or when the exchange is done. If this option is true to complete eager, then the idempotent consumer will trigger its completion when the exchange reached  [...]
     "skipDuplicate": { "index": 7, "kind": "attribute", "displayName": "Skip Duplicate", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Sets whether to skip duplicates or not. The default behavior is to skip duplicates. A duplicate message would have the Exchange property org.apache.camel.Exchange#DUPLICATE_MESSAGE set to a Boolean#TRUE value. A non [...]
     "removeOnFailure": { "index": 8, "kind": "attribute", "displayName": "Remove On Failure", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Sets whether to remove or keep the key on failure. The default behavior is to remove the key on failure." },
-    "outputs": { "index": 9, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance [...]
+    "outputs": { "index": 9, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "k [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/intercept.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/intercept.json
index e1063c592b5..6d4f94024e6 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/intercept.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/intercept.json
@@ -15,6 +15,6 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/interceptFrom.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/interceptFrom.json
index 2d90e3a6be8..3e5931fdec3 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/interceptFrom.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/interceptFrom.json
@@ -16,6 +16,6 @@
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "uri": { "index": 3, "kind": "attribute", "displayName": "Uri", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Intercept incoming messages from the uri or uri pattern. If this option is not configured, then all incoming messages is intercepted." },
-    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/interceptSendToEndpoint.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/interceptSendToEndpoint.json
index d2163bf0f37..0a46cf8829a 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/interceptSendToEndpoint.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/interceptSendToEndpoint.json
@@ -18,6 +18,6 @@
     "uri": { "index": 3, "kind": "attribute", "displayName": "Uri", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Intercept sending to the uri or uri pattern." },
     "skipSendToOriginalEndpoint": { "index": 4, "kind": "attribute", "displayName": "Skip Send To Original Endpoint", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "If set to true then the message is not sent to the original endpoint. By default (false) the message is both intercepted and then sent to the original endpoint." },
     "afterUri": { "index": 5, "kind": "attribute", "displayName": "After Uri", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "After sending to the endpoint then send the message to this uri which allows to process its result." },
-    "outputs": { "index": 6, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 6, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/kamelet.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/kamelet.json
index 4bcc06c5bd0..e9ea36154c1 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/kamelet.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/kamelet.json
@@ -16,6 +16,6 @@
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "name": { "index": 3, "kind": "attribute", "displayName": "Name", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of the Kamelet (templateId\/routeId) to call. Options for the kamelet can be specified using uri syntax, eg mynamecount=4&type=gold." },
-    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/loadBalance.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/loadBalance.json
index 06f242f0554..e1965f2d6a6 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/loadBalance.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/loadBalance.json
@@ -16,7 +16,7 @@
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "loadBalancerType": { "index": 3, "kind": "element", "displayName": "Load Balancer Type", "required": true, "type": "object", "javaType": "org.apache.camel.model.LoadBalancerDefinition", "oneOf": [ "customLoadBalancer", "failover", "random", "roundRobin", "sticky", "topic", "weighted" ], "deprecated": false, "autowired": false, "secret": false, "description": "The load balancer to be used" },
-    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
     "inheritErrorHandler": { "index": 5, "kind": "attribute", "displayName": "Inherit Error Handler", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether or not to inherit the configured error handler. The default value is true. You can use this to disable using the inherited error handler for a given DSL such as a load balancer where you want to use a custom e [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/loop.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/loop.json
index 24ad0a7819a..530b30462ca 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/loop.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/loop.json
@@ -19,6 +19,6 @@
     "copy": { "index": 4, "kind": "attribute", "displayName": "Copy", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the copy attribute is true, a copy of the input Exchange is used for each iteration. That means each iteration will start from a copy of the same message. By default loop will loop the same exchange all over, so each iteration may [...]
     "doWhile": { "index": 5, "kind": "attribute", "displayName": "Do While", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enables the while loop that loops until the predicate evaluates to false or null." },
     "breakOnShutdown": { "index": 6, "kind": "attribute", "displayName": "Break On Shutdown", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the breakOnShutdown attribute is true, then the loop will not iterate until it reaches the end when Camel is shut down." },
-    "outputs": { "index": 7, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance [...]
+    "outputs": { "index": 7, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "k [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/multicast.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/multicast.json
index 6c6abaf464d..f1679366381 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/multicast.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/multicast.json
@@ -27,6 +27,6 @@
     "executorService": { "index": 12, "kind": "attribute", "displayName": "Executor Service", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.concurrent.ExecutorService", "deprecated": false, "autowired": false, "secret": false, "description": "Refers to a custom Thread Pool to be used for parallel processing. Notice if you set this option, then parallel processing is automatic implied, and you do not have to enable that option as well." },
     "onPrepare": { "index": 13, "kind": "attribute", "displayName": "On Prepare", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.Processor", "deprecated": false, "autowired": false, "secret": false, "description": "Uses the Processor when preparing the org.apache.camel.Exchange to be send. This can be used to deep-clone messages that should be send, or any custom logic needed before the exchange is send." },
     "shareUnitOfWork": { "index": 14, "kind": "attribute", "displayName": "Share Unit Of Work", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Shares the org.apache.camel.spi.UnitOfWork with the parent and each of the sub messages. Multicast will by default not share unit of work between the parent exchange and each multicasted exchange. This means [...]
-    "outputs": { "index": 15, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "on [...]
+    "outputs": { "index": 15, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast" [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/onCompletion.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/onCompletion.json
index 0e4b42cfeec..a2ac866950c 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/onCompletion.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/onCompletion.json
@@ -22,6 +22,6 @@
     "executorService": { "index": 7, "kind": "attribute", "displayName": "Executor Service", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.concurrent.ExecutorService", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom Thread Pool to be used for parallel processing. Notice if you set this option, then parallel processing is automatic implied, and you do not have to enable that option as well." },
     "useOriginalMessage": { "index": 8, "kind": "attribute", "displayName": "Use Original Message", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input message body when an org.apache.camel.Exchange for this on completion. The original input message is defensively copied, and the copied message body is converted to org.apache [...]
     "onWhen": { "index": 9, "kind": "element", "displayName": "On When", "required": false, "type": "object", "javaType": "org.apache.camel.model.WhenDefinition", "deprecated": false, "autowired": false, "secret": false, "asPredicate": true, "description": "Sets an additional predicate that should be true before the onCompletion is triggered. To be used for fine grained controlling whether a completion callback should be invoked or not" },
-    "outputs": { "index": 10, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "on [...]
+    "outputs": { "index": 10, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast" [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/onException.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/onException.json
index 6de27e20851..2da14d671a7 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/onException.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/onException.json
@@ -26,6 +26,6 @@
     "onExceptionOccurredRef": { "index": 11, "kind": "attribute", "displayName": "On Exception Occurred Ref", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor that should be processed just after an exception occurred. Can be used to perform custom logging about the occurred exception at the exact time it happened. Important: Any exception thro [...]
     "useOriginalMessage": { "index": 12, "kind": "attribute", "displayName": "Use Original Message", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input org.apache.camel.Message (original body and headers) when an org.apache.camel.Exchange is moved to the dead letter queue. Notice: this only applies when all redeliveries atte [...]
     "useOriginalBody": { "index": 13, "kind": "attribute", "displayName": "Use Original Body", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input org.apache.camel.Message body (original body only) when an org.apache.camel.Exchange is moved to the dead letter queue. Notice: this only applies when all redeliveries attempt have [...]
-    "outputs": { "index": 14, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "on [...]
+    "outputs": { "index": 14, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast" [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/onFallback.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/onFallback.json
index 1c1774c10a9..38f930b21c6 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/onFallback.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/onFallback.json
@@ -16,6 +16,6 @@
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "fallbackViaNetwork": { "index": 3, "kind": "attribute", "displayName": "Fallback Via Network", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the fallback goes over the network. If the fallback will go over the network it is another possible point of failure. It is important to execute the fallback command on a separate thread-pool, ot [...]
-    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance [...]
+    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "k [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/otherwise.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/otherwise.json
index cce4b703fe8..11159f7e90b 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/otherwise.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/otherwise.json
@@ -15,6 +15,6 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/pipeline.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/pipeline.json
index 85ccd199df1..e7390054ea6 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/pipeline.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/pipeline.json
@@ -15,6 +15,6 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/resequence.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/resequence.json
index 4a12cdfaffe..d35481f201c 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/resequence.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/resequence.json
@@ -17,6 +17,6 @@
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "expression": { "index": 3, "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "sec [...]
     "resequencerConfig": { "index": 4, "kind": "element", "displayName": "Resequencer Config", "required": true, "type": "object", "javaType": "org.apache.camel.model.config.ResequencerConfig", "oneOf": [ "batchConfig", "streamConfig" ], "deprecated": false, "autowired": false, "secret": false, "description": "To configure the resequencer in using either batch or stream configuration. Will by default use batch configuration." },
-    "outputs": { "index": 5, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 5, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/route.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/route.json
index d4b9c4b06b2..c54e2e80e4e 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/route.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/route.json
@@ -32,6 +32,6 @@
     "inputType": { "index": 17, "kind": "element", "displayName": "Input Type", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.model.InputTypeDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Declare the expected data type of the input message. If the actual message type is different at runtime, camel look for a required org.apache.camel.spi.Transformer and apply if exists. The type name consists of two parts,  [...]
     "outputType": { "index": 18, "kind": "element", "displayName": "Output Type", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.model.OutputTypeDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Declare the expected data type of the output message. If the actual message type is different at runtime, camel look for a required org.apache.camel.spi.Transformer and apply if exists. The type name consists of two par [...]
     "input": { "index": 19, "kind": "element", "displayName": "Input", "required": true, "type": "object", "javaType": "org.apache.camel.model.FromDefinition", "oneOf": [ "from" ], "deprecated": false, "autowired": false, "secret": false, "description": "Input to the route." },
-    "outputs": { "index": 20, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<?>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loo [...]
+    "outputs": { "index": 20, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<?>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "load [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/saga.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/saga.json
index 2503f7defe6..4f14270e411 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/saga.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/saga.json
@@ -22,6 +22,6 @@
     "compensation": { "index": 7, "kind": "element", "displayName": "Compensation", "required": false, "type": "object", "javaType": "org.apache.camel.model.SagaActionUriDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "The compensation endpoint URI that must be called to compensate all changes done in the route. The route corresponding to the compensation URI must perform compensation and complete without error. If errors occur during compensation, t [...]
     "completion": { "index": 8, "kind": "element", "displayName": "Completion", "required": false, "type": "object", "javaType": "org.apache.camel.model.SagaActionUriDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "The completion endpoint URI that will be called when the Saga is completed successfully. The route corresponding to the completion URI must perform completion tasks and terminate without error. If errors occur during completion, the saga s [...]
     "option": { "index": 9, "kind": "element", "displayName": "Option", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.PropertyExpressionDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to save properties of the current exchange in order to re-use them in a compensation\/completion callback route. Options are usually helpful e.g. to store and retrieve identifiers of objects that sho [...]
-    "outputs": { "index": 10, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "on [...]
+    "outputs": { "index": 10, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast" [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/split.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/split.json
index 395a1cb544a..edf22cd176d 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/split.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/split.json
@@ -29,6 +29,6 @@
     "executorService": { "index": 14, "kind": "attribute", "displayName": "Executor Service", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.concurrent.ExecutorService", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom Thread Pool to be used for parallel processing. Notice if you set this option, then parallel processing is automatically implied, and you do not have to enable that option as well." },
     "onPrepare": { "index": 15, "kind": "attribute", "displayName": "On Prepare", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.Processor", "deprecated": false, "autowired": false, "secret": false, "description": "Uses the Processor when preparing the org.apache.camel.Exchange to be sent. This can be used to deep-clone messages that should be sent, or any custom logic needed before the exchange is sent." },
     "shareUnitOfWork": { "index": 16, "kind": "attribute", "displayName": "Share Unit Of Work", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Shares the org.apache.camel.spi.UnitOfWork with the parent and each of the sub messages. Splitter will by default not share unit of work between the parent exchange and each split exchange. This means each s [...]
-    "outputs": { "index": 17, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalanc [...]
+    "outputs": { "index": 17, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", " [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/step.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/step.json
index 2d47cf3b901..8f343dbb807 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/step.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/step.json
@@ -15,6 +15,6 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/when.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/when.json
index c9278a4adae..575173bbb67 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/when.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/when.json
@@ -16,6 +16,6 @@
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "expression": { "index": 3, "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "sec [...]
-    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance [...]
+    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "k [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/whenSkipSendToEndpoint.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/whenSkipSendToEndpoint.json
index 61cd7cd5fe9..e343ba7a734 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/whenSkipSendToEndpoint.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/whenSkipSendToEndpoint.json
@@ -16,6 +16,6 @@
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "expression": { "index": 3, "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "sec [...]
-    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance [...]
+    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "k [...]
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
index ce99aff5108..0f9f530534a 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
@@ -240,6 +240,15 @@ Converts the message body to another type
       <xs:documentation xml:lang="en">
 <![CDATA[
 Converts the message header to another type
+]]>
+      </xs:documentation>
+    </xs:annotation>
+  </xs:element>
+  <xs:element name="convertVariableTo" type="tns:convertVariableDefinition">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+<![CDATA[
+Converts the variable to another type
 ]]>
       </xs:documentation>
     </xs:annotation>
@@ -3497,6 +3506,7 @@ will fallback to use the fixed value if the Expression result was null or 0.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -4058,6 +4068,7 @@ controlling whether a thrown exception should be intercepted by this exception t
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -4164,6 +4175,7 @@ controlling whether a thrown exception should be intercepted by this exception t
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -4263,6 +4275,7 @@ during startup to keep at runtime only the branch that matched. Default value: f
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -4345,6 +4358,7 @@ during startup to keep at runtime only the branch that matched. Default value: f
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -4794,6 +4808,7 @@ References to a custom thread pool to use when bulkhead is enabled.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -5044,6 +5059,52 @@ is null. Default value: true
             <xs:documentation xml:lang="en">
 <![CDATA[
 To use a specific charset when converting.
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="convertVariableDefinition">
+    <xs:complexContent>
+      <xs:extension base="tns:noOutputDefinition">
+        <xs:sequence/>
+        <xs:attribute name="name" type="xs:string" use="required">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+Name of variable to convert its value The simple language can be used to define a dynamic evaluated header name to be
+used. Otherwise a constant name will be used.
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="type" type="xs:string" use="required">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+The java type to convert to.
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="mandatory" type="xs:string">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+When mandatory then the conversion must return a value (cannot be null), if this is not possible then
+NoTypeConversionAvailableException is thrown. Setting this to false could mean conversion is not possible and the value
+is null. Default value: true
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="charset" type="xs:string">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+To use a specific charset when converting.
 ]]>
             </xs:documentation>
           </xs:annotation>
@@ -5846,6 +5907,7 @@ Sets the logging level to use for logging transactional rollback. This option is
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -5935,6 +5997,7 @@ predicate evaluated as true or false.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -6083,6 +6146,7 @@ Global option value.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -6242,6 +6306,7 @@ Whether if validation is required for this input type. Default value: false
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -6338,6 +6403,7 @@ intercepted.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -6445,6 +6511,7 @@ After sending to the endpoint then send the message to this uri which allows to
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -6543,6 +6610,7 @@ mynamecount=4&type=gold.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -6853,6 +6921,7 @@ To refer to a custom logger instance to lookup from the registry.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -10152,6 +10221,7 @@ maximum decompressed size. Default value: 1073741824
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -10374,6 +10444,7 @@ controlling whether a completion callback should be invoked or not.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -10571,6 +10642,7 @@ its considered handled as well.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -10828,6 +10900,7 @@ one of the available events. Implementations should not assume the predicate to
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -10907,6 +10980,7 @@ one of the available events. Implementations should not assume the predicate to
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -11515,6 +11589,7 @@ Name of variable to remove.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -11862,6 +11937,7 @@ Reference to the routes in the xml dsl.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -12294,6 +12370,7 @@ actions. Option values will be transformed into input headers of the compensatio
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -12727,6 +12804,7 @@ Sets the comparator to use for sorting.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -12956,6 +13034,7 @@ individual unit of work. Default value: false
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -13511,6 +13590,7 @@ Whether to auto startup components when toD is starting up. Default value: true
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
@@ -13650,6 +13730,7 @@ To type used as a target data type in the transformation.
             <xs:element ref="tns:claimCheck"/>
             <xs:element ref="tns:convertBodyTo"/>
             <xs:element ref="tns:convertHeaderTo"/>
+            <xs:element ref="tns:convertVariableTo"/>
             <xs:element ref="tns:delay"/>
             <xs:element ref="tns:dynamicRouter"/>
             <xs:element ref="tns:enrich"/>
diff --git a/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockExpressionClauseSupport.java b/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockExpressionClauseSupport.java
index 94061bd5ab3..b21a8958e20 100644
--- a/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockExpressionClauseSupport.java
+++ b/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockExpressionClauseSupport.java
@@ -275,6 +275,20 @@ public class MockExpressionClauseSupport<T> {
         return expression(ExpressionBuilder.languageExpression(language, expression));
     }
 
+    /**
+     * An expression of a variable of the given name
+     */
+    public T variable(String name) {
+        return expression(ExpressionBuilder.variableExpression(name));
+    }
+
+    /**
+     * An expression of the exchange scoped variables
+     */
+    public T variables() {
+        return expression(ExpressionBuilder.variablesExpression());
+    }
+
     // Properties
     // -------------------------------------------------------------------------
 
diff --git a/core/camel-api/src/main/java/org/apache/camel/NoSuchHeaderOrPropertyException.java b/core/camel-api/src/main/java/org/apache/camel/NoSuchHeaderOrPropertyException.java
index 8e8d4221d4a..54798a82dd9 100644
--- a/core/camel-api/src/main/java/org/apache/camel/NoSuchHeaderOrPropertyException.java
+++ b/core/camel-api/src/main/java/org/apache/camel/NoSuchHeaderOrPropertyException.java
@@ -24,7 +24,7 @@ public class NoSuchHeaderOrPropertyException extends CamelExchangeException {
 
     public NoSuchHeaderOrPropertyException(Exchange exchange, String headerName, String propertyName, Class<?> type) {
         super(String.format(
-                "Np '%s' header or '%s' property available of type: %s (header: %s, property: %s)",
+                "No '%s' header or '%s' property available of type: %s (header: %s, property: %s)",
                 headerName,
                 propertyName,
                 type.getName(),
diff --git a/core/camel-api/src/main/java/org/apache/camel/NoSuchVariableException.java b/core/camel-api/src/main/java/org/apache/camel/NoSuchVariableException.java
new file mode 100644
index 00000000000..8521c7d768f
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/NoSuchVariableException.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel;
+
+public class NoSuchVariableException extends CamelExchangeException {
+
+    private final String variableName;
+    private final transient Class<?> type;
+
+    public NoSuchVariableException(Exchange exchange, String variableName) {
+        super(String.format(
+                "No '%s' variable available", variableName),
+              exchange);
+        this.variableName = variableName;
+        this.type = null;
+    }
+
+    public NoSuchVariableException(Exchange exchange, String variableName, Class<?> type) {
+        super(String.format(
+                "No '%s' variable available of type: %s",
+                variableName,
+                type.getName()),
+              exchange);
+        this.variableName = variableName;
+        this.type = type;
+    }
+
+    public String getVariableName() {
+        return variableName;
+    }
+
+    public Class<?> getType() {
+        return type;
+    }
+
+}
diff --git a/core/camel-core-engine/src/main/docs/modules/eips/examples/json/convertVariableTo.json b/core/camel-core-engine/src/main/docs/modules/eips/examples/json/convertVariableTo.json
new file mode 120000
index 00000000000..04ad5102d37
--- /dev/null
+++ b/core/camel-core-engine/src/main/docs/modules/eips/examples/json/convertVariableTo.json
@@ -0,0 +1 @@
+../../../../../../../../camel-core-model/src/generated/resources/org/apache/camel/model/convertVariableTo.json
\ No newline at end of file
diff --git a/core/camel-core-engine/src/main/docs/modules/eips/nav.adoc b/core/camel-core-engine/src/main/docs/modules/eips/nav.adoc
index 4bca724bdb5..fdd39c3c2d2 100644
--- a/core/camel-core-engine/src/main/docs/modules/eips/nav.adoc
+++ b/core/camel-core-engine/src/main/docs/modules/eips/nav.adoc
@@ -16,6 +16,7 @@
 ** xref:content-filter-eip.adoc[Content Filter]
 ** xref:convertBodyTo-eip.adoc[Convert Body To]
 ** xref:convertHeaderTo-eip.adoc[Convert Header To]
+** xref:convertVariableTo-eip.adoc[Convert Variable To]
 ** xref:correlation-identifier.adoc[Correlation Identifier]
 ** xref:customLoadBalancer-eip.adoc[Custom Load Balancer]
 ** xref:dead-letter-channel.adoc[Dead Letter Channel]
diff --git a/core/camel-core-engine/src/main/docs/modules/eips/pages/convertVariableTo-eip.adoc b/core/camel-core-engine/src/main/docs/modules/eips/pages/convertVariableTo-eip.adoc
new file mode 100644
index 00000000000..5c53e8bdd34
--- /dev/null
+++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/convertVariableTo-eip.adoc
@@ -0,0 +1,109 @@
+= Convert Variable To EIP
+:doctitle: Convert Variable To
+:shortname: convertVariableTo
+:description: Converts the variable to another type
+:since: 
+:supportlevel: Stable
+:tabs-sync-option:
+
+The ConvertVariableTo EIP allows you to convert a variable to a different type.
+
+// eip options: START
+include::partial$eip-options.adoc[]
+// eip options: END
+
+The type is a FQN classname (fully qualified), so for example `java.lang.String`, `com.foo.MyBean` etc.
+However, Camel has shorthand for common Java types, most noticeable `String` can be used instead of `java.lang.String`.
+You can also use `byte[]` for a byte array.
+
+== Example
+
+For example to convert the foo variable to `String`:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("seda:foo")
+  .convertVariableTo("foo", String.class)
+  .log("The variable content: ${variable.foo}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="seda:foo"/>
+  <convertVariableTo name="foo" type="String"/>
+  <log message="The variable content: ${variable.foo}"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- from:
+    uri: seda:foo
+    steps:
+      - convertVariableTo:
+          name: foo
+          type: String
+      - log:
+          message: "The variable content: ${variable.foo}"
+----
+====
+
+=== Dynamic variable name
+
+The ConvertVariableTo supports using xref:components:languages:simple-language.adoc[Simple] language for dynamic variable name.
+
+Suppose you have multiple variables:
+
+- region
+- emea
+- na
+- pacific
+
+And that region points to either ema, na or pacific which has some order details.
+Then you can use dynamic variable to convert the header of choice. Now suppose that the region variable has value `emea`:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("seda:foo")
+  .convertVariableTo("${variable.region}", String.class)
+  .log("Order from EMEA: ${variable.emea}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="seda:foo"/>
+  <convertVariableTo name="${variable.region}" type="String"/>
+  <log message="Order from EMEA: ${variable.emea}"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- from:
+    uri: seda:foo
+    steps:
+      - convertVariableTo:
+          name: ${variable.region}
+          type: String
+      - log:
+          message: "Order from EMEA: ${variable.emea}"
+----
+====
diff --git a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
index dd1f1353425..fd135d9bdc6 100644
--- a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
+++ b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
@@ -23,6 +23,7 @@ consulServiceDiscovery
 contextScan
 convertBodyTo
 convertHeaderTo
+convertVariableTo
 crypto
 csimple
 csv
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/aggregate.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/aggregate.json
index 6411c8b6422..2a5e8a5d0f4 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/aggregate.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/aggregate.json
@@ -42,6 +42,6 @@
     "discardOnAggregationFailure": { "index": 27, "kind": "attribute", "displayName": "Discard On Aggregation Failure", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Discards the aggregated message when aggregation failed (an exception was thrown from AggregationStrategy . This means the partly aggregated message is dropped and not sent out of the [...]
     "forceCompletionOnStop": { "index": 28, "kind": "attribute", "displayName": "Force Completion On Stop", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Indicates to complete all current aggregated exchanges when the context is stopped" },
     "completeAllOnStop": { "index": 29, "kind": "attribute", "displayName": "Complete All On Stop", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Indicates to wait to complete all current and partial (pending) aggregated exchanges when the context is stopped. This also means that we will wait for all pending exchanges which are stored in the aggre [...]
-    "outputs": { "index": 30, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "on [...]
+    "outputs": { "index": 30, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast" [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/circuitBreaker.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/circuitBreaker.json
index 9cd6e592cfc..e34dd61ff59 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/circuitBreaker.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/circuitBreaker.json
@@ -19,6 +19,6 @@
     "resilience4jConfiguration": { "index": 4, "kind": "element", "displayName": "Resilience4j Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.model.Resilience4jConfigurationDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Configures the circuit breaker to use Resilience4j with the given configuration." },
     "faultToleranceConfiguration": { "index": 5, "kind": "element", "displayName": "Fault Tolerance Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.model.FaultToleranceConfigurationDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Configures the circuit breaker to use MicroProfile Fault Tolerance with the given configuration." },
     "onFallback": { "index": 6, "kind": "element", "displayName": "On Fallback", "required": false, "type": "object", "javaType": "org.apache.camel.model.OnFallbackDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "The fallback route path to execute that does not go over the network. This should be a static or cached result that can immediately be returned upon failure. If the fallback requires network connection then use onFallbackViaNetwork() ." },
-    "outputs": { "index": 7, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 7, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/convertVariableTo.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/convertVariableTo.json
new file mode 100644
index 00000000000..ffb99653c99
--- /dev/null
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/convertVariableTo.json
@@ -0,0 +1,23 @@
+{
+  "model": {
+    "kind": "model",
+    "name": "convertVariableTo",
+    "title": "Convert Variable To",
+    "description": "Converts the variable to another type",
+    "deprecated": false,
+    "label": "eip,transformation",
+    "javaType": "org.apache.camel.model.ConvertVariableDefinition",
+    "abstract": false,
+    "input": true,
+    "output": false
+  },
+  "properties": {
+    "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
+    "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
+    "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
+    "name": { "index": 3, "kind": "attribute", "displayName": "Name", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of variable to convert its value The simple language can be used to define a dynamic evaluated header name to be used. Otherwise a constant name will be used." },
+    "type": { "index": 4, "kind": "attribute", "displayName": "Type", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The java type to convert to" },
+    "mandatory": { "index": 5, "kind": "attribute", "displayName": "Mandatory", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "When mandatory then the conversion must return a value (cannot be null), if this is not possible then NoTypeConversionAvailableException is thrown. Setting this to false could mean conversion is not possible and the value is [...]
+    "charset": { "index": 6, "kind": "attribute", "displayName": "Charset", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a specific charset when converting" }
+  }
+}
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/doCatch.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/doCatch.json
index adb84178cff..66b0c0eadb9 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/doCatch.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/doCatch.json
@@ -17,6 +17,6 @@
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "exception": { "index": 3, "kind": "element", "displayName": "Exception", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "The exception(s) to catch." },
     "onWhen": { "index": 4, "kind": "element", "displayName": "On When", "required": false, "type": "object", "javaType": "org.apache.camel.model.WhenDefinition", "deprecated": false, "autowired": false, "secret": false, "asPredicate": true, "description": "Sets an additional predicate that should be true before the onCatch is triggered. To be used for fine grained controlling whether a thrown exception should be intercepted by this exception type or not." },
-    "outputs": { "index": 5, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 5, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/doFinally.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/doFinally.json
index 6eef88af181..4a89b16f38d 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/doFinally.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/doFinally.json
@@ -15,6 +15,6 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/doTry.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/doTry.json
index 8ac3754360d..067e33d0ee7 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/doTry.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/doTry.json
@@ -15,6 +15,6 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/filter.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/filter.json
index 13eb266ab0d..208e188fee3 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/filter.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/filter.json
@@ -17,6 +17,6 @@
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "expression": { "index": 3, "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "sec [...]
     "statusPropertyName": { "index": 4, "kind": "attribute", "displayName": "Status Property Name", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of exchange property to use for storing the status of the filtering. Setting this allows to know if the filter predicate evaluated as true or false." },
-    "outputs": { "index": 5, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance [...]
+    "outputs": { "index": 5, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "k [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/idempotentConsumer.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/idempotentConsumer.json
index 149004e15b2..b6925b0a6a9 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/idempotentConsumer.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/idempotentConsumer.json
@@ -21,6 +21,6 @@
     "completionEager": { "index": 6, "kind": "attribute", "displayName": "Completion Eager", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether to complete the idempotent consumer eager or when the exchange is done. If this option is true to complete eager, then the idempotent consumer will trigger its completion when the exchange reached  [...]
     "skipDuplicate": { "index": 7, "kind": "attribute", "displayName": "Skip Duplicate", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Sets whether to skip duplicates or not. The default behavior is to skip duplicates. A duplicate message would have the Exchange property org.apache.camel.Exchange#DUPLICATE_MESSAGE set to a Boolean#TRUE value. A non [...]
     "removeOnFailure": { "index": 8, "kind": "attribute", "displayName": "Remove On Failure", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Sets whether to remove or keep the key on failure. The default behavior is to remove the key on failure." },
-    "outputs": { "index": 9, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance [...]
+    "outputs": { "index": 9, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "k [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/intercept.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/intercept.json
index e1063c592b5..6d4f94024e6 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/intercept.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/intercept.json
@@ -15,6 +15,6 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/interceptFrom.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/interceptFrom.json
index 2d90e3a6be8..3e5931fdec3 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/interceptFrom.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/interceptFrom.json
@@ -16,6 +16,6 @@
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "uri": { "index": 3, "kind": "attribute", "displayName": "Uri", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Intercept incoming messages from the uri or uri pattern. If this option is not configured, then all incoming messages is intercepted." },
-    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/interceptSendToEndpoint.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/interceptSendToEndpoint.json
index d2163bf0f37..0a46cf8829a 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/interceptSendToEndpoint.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/interceptSendToEndpoint.json
@@ -18,6 +18,6 @@
     "uri": { "index": 3, "kind": "attribute", "displayName": "Uri", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Intercept sending to the uri or uri pattern." },
     "skipSendToOriginalEndpoint": { "index": 4, "kind": "attribute", "displayName": "Skip Send To Original Endpoint", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "If set to true then the message is not sent to the original endpoint. By default (false) the message is both intercepted and then sent to the original endpoint." },
     "afterUri": { "index": 5, "kind": "attribute", "displayName": "After Uri", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "After sending to the endpoint then send the message to this uri which allows to process its result." },
-    "outputs": { "index": 6, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 6, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index b/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
index 72031091516..9c0bf809648 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
@@ -9,6 +9,7 @@ ClaimCheckOperation
 ContextScanDefinition
 ConvertBodyDefinition
 ConvertHeaderDefinition
+ConvertVariableDefinition
 DataFormatDefinition
 DelayDefinition
 DynamicRouterDefinition
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/kamelet.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/kamelet.json
index 4bcc06c5bd0..e9ea36154c1 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/kamelet.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/kamelet.json
@@ -16,6 +16,6 @@
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "name": { "index": 3, "kind": "attribute", "displayName": "Name", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of the Kamelet (templateId\/routeId) to call. Options for the kamelet can be specified using uri syntax, eg mynamecount=4&type=gold." },
-    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/loadBalance.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/loadBalance.json
index 06f242f0554..e1965f2d6a6 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/loadBalance.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/loadBalance.json
@@ -16,7 +16,7 @@
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "loadBalancerType": { "index": 3, "kind": "element", "displayName": "Load Balancer Type", "required": true, "type": "object", "javaType": "org.apache.camel.model.LoadBalancerDefinition", "oneOf": [ "customLoadBalancer", "failover", "random", "roundRobin", "sticky", "topic", "weighted" ], "deprecated": false, "autowired": false, "secret": false, "description": "The load balancer to be used" },
-    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
     "inheritErrorHandler": { "index": 5, "kind": "attribute", "displayName": "Inherit Error Handler", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether or not to inherit the configured error handler. The default value is true. You can use this to disable using the inherited error handler for a given DSL such as a load balancer where you want to use a custom e [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/loop.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/loop.json
index 24ad0a7819a..530b30462ca 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/loop.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/loop.json
@@ -19,6 +19,6 @@
     "copy": { "index": 4, "kind": "attribute", "displayName": "Copy", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the copy attribute is true, a copy of the input Exchange is used for each iteration. That means each iteration will start from a copy of the same message. By default loop will loop the same exchange all over, so each iteration may [...]
     "doWhile": { "index": 5, "kind": "attribute", "displayName": "Do While", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enables the while loop that loops until the predicate evaluates to false or null." },
     "breakOnShutdown": { "index": 6, "kind": "attribute", "displayName": "Break On Shutdown", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the breakOnShutdown attribute is true, then the loop will not iterate until it reaches the end when Camel is shut down." },
-    "outputs": { "index": 7, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance [...]
+    "outputs": { "index": 7, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "k [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/multicast.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/multicast.json
index 6c6abaf464d..f1679366381 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/multicast.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/multicast.json
@@ -27,6 +27,6 @@
     "executorService": { "index": 12, "kind": "attribute", "displayName": "Executor Service", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.concurrent.ExecutorService", "deprecated": false, "autowired": false, "secret": false, "description": "Refers to a custom Thread Pool to be used for parallel processing. Notice if you set this option, then parallel processing is automatic implied, and you do not have to enable that option as well." },
     "onPrepare": { "index": 13, "kind": "attribute", "displayName": "On Prepare", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.Processor", "deprecated": false, "autowired": false, "secret": false, "description": "Uses the Processor when preparing the org.apache.camel.Exchange to be send. This can be used to deep-clone messages that should be send, or any custom logic needed before the exchange is send." },
     "shareUnitOfWork": { "index": 14, "kind": "attribute", "displayName": "Share Unit Of Work", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Shares the org.apache.camel.spi.UnitOfWork with the parent and each of the sub messages. Multicast will by default not share unit of work between the parent exchange and each multicasted exchange. This means [...]
-    "outputs": { "index": 15, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "on [...]
+    "outputs": { "index": 15, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast" [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/onCompletion.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/onCompletion.json
index 0e4b42cfeec..a2ac866950c 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/onCompletion.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/onCompletion.json
@@ -22,6 +22,6 @@
     "executorService": { "index": 7, "kind": "attribute", "displayName": "Executor Service", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.concurrent.ExecutorService", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom Thread Pool to be used for parallel processing. Notice if you set this option, then parallel processing is automatic implied, and you do not have to enable that option as well." },
     "useOriginalMessage": { "index": 8, "kind": "attribute", "displayName": "Use Original Message", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input message body when an org.apache.camel.Exchange for this on completion. The original input message is defensively copied, and the copied message body is converted to org.apache [...]
     "onWhen": { "index": 9, "kind": "element", "displayName": "On When", "required": false, "type": "object", "javaType": "org.apache.camel.model.WhenDefinition", "deprecated": false, "autowired": false, "secret": false, "asPredicate": true, "description": "Sets an additional predicate that should be true before the onCompletion is triggered. To be used for fine grained controlling whether a completion callback should be invoked or not" },
-    "outputs": { "index": 10, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "on [...]
+    "outputs": { "index": 10, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast" [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/onException.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/onException.json
index 6de27e20851..2da14d671a7 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/onException.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/onException.json
@@ -26,6 +26,6 @@
     "onExceptionOccurredRef": { "index": 11, "kind": "attribute", "displayName": "On Exception Occurred Ref", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor that should be processed just after an exception occurred. Can be used to perform custom logging about the occurred exception at the exact time it happened. Important: Any exception thro [...]
     "useOriginalMessage": { "index": 12, "kind": "attribute", "displayName": "Use Original Message", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input org.apache.camel.Message (original body and headers) when an org.apache.camel.Exchange is moved to the dead letter queue. Notice: this only applies when all redeliveries atte [...]
     "useOriginalBody": { "index": 13, "kind": "attribute", "displayName": "Use Original Body", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input org.apache.camel.Message body (original body only) when an org.apache.camel.Exchange is moved to the dead letter queue. Notice: this only applies when all redeliveries attempt have [...]
-    "outputs": { "index": 14, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "on [...]
+    "outputs": { "index": 14, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast" [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/onFallback.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/onFallback.json
index 1c1774c10a9..38f930b21c6 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/onFallback.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/onFallback.json
@@ -16,6 +16,6 @@
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "fallbackViaNetwork": { "index": 3, "kind": "attribute", "displayName": "Fallback Via Network", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the fallback goes over the network. If the fallback will go over the network it is another possible point of failure. It is important to execute the fallback command on a separate thread-pool, ot [...]
-    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance [...]
+    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "k [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/otherwise.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/otherwise.json
index cce4b703fe8..11159f7e90b 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/otherwise.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/otherwise.json
@@ -15,6 +15,6 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/pipeline.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/pipeline.json
index 85ccd199df1..e7390054ea6 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/pipeline.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/pipeline.json
@@ -15,6 +15,6 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/resequence.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/resequence.json
index 4a12cdfaffe..d35481f201c 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/resequence.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/resequence.json
@@ -17,6 +17,6 @@
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "expression": { "index": 3, "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "sec [...]
     "resequencerConfig": { "index": 4, "kind": "element", "displayName": "Resequencer Config", "required": true, "type": "object", "javaType": "org.apache.camel.model.config.ResequencerConfig", "oneOf": [ "batchConfig", "streamConfig" ], "deprecated": false, "autowired": false, "secret": false, "description": "To configure the resequencer in using either batch or stream configuration. Will by default use batch configuration." },
-    "outputs": { "index": 5, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 5, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/route.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/route.json
index d4b9c4b06b2..c54e2e80e4e 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/route.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/route.json
@@ -32,6 +32,6 @@
     "inputType": { "index": 17, "kind": "element", "displayName": "Input Type", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.model.InputTypeDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Declare the expected data type of the input message. If the actual message type is different at runtime, camel look for a required org.apache.camel.spi.Transformer and apply if exists. The type name consists of two parts,  [...]
     "outputType": { "index": 18, "kind": "element", "displayName": "Output Type", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.model.OutputTypeDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Declare the expected data type of the output message. If the actual message type is different at runtime, camel look for a required org.apache.camel.spi.Transformer and apply if exists. The type name consists of two par [...]
     "input": { "index": 19, "kind": "element", "displayName": "Input", "required": true, "type": "object", "javaType": "org.apache.camel.model.FromDefinition", "oneOf": [ "from" ], "deprecated": false, "autowired": false, "secret": false, "description": "Input to the route." },
-    "outputs": { "index": 20, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<?>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loo [...]
+    "outputs": { "index": 20, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<?>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "load [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/saga.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/saga.json
index 2503f7defe6..4f14270e411 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/saga.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/saga.json
@@ -22,6 +22,6 @@
     "compensation": { "index": 7, "kind": "element", "displayName": "Compensation", "required": false, "type": "object", "javaType": "org.apache.camel.model.SagaActionUriDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "The compensation endpoint URI that must be called to compensate all changes done in the route. The route corresponding to the compensation URI must perform compensation and complete without error. If errors occur during compensation, t [...]
     "completion": { "index": 8, "kind": "element", "displayName": "Completion", "required": false, "type": "object", "javaType": "org.apache.camel.model.SagaActionUriDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "The completion endpoint URI that will be called when the Saga is completed successfully. The route corresponding to the completion URI must perform completion tasks and terminate without error. If errors occur during completion, the saga s [...]
     "option": { "index": 9, "kind": "element", "displayName": "Option", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.PropertyExpressionDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to save properties of the current exchange in order to re-use them in a compensation\/completion callback route. Options are usually helpful e.g. to store and retrieve identifiers of objects that sho [...]
-    "outputs": { "index": 10, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "on [...]
+    "outputs": { "index": 10, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast" [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/split.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/split.json
index 395a1cb544a..edf22cd176d 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/split.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/split.json
@@ -29,6 +29,6 @@
     "executorService": { "index": 14, "kind": "attribute", "displayName": "Executor Service", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.concurrent.ExecutorService", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom Thread Pool to be used for parallel processing. Notice if you set this option, then parallel processing is automatically implied, and you do not have to enable that option as well." },
     "onPrepare": { "index": 15, "kind": "attribute", "displayName": "On Prepare", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.Processor", "deprecated": false, "autowired": false, "secret": false, "description": "Uses the Processor when preparing the org.apache.camel.Exchange to be sent. This can be used to deep-clone messages that should be sent, or any custom logic needed before the exchange is sent." },
     "shareUnitOfWork": { "index": 16, "kind": "attribute", "displayName": "Share Unit Of Work", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Shares the org.apache.camel.spi.UnitOfWork with the parent and each of the sub messages. Splitter will by default not share unit of work between the parent exchange and each split exchange. This means each s [...]
-    "outputs": { "index": 17, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalanc [...]
+    "outputs": { "index": 17, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", " [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/step.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/step.json
index 2d47cf3b901..8f343dbb807 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/step.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/step.json
@@ -15,6 +15,6 @@
     "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
-    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", "onCompletion", "onE [...]
+    "outputs": { "index": 3, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance", "log", "loop", "marshal", "multicast", [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/when.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/when.json
index c9278a4adae..575173bbb67 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/when.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/when.json
@@ -16,6 +16,6 @@
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "expression": { "index": 3, "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "sec [...]
-    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance [...]
+    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "k [...]
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/whenSkipSendToEndpoint.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/whenSkipSendToEndpoint.json
index 61cd7cd5fe9..e343ba7a734 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/whenSkipSendToEndpoint.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/whenSkipSendToEndpoint.json
@@ -16,6 +16,6 @@
     "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" },
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." },
     "expression": { "index": 3, "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "sec [...]
-    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "kamelet", "loadBalance [...]
+    "outputs": { "index": 4, "kind": "element", "displayName": "Outputs", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ProcessorDefinition<java.lang.Object>>", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", "claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", "doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", "idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", "k [...]
   }
 }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertHeaderDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertHeaderDefinition.java
index 5ef26087319..6839c1268e4 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertHeaderDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertHeaderDefinition.java
@@ -86,7 +86,7 @@ public class ConvertHeaderDefinition extends NoOutputDefinition<ConvertHeaderDef
 
     @Override
     public String getLabel() {
-        return "convertBodyTo[" + getType() + "]";
+        return "convertHeaderTo[" + getType() + "]";
     }
 
     /**
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertHeaderDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertVariableDefinition.java
similarity index 82%
copy from core/camel-core-model/src/main/java/org/apache/camel/model/ConvertHeaderDefinition.java
copy to core/camel-core-model/src/main/java/org/apache/camel/model/ConvertVariableDefinition.java
index 5ef26087319..8e650af2777 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertHeaderDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertVariableDefinition.java
@@ -25,12 +25,12 @@ import jakarta.xml.bind.annotation.XmlTransient;
 import org.apache.camel.spi.Metadata;
 
 /**
- * Converts the message header to another type
+ * Converts the variable to another type
  */
 @Metadata(label = "eip,transformation")
-@XmlRootElement(name = "convertHeaderTo")
+@XmlRootElement(name = "convertVariableTo")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class ConvertHeaderDefinition extends NoOutputDefinition<ConvertHeaderDefinition> {
+public class ConvertVariableDefinition extends NoOutputDefinition<ConvertVariableDefinition> {
 
     @XmlTransient
     private Class<?> typeClass;
@@ -46,28 +46,28 @@ public class ConvertHeaderDefinition extends NoOutputDefinition<ConvertHeaderDef
     @Metadata(label = "advanced")
     private String charset;
 
-    public ConvertHeaderDefinition() {
+    public ConvertVariableDefinition() {
     }
 
-    public ConvertHeaderDefinition(String name, String type) {
+    public ConvertVariableDefinition(String name, String type) {
         setName(name);
         setType(type);
     }
 
-    public ConvertHeaderDefinition(String name, Class<?> typeClass) {
+    public ConvertVariableDefinition(String name, Class<?> typeClass) {
         setName(name);
         setTypeClass(typeClass);
         setType(typeClass.getCanonicalName());
     }
 
-    public ConvertHeaderDefinition(String name, Class<?> typeClass, boolean mandatory) {
+    public ConvertVariableDefinition(String name, Class<?> typeClass, boolean mandatory) {
         setName(name);
         setTypeClass(typeClass);
         setType(typeClass.getCanonicalName());
         setMandatory(mandatory ? "true" : "false");
     }
 
-    public ConvertHeaderDefinition(String name, Class<?> typeClass, String charset) {
+    public ConvertVariableDefinition(String name, Class<?> typeClass, String charset) {
         setName(name);
         setTypeClass(typeClass);
         setType(typeClass.getCanonicalName());
@@ -76,21 +76,21 @@ public class ConvertHeaderDefinition extends NoOutputDefinition<ConvertHeaderDef
 
     @Override
     public String toString() {
-        return "ConvertHeaderTo[" + getName() + ": " + getType() + "]";
+        return "ConvertVariableTo[" + getName() + ": " + getType() + "]";
     }
 
     @Override
     public String getShortName() {
-        return "convertHeaderTo";
+        return "convertVariableTo";
     }
 
     @Override
     public String getLabel() {
-        return "convertBodyTo[" + getType() + "]";
+        return "convertVariableTo[" + getType() + "]";
     }
 
     /**
-     * Name of message header to convert its value
+     * Name of variable to convert its value
      * <p/>
      * The <tt>simple</tt> language can be used to define a dynamic evaluated header name to be used. Otherwise a
      * constant name will be used.
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
index af8278dd62a..46dee7fa71e 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
@@ -2858,6 +2858,44 @@ public abstract class ProcessorDefinition<Type extends ProcessorDefinition<Type>
         return asType();
     }
 
+    /**
+     * Converts the variable to the specified type
+     *
+     * @param  name the variable name
+     * @param  type the type to convert to
+     * @return      the builder
+     */
+    public Type convertVariableTo(String name, Class<?> type) {
+        addOutput(new ConvertVariableDefinition(name, type));
+        return asType();
+    }
+
+    /**
+     * Converts the variable to the specified type
+     *
+     * @param  name      the variable name
+     * @param  type      the type to convert to
+     * @param  mandatory whether to use mandatory type conversion or not
+     * @return           the builder
+     */
+    public Type convertVariableTo(String name, Class<?> type, boolean mandatory) {
+        addOutput(new ConvertVariableDefinition(name, type, mandatory));
+        return asType();
+    }
+
+    /**
+     * Converts the variable to the specified type
+     *
+     * @param  name    the variable name
+     * @param  type    the type to convert to
+     * @param  charset the charset to use by type converters (not all converters support specific charset)
+     * @return         the builder
+     */
+    public Type convertVariableTo(String name, Class<?> type, String charset) {
+        addOutput(new ConvertVariableDefinition(name, type, charset));
+        return asType();
+    }
+
     /**
      * Sorts the expression using a default sorting based on toString representation.
      *
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ConvertVariableReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ConvertVariableReifier.java
new file mode 100644
index 00000000000..15a057b543d
--- /dev/null
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ConvertVariableReifier.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.reifier;
+
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+
+import org.apache.camel.Expression;
+import org.apache.camel.Processor;
+import org.apache.camel.Route;
+import org.apache.camel.model.ConvertVariableDefinition;
+import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.support.LanguageSupport;
+import org.apache.camel.support.processor.ConvertVariableProcessor;
+
+public class ConvertVariableReifier extends ProcessorReifier<ConvertVariableDefinition> {
+
+    public ConvertVariableReifier(Route route, ProcessorDefinition<?> definition) {
+        super(route, ConvertVariableDefinition.class.cast(definition));
+    }
+
+    @Override
+    public Processor createProcessor() throws Exception {
+        String key = parseString(definition.getName());
+        Expression nameExpr;
+        if (LanguageSupport.hasSimpleFunction(key)) {
+            nameExpr = camelContext.resolveLanguage("simple").createExpression(key);
+        } else {
+            nameExpr = camelContext.resolveLanguage("constant").createExpression(key);
+        }
+        nameExpr.init(camelContext);
+        Class<?> typeClass = parse(Class.class, or(definition.getTypeClass(), parseString(definition.getType())));
+        String charset = validateCharset(parseString(definition.getCharset()));
+        boolean mandatory = true;
+        if (definition.getMandatory() != null) {
+            mandatory = parseBoolean(definition.getMandatory(), true);
+        }
+        return new ConvertVariableProcessor(key, nameExpr, typeClass, charset, mandatory);
+    }
+
+    public static String validateCharset(String charset) throws UnsupportedCharsetException {
+        if (charset != null) {
+            if (Charset.isSupported(charset)) {
+                return Charset.forName(charset).name();
+            }
+            throw new UnsupportedCharsetException(charset);
+        }
+        return null;
+    }
+
+}
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ProcessorReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
index e35292084fa..32bbdb1aacd 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
@@ -42,6 +42,7 @@ import org.apache.camel.model.CircuitBreakerDefinition;
 import org.apache.camel.model.ClaimCheckDefinition;
 import org.apache.camel.model.ConvertBodyDefinition;
 import org.apache.camel.model.ConvertHeaderDefinition;
+import org.apache.camel.model.ConvertVariableDefinition;
 import org.apache.camel.model.DelayDefinition;
 import org.apache.camel.model.DynamicRouterDefinition;
 import org.apache.camel.model.EnrichDefinition;
@@ -219,6 +220,8 @@ public abstract class ProcessorReifier<T extends ProcessorDefinition<?>> extends
             return new ConvertBodyReifier(route, definition);
         } else if (definition instanceof ConvertHeaderDefinition) {
             return new ConvertHeaderReifier(route, definition);
+        } else if (definition instanceof ConvertVariableDefinition) {
+            return new ConvertVariableReifier(route, definition);
         } else if (definition instanceof DelayDefinition) {
             return new DelayReifier(route, definition);
         } else if (definition instanceof DynamicRouterDefinition) {
diff --git a/core/camel-core/src/test/java/org/apache/camel/model/XmlParseTest.java b/core/camel-core/src/test/java/org/apache/camel/model/XmlParseTest.java
index 86bd8a396df..5302c1f5c78 100644
--- a/core/camel-core/src/test/java/org/apache/camel/model/XmlParseTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/model/XmlParseTest.java
@@ -167,6 +167,15 @@ public class XmlParseTest extends XmlTestSupport {
         assertEquals("java.lang.Integer", node.getType());
     }
 
+    @Test
+    public void testParseConvertVariableXml() throws Exception {
+        RouteDefinition route = assertOneRoute("convertVariable.xml");
+        assertFrom(route, "seda:a");
+        ConvertVariableDefinition node = assertOneProcessorInstanceOf(ConvertVariableDefinition.class, route);
+        assertEquals("foo", node.getName());
+        assertEquals("java.lang.Integer", node.getType());
+    }
+
     @Test
     public void testParseRoutingSlipXml() throws Exception {
         RouteDefinition route = assertOneRoute("routingSlip.xml");
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/converter/ConvertVariableTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/converter/ConvertVariableTest.java
new file mode 100644
index 00000000000..0d0564a11d7
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/converter/ConvertVariableTest.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.processor.converter;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Date;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.NoSuchVariableException;
+import org.apache.camel.NoTypeConversionAvailableException;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.builder.ExchangeBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+public class ConvertVariableTest extends ContextTestSupport {
+
+    @Test
+    public void testConvertBodyTo() {
+        try {
+            context.addRoutes(new RouteBuilder() {
+                public void configure() {
+                    // set an invalid charset
+                    from("direct:invalid").convertVariableTo("foo", String.class, "ASSI").to("mock:endpoint");
+                }
+            });
+            fail("Should have thrown an exception");
+        } catch (Exception e) {
+            assertIsInstanceOf(UnsupportedCharsetException.class, e.getCause());
+        }
+    }
+
+    @Test
+    public void testConvertBodyCharset() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            public void configure() {
+                from("direct:foo").setVariable("foo", header("foo")).removeHeader("foo")
+                        .convertVariableTo("foo", byte[].class, "iso-8859-1").to("mock:foo");
+            }
+        });
+
+        getMockEndpoint("mock:foo").expectedMessageCount(1);
+        // do not propagate charset to avoid side effects with double conversion
+        // etc
+        getMockEndpoint("mock:foo").message(0).exchangeProperty(Exchange.CHARSET_NAME).isNull();
+
+        template.sendBodyAndHeader("direct:foo", null, "foo", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testConvertBodyCharsetWithExistingCharsetName() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            public void configure() {
+                from("direct:foo").setVariable("foo", header("foo")).removeHeader("foo")
+                        .convertVariableTo("foo", byte[].class, "iso-8859-1").to("mock:foo");
+            }
+        });
+
+        getMockEndpoint("mock:foo").expectedMessageCount(1);
+        // do not propagate charset to avoid side effects with double conversion
+        // etc
+        getMockEndpoint("mock:foo").message(0).exchangeProperty(Exchange.CHARSET_NAME).isEqualTo("UTF-8");
+
+        Exchange srcExchange = ExchangeBuilder.anExchange(context).withProperty(Exchange.CHARSET_NAME, "UTF-8")
+                .withHeader("foo", "Hello World").build();
+
+        template.send("direct:foo", srcExchange);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testConvertToInteger() throws Exception {
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.expectedVariableReceived("foo", 11);
+
+        template.sendBodyAndHeader("direct:start", null, "foo", 11);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testConvertToIntegerNotMandatory() throws Exception {
+        // mandatory should fail
+        try {
+            template.sendBodyAndHeader("direct:start", null, "foo", Double.NaN);
+            fail();
+        } catch (Exception e) {
+            assertIsInstanceOf(NoTypeConversionAvailableException.class, e.getCause());
+        }
+
+        // optional should cause null body
+        getMockEndpoint("mock:result").expectedMessageCount(1);
+        getMockEndpoint("mock:result").message(0).body().isNull();
+
+        template.sendBodyAndHeader("direct:optional", null, "foo", Double.NaN);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testConvertNullBody() throws Exception {
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.expectedMessageCount(0);
+
+        try {
+            template.sendBodyAndHeader("direct:start", null, "foo", null);
+            fail("Should have thrown an exception");
+        } catch (Exception e) {
+            NoSuchVariableException nv = assertIsInstanceOf(NoSuchVariableException.class, e.getCause());
+            assertEquals("foo", nv.getVariableName());
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testConvertFailed() throws Exception {
+        getMockEndpoint("mock:result").expectedMessageCount(0);
+
+        try {
+            template.sendBodyAndHeader("direct:invalid", null, "foo", "11");
+            fail("Should have thrown an exception");
+        } catch (RuntimeCamelException e) {
+            boolean b = e.getCause() instanceof NoTypeConversionAvailableException;
+            assertTrue(b);
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testConvertToBytesCharset() throws Exception {
+        byte[] body = "Hello World".getBytes("iso-8859-1");
+
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.expectedVariableReceived("foo", body);
+
+        template.sendBodyAndHeader("direct:charset", null, "foo", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testConvertToStringCharset() throws Exception {
+        String body = "Hello World";
+
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.expectedVariableReceived("foo", body);
+
+        template.sendBodyAndHeader("direct:charset3", null, "foo", new ByteArrayInputStream(body.getBytes("utf-16")));
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testConvertToBytesCharsetFail() throws Exception {
+        byte[] body = "Hello World".getBytes("utf-8");
+
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.expectedVariableReceived("foo", body);
+        result.expectedMessageCount(1);
+
+        template.sendBodyAndHeader("direct:charset2", null, "foo", "Hello World");
+
+        // should NOT be okay as we expected utf-8 but got it in utf-16
+        result.assertIsNotSatisfied();
+    }
+
+    // does not work on AIX
+    @DisabledOnOs(OS.AIX)
+    @Test
+    public void testConvertToStringCharsetFail() throws Exception {
+        String body = "Hell\u00F6 W\u00F6rld";
+
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.expectedVariableReceived("foo", body);
+        result.expectedMessageCount(1);
+
+        template.sendBodyAndHeader("direct:charset3", null, "foo", new ByteArrayInputStream(body.getBytes("utf-8")));
+
+        // should NOT be okay as we expected utf-8 but got it in utf-16
+        result.assertIsNotSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:start").setVariable("foo", header("foo")).removeHeader("foo")
+                        .convertVariableTo("foo", Integer.class).to("mock:result");
+                from("direct:optional").setVariable("foo", header("foo")).removeHeader("foo")
+                        .convertVariableTo("foo", Integer.class, false).to("mock:result");
+                from("direct:invalid").setVariable("foo", header("foo")).removeHeader("foo")
+                        .convertVariableTo("foo", Date.class).to("mock:result");
+                from("direct:charset").setVariable("foo", header("foo")).removeHeader("foo")
+                        .convertVariableTo("foo", byte[].class, "iso-8859-1").to("mock:result");
+                from("direct:charset2").setVariable("foo", header("foo")).removeHeader("foo")
+                        .convertVariableTo("foo", byte[].class, "utf-16").to("mock:result");
+                from("direct:charset3").setVariable("foo", header("foo")).removeHeader("foo")
+                        .convertVariableTo("foo", String.class, "utf-16").to("mock:result");
+            }
+        };
+    }
+
+}
diff --git a/core/camel-core/src/test/resources/org/apache/camel/model/convertVariable.xml b/core/camel-core/src/test/resources/org/apache/camel/model/convertVariable.xml
new file mode 100644
index 00000000000..9761846071b
--- /dev/null
+++ b/core/camel-core/src/test/resources/org/apache/camel/model/convertVariable.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<routes id="camel" xmlns="http://camel.apache.org/schema/spring">
+  <route>
+    <from uri="seda:a"/>
+    <convertVariableTo name="foo" type="java.lang.Integer"/>
+  </route>
+</routes>
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedConvertVariableMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedConvertVariableMBean.java
new file mode 100644
index 00000000000..eb515328221
--- /dev/null
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedConvertVariableMBean.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.api.management.mbean;
+
+import org.apache.camel.api.management.ManagedAttribute;
+
+public interface ManagedConvertVariableMBean extends ManagedProcessorMBean {
+
+    @ManagedAttribute(description = "The variable name")
+    String getName();
+
+    @ManagedAttribute(description = "The java type to convert to")
+    String getType();
+
+    @ManagedAttribute(description = "To use a specific charset when converting")
+    String getCharset();
+
+}
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementObjectStrategy.java b/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementObjectStrategy.java
index ee31f12b21a..6945ddacc43 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementObjectStrategy.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementObjectStrategy.java
@@ -45,6 +45,7 @@ import org.apache.camel.management.mbean.ManagedComponent;
 import org.apache.camel.management.mbean.ManagedConsumer;
 import org.apache.camel.management.mbean.ManagedConvertBody;
 import org.apache.camel.management.mbean.ManagedConvertHeader;
+import org.apache.camel.management.mbean.ManagedConvertVariable;
 import org.apache.camel.management.mbean.ManagedCustomLoadBalancer;
 import org.apache.camel.management.mbean.ManagedDataFormat;
 import org.apache.camel.management.mbean.ManagedDelayer;
@@ -196,6 +197,7 @@ import org.apache.camel.spi.SupervisingRouteController;
 import org.apache.camel.support.ScheduledPollConsumer;
 import org.apache.camel.support.processor.ConvertBodyProcessor;
 import org.apache.camel.support.processor.ConvertHeaderProcessor;
+import org.apache.camel.support.processor.ConvertVariableProcessor;
 import org.apache.camel.support.processor.MarshalProcessor;
 import org.apache.camel.support.processor.PredicateValidatingProcessor;
 import org.apache.camel.support.processor.ThroughputLogger;
@@ -359,6 +361,8 @@ public class DefaultManagementObjectStrategy implements ManagementObjectStrategy
                 answer = new ManagedConvertBody(context, (ConvertBodyProcessor) target, definition);
             } else if (target instanceof ConvertHeaderProcessor) {
                 answer = new ManagedConvertHeader(context, (ConvertHeaderProcessor) target, definition);
+            } else if (target instanceof ConvertVariableProcessor) {
+                answer = new ManagedConvertVariable(context, (ConvertVariableProcessor) target, definition);
             } else if (target instanceof ChoiceProcessor) {
                 answer = new ManagedChoice(context, (ChoiceProcessor) target, definition);
             } else if (target instanceof ClaimCheckProcessor) {
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedConvertVariable.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedConvertVariable.java
new file mode 100644
index 00000000000..ae2929500a6
--- /dev/null
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedConvertVariable.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.management.mbean;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.api.management.mbean.ManagedConvertVariableMBean;
+import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.support.processor.ConvertVariableProcessor;
+
+@ManagedResource(description = "Managed ConvertVariable")
+public class ManagedConvertVariable extends ManagedProcessor implements ManagedConvertVariableMBean {
+    private final ConvertVariableProcessor processor;
+
+    public ManagedConvertVariable(CamelContext context, ConvertVariableProcessor processor, ProcessorDefinition<?> definition) {
+        super(context, processor, definition);
+        this.processor = processor;
+    }
+
+    @Override
+    public String getName() {
+        return processor.getName();
+    }
+
+    @Override
+    public String getType() {
+        return processor.getType().getCanonicalName();
+    }
+
+    @Override
+    public String getCharset() {
+        return processor.getCharset();
+    }
+}
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/processor/ConvertVariableProcessor.java b/core/camel-support/src/main/java/org/apache/camel/support/processor/ConvertVariableProcessor.java
new file mode 100644
index 00000000000..203b9dca517
--- /dev/null
+++ b/core/camel-support/src/main/java/org/apache/camel/support/processor/ConvertVariableProcessor.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.support.processor;
+
+import java.util.concurrent.CompletableFuture;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.AsyncProcessor;
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePropertyKey;
+import org.apache.camel.Expression;
+import org.apache.camel.NoSuchVariableException;
+import org.apache.camel.spi.IdAware;
+import org.apache.camel.spi.RouteIdAware;
+import org.apache.camel.spi.VariableRepository;
+import org.apache.camel.spi.VariableRepositoryFactory;
+import org.apache.camel.support.AsyncCallbackToCompletableFutureAdapter;
+import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
+
+/**
+ * A processor which converts the variable to be of the given type
+ */
+public class ConvertVariableProcessor extends ServiceSupport
+        implements AsyncProcessor, IdAware, RouteIdAware, CamelContextAware {
+    private CamelContext camelContext;
+    private VariableRepositoryFactory factory;
+    private String id;
+    private String routeId;
+    private final String name;
+    private final Expression variableName;
+    private final Class<?> type;
+    private final String charset;
+    private final boolean mandatory;
+
+    public ConvertVariableProcessor(String name, Expression variableName, Class<?> type, String charset, boolean mandatory) {
+        ObjectHelper.notNull(variableName, "variableName");
+        ObjectHelper.notNull(type, "type", this);
+        this.name = name;
+        this.variableName = variableName;
+        this.type = type;
+        this.charset = IOHelper.normalizeCharset(charset);
+        this.mandatory = mandatory;
+    }
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
+    public String toString() {
+        return id;
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public String getRouteId() {
+        return routeId;
+    }
+
+    @Override
+    public void setRouteId(String routeId) {
+        this.routeId = routeId;
+    }
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        // what is the variable name
+        String name = variableName.evaluate(exchange, String.class);
+        String key = name;
+
+        VariableRepository repo = null;
+        Object value;
+        String id = StringHelper.before(key, ":");
+        if (id != null) {
+            key = StringHelper.after(key, ":");
+            repo = factory.getVariableRepository(id);
+            if (repo == null) {
+                throw new IllegalArgumentException("VariableRepository with id: " + id + " does not exists");
+            }
+            value = repo.getVariable(key);
+        } else {
+            value = exchange.getVariable(key);
+        }
+
+        if (value == null && mandatory) {
+            throw new NoSuchVariableException(exchange, name);
+        } else if (value == null) {
+            // only convert if there is a variable
+            return;
+        }
+
+        String originalCharsetName = null;
+        if (charset != null) {
+            originalCharsetName = exchange.getProperty(ExchangePropertyKey.CHARSET_NAME, String.class);
+            // override existing charset with configured charset as that is what the user
+            // have explicit configured and expects to be used
+            exchange.setProperty(ExchangePropertyKey.CHARSET_NAME, charset);
+        }
+        if (mandatory) {
+            value = exchange.getContext().getTypeConverter().mandatoryConvertTo(type, exchange, value);
+        } else {
+            value = exchange.getContext().getTypeConverter().convertTo(type, exchange, value);
+        }
+
+        if (repo != null) {
+            repo.setVariable(key, value);
+        } else {
+            exchange.setVariable(key, value);
+        }
+
+        // remove or restore charset when we are done as we should not propagate that,
+        // as that can lead to double converting later on
+        if (charset != null) {
+            if (originalCharsetName != null && !originalCharsetName.isEmpty()) {
+                exchange.setProperty(ExchangePropertyKey.CHARSET_NAME, originalCharsetName);
+            } else {
+                exchange.removeProperty(ExchangePropertyKey.CHARSET_NAME);
+            }
+        }
+    }
+
+    @Override
+    public CompletableFuture<Exchange> processAsync(Exchange exchange) {
+        AsyncCallbackToCompletableFutureAdapter<Exchange> callback = new AsyncCallbackToCompletableFutureAdapter<>(exchange);
+        process(exchange, callback);
+        return callback.getFuture();
+    }
+
+    @Override
+    public boolean process(Exchange exchange, AsyncCallback callback) {
+        try {
+            process(exchange);
+        } catch (Exception e) {
+            exchange.setException(e);
+        }
+        callback.done(true);
+        return true;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Class<?> getType() {
+        return type;
+    }
+
+    public String getCharset() {
+        return charset;
+    }
+
+    @Override
+    protected void doBuild() throws Exception {
+        ObjectHelper.notNull(camelContext, "camelContext");
+        factory = camelContext.getCamelContextExtension().getContextPlugin(VariableRepositoryFactory.class);
+    }
+}
diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index d1904e585ab..29bbc496d4f 100644
--- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -324,6 +324,18 @@ public class ModelParser extends BaseParser {
             return true;
         }, optionalIdentifiedDefinitionElementHandler(), noValueHandler());
     }
+    protected ConvertVariableDefinition doParseConvertVariableDefinition() throws IOException, XmlPullParserException {
+        return doParse(new ConvertVariableDefinition(), (def, key, val) -> {
+            switch (key) {
+                case "charset": def.setCharset(val); break;
+                case "mandatory": def.setMandatory(val); break;
+                case "name": def.setName(val); break;
+                case "type": def.setType(val); break;
+                default: return processorDefinitionAttributeHandler().accept(def, key, val);
+            }
+            return true;
+        }, optionalIdentifiedDefinitionElementHandler(), noValueHandler());
+    }
     protected DataFormatDefinition doParseDataFormatDefinition() throws IOException, XmlPullParserException {
         return doParse(new DataFormatDefinition(), 
             identifiedTypeAttributeHandler(),  noElementHandler(), noValueHandler());
@@ -3460,6 +3472,7 @@ public class ModelParser extends BaseParser {
             case "claimCheck": return doParseClaimCheckDefinition();
             case "convertBodyTo": return doParseConvertBodyDefinition();
             case "convertHeaderTo": return doParseConvertHeaderDefinition();
+            case "convertVariableTo": return doParseConvertVariableDefinition();
             case "delay": return doParseDelayDefinition();
             case "dynamicRouter": return doParseDynamicRouterDefinition();
             case "enrich": return doParseEnrichDefinition();
diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
index 9819165689c..29576e4c78e 100644
--- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
+++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
@@ -88,6 +88,11 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         doWriteConvertHeaderDefinition("convertHeaderTo", def);
     }
+    public void writeConvertVariableDefinition(
+            ConvertVariableDefinition def)
+            throws IOException {
+        doWriteConvertVariableDefinition("convertVariableTo", def);
+    }
     public void writeDelayDefinition(DelayDefinition def) throws IOException {
         doWriteDelayDefinition("delay", def);
     }
@@ -1188,6 +1193,18 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("mandatory", def.getMandatory());
         endElement(name);
     }
+    protected void doWriteConvertVariableDefinition(
+            String name,
+            ConvertVariableDefinition def)
+            throws IOException {
+        startElement(name);
+        doWriteProcessorDefinitionAttributes(def);
+        doWriteAttribute("charset", def.getCharset());
+        doWriteAttribute("name", def.getName());
+        doWriteAttribute("type", def.getType());
+        doWriteAttribute("mandatory", def.getMandatory());
+        endElement(name);
+    }
     protected void doWriteDataFormatDefinitionAttributes(
             DataFormatDefinition def)
             throws IOException {
@@ -4791,6 +4808,7 @@ public class ModelWriter extends BaseWriter {
                 case "ClaimCheckDefinition" -> doWriteClaimCheckDefinition("claimCheck", (ClaimCheckDefinition) v);
                 case "ConvertBodyDefinition" -> doWriteConvertBodyDefinition("convertBodyTo", (ConvertBodyDefinition) v);
                 case "ConvertHeaderDefinition" -> doWriteConvertHeaderDefinition("convertHeaderTo", (ConvertHeaderDefinition) v);
+                case "ConvertVariableDefinition" -> doWriteConvertVariableDefinition("convertVariableTo", (ConvertVariableDefinition) v);
                 case "DelayDefinition" -> doWriteDelayDefinition("delay", (DelayDefinition) v);
                 case "DynamicRouterDefinition" -> doWriteDynamicRouterDefinition("dynamicRouter", (DynamicRouterDefinition) v);
                 case "EnrichDefinition" -> doWriteEnrichDefinition("enrich", (EnrichDefinition) v);
@@ -4898,6 +4916,7 @@ public class ModelWriter extends BaseWriter {
                 case "ClaimCheckDefinition" -> doWriteClaimCheckDefinition("claimCheck", (ClaimCheckDefinition) v);
                 case "ConvertBodyDefinition" -> doWriteConvertBodyDefinition("convertBodyTo", (ConvertBodyDefinition) v);
                 case "ConvertHeaderDefinition" -> doWriteConvertHeaderDefinition("convertHeaderTo", (ConvertHeaderDefinition) v);
+                case "ConvertVariableDefinition" -> doWriteConvertVariableDefinition("convertVariableTo", (ConvertVariableDefinition) v);
                 case "DelayDefinition" -> doWriteDelayDefinition("delay", (DelayDefinition) v);
                 case "DynamicRouterDefinition" -> doWriteDynamicRouterDefinition("dynamicRouter", (DynamicRouterDefinition) v);
                 case "EnrichDefinition" -> doWriteEnrichDefinition("enrich", (EnrichDefinition) v);
diff --git a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
index 6e45d23c7d9..eb43c07425c 100644
--- a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
+++ b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
@@ -88,6 +88,11 @@ public class ModelWriter extends BaseWriter {
             throws IOException {
         doWriteConvertHeaderDefinition("convertHeaderTo", def);
     }
+    public void writeConvertVariableDefinition(
+            ConvertVariableDefinition def)
+            throws IOException {
+        doWriteConvertVariableDefinition("convertVariableTo", def);
+    }
     public void writeDelayDefinition(DelayDefinition def) throws IOException {
         doWriteDelayDefinition("delay", def);
     }
@@ -1188,6 +1193,18 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("mandatory", def.getMandatory());
         endElement(name);
     }
+    protected void doWriteConvertVariableDefinition(
+            String name,
+            ConvertVariableDefinition def)
+            throws IOException {
+        startElement(name);
+        doWriteProcessorDefinitionAttributes(def);
+        doWriteAttribute("charset", def.getCharset());
+        doWriteAttribute("name", def.getName());
+        doWriteAttribute("type", def.getType());
+        doWriteAttribute("mandatory", def.getMandatory());
+        endElement(name);
+    }
     protected void doWriteDataFormatDefinitionAttributes(
             DataFormatDefinition def)
             throws IOException {
@@ -4791,6 +4808,7 @@ public class ModelWriter extends BaseWriter {
                 case "ClaimCheckDefinition" -> doWriteClaimCheckDefinition("claimCheck", (ClaimCheckDefinition) v);
                 case "ConvertBodyDefinition" -> doWriteConvertBodyDefinition("convertBodyTo", (ConvertBodyDefinition) v);
                 case "ConvertHeaderDefinition" -> doWriteConvertHeaderDefinition("convertHeaderTo", (ConvertHeaderDefinition) v);
+                case "ConvertVariableDefinition" -> doWriteConvertVariableDefinition("convertVariableTo", (ConvertVariableDefinition) v);
                 case "DelayDefinition" -> doWriteDelayDefinition("delay", (DelayDefinition) v);
                 case "DynamicRouterDefinition" -> doWriteDynamicRouterDefinition("dynamicRouter", (DynamicRouterDefinition) v);
                 case "EnrichDefinition" -> doWriteEnrichDefinition("enrich", (EnrichDefinition) v);
@@ -4898,6 +4916,7 @@ public class ModelWriter extends BaseWriter {
                 case "ClaimCheckDefinition" -> doWriteClaimCheckDefinition("claimCheck", (ClaimCheckDefinition) v);
                 case "ConvertBodyDefinition" -> doWriteConvertBodyDefinition("convertBodyTo", (ConvertBodyDefinition) v);
                 case "ConvertHeaderDefinition" -> doWriteConvertHeaderDefinition("convertHeaderTo", (ConvertHeaderDefinition) v);
+                case "ConvertVariableDefinition" -> doWriteConvertVariableDefinition("convertVariableTo", (ConvertVariableDefinition) v);
                 case "DelayDefinition" -> doWriteDelayDefinition("delay", (DelayDefinition) v);
                 case "DynamicRouterDefinition" -> doWriteDynamicRouterDefinition("dynamicRouter", (DynamicRouterDefinition) v);
                 case "EnrichDefinition" -> doWriteEnrichDefinition("enrich", (EnrichDefinition) v);
diff --git a/docs/user-manual/modules/ROOT/pages/variables.adoc b/docs/user-manual/modules/ROOT/pages/variables.adoc
index e27b92286bf..275369402bd 100644
--- a/docs/user-manual/modules/ROOT/pages/variables.adoc
+++ b/docs/user-manual/modules/ROOT/pages/variables.adoc
@@ -75,7 +75,7 @@ String str = context.getVariable("myGlobalKey", String.class);
 == Setting and getting variables from DSL
 
 It is also possible to use variables in Camel xref:routes.adoc[routes] using the
-setVariable and removeVariable EIPs.
+setVariable, removeVariable, and convertVariableTo EIPs.
 
 These EIPs makes it possible to set and remove variables from routes. And you can also access variables from the xref:components:languages:simple-language.adoc[Simple] language.
 
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
index 03e230868e0..3984352312e 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
@@ -19,6 +19,7 @@ import org.apache.camel.model.ClaimCheckDefinition;
 import org.apache.camel.model.ContextScanDefinition;
 import org.apache.camel.model.ConvertBodyDefinition;
 import org.apache.camel.model.ConvertHeaderDefinition;
+import org.apache.camel.model.ConvertVariableDefinition;
 import org.apache.camel.model.DataFormatDefinition;
 import org.apache.camel.model.DelayDefinition;
 import org.apache.camel.model.DynamicRouterDefinition;
@@ -2648,6 +2649,90 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
         }
     }
 
+    @YamlType(
+            nodes = {
+                    "convert-variable-to",
+                    "convertVariableTo"
+            },
+            types = org.apache.camel.model.ConvertVariableDefinition.class,
+            order = org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
+            displayName = "Convert Variable To",
+            description = "Converts the variable to another type",
+            deprecated = false,
+            properties = {
+                    @YamlProperty(name = "charset", type = "string", description = "To use a specific charset when converting", displayName = "Charset"),
+                    @YamlProperty(name = "description", type = "string", description = "Sets the description of this node", displayName = "Description"),
+                    @YamlProperty(name = "disabled", type = "boolean", description = "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime.", displayName = "Disabled"),
+                    @YamlProperty(name = "id", type = "string", description = "Sets the id of this node", displayName = "Id"),
+                    @YamlProperty(name = "inheritErrorHandler", type = "boolean"),
+                    @YamlProperty(name = "mandatory", type = "boolean", description = "When mandatory then the conversion must return a value (cannot be null), if this is not possible then NoTypeConversionAvailableException is thrown. Setting this to false could mean conversion is not possible and the value is null.", displayName = "Mandatory"),
+                    @YamlProperty(name = "name", type = "string", required = true, description = "Name of variable to convert its value The simple language can be used to define a dynamic evaluated header name to be used. Otherwise a constant name will be used.", displayName = "Name"),
+                    @YamlProperty(name = "type", type = "string", required = true, description = "The java type to convert to", displayName = "Type")
+            }
+    )
+    public static class ConvertVariableDefinitionDeserializer extends YamlDeserializerBase<ConvertVariableDefinition> {
+        public ConvertVariableDefinitionDeserializer() {
+            super(ConvertVariableDefinition.class);
+        }
+
+        @Override
+        protected ConvertVariableDefinition newInstance() {
+            return new ConvertVariableDefinition();
+        }
+
+        @Override
+        protected boolean setProperty(ConvertVariableDefinition target, String propertyKey,
+                String propertyName, Node node) {
+            propertyKey = org.apache.camel.util.StringHelper.dashToCamelCase(propertyKey);
+            switch(propertyKey) {
+                case "charset": {
+                    String val = asText(node);
+                    target.setCharset(val);
+                    break;
+                }
+                case "disabled": {
+                    String val = asText(node);
+                    target.setDisabled(val);
+                    break;
+                }
+                case "inheritErrorHandler": {
+                    String val = asText(node);
+                    target.setInheritErrorHandler(java.lang.Boolean.valueOf(val));
+                    break;
+                }
+                case "mandatory": {
+                    String val = asText(node);
+                    target.setMandatory(val);
+                    break;
+                }
+                case "name": {
+                    String val = asText(node);
+                    target.setName(val);
+                    break;
+                }
+                case "type": {
+                    String val = asText(node);
+                    target.setType(val);
+                    break;
+                }
+                case "id": {
+                    String val = asText(node);
+                    target.setId(val);
+                    break;
+                }
+                case "description": {
+                    String val = asText(node);
+                    target.setDescription(val);
+                    break;
+                }
+                default: {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
     @YamlType(
             nodes = "crypto",
             types = org.apache.camel.model.dataformat.CryptoDataFormat.class,
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
index 41dcf485515..77fa9f0cb16 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
@@ -87,6 +87,9 @@ public final class ModelDeserializersResolver implements YamlDeserializerResolve
             case "convert-header-to": return new ModelDeserializers.ConvertHeaderDefinitionDeserializer();
             case "convertHeaderTo": return new ModelDeserializers.ConvertHeaderDefinitionDeserializer();
             case "org.apache.camel.model.ConvertHeaderDefinition": return new ModelDeserializers.ConvertHeaderDefinitionDeserializer();
+            case "convert-variable-to": return new ModelDeserializers.ConvertVariableDefinitionDeserializer();
+            case "convertVariableTo": return new ModelDeserializers.ConvertVariableDefinitionDeserializer();
+            case "org.apache.camel.model.ConvertVariableDefinition": return new ModelDeserializers.ConvertVariableDefinitionDeserializer();
             case "crypto": return new ModelDeserializers.CryptoDataFormatDeserializer();
             case "org.apache.camel.model.dataformat.CryptoDataFormat": return new ModelDeserializers.CryptoDataFormatDeserializer();
             case "csv": return new ModelDeserializers.CsvDataFormatDeserializer();
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
index bb91046902f..420ef377c91 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
@@ -34,6 +34,9 @@
           "convertHeaderTo" : {
             "$ref" : "#/items/definitions/org.apache.camel.model.ConvertHeaderDefinition"
           },
+          "convertVariableTo" : {
+            "$ref" : "#/items/definitions/org.apache.camel.model.ConvertVariableDefinition"
+          },
           "delay" : {
             "$ref" : "#/items/definitions/org.apache.camel.model.DelayDefinition"
           },
@@ -852,6 +855,50 @@
         },
         "required" : [ "name", "type" ]
       },
+      "org.apache.camel.model.ConvertVariableDefinition" : {
+        "title" : "Convert Variable To",
+        "description" : "Converts the variable to another type",
+        "type" : "object",
+        "additionalProperties" : false,
+        "properties" : {
+          "charset" : {
+            "type" : "string",
+            "title" : "Charset",
+            "description" : "To use a specific charset when converting"
+          },
+          "description" : {
+            "type" : "string",
+            "title" : "Description",
+            "description" : "Sets the description of this node"
+          },
+          "disabled" : {
+            "type" : "boolean",
+            "title" : "Disabled",
+            "description" : "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime."
+          },
+          "id" : {
+            "type" : "string",
+            "title" : "Id",
+            "description" : "Sets the id of this node"
+          },
+          "mandatory" : {
+            "type" : "boolean",
+            "title" : "Mandatory",
+            "description" : "When mandatory then the conversion must return a value (cannot be null), if this is not possible then NoTypeConversionAvailableException is thrown. Setting this to false could mean conversion is not possible and the value is null."
+          },
+          "name" : {
+            "type" : "string",
+            "title" : "Name",
+            "description" : "Name of variable to convert its value The simple language can be used to define a dynamic evaluated header name to be used. Otherwise a constant name will be used."
+          },
+          "type" : {
+            "type" : "string",
+            "title" : "Type",
+            "description" : "The java type to convert to"
+          }
+        },
+        "required" : [ "name", "type" ]
+      },
       "org.apache.camel.model.DataFormatDefinition" : {
         "type" : "object",
         "additionalProperties" : false,
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ConvertVariableTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ConvertVariableTest.groovy
new file mode 100644
index 00000000000..6f8436077be
--- /dev/null
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ConvertVariableTest.groovy
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.yaml
+
+import org.apache.camel.component.mock.MockEndpoint
+import org.apache.camel.dsl.yaml.support.YamlTestSupport
+import org.apache.camel.model.ConvertHeaderDefinition
+import org.apache.camel.model.ConvertVariableDefinition
+import org.junit.jupiter.api.Assertions
+
+class ConvertVariableTest extends YamlTestSupport {
+
+    def "convert-header-to"() {
+        setup:
+            loadRoutes '''
+                - from:
+                    uri: "direct:start"
+                    steps:    
+                      - setVariable:
+                          name: foo
+                          constant: "Hello World"
+                      - convertVariableTo:
+                          name: foo  
+                          type: "java.lang.String"
+                          charset: "UTF8"
+                      - to: "mock:result"
+            '''
+
+            withMock('mock:result') {
+                expectedVariableReceived("foo", 'Hello World')
+            }
+        when:
+            context.start()
+
+            withTemplate {
+                to('direct:start').send()
+            }
+        then:
+            context.routeDefinitions.size() == 1
+
+            with(context.routeDefinitions[0].outputs[1], ConvertVariableDefinition) {
+                name == 'foo'
+                type == 'java.lang.String'
+                charset == 'UTF8'
+            }
+
+            MockEndpoint.assertIsSatisfied(context)
+    }
+
+    def "Error: kebab-case: convert-variable-to"() {
+        when:
+        var route = '''
+                - from:
+                    uri: "direct:start"
+                    steps:    
+                      - convert-variable-to:
+                          name: foo  
+                          type: "java.lang.String"
+                          charset: "UTF8"
+                      - to: "mock:result"
+            '''
+
+        withMock('mock:result') {
+            expectedVariableReceived("foo", 'Hello World')
+        }
+        then:
+        try {
+            loadRoutes(route)
+            Assertions.fail("Should have thrown exception")
+        } catch (e) {
+            Assertions.assertTrue(e.message.contains("additional properties"))
+        }
+    }
+}