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 13:43:36 UTC

(camel) branch main updated: Toname (#12635)

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

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


The following commit(s) were added to refs/heads/main by this push:
     new a3e11a30fbb Toname (#12635)
a3e11a30fbb is described below

commit a3e11a30fbb183d449d665c5c5d85ea7bdb02186
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Jan 2 14:43:30 2024 +0100

    Toname (#12635)
    
    CAMEL-20288: camel-core - Convert header and variable To another name
---
 .../camel/catalog/models/convertHeaderTo.json      |  5 ++-
 .../camel/catalog/models/convertVariableTo.json    |  5 ++-
 .../apache/camel/catalog/schemas/camel-spring.xsd  | 22 +++++++++++
 .../processor/SpringConvertVariableTest.java       | 22 +++++------
 .../camel/spring/processor/convertHeader.xml       |  6 +++
 .../{convertHeader.xml => convertVariable.xml}     | 45 +++++++++++++++++++---
 .../modules/eips/pages/convertHeaderTo-eip.adoc    | 44 +++++++++++++++++++++
 .../modules/eips/pages/convertVariableTo-eip.adoc  | 44 +++++++++++++++++++++
 .../org/apache/camel/model/convertHeaderTo.json    |  5 ++-
 .../org/apache/camel/model/convertVariableTo.json  |  5 ++-
 .../camel/model/ConvertHeaderDefinition.java       | 24 ++++++++++++
 .../camel/model/ConvertVariableDefinition.java     | 24 ++++++++++++
 .../apache/camel/model/ProcessorDefinition.java    | 26 +++++++++++++
 .../apache/camel/reifier/ConvertHeaderReifier.java | 14 ++++++-
 .../camel/reifier/ConvertVariableReifier.java      | 14 ++++++-
 .../processor/converter/ConvertHeaderTest.java     | 14 +++++++
 .../processor/converter/ConvertVariableTest.java   | 16 ++++++++
 .../mbean/ManagedConvertHeaderMBean.java           |  3 ++
 .../mbean/ManagedConvertVariableMBean.java         |  3 ++
 .../management/mbean/ManagedConvertHeader.java     |  5 +++
 .../management/mbean/ManagedConvertVariable.java   |  5 +++
 .../support/processor/ConvertHeaderProcessor.java  | 14 ++++++-
 .../processor/ConvertVariableProcessor.java        | 16 ++++++--
 .../java/org/apache/camel/xml/in/ModelParser.java  |  2 +
 .../java/org/apache/camel/xml/out/ModelWriter.java |  2 +
 .../org/apache/camel/yaml/out/ModelWriter.java     |  2 +
 .../dsl/yaml/deserializers/ModelDeserializers.java | 12 ++++++
 .../generated/resources/schema/camelYamlDsl.json   | 10 +++++
 .../apache/camel/dsl/yaml/ConvertHeaderTest.groovy | 36 +++++++++++++++++
 .../camel/dsl/yaml/ConvertVariableTest.groovy      | 39 +++++++++++++++++++
 30 files changed, 451 insertions(+), 33 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/convertHeaderTo.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/convertHeaderTo.json
index 8567cc09065..0e2e103a2f2 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/convertHeaderTo.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/convertHeaderTo.json
@@ -17,7 +17,8 @@
     "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 message header 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" }
+    "toName": { "index": 5, "kind": "attribute", "displayName": "To Name", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use another header to store the result. By default, the result is stored in the same header. This option allows to use another header. The simple language can be used to define a dynamic evaluated header name to be used. Otherwise a constant name will be used." },
+    "mandatory": { "index": 6, "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": 7, "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/convertVariableTo.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/convertVariableTo.json
index ffb99653c99..5463dc826fb 100644
--- 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
@@ -17,7 +17,8 @@
     "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" }
+    "toName": { "index": 5, "kind": "attribute", "displayName": "To Name", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use another variable to store the result. By default, the result is stored in the same variable. This option allows to use another variable. The simple language can be used to define a dynamic evaluated variable name to be used. Otherwise a constant name will be used." },
+    "mandatory": { "index": 6, "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": 7, "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/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
index 0f9f530534a..0a2eeab461d 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
@@ -5039,6 +5039,17 @@ be used. Otherwise a constant name will be used.
             <xs:documentation xml:lang="en">
 <![CDATA[
 The java type to convert to.
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="toName" type="xs:string">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+To use another header to store the result. By default, the result is stored in the same header. This option allows to
+use another header. 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>
@@ -5085,6 +5096,17 @@ used. Otherwise a constant name will be used.
             <xs:documentation xml:lang="en">
 <![CDATA[
 The java type to convert to.
+]]>
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="toName" type="xs:string">
+          <xs:annotation>
+            <xs:documentation xml:lang="en">
+<![CDATA[
+To use another variable to store the result. By default, the result is stored in the same variable. This option allows
+to use another variable. The simple language can be used to define a dynamic evaluated variable name to be used.
+Otherwise a constant name will be used.
 ]]>
             </xs:documentation>
           </xs:annotation>
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedConvertHeaderMBean.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringConvertVariableTest.java
similarity index 61%
copy from core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedConvertHeaderMBean.java
copy to components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringConvertVariableTest.java
index a2f558e7aae..e7367ef69fd 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedConvertHeaderMBean.java
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringConvertVariableTest.java
@@ -14,19 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.api.management.mbean;
+package org.apache.camel.spring.processor;
 
-import org.apache.camel.api.management.ManagedAttribute;
+import org.apache.camel.CamelContext;
+import org.apache.camel.processor.converter.ConvertVariableTest;
 
-public interface ManagedConvertHeaderMBean extends ManagedProcessorMBean {
-
-    @ManagedAttribute(description = "The header name")
-    String getName();
-
-    @ManagedAttribute(description = "The java type to convert to")
-    String getType();
-
-    @ManagedAttribute(description = "To use a specific charset when converting")
-    String getCharset();
+import static org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
 
+public class SpringConvertVariableTest extends ConvertVariableTest {
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        return createSpringCamelContext(this,
+                "org/apache/camel/spring/processor/convertVariable.xml");
+    }
 }
diff --git a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/convertHeader.xml b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/convertHeader.xml
index a93fcf95cbf..9ac4c52426c 100644
--- a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/convertHeader.xml
+++ b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/convertHeader.xml
@@ -64,6 +64,12 @@
             <to uri="mock:result"/>
         </route>
 
+        <route>
+            <from uri="direct:bar"/>
+            <convertHeaderTo name="foo" toName="bar" type="java.lang.Integer"/>
+            <to uri="mock:result"/>
+        </route>
+
     </camelContext>
     <!-- END SNIPPET: example -->
 </beans>
diff --git a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/convertHeader.xml b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/convertVariable.xml
similarity index 56%
copy from components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/convertHeader.xml
copy to components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/convertVariable.xml
index a93fcf95cbf..57c958bec68 100644
--- a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/convertHeader.xml
+++ b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/convertVariable.xml
@@ -30,40 +30,73 @@
 
         <route>
             <from uri="direct:start"/>
-            <convertHeaderTo name="foo" type="java.lang.Integer"/>
+            <setVariable name="foo">
+                <header>foo</header>
+            </setVariable>
+            <removeHeader name="foo"/>
+            <convertVariableTo name="foo" type="java.lang.Integer"/>
             <to uri="mock:result"/>
         </route>
 
         <route>
             <from uri="direct:optional"/>
-            <convertHeaderTo name="foo" type="java.lang.Integer" mandatory="false"/>
+            <setVariable name="foo">
+                <header>foo</header>
+            </setVariable>
+            <removeHeader name="foo"/>
+            <convertVariableTo name="foo" type="java.lang.Integer" mandatory="false"/>
             <to uri="mock:result"/>
         </route>
 
         <route>
             <from uri="direct:invalid"/>
-            <convertHeaderTo name="foo" type="java.util.Date"/>
+            <setVariable name="foo">
+                <header>foo</header>
+            </setVariable>
+            <removeHeader name="foo"/>
+            <convertVariableTo name="foo" type="java.util.Date"/>
             <to uri="mock:result"/>
         </route>
 
         <route>
             <from uri="direct:charset"/>
-            <convertHeaderTo name="foo" type="java.lang.byte[]" charset="iso-8859-1"/>
+            <setVariable name="foo">
+                <header>foo</header>
+            </setVariable>
+            <removeHeader name="foo"/>
+            <convertVariableTo name="foo" type="java.lang.byte[]" charset="iso-8859-1"/>
             <to uri="mock:result"/>
         </route>
 
         <route>
             <from uri="direct:charset2"/>
-            <convertHeaderTo name="foo" type="java.lang.byte[]" charset="utf-16"/>
+            <setVariable name="foo">
+                <header>foo</header>
+            </setVariable>
+            <removeHeader name="foo"/>
+            <convertVariableTo name="foo" type="java.lang.byte[]" charset="utf-16"/>
             <to uri="mock:result"/>
         </route>
         
         <route>
             <from uri="direct:charset3"/>
-            <convertHeaderTo name="foo" type="java.lang.String" charset="utf-16"/>
+            <setVariable name="foo">
+                <header>foo</header>
+            </setVariable>
+            <removeHeader name="foo"/>
+            <convertVariableTo name="foo" type="java.lang.String" charset="utf-16"/>
             <to uri="mock:result"/>
         </route>
 
+        <route>
+            <from uri="direct:bar"/>
+            <setVariable name="foo">
+                <header>foo</header>
+            </setVariable>
+            <removeHeader name="foo"/>
+            <convertVariableTo name="foo" toName="bar" type="java.lang.Integer"/>
+            <to uri="mock:result"/>
+        </route>
     </camelContext>
     <!-- END SNIPPET: example -->
 </beans>
diff --git a/core/camel-core-engine/src/main/docs/modules/eips/pages/convertHeaderTo-eip.adoc b/core/camel-core-engine/src/main/docs/modules/eips/pages/convertHeaderTo-eip.adoc
index 659e7c8eb87..df04a1ac43b 100644
--- a/core/camel-core-engine/src/main/docs/modules/eips/pages/convertHeaderTo-eip.adoc
+++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/convertHeaderTo-eip.adoc
@@ -57,6 +57,50 @@ YAML::
 ----
 ====
 
+=== Convert to another header
+
+By default, the converted value is replaced in the existing header. However, you can tell Camel to store the result into another header,
+such as shown below where the value is stored in the `bar` header:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("seda:foo")
+  .convertHeaderTo("foo", "bar", String.class)
+  .log("The header content: ${header.bar}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="seda:foo"/>
+  <convertHeaderTo name="foo" toName="bar" type="String"/>
+  <log message="The header content: ${header.bar}"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- from:
+    uri: seda:foo
+    steps:
+      - convertHeaderTo:
+          name: foo
+          toName: bar
+          type: String
+      - log:
+          message: "The header content: ${header.bar}"
+----
+====
+
+
 === Dynamic header name
 
 The ConvertHeaderTo supports using xref:components:languages:simple-language.adoc[Simple] language for dynamic header name.
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
index 5c53e8bdd34..2d91349f193 100644
--- 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
@@ -57,6 +57,50 @@ YAML::
 ----
 ====
 
+=== Convert to another variable
+
+By default, the converted value is replaced in the existing variable. However, you can tell Camel to store the result into another variable,
+such as shown below where the value is stored in the `bar` variable:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("seda:foo")
+  .convertVariableTo("foo", "bar", String.class)
+  .log("The variable content: ${variable.bar}");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from uri="seda:foo"/>
+  <convertVariableTo name="foo" toName="bar" type="String"/>
+  <log message="The variable content: ${variable.bar}"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- from:
+    uri: seda:foo
+    steps:
+      - convertVariableTo:
+          name: foo
+          toName: bar
+          type: String
+      - log:
+          message: "The variable content: ${variable.bar}"
+----
+====
+
+
 === Dynamic variable name
 
 The ConvertVariableTo supports using xref:components:languages:simple-language.adoc[Simple] language for dynamic variable name.
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/convertHeaderTo.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/convertHeaderTo.json
index 8567cc09065..0e2e103a2f2 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/convertHeaderTo.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/convertHeaderTo.json
@@ -17,7 +17,8 @@
     "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 message header 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" }
+    "toName": { "index": 5, "kind": "attribute", "displayName": "To Name", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use another header to store the result. By default, the result is stored in the same header. This option allows to use another header. The simple language can be used to define a dynamic evaluated header name to be used. Otherwise a constant name will be used." },
+    "mandatory": { "index": 6, "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": 7, "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/convertVariableTo.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/convertVariableTo.json
index ffb99653c99..5463dc826fb 100644
--- 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
@@ -17,7 +17,8 @@
     "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" }
+    "toName": { "index": 5, "kind": "attribute", "displayName": "To Name", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use another variable to store the result. By default, the result is stored in the same variable. This option allows to use another variable. The simple language can be used to define a dynamic evaluated variable name to be used. Otherwise a constant name will be used." },
+    "mandatory": { "index": 6, "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": 7, "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/main/java/org/apache/camel/model/ConvertHeaderDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertHeaderDefinition.java
index 6839c1268e4..89dab3ddb63 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
@@ -40,6 +40,8 @@ public class ConvertHeaderDefinition extends NoOutputDefinition<ConvertHeaderDef
     @XmlAttribute(required = true)
     private String type;
     @XmlAttribute
+    private String toName;
+    @XmlAttribute
     @Metadata(label = "advanced", javaType = "java.lang.Boolean", defaultValue = "true")
     private String mandatory;
     @XmlAttribute
@@ -60,6 +62,13 @@ public class ConvertHeaderDefinition extends NoOutputDefinition<ConvertHeaderDef
         setType(typeClass.getCanonicalName());
     }
 
+    public ConvertHeaderDefinition(String name, String toName, Class<?> typeClass) {
+        setName(name);
+        setToName(toName);
+        setTypeClass(typeClass);
+        setType(typeClass.getCanonicalName());
+    }
+
     public ConvertHeaderDefinition(String name, Class<?> typeClass, boolean mandatory) {
         setName(name);
         setTypeClass(typeClass);
@@ -103,6 +112,21 @@ public class ConvertHeaderDefinition extends NoOutputDefinition<ConvertHeaderDef
         return name;
     }
 
+    public String getToName() {
+        return toName;
+    }
+
+    /**
+     * To use another header to store the result. By default, the result is stored in the same header. This option
+     * allows to use another header.
+     * <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.
+     */
+    public void setToName(String toName) {
+        this.toName = toName;
+    }
+
     public String getType() {
         return type;
     }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertVariableDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertVariableDefinition.java
index 8e650af2777..0ee738e598b 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertVariableDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/ConvertVariableDefinition.java
@@ -40,6 +40,8 @@ public class ConvertVariableDefinition extends NoOutputDefinition<ConvertVariabl
     @XmlAttribute(required = true)
     private String type;
     @XmlAttribute
+    private String toName;
+    @XmlAttribute
     @Metadata(label = "advanced", javaType = "java.lang.Boolean", defaultValue = "true")
     private String mandatory;
     @XmlAttribute
@@ -60,6 +62,13 @@ public class ConvertVariableDefinition extends NoOutputDefinition<ConvertVariabl
         setType(typeClass.getCanonicalName());
     }
 
+    public ConvertVariableDefinition(String name, String toName, Class<?> typeClass) {
+        setName(name);
+        setToName(toName);
+        setTypeClass(typeClass);
+        setType(typeClass.getCanonicalName());
+    }
+
     public ConvertVariableDefinition(String name, Class<?> typeClass, boolean mandatory) {
         setName(name);
         setTypeClass(typeClass);
@@ -103,6 +112,21 @@ public class ConvertVariableDefinition extends NoOutputDefinition<ConvertVariabl
         return name;
     }
 
+    public String getToName() {
+        return toName;
+    }
+
+    /**
+     * To use another variable to store the result. By default, the result is stored in the same variable. This option
+     * allows to use another variable.
+     * <p/>
+     * The <tt>simple</tt> language can be used to define a dynamic evaluated variable name to be used. Otherwise a
+     * constant name will be used.
+     */
+    public void setToName(String toName) {
+        this.toName = toName;
+    }
+
     public String getType() {
         return type;
     }
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 46dee7fa71e..27e520df1ac 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
@@ -2832,6 +2832,19 @@ public abstract class ProcessorDefinition<Type extends ProcessorDefinition<Type>
         return asType();
     }
 
+    /**
+     * Converts the IN message header to the specified type
+     *
+     * @param  name   the header name
+     * @param  toName to use another header to store the result
+     * @param  type   the type to convert to
+     * @return        the builder
+     */
+    public Type convertHeaderTo(String name, String toName, Class<?> type) {
+        addOutput(new ConvertHeaderDefinition(name, toName, type));
+        return asType();
+    }
+
     /**
      * Converts the IN message header to the specified type
      *
@@ -2870,6 +2883,19 @@ public abstract class ProcessorDefinition<Type extends ProcessorDefinition<Type>
         return asType();
     }
 
+    /**
+     * Converts the variable to the specified type
+     *
+     * @param  name   the variable name
+     * @param  toName to use another variable to store the result
+     * @param  type   the type to convert to
+     * @return        the builder
+     */
+    public Type convertVariableTo(String name, String toName, Class<?> type) {
+        addOutput(new ConvertVariableDefinition(name, toName, type));
+        return asType();
+    }
+
     /**
      * Converts the variable to the specified type
      *
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ConvertHeaderReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ConvertHeaderReifier.java
index 6e971b1092a..f184409b4fa 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ConvertHeaderReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ConvertHeaderReifier.java
@@ -43,13 +43,25 @@ public class ConvertHeaderReifier extends ProcessorReifier<ConvertHeaderDefiniti
             nameExpr = camelContext.resolveLanguage("constant").createExpression(key);
         }
         nameExpr.init(camelContext);
+
+        String toKey = parseString(definition.getToName());
+        Expression toNameExpr = null;
+        if (toKey != null) {
+            if (LanguageSupport.hasSimpleFunction(toKey)) {
+                toNameExpr = camelContext.resolveLanguage("simple").createExpression(toKey);
+            } else {
+                toNameExpr = camelContext.resolveLanguage("constant").createExpression(toKey);
+            }
+            toNameExpr.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 ConvertHeaderProcessor(key, nameExpr, typeClass, charset, mandatory);
+        return new ConvertHeaderProcessor(key, nameExpr, toKey, toNameExpr, typeClass, charset, mandatory);
     }
 
     public static String validateCharset(String charset) throws UnsupportedCharsetException {
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
index 15a057b543d..395cf43d695 100644
--- 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
@@ -43,13 +43,25 @@ public class ConvertVariableReifier extends ProcessorReifier<ConvertVariableDefi
             nameExpr = camelContext.resolveLanguage("constant").createExpression(key);
         }
         nameExpr.init(camelContext);
+
+        String toKey = parseString(definition.getToName());
+        Expression toNameExpr = null;
+        if (toKey != null) {
+            if (LanguageSupport.hasSimpleFunction(toKey)) {
+                toNameExpr = camelContext.resolveLanguage("simple").createExpression(toKey);
+            } else {
+                toNameExpr = camelContext.resolveLanguage("constant").createExpression(toKey);
+            }
+            toNameExpr.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);
+        return new ConvertVariableProcessor(key, nameExpr, toKey, toNameExpr, typeClass, charset, mandatory);
     }
 
     public static String validateCharset(String charset) throws UnsupportedCharsetException {
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/converter/ConvertHeaderTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/converter/ConvertHeaderTest.java
index c3a5be38fcc..0680c6f6be0 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/converter/ConvertHeaderTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/converter/ConvertHeaderTest.java
@@ -100,6 +100,19 @@ public class ConvertHeaderTest extends ContextTestSupport {
         assertMockEndpointsSatisfied();
     }
 
+    @Test
+    public void testConvertToName() throws Exception {
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.expectedHeaderReceived("foo", "11");
+        result.expectedHeaderReceived("bar", 11);
+        result.message(0).header("foo").isInstanceOf(String.class);
+        result.message(0).header("bar").isInstanceOf(Integer.class);
+
+        template.sendBodyAndHeader("direct:bar", null, "foo", "11");
+
+        assertMockEndpointsSatisfied();
+    }
+
     @Test
     public void testConvertToIntegerNotMandatory() throws Exception {
         // mandatory should fail
@@ -209,6 +222,7 @@ public class ConvertHeaderTest extends ContextTestSupport {
                 from("direct:charset").convertHeaderTo("foo", byte[].class, "iso-8859-1").to("mock:result");
                 from("direct:charset2").convertHeaderTo("foo", byte[].class, "utf-16").to("mock:result");
                 from("direct:charset3").convertHeaderTo("foo", String.class, "utf-16").to("mock:result");
+                from("direct:bar").convertHeaderTo("foo", "bar", Integer.class).to("mock:result");
             }
         };
     }
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
index 0d0564a11d7..0f9724ed120 100644
--- 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
@@ -104,6 +104,19 @@ public class ConvertVariableTest extends ContextTestSupport {
         assertMockEndpointsSatisfied();
     }
 
+    @Test
+    public void testConvertToName() throws Exception {
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.expectedVariableReceived("foo", "11");
+        result.expectedVariableReceived("bar", 11);
+        result.message(0).variable("foo").isInstanceOf(String.class);
+        result.message(0).variable("bar").isInstanceOf(Integer.class);
+
+        template.sendBodyAndHeader("direct:bar", null, "foo", "11");
+
+        assertMockEndpointsSatisfied();
+    }
+
     @Test
     public void testConvertToIntegerNotMandatory() throws Exception {
         // mandatory should fail
@@ -224,6 +237,9 @@ public class ConvertVariableTest extends ContextTestSupport {
                         .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");
+                from("direct:bar").setVariable("foo", header("foo")).removeHeader("foo")
+                        .convertVariableTo("foo", "bar", Integer.class).to("mock:result");
+
             }
         };
     }
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedConvertHeaderMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedConvertHeaderMBean.java
index a2f558e7aae..fdc0acf36a9 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedConvertHeaderMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedConvertHeaderMBean.java
@@ -23,6 +23,9 @@ public interface ManagedConvertHeaderMBean extends ManagedProcessorMBean {
     @ManagedAttribute(description = "The header name")
     String getName();
 
+    @ManagedAttribute(description = "If the result should be stored in another header")
+    String getToName();
+
     @ManagedAttribute(description = "The java type to convert to")
     String getType();
 
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
index eb515328221..3983f75d88c 100644
--- 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
@@ -23,6 +23,9 @@ public interface ManagedConvertVariableMBean extends ManagedProcessorMBean {
     @ManagedAttribute(description = "The variable name")
     String getName();
 
+    @ManagedAttribute(description = "If the result should be stored in another variable")
+    String getToName();
+
     @ManagedAttribute(description = "The java type to convert to")
     String getType();
 
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedConvertHeader.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedConvertHeader.java
index 03797f8fd3a..82b1d500eb8 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedConvertHeader.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedConvertHeader.java
@@ -36,6 +36,11 @@ public class ManagedConvertHeader extends ManagedProcessor implements ManagedCon
         return processor.getName();
     }
 
+    @Override
+    public String getToName() {
+        return processor.getToName();
+    }
+
     @Override
     public String getType() {
         return processor.getType().getCanonicalName();
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
index ae2929500a6..b8cc1c00530 100644
--- 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
@@ -36,6 +36,11 @@ public class ManagedConvertVariable extends ManagedProcessor implements ManagedC
         return processor.getName();
     }
 
+    @Override
+    public String getToName() {
+        return processor.getToName();
+    }
+
     @Override
     public String getType() {
         return processor.getType().getCanonicalName();
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/processor/ConvertHeaderProcessor.java b/core/camel-support/src/main/java/org/apache/camel/support/processor/ConvertHeaderProcessor.java
index 2b7c25a6a5d..705ac589fbd 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/processor/ConvertHeaderProcessor.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/processor/ConvertHeaderProcessor.java
@@ -40,15 +40,20 @@ public class ConvertHeaderProcessor extends ServiceSupport implements AsyncProce
     private String routeId;
     private final String name;
     private final Expression headerName;
+    private final String toName;
+    private final Expression toHeaderName;
     private final Class<?> type;
     private final String charset;
     private final boolean mandatory;
 
-    public ConvertHeaderProcessor(String name, Expression headerName, Class<?> type, String charset, boolean mandatory) {
+    public ConvertHeaderProcessor(String name, Expression headerName, String toName, Expression toHeaderName,
+                                  Class<?> type, String charset, boolean mandatory) {
         ObjectHelper.notNull(headerName, "headerName");
         ObjectHelper.notNull(type, "type", this);
         this.name = name;
         this.headerName = headerName;
+        this.toName = toName;
+        this.toHeaderName = toHeaderName;
         this.type = type;
         this.charset = IOHelper.normalizeCharset(charset);
         this.mandatory = mandatory;
@@ -85,6 +90,7 @@ public class ConvertHeaderProcessor extends ServiceSupport implements AsyncProce
 
         // what is the header name
         String name = headerName.evaluate(exchange, String.class);
+        String targetName = toHeaderName != null ? toHeaderName.evaluate(exchange, String.class) : name;
 
         if (old.getHeader(name) == null) {
             // only convert if there is a header
@@ -114,7 +120,7 @@ public class ConvertHeaderProcessor extends ServiceSupport implements AsyncProce
         } else {
             value = exchange.getContext().getTypeConverter().convertTo(type, exchange, value);
         }
-        old.setHeader(name, value);
+        old.setHeader(targetName, value);
 
         // remove or restore charset when we are done as we should not propagate that,
         // as that can lead to double converting later on
@@ -149,6 +155,10 @@ public class ConvertHeaderProcessor extends ServiceSupport implements AsyncProce
         return name;
     }
 
+    public String getToName() {
+        return toName;
+    }
+
     public Class<?> getType() {
         return type;
     }
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
index 203b9dca517..9287902a0d7 100644
--- 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
@@ -47,15 +47,20 @@ public class ConvertVariableProcessor extends ServiceSupport
     private String routeId;
     private final String name;
     private final Expression variableName;
+    private final String toName;
+    private final Expression toVariableName;
     private final Class<?> type;
     private final String charset;
     private final boolean mandatory;
 
-    public ConvertVariableProcessor(String name, Expression variableName, Class<?> type, String charset, boolean mandatory) {
+    public ConvertVariableProcessor(String name, Expression variableName, String toName, Expression toVariableName,
+                                    Class<?> type, String charset, boolean mandatory) {
         ObjectHelper.notNull(variableName, "variableName");
         ObjectHelper.notNull(type, "type", this);
         this.name = name;
         this.variableName = variableName;
+        this.toName = toName;
+        this.toVariableName = toVariableName;
         this.type = type;
         this.charset = IOHelper.normalizeCharset(charset);
         this.mandatory = mandatory;
@@ -101,6 +106,7 @@ public class ConvertVariableProcessor extends ServiceSupport
         // what is the variable name
         String name = variableName.evaluate(exchange, String.class);
         String key = name;
+        String targetName = toVariableName != null ? toVariableName.evaluate(exchange, String.class) : name;
 
         VariableRepository repo = null;
         Object value;
@@ -137,9 +143,9 @@ public class ConvertVariableProcessor extends ServiceSupport
         }
 
         if (repo != null) {
-            repo.setVariable(key, value);
+            repo.setVariable(targetName, value);
         } else {
-            exchange.setVariable(key, value);
+            exchange.setVariable(targetName, value);
         }
 
         // remove or restore charset when we are done as we should not propagate that,
@@ -175,6 +181,10 @@ public class ConvertVariableProcessor extends ServiceSupport
         return name;
     }
 
+    public String getToName() {
+        return toName;
+    }
+
     public Class<?> getType() {
         return type;
     }
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 29bbc496d4f..619765f2b6a 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
@@ -318,6 +318,7 @@ public class ModelParser extends BaseParser {
                 case "charset": def.setCharset(val); break;
                 case "mandatory": def.setMandatory(val); break;
                 case "name": def.setName(val); break;
+                case "toName": def.setToName(val); break;
                 case "type": def.setType(val); break;
                 default: return processorDefinitionAttributeHandler().accept(def, key, val);
             }
@@ -330,6 +331,7 @@ public class ModelParser extends BaseParser {
                 case "charset": def.setCharset(val); break;
                 case "mandatory": def.setMandatory(val); break;
                 case "name": def.setName(val); break;
+                case "toName": def.setToName(val); break;
                 case "type": def.setType(val); break;
                 default: return processorDefinitionAttributeHandler().accept(def, key, val);
             }
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 29576e4c78e..3c09b466f42 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
@@ -1188,6 +1188,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("charset", def.getCharset());
+        doWriteAttribute("toName", def.getToName());
         doWriteAttribute("name", def.getName());
         doWriteAttribute("type", def.getType());
         doWriteAttribute("mandatory", def.getMandatory());
@@ -1200,6 +1201,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("charset", def.getCharset());
+        doWriteAttribute("toName", def.getToName());
         doWriteAttribute("name", def.getName());
         doWriteAttribute("type", def.getType());
         doWriteAttribute("mandatory", def.getMandatory());
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 eb43c07425c..312d4b3fba2 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
@@ -1188,6 +1188,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("charset", def.getCharset());
+        doWriteAttribute("toName", def.getToName());
         doWriteAttribute("name", def.getName());
         doWriteAttribute("type", def.getType());
         doWriteAttribute("mandatory", def.getMandatory());
@@ -1200,6 +1201,7 @@ public class ModelWriter extends BaseWriter {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
         doWriteAttribute("charset", def.getCharset());
+        doWriteAttribute("toName", def.getToName());
         doWriteAttribute("name", def.getName());
         doWriteAttribute("type", def.getType());
         doWriteAttribute("mandatory", def.getMandatory());
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 3984352312e..a14e2849863 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
@@ -2583,6 +2583,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     @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 message header 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 = "toName", type = "string", description = "To use another header to store the result. By default, the result is stored in the same header. This option allows to use another header. The simple language can be used to define a dynamic evaluated header name to be used. Otherwise a constant name will be used.", displayName = "To Name"),
                     @YamlProperty(name = "type", type = "string", required = true, description = "The java type to convert to", displayName = "Type")
             }
     )
@@ -2626,6 +2627,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     target.setName(val);
                     break;
                 }
+                case "toName": {
+                    String val = asText(node);
+                    target.setToName(val);
+                    break;
+                }
                 case "type": {
                     String val = asText(node);
                     target.setType(val);
@@ -2667,6 +2673,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     @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 = "toName", type = "string", description = "To use another variable to store the result. By default, the result is stored in the same variable. This option allows to use another variable. The simple language can be used to define a dynamic evaluated variable name to be used. Otherwise a constant name will be used.", displayName = "To Name"),
                     @YamlProperty(name = "type", type = "string", required = true, description = "The java type to convert to", displayName = "Type")
             }
     )
@@ -2710,6 +2717,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     target.setName(val);
                     break;
                 }
+                case "toName": {
+                    String val = asText(node);
+                    target.setToName(val);
+                    break;
+                }
                 case "type": {
                     String val = asText(node);
                     target.setType(val);
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 420ef377c91..df5d2b48600 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
@@ -847,6 +847,11 @@
             "title" : "Name",
             "description" : "Name of message header 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."
           },
+          "toName" : {
+            "type" : "string",
+            "title" : "To Name",
+            "description" : "To use another header to store the result. By default, the result is stored in the same header. This option allows to use another header. 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",
@@ -891,6 +896,11 @@
             "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."
           },
+          "toName" : {
+            "type" : "string",
+            "title" : "To Name",
+            "description" : "To use another variable to store the result. By default, the result is stored in the same variable. This option allows to use another variable. The simple language can be used to define a dynamic evaluated variable name to be used. Otherwise a constant name will be used."
+          },
           "type" : {
             "type" : "string",
             "title" : "Type",
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ConvertHeaderTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ConvertHeaderTest.groovy
index e920c5c8a46..bf58edd4d8a 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ConvertHeaderTest.groovy
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ConvertHeaderTest.groovy
@@ -57,6 +57,42 @@ class ConvertHeaderTest extends YamlTestSupport {
             MockEndpoint.assertIsSatisfied(context)
     }
 
+    def "convert-header-another-to"() {
+        setup:
+        loadRoutes '''
+                - from:
+                    uri: "direct:start"
+                    steps:    
+                      - convertHeaderTo:
+                          name: foo
+                          toName: bar  
+                          type: "java.lang.String"
+                          charset: "UTF8"
+                      - to: "mock:result"
+            '''
+
+        withMock('mock:result') {
+            expectedHeaderReceived("bar", 'test')
+        }
+        when:
+        context.start()
+
+        withTemplate {
+            to('direct:start').withHeader("foo", 'test'.bytes).send()
+        }
+        then:
+        context.routeDefinitions.size() == 1
+
+        with(context.routeDefinitions[0].outputs[0], ConvertHeaderDefinition) {
+            name == 'foo'
+            toName == 'bar'
+            type == 'java.lang.String'
+            charset == 'UTF8'
+        }
+
+        MockEndpoint.assertIsSatisfied(context)
+    }
+
     def "Error: kebab-case: convert-header-to"() {
         when:
         var route = '''
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
index 6f8436077be..637c0aa1886 100644
--- 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
@@ -61,6 +61,45 @@ class ConvertVariableTest extends YamlTestSupport {
             MockEndpoint.assertIsSatisfied(context)
     }
 
+    def "convert-variable-another-to"() {
+        setup:
+        loadRoutes '''
+                - from:
+                    uri: "direct:start"
+                    steps:
+                      - setVariable:
+                          name: foo
+                          constant: "Hello World"
+                      - convertVariableTo:
+                          name: foo
+                          toName: bar
+                          type: "java.lang.String"
+                          charset: "UTF8"
+                      - to: "mock:result"
+            '''
+
+        withMock('mock:result') {
+            expectedVariableReceived("foo", 'Hello World')
+        }
+        when:
+        context.start()
+
+        withTemplate {
+            to('direct:start').withHeader("foo", 'test'.bytes).send()
+        }
+        then:
+        context.routeDefinitions.size() == 1
+
+        with(context.routeDefinitions[0].outputs[1], ConvertVariableDefinition) {
+            name == 'foo'
+            toName == 'bar'
+            type == 'java.lang.String'
+            charset == 'UTF8'
+        }
+
+        MockEndpoint.assertIsSatisfied(context)
+    }
+
     def "Error: kebab-case: convert-variable-to"() {
         when:
         var route = '''