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

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

commit 7479f2567e22062331024f2b5b84d57334b9940c
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Mon Jan 22 17:02:45 2024 +0100

    CAMEL-19749: EIPs should make it easy to use together with variables.
---
 .../resources/org/apache/camel/model/toD.json      | 12 +--
 .../resources/org/apache/camel/model/wireTap.json  | 12 +--
 .../apache/camel/model/ProcessorDefinition.java    | 34 +++++++++
 .../apache/camel/model/ToDynamicDefinition.java    | 46 +++++++++++
 .../camel/processor/SendDynamicProcessor.java      | 46 +++++++++++
 .../org/apache/camel/reifier/ToDynamicReifier.java |  2 +
 .../camel/processor/ToDynamicVariableTest.java     | 89 ++++++++++++++++++++++
 .../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 +
 10 files changed, 237 insertions(+), 10 deletions(-)

diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/toD.json 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/toD.json
index d914a72f257..2f1ff5355c4 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/toD.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/toD.json
@@ -16,10 +16,12 @@
     "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": true, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
uri of the endpoint to send to. The uri can be dynamic computed using the 
org.apache.camel.language.simple.SimpleLanguage expression." },
-    "pattern": { "index": 4, "kind": "attribute", "displayName": "Pattern", 
"label": "advanced", "required": false, "type": "enum", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the optional ExchangePattern used to invoke this endpoint" },
-    "cacheSize": { "index": 5, "kind": "attribute", "displayName": "Cache 
Size", "label": "advanced", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the maximum size used by the 
org.apache.camel.spi.ProducerCache which is used to cache and reuse producers 
when using this recipient list, when uris are reused. Beware that when using 
dynamic endpoints then it affects how well the cache can [...]
-    "ignoreInvalidEndpoint": { "index": 6, "kind": "attribute", "displayName": 
"Ignore Invalid Endpoint", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "Whether to 
ignore invalid endpoint URIs and skip sending the message." },
-    "allowOptimisedComponents": { "index": 7, "kind": "attribute", 
"displayName": "Allow Optimised Components", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether to allow components to optimise toD if they are 
org.apache.camel.spi.SendDynamicAware ." },
-    "autoStartComponents": { "index": 8, "kind": "attribute", "displayName": 
"Auto Start Components", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "description": "Whether to auto 
startup components when toD is starting up." }
+    "variableSend": { "index": 4, "kind": "attribute", "displayName": 
"Variable Send", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "To use a variable to store the received message body (only 
body, not headers). This is handy for easy access to the received message body 
via variables. Important: When using receive variable then the received body is 
stored only in this variable and not on the  [...]
+    "variableReceive": { "index": 5, "kind": "attribute", "displayName": 
"Variable Receive", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "To use a variable as the source for the message body to send. 
This makes it handy to use variables for user data and to easily control what 
data to use for sending and receiving. Important: When using send variable then 
the message body is taken from this  [...]
+    "pattern": { "index": 6, "kind": "attribute", "displayName": "Pattern", 
"label": "advanced", "required": false, "type": "enum", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the optional ExchangePattern used to invoke this endpoint" },
+    "cacheSize": { "index": 7, "kind": "attribute", "displayName": "Cache 
Size", "label": "advanced", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the maximum size used by the 
org.apache.camel.spi.ProducerCache which is used to cache and reuse producers 
when using this recipient list, when uris are reused. Beware that when using 
dynamic endpoints then it affects how well the cache can [...]
+    "ignoreInvalidEndpoint": { "index": 8, "kind": "attribute", "displayName": 
"Ignore Invalid Endpoint", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "Whether to 
ignore invalid endpoint URIs and skip sending the message." },
+    "allowOptimisedComponents": { "index": 9, "kind": "attribute", 
"displayName": "Allow Optimised Components", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether to allow components to optimise toD if they are 
org.apache.camel.spi.SendDynamicAware ." },
+    "autoStartComponents": { "index": 10, "kind": "attribute", "displayName": 
"Auto Start Components", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "description": "Whether to auto 
startup components when toD is starting up." }
   }
 }
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/wireTap.json
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/wireTap.json
index 46d3a6d7432..3681587d368 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/wireTap.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/wireTap.json
@@ -20,10 +20,12 @@
     "onPrepare": { "index": 5, "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." },
     "executorService": { "index": 6, "kind": "attribute", "displayName": 
"Executor Service", "label": "advanced", "required": false, "type": "object", 
"javaType": "java.util.concurrent.ExecutorService", "deprecated": false, 
"autowired": false, "secret": false, "description": "Uses a custom thread pool" 
},
     "uri": { "index": 7, "kind": "attribute", "displayName": "Uri", 
"required": true, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
uri of the endpoint to send to. The uri can be dynamic computed using the 
org.apache.camel.language.simple.SimpleLanguage expression." },
-    "pattern": { "index": 8, "kind": "attribute", "displayName": "Pattern", 
"label": "advanced", "required": false, "type": "enum", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the optional ExchangePattern used to invoke this endpoint" },
-    "cacheSize": { "index": 9, "kind": "attribute", "displayName": "Cache 
Size", "label": "advanced", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the maximum size used by the 
org.apache.camel.spi.ProducerCache which is used to cache and reuse producers 
when using this recipient list, when uris are reused. Beware that when using 
dynamic endpoints then it affects how well the cache can [...]
-    "ignoreInvalidEndpoint": { "index": 10, "kind": "attribute", 
"displayName": "Ignore Invalid Endpoint", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to ignore invalid endpoint URIs and skip sending the message." },
-    "allowOptimisedComponents": { "index": 11, "kind": "attribute", 
"displayName": "Allow Optimised Components", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether to allow components to optimise toD if they are 
org.apache.camel.spi.SendDynamicAware ." },
-    "autoStartComponents": { "index": 12, "kind": "attribute", "displayName": 
"Auto Start Components", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "description": "Whether to auto 
startup components when toD is starting up." }
+    "variableSend": { "index": 8, "kind": "attribute", "displayName": 
"Variable Send", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "To use a variable to store the received message body (only 
body, not headers). This is handy for easy access to the received message body 
via variables. Important: When using receive variable then the received body is 
stored only in this variable and not on the  [...]
+    "variableReceive": { "index": 9, "kind": "attribute", "displayName": 
"Variable Receive", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "To use a variable as the source for the message body to send. 
This makes it handy to use variables for user data and to easily control what 
data to use for sending and receiving. Important: When using send variable then 
the message body is taken from this  [...]
+    "pattern": { "index": 10, "kind": "attribute", "displayName": "Pattern", 
"label": "advanced", "required": false, "type": "enum", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the optional ExchangePattern used to invoke this endpoint" },
+    "cacheSize": { "index": 11, "kind": "attribute", "displayName": "Cache 
Size", "label": "advanced", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the maximum size used by the 
org.apache.camel.spi.ProducerCache which is used to cache and reuse producers 
when using this recipient list, when uris are reused. Beware that when using 
dynamic endpoints then it affects how well the cache ca [...]
+    "ignoreInvalidEndpoint": { "index": 12, "kind": "attribute", 
"displayName": "Ignore Invalid Endpoint", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to ignore invalid endpoint URIs and skip sending the message." },
+    "allowOptimisedComponents": { "index": 13, "kind": "attribute", 
"displayName": "Allow Optimised Components", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether to allow components to optimise toD if they are 
org.apache.camel.spi.SendDynamicAware ." },
+    "autoStartComponents": { "index": 14, "kind": "attribute", "displayName": 
"Auto Start Components", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "description": "Whether to auto 
startup components when toD is starting up." }
   }
 }
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 5d6e933a95b..63a1cd5e5b8 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
@@ -295,6 +295,22 @@ public abstract class ProcessorDefinition<Type extends 
ProcessorDefinition<Type>
         return asType();
     }
 
+    /**
+     * Sends the exchange to the given dynamic endpoint
+     *
+     * @param  uri             the dynamic endpoint to send to (resolved using 
simple language by default)
+     * @param  variableSend    to use a variable as the source for the message 
body to send.
+     * @param  variableReceive to use a variable to store the received message 
body (only body, not headers).
+     * @return                 the builder
+     */
+    public Type toD(@AsEndpointUri String uri, String variableSend, String 
variableReceive) {
+        ToDynamicDefinition answer = new ToDynamicDefinition(uri);
+        answer.setVariableSend(variableSend);
+        answer.setVariableReceive(variableReceive);
+        addOutput(answer);
+        return asType();
+    }
+
     /**
      * Sends the exchange to the given dynamic endpoint
      *
@@ -308,6 +324,24 @@ public abstract class ProcessorDefinition<Type extends 
ProcessorDefinition<Type>
         return asType();
     }
 
+    /**
+     * Sends the exchange to the given dynamic endpoint
+     *
+     * @param  endpointProducerBuilder the dynamic endpoint to send to 
(resolved using simple language by default)
+     * @param  variableSend            to use a variable as the source for the 
message body to send.
+     * @param  variableReceive         to use a variable to store the received 
message body (only body, not headers).
+     * @return                         the builder
+     */
+    public Type toD(
+            @AsEndpointUri EndpointProducerBuilder endpointProducerBuilder, 
String variableSend, String variableReceive) {
+        ToDynamicDefinition answer = new ToDynamicDefinition();
+        answer.setEndpointProducerBuilder(endpointProducerBuilder);
+        answer.setVariableSend(variableSend);
+        answer.setVariableReceive(variableReceive);
+        addOutput(answer);
+        return asType();
+    }
+
     /**
      * Sends the exchange to the given dynamic endpoint
      *
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/ToDynamicDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/ToDynamicDefinition.java
index c7fb6363198..3daac2cbf52 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/ToDynamicDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/ToDynamicDefinition.java
@@ -23,6 +23,7 @@ import jakarta.xml.bind.annotation.XmlRootElement;
 import jakarta.xml.bind.annotation.XmlTransient;
 
 import org.apache.camel.ExchangePattern;
+import org.apache.camel.Message;
 import org.apache.camel.builder.EndpointProducerBuilder;
 import org.apache.camel.spi.AsEndpointUri;
 import org.apache.camel.spi.Metadata;
@@ -42,6 +43,10 @@ public class ToDynamicDefinition extends 
NoOutputDefinition<ToDynamicDefinition>
     @Metadata(required = true)
     private String uri;
     @XmlAttribute
+    private String variableSend;
+    @XmlAttribute
+    private String variableReceive;
+    @XmlAttribute
     @Metadata(label = "advanced", javaType = 
"org.apache.camel.ExchangePattern", enums = "InOnly,InOut")
     private String pattern;
     @XmlAttribute
@@ -101,6 +106,31 @@ public class ToDynamicDefinition extends 
NoOutputDefinition<ToDynamicDefinition>
         return this;
     }
 
+    /**
+     * To use a variable as the source for the message body to send. This 
makes it handy to use variables for user data
+     * and to easily control what data to use for sending and receiving.
+     *
+     * Important: When using send variable then the message body is taken from 
this variable instead of the current
+     * {@link Message}, however the headers from the {@link Message} will 
still be used as well. In other words, the
+     * variable is used instead of the message body, but everything else is as 
usual.
+     */
+    public ToDynamicDefinition variableReceive(String variableReceive) {
+        setVariableReceive(variableReceive);
+        return this;
+    }
+
+    /**
+     * To use a variable to store the received message body (only body, not 
headers). This is handy for easy access to
+     * the received message body via variables.
+     *
+     * Important: When using receive variable then the received body is stored 
only in this variable and <b>not</b> on
+     * the current {@link org.apache.camel.Message}.
+     */
+    public ToDynamicDefinition variableSend(String variableSend) {
+        setVariableSend(variableSend);
+        return this;
+    }
+
     /**
      * Sets the optional {@link ExchangePattern} used to invoke this endpoint
      */
@@ -230,6 +260,22 @@ public class ToDynamicDefinition extends 
NoOutputDefinition<ToDynamicDefinition>
         this.endpointProducerBuilder = endpointProducerBuilder;
     }
 
+    public String getVariableSend() {
+        return variableSend;
+    }
+
+    public void setVariableSend(String variableSend) {
+        this.variableSend = variableSend;
+    }
+
+    public String getVariableReceive() {
+        return variableReceive;
+    }
+
+    public void setVariableReceive(String variableReceive) {
+        this.variableReceive = variableReceive;
+    }
+
     public String getPattern() {
         return pattern;
     }
diff --git 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/SendDynamicProcessor.java
 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/SendDynamicProcessor.java
index fc842482972..13620cc6ce6 100644
--- 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/SendDynamicProcessor.java
+++ 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/SendDynamicProcessor.java
@@ -58,6 +58,8 @@ public class SendDynamicProcessor extends 
AsyncProcessorSupport implements IdAwa
     protected CamelContext camelContext;
     protected final String uri;
     protected final Expression expression;
+    protected String variableSend;
+    protected String variableReceive;
     protected ExchangePattern pattern;
     protected ProducerCache producerCache;
     protected String id;
@@ -99,6 +101,8 @@ public class SendDynamicProcessor extends 
AsyncProcessorSupport implements IdAwa
 
     @Override
     public boolean process(Exchange exchange, final AsyncCallback callback) {
+        // TODO: variables
+
         if (!isStarted()) {
             exchange.setException(new IllegalStateException("SendProcessor has 
not been started: " + this));
             callback.done(true);
@@ -172,6 +176,20 @@ public class SendDynamicProcessor extends 
AsyncProcessorSupport implements IdAwa
             return true;
         }
 
+        // if we should store the received message body in a variable,
+        // then we need to preserve the original message body
+        Object body = null;
+        if (variableReceive != null) {
+            try {
+                body = exchange.getMessage().getBody();
+            } catch (Exception throwable) {
+                exchange.setException(throwable);
+                callback.done(true);
+                return true;
+            }
+        }
+        final Object originalBody = body;
+
         // send the exchange to the destination using the producer cache
         final Processor preProcessor = preAwareProcessor;
         final Processor postProcessor = postAwareProcessor;
@@ -184,6 +202,12 @@ public class SendDynamicProcessor extends 
AsyncProcessorSupport implements IdAwa
                 if (preProcessor != null) {
                     preProcessor.process(target);
                 }
+                // replace message body with variable
+                if (variableSend != null) {
+                    // it may be a global variable
+                    Object value = ExchangeHelper.getVariable(exchange, 
variableSend);
+                    exchange.getMessage().setBody(value);
+                }
             } catch (Exception t) {
                 e.setException(t);
                 // restore previous MEP
@@ -208,6 +232,12 @@ public class SendDynamicProcessor extends 
AsyncProcessorSupport implements IdAwa
                     if (stopEndpoint) {
                         ServiceHelper.stopAndShutdownService(endpoint);
                     }
+                    // result should be stored in variable instead of message 
body
+                    if (variableReceive != null) {
+                        Object value = exchange.getMessage().getBody();
+                        ExchangeHelper.setVariable(exchange, variableReceive, 
value);
+                        exchange.getMessage().setBody(originalBody);
+                    }
                     // signal we are done
                     c.done(doneSync);
                 }
@@ -410,6 +440,22 @@ public class SendDynamicProcessor extends 
AsyncProcessorSupport implements IdAwa
         this.pattern = pattern;
     }
 
+    public String getVariableSend() {
+        return variableSend;
+    }
+
+    public void setVariableSend(String variableSend) {
+        this.variableSend = variableSend;
+    }
+
+    public String getVariableReceive() {
+        return variableReceive;
+    }
+
+    public void setVariableReceive(String variableReceive) {
+        this.variableReceive = variableReceive;
+    }
+
     public boolean isIgnoreInvalidEndpoint() {
         return ignoreInvalidEndpoint;
     }
diff --git 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ToDynamicReifier.java
 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ToDynamicReifier.java
index f9fb814c5d8..cfa004429fa 100644
--- 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ToDynamicReifier.java
+++ 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ToDynamicReifier.java
@@ -56,6 +56,8 @@ public class ToDynamicReifier<T extends ToDynamicDefinition> 
extends ProcessorRe
         SendDynamicProcessor processor = new SendDynamicProcessor(uri, exp);
         processor.setCamelContext(camelContext);
         processor.setPattern(parse(ExchangePattern.class, 
definition.getPattern()));
+        processor.setVariableSend(definition.getVariableSend());
+        processor.setVariableReceive(definition.getVariableReceive());
         Integer num = parseInt(definition.getCacheSize());
         if (num != null) {
             processor.setCacheSize(num);
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/ToDynamicVariableTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/ToDynamicVariableTest.java
new file mode 100644
index 00000000000..06f87a05cbb
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/ToDynamicVariableTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.Test;
+
+public class ToDynamicVariableTest extends ContextTestSupport {
+
+    @Test
+    public void testSend() throws Exception {
+        getMockEndpoint("mock:before").expectedBodiesReceived("World");
+        getMockEndpoint("mock:before").expectedVariableReceived("hello", 
"Camel");
+        getMockEndpoint("mock:result").expectedBodiesReceived("Bye Camel");
+        getMockEndpoint("mock:result").expectedVariableReceived("hello", 
"Camel");
+
+        template.sendBodyAndHeader("direct:send", "World", "where", "foo");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testReceive() throws Exception {
+        getMockEndpoint("mock:after").expectedBodiesReceived("World");
+        getMockEndpoint("mock:after").expectedVariableReceived("bye", "Bye 
World");
+        getMockEndpoint("mock:result").expectedBodiesReceived("Bye World");
+        getMockEndpoint("mock:result").expectedVariableReceived("bye", "Bye 
World");
+
+        template.sendBodyAndHeader("direct:receive", "World", "where", "foo");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testSendAndReceive() throws Exception {
+        getMockEndpoint("mock:before").expectedBodiesReceived("World");
+        getMockEndpoint("mock:before").expectedVariableReceived("hello", 
"Camel");
+        getMockEndpoint("mock:result").expectedBodiesReceived("World");
+        getMockEndpoint("mock:result").expectedVariableReceived("bye", "Bye 
Camel");
+
+        template.sendBodyAndHeader("direct:sendAndReceive", "World", "where", 
"foo");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:send")
+                        .setVariable("hello", simple("Camel"))
+                        .to("mock:before")
+                        .toD("direct:${header.where}", "hello", null)
+                        .to("mock:result");
+
+                from("direct:receive")
+                        .toD("direct:${header.where}", null, "bye")
+                        .to("mock:after")
+                        .setBody(simple("${variable:bye}"))
+                        .to("mock:result");
+
+                from("direct:sendAndReceive")
+                        .setVariable("hello", simple("Camel"))
+                        .to("mock:before")
+                        .toD("direct:${header.where}", "hello", "bye")
+                        .to("mock:result");
+
+                from("direct:foo")
+                        .transform().simple("Bye ${body}");
+            }
+        };
+    }
+}
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 a2b661193ca..ccc33dcc6d1 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
@@ -1555,6 +1555,8 @@ public class ModelParser extends BaseParser {
                 case "ignoreInvalidEndpoint": 
def.setIgnoreInvalidEndpoint(val); break;
                 case "pattern": def.setPattern(val); break;
                 case "uri": def.setUri(val); break;
+                case "variableReceive": def.setVariableReceive(val); break;
+                case "variableSend": def.setVariableSend(val); break;
                 default: return 
processorDefinitionAttributeHandler().accept(def, key, val);
             }
             return true;
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 7e16687fce7..b012cca083c 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
@@ -2437,6 +2437,8 @@ public class ModelWriter extends BaseWriter {
             ToDynamicDefinition def)
             throws IOException {
         doWriteProcessorDefinitionAttributes(def);
+        doWriteAttribute("variableReceive", def.getVariableReceive());
+        doWriteAttribute("variableSend", def.getVariableSend());
         doWriteAttribute("cacheSize", def.getCacheSize());
         doWriteAttribute("ignoreInvalidEndpoint", 
def.getIgnoreInvalidEndpoint());
         doWriteAttribute("autoStartComponents", def.getAutoStartComponents());
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 da3fa16773b..cecac392932 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
@@ -2437,6 +2437,8 @@ public class ModelWriter extends BaseWriter {
             ToDynamicDefinition def)
             throws IOException {
         doWriteProcessorDefinitionAttributes(def);
+        doWriteAttribute("variableReceive", def.getVariableReceive());
+        doWriteAttribute("variableSend", def.getVariableSend());
         doWriteAttribute("cacheSize", def.getCacheSize());
         doWriteAttribute("ignoreInvalidEndpoint", 
def.getIgnoreInvalidEndpoint());
         doWriteAttribute("autoStartComponents", def.getAutoStartComponents());

Reply via email to