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 80784f015c624a3aceb6fc0d637a1b076e96d955 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Fri Jan 19 12:25:50 2024 +0100 CAMEL-19749: EIPs should make it easy to use together with variables. --- .../org/apache/camel/catalog/models/from.json | 3 +- .../spring/processor/SpringFromVariableTest.java | 29 +++++++++++++ .../camel/spring/processor/FromVariableTest.xml | 42 +++++++++++++++++++ .../resources/org/apache/camel/model/from.json | 3 +- .../org/apache/camel/builder/RouteBuilder.java | 46 ++++++++++++++++++++- .../org/apache/camel/model/FromDefinition.java | 15 +++++++ .../org/apache/camel/model/RouteDefinition.java | 30 ++++++++++++++ .../org/apache/camel/model/RoutesDefinition.java | 34 +++++++++++++++ .../org/apache/camel/reifier/RouteReifier.java | 44 ++++++++++++++++++++ .../apache/camel/processor/FromVariableTest.java | 48 ++++++++++++++++++++++ .../java/org/apache/camel/xml/in/ModelParser.java | 9 ++-- .../java/org/apache/camel/xml/out/ModelWriter.java | 1 + .../org/apache/camel/yaml/out/ModelWriter.java | 1 + .../camel/builder/endpoint/FromVariableTest.java | 48 ++++++++++++++++++++++ 14 files changed, 345 insertions(+), 8 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/from.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/from.json index 6504f349019..b753ab0fa4f 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/from.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/from.json @@ -14,6 +14,7 @@ "properties": { "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" }, "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }, - "uri": { "index": 2, "kind": "attribute", "displayName": "Uri", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the URI of the endpoint to use" } + "uri": { "index": 2, "kind": "attribute", "displayName": "Uri", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the URI of the endpoint to use" }, + "variable": { "index": 3, "kind": "attribute", "displayName": "Variable", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a variable to store a copy of the incoming message body (only body, not headers). This is handy for easy access to the incoming message body via variables." } } } diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringFromVariableTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringFromVariableTest.java new file mode 100644 index 00000000000..6d40ec5f7a0 --- /dev/null +++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringFromVariableTest.java @@ -0,0 +1,29 @@ +/* + * 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.spring.processor; + +import org.apache.camel.CamelContext; +import org.apache.camel.processor.FromVariableTest; + +import static org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext; + +public class SpringFromVariableTest extends FromVariableTest { + @Override + protected CamelContext createCamelContext() throws Exception { + return createSpringCamelContext(this, "org/apache/camel/spring/processor/FromVariableTest.xml"); + } +} diff --git a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/FromVariableTest.xml b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/FromVariableTest.xml new file mode 100644 index 00000000000..00e697e7f59 --- /dev/null +++ b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/FromVariableTest.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd + "> + + <!-- START SNIPPET: example --> + <camelContext xmlns="http://camel.apache.org/schema/spring"> + <jmxAgent id="jmx" disabled="true"/> + <route> + <from uri="direct:start" variable="myKey"/> + <transform><simple>Bye ${body}</simple></transform> + <to uri="mock:foo"/> + <setBody> + <simple>${variable:myKey}</simple> + </setBody> + <to uri="mock:result"/> + </route> + </camelContext> + <!-- END SNIPPET: example --> + +</beans> diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/from.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/from.json index 6504f349019..b753ab0fa4f 100644 --- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/from.json +++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/from.json @@ -14,6 +14,7 @@ "properties": { "id": { "index": 0, "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" }, "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }, - "uri": { "index": 2, "kind": "attribute", "displayName": "Uri", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the URI of the endpoint to use" } + "uri": { "index": 2, "kind": "attribute", "displayName": "Uri", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the URI of the endpoint to use" }, + "variable": { "index": 3, "kind": "attribute", "displayName": "Variable", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a variable to store a copy of the incoming message body (only body, not headers). This is handy for easy access to the incoming message body via variables." } } } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/builder/RouteBuilder.java b/core/camel-core-model/src/main/java/org/apache/camel/builder/RouteBuilder.java index 0be85d0471c..6c3d491ae99 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/builder/RouteBuilder.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/builder/RouteBuilder.java @@ -389,6 +389,24 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild return answer; } + /** + * Creates an input to the route, and use a variable to store a copy of the incoming message body (only body, not + * headers). This is handy for easy access to the incoming message body via variables. + * + * @param uri the from uri + * @param variable the name of the variable + * @return the builder + */ + public RouteDefinition fromV(String uri, String variable) { + getRouteCollection().setCamelContext(getContext()); + if (resource != null) { + getRouteCollection().setResource(resource); + } + RouteDefinition answer = getRouteCollection().fromV(uri, variable); + configureRoute(answer); + return answer; + } + /** * Creates a new route from the given endpoint * @@ -405,12 +423,36 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild return answer; } - public RouteDefinition from(EndpointConsumerBuilder endpointDefinition) { + /** + * Creates a new route from the given endpoint + * + * @param endpoint the from endpoint + * @return the builder + */ + public RouteDefinition from(EndpointConsumerBuilder endpoint) { + getRouteCollection().setCamelContext(getContext()); + if (resource != null) { + getRouteCollection().setResource(resource); + } + RouteDefinition answer = getRouteCollection().from(endpoint); + configureRoute(answer); + return answer; + } + + /** + * Creates an input to the route, and use a variable to store a copy of the incoming message body (only body, not + * headers). This is handy for easy access to the incoming message body via variables. + * + * @param endpoint the from endpoint + * @param variable the name of the variable + * @return the builder + */ + public RouteDefinition fromV(EndpointConsumerBuilder endpoint, String variable) { getRouteCollection().setCamelContext(getContext()); if (resource != null) { getRouteCollection().setResource(resource); } - RouteDefinition answer = getRouteCollection().from(endpointDefinition); + RouteDefinition answer = getRouteCollection().fromV(endpoint, variable); configureRoute(answer); return answer; } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/FromDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/FromDefinition.java index bde1beabd29..a0b29da52ee 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/FromDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/FromDefinition.java @@ -45,6 +45,8 @@ public class FromDefinition extends OptionalIdentifiedDefinition<FromDefinition> @XmlAttribute @Metadata(required = true) private String uri; + @XmlAttribute + private String variable; public FromDefinition() { } @@ -119,6 +121,19 @@ public class FromDefinition extends OptionalIdentifiedDefinition<FromDefinition> this.uri = uri; } + public String getVariable() { + return variable; + } + + /** + * To use a variable to store a copy of the incoming message body (only body, not headers). + * + * This is handy for easy access to the incoming message body via variables. + */ + public void setVariable(String variable) { + this.variable = variable; + } + /** * Gets tne endpoint if an {@link Endpoint} instance was set. * <p/> diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java index 1944ca9474e..dc4fc72c2cd 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java @@ -217,6 +217,36 @@ public class RouteDefinition extends OutputDefinition<RouteDefinition> return this; } + /** + * Creates an input to the route, and use a variable to store a copy of the incoming message body (only body, not headers). + * This is handy for easy access to the incoming message body via variables. + * + * @param uri the from uri + * @param variable the name of the variable + * @return the builder + */ + public RouteDefinition fromV(@AsEndpointUri String uri, String variable) { + FromDefinition from = new FromDefinition(uri); + from.setVariable(variable); + setInput(from); + return this; + } + + /** + * Creates an input to the route, and use a variable to store a copy of the incoming message body (only body, not headers). + * This is handy for easy access to the incoming message body via variables. + * + * @param endpoint the from endpoint + * @param variable the name of the variable + * @return the builder + */ + public RouteDefinition fromV(EndpointConsumerBuilder endpoint, String variable) { + FromDefinition from = new FromDefinition(endpoint); + from.setVariable(variable); + setInput(from); + return this; + } + /** * The route configuration id or pattern this route should use for configuration. Multiple id/pattern can be * separated by comma. diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RoutesDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RoutesDefinition.java index 3eca50291bb..d6dcb4832c0 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/RoutesDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RoutesDefinition.java @@ -196,6 +196,20 @@ public class RoutesDefinition extends OptionalIdentifiedDefinition<RoutesDefinit return route(route); } + /** + * Creates an input to the route, and use a variable to store a copy of the incoming message body (only body, not headers). + * This is handy for easy access to the incoming message body via variables. + * + * @param uri the from uri + * @param variable the name of the variable + * @return the builder + */ + public RouteDefinition fromV(@AsEndpointUri String uri, String variable) { + RouteDefinition route = createRoute(); + route.fromV(uri, variable); + return route(route); + } + /** * Creates a new route from the given endpoint * @@ -208,12 +222,32 @@ public class RoutesDefinition extends OptionalIdentifiedDefinition<RoutesDefinit return route(route); } + /** + * Creates a new route from the given endpoint + * + * @param endpoint the from endpoint + * @return the builder + */ public RouteDefinition from(EndpointConsumerBuilder endpoint) { RouteDefinition route = createRoute(); route.from(endpoint); return route(route); } + /** + * Creates an input to the route, and use a variable to store a copy of the incoming message body (only body, not headers). + * This is handy for easy access to the incoming message body via variables. + * + * @param endpoint the from endpoint + * @param variable the name of the variable + * @return the builder + */ + public RouteDefinition fromV(EndpointConsumerBuilder endpoint, String variable) { + RouteDefinition route = createRoute(); + route.fromV(endpoint, variable); + return route(route); + } + /** * Creates a new route using the given route. * <p/> diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RouteReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RouteReifier.java index ae12fef7187..8d1088b5e11 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RouteReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RouteReifier.java @@ -26,6 +26,7 @@ import org.apache.camel.CamelContext; import org.apache.camel.Endpoint; import org.apache.camel.EndpointConsumerResolver; import org.apache.camel.ErrorHandlerFactory; +import org.apache.camel.Exchange; import org.apache.camel.FailedToCreateRouteException; import org.apache.camel.Processor; import org.apache.camel.Route; @@ -41,6 +42,7 @@ import org.apache.camel.model.RouteDefinition; import org.apache.camel.processor.ContractAdvice; import org.apache.camel.processor.RoutePipeline; import org.apache.camel.reifier.rest.RestBindingReifier; +import org.apache.camel.spi.CamelInternalProcessorAdvice; import org.apache.camel.spi.Contract; import org.apache.camel.spi.ErrorHandlerAware; import org.apache.camel.spi.InternalProcessor; @@ -100,12 +102,20 @@ public class RouteReifier extends ProcessorReifier<RouteDefinition> { // create route String id = definition.idOrCreate(camelContext.getCamelContextExtension().getContextPlugin(NodeIdFactory.class)); String desc = definition.getDescriptionText(); + Route route = PluginHelper.getRouteFactory(camelContext).createRoute(camelContext, definition, id, desc, endpoint, definition.getResource()); // configure error handler route.setErrorHandlerFactory(definition.getErrorHandlerFactory()); + // configure variable + String variable = definition.getInput().getVariable(); + if (variable != null) { + // when using variable we need to turn on original message + route.setAllowUseOriginalMessage(true); + } + // configure tracing if (definition.getTrace() != null) { Boolean isTrace = parseBoolean(definition.getTrace()); @@ -318,6 +328,11 @@ public class RouteReifier extends ProcessorReifier<RouteDefinition> { camelContext.setUseDataType(true); } + // wrap with variable + if (variable != null) { + internal.addAdvice(new VariableAdvice(variable)); + } + // and create the route that wraps all of this route.setProcessor(internal); route.getProperties().putAll(routeProperties); @@ -405,4 +420,33 @@ public class RouteReifier extends ProcessorReifier<RouteDefinition> { return routeProperties; } + /** + * Advice for copying the message body into a variable + */ + private static class VariableAdvice implements CamelInternalProcessorAdvice<Object> { + + private final String name; + + public VariableAdvice(String name) { + this.name = name; + } + + @Override + public Object before(Exchange exchange) throws Exception { + Object body = exchange.getMessage().getBody(); + exchange.setVariable(name, body); + return null; + } + + @Override + public void after(Exchange exchange, Object data) throws Exception { + // noop + } + + @Override + public boolean hasState() { + return false; + } + } + } diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/FromVariableTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/FromVariableTest.java new file mode 100644 index 00000000000..3dfc5800ee8 --- /dev/null +++ b/core/camel-core/src/test/java/org/apache/camel/processor/FromVariableTest.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.processor; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.builder.RouteBuilder; +import org.junit.jupiter.api.Test; + +public class FromVariableTest extends ContextTestSupport { + + @Test + public void testOriginalBody() throws Exception { + getMockEndpoint("mock:foo").expectedBodiesReceived("Bye World"); + getMockEndpoint("mock:result").expectedBodiesReceived("World"); + + template.sendBody("direct:start", "World"); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + fromV("direct:start", "myKey") + .transform().simple("Bye ${body}") + .to("mock:foo") + .setBody(simple("${variable:myKey}")) + .to("mock:result"); + } + }; + } +} 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 619765f2b6a..61c0e7c0174 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 @@ -476,11 +476,12 @@ public class ModelParser extends BaseParser { } protected FromDefinition doParseFromDefinition() throws IOException, XmlPullParserException { return doParse(new FromDefinition(), (def, key, val) -> { - if ("uri".equals(key)) { - def.setUri(val); - return true; + switch (key) { + case "uri": def.setUri(val); break; + case "variable": def.setVariable(val); break; + default: return optionalIdentifiedDefinitionAttributeHandler().accept(def, key, val); } - return optionalIdentifiedDefinitionAttributeHandler().accept(def, key, val); + return true; }, optionalIdentifiedDefinitionElementHandler(), noValueHandler()); } protected GlobalOptionDefinition doParseGlobalOptionDefinition() throws IOException, XmlPullParserException { 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 3c09b466f42..023547e5bd8 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 @@ -1365,6 +1365,7 @@ public class ModelWriter extends BaseWriter { throws IOException { startElement(name); doWriteOptionalIdentifiedDefinitionAttributes(def); + doWriteAttribute("variable", def.getVariable()); doWriteAttribute("uri", def.getUri()); endElement(name); } 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 312d4b3fba2..4daf3bd618d 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 @@ -1365,6 +1365,7 @@ public class ModelWriter extends BaseWriter { throws IOException { startElement(name); doWriteOptionalIdentifiedDefinitionAttributes(def); + doWriteAttribute("variable", def.getVariable()); doWriteAttribute("uri", def.getUri()); endElement(name); } diff --git a/dsl/camel-endpointdsl/src/test/java/org/apache/camel/builder/endpoint/FromVariableTest.java b/dsl/camel-endpointdsl/src/test/java/org/apache/camel/builder/endpoint/FromVariableTest.java new file mode 100644 index 00000000000..d10b4de92f1 --- /dev/null +++ b/dsl/camel-endpointdsl/src/test/java/org/apache/camel/builder/endpoint/FromVariableTest.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.builder.endpoint; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.junit.jupiter.api.Test; + +public class FromVariableTest extends BaseEndpointDslTest { + + @Test + public void testOriginalBody() throws Exception { + getMockEndpoint("mock:foo").expectedBodiesReceived("Bye World"); + getMockEndpoint("mock:result").expectedBodiesReceived("World"); + + template.sendBody("direct:start", "World"); + + MockEndpoint.assertIsSatisfied(context); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new EndpointRouteBuilder() { + public void configure() throws Exception { + fromV(direct("start").advanced().synchronous(false), "myKey") + .transform().simple("Bye ${body}") + .to("mock:foo") + .setBody(simple("${variable:myKey}")) + .to("mock:result"); + } + }; + } + +}