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 347016a0fc6991e626dcf12916cbb175c3af00a0 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Tue Jan 23 12:03:24 2024 +0100 CAMEL-19749: EIPs should make it easy to use together with variables. --- .../org/apache/camel/catalog/models/enrich.json | 20 +- .../apache/camel/catalog/schemas/camel-spring.xsd | 22 ++ .../spring/processor/SpringEnrichVariableTest.java | 29 +++ .../camel/spring/processor/EnrichVariableTest.xml | 72 ++++++ .../resources/org/apache/camel/model/enrich.json | 20 +- .../org/apache/camel/model/EnrichDefinition.java | 44 ++++ .../java/org/apache/camel/processor/Enricher.java | 40 ++++ .../org/apache/camel/processor/PollEnricher.java | 2 +- .../org/apache/camel/reifier/EnrichReifier.java | 2 + .../apache/camel/processor/EnrichVariableTest.java | 89 +++++++ .../api/management/mbean/ManagedEnricherMBean.java | 6 + .../camel/management/mbean/ManagedEnricher.java | 10 + .../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 | 14 +- .../generated/resources/schema/camelYamlDsl.json | 10 + .../camel/dsl/yaml/EnrichVariableTest.groovy | 264 +++++++++++++++++++++ 18 files changed, 630 insertions(+), 20 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/enrich.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/enrich.json index 7326f89b55c..e11f1e6a6be 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/enrich.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/enrich.json @@ -16,14 +16,16 @@ "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }, "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." }, "expression": { "index": 3, "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "sec [...] - "aggregationStrategy": { "index": 4, "kind": "attribute", "displayName": "Aggregation Strategy", "required": false, "type": "object", "javaType": "org.apache.camel.AggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the AggregationStrategy to be used to merge the reply from the external service, into a single outgoing message. By default Camel will use the reply from the external service as outgoing message." }, - "aggregationStrategyMethodName": { "index": 5, "kind": "attribute", "displayName": "Aggregation Strategy Method Name", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option can be used to explicit declare the method name to use, when using POJOs as the AggregationStrategy." }, - "aggregationStrategyMethodAllowNull": { "index": 6, "kind": "attribute", "displayName": "Aggregation Strategy Method Allow Null", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "If this option is false then the aggregate method is not used if there was no data to enrich. If this option is true then null values is used as the oldExchange (when no data to enrich), when us [...] - "aggregateOnException": { "index": 7, "kind": "attribute", "displayName": "Aggregate On Exception", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If this option is false then the aggregate method is not used if there was an exception thrown while trying to retrieve the data to enrich from the resource. Setting this option to true allows end us [...] - "shareUnitOfWork": { "index": 8, "kind": "attribute", "displayName": "Share Unit Of Work", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Shares the org.apache.camel.spi.UnitOfWork with the parent and the resource exchange. Enrich will by default not share unit of work between the parent exchange and the resource exchange. This means the resour [...] - "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 producer when uris are reused. Beware that when using dynamic endpoints then it affects how well the cache can be utilized. If each dynamic end [...] - "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": "Ignore the invalidate endpoint exception when try to create a producer with that endpoint" }, - "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 enricher 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 enricher 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 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 o [...] + "aggregationStrategy": { "index": 6, "kind": "attribute", "displayName": "Aggregation Strategy", "required": false, "type": "object", "javaType": "org.apache.camel.AggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the AggregationStrategy to be used to merge the reply from the external service, into a single outgoing message. By default Camel will use the reply from the external service as outgoing message." }, + "aggregationStrategyMethodName": { "index": 7, "kind": "attribute", "displayName": "Aggregation Strategy Method Name", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option can be used to explicit declare the method name to use, when using POJOs as the AggregationStrategy." }, + "aggregationStrategyMethodAllowNull": { "index": 8, "kind": "attribute", "displayName": "Aggregation Strategy Method Allow Null", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "If this option is false then the aggregate method is not used if there was no data to enrich. If this option is true then null values is used as the oldExchange (when no data to enrich), when us [...] + "aggregateOnException": { "index": 9, "kind": "attribute", "displayName": "Aggregate On Exception", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If this option is false then the aggregate method is not used if there was an exception thrown while trying to retrieve the data to enrich from the resource. Setting this option to true allows end us [...] + "shareUnitOfWork": { "index": 10, "kind": "attribute", "displayName": "Share Unit Of Work", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Shares the org.apache.camel.spi.UnitOfWork with the parent and the resource exchange. Enrich will by default not share unit of work between the parent exchange and the resource exchange. This means the resou [...] + "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 producer when uris are reused. Beware that when using dynamic endpoints then it affects how well the cache can be utilized. If each dynamic en [...] + "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": "Ignore the invalidate endpoint exception when try to create a producer with that endpoint" }, + "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 enricher 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 enricher is starting up." } } } 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 be712c5bf41..0dc0cfd581e 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 @@ -5300,6 +5300,28 @@ reduce memory usage to avoid storing too many non frequent used producers. <xs:element ref="tns:xpath"/> <xs:element ref="tns:xquery"/> </xs:choice> + <xs:attribute name="variableSend" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +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 current org.apache.camel.Message . +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="variableReceive" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +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 current org.apache.camel.Message . +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> <xs:attribute name="aggregationStrategy" type="xs:string"> <xs:annotation> <xs:documentation xml:lang="en"> diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringEnrichVariableTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringEnrichVariableTest.java new file mode 100644 index 00000000000..3e4c8769f42 --- /dev/null +++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringEnrichVariableTest.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.EnrichVariableTest; + +import static org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext; + +public class SpringEnrichVariableTest extends EnrichVariableTest { + @Override + protected CamelContext createCamelContext() throws Exception { + return createSpringCamelContext(this, "org/apache/camel/spring/processor/EnrichVariableTest.xml"); + } +} diff --git a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/EnrichVariableTest.xml b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/EnrichVariableTest.xml new file mode 100644 index 00000000000..a6b15b135e6 --- /dev/null +++ b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/EnrichVariableTest.xml @@ -0,0 +1,72 @@ +<?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:send"/> + <setVariable name="hello"> + <simple>Camel</simple> + </setVariable> + <to uri="mock:before"/> + <enrich variableSend="hello"> + <constant>direct:foo</constant> + </enrich> + <to uri="mock:result"/> + </route> + <route> + <from uri="direct:receive"/> + <enrich variableReceive="bye"> + <constant>direct:foo</constant> + </enrich> + <to uri="mock:after"/> + <setBody> + <simple>${variable:bye}</simple> + </setBody> + <to uri="mock:result"/> + </route> + <route> + <from uri="direct:sendAndReceive"/> + <setVariable name="hello"> + <simple>Camel</simple> + </setVariable> + <to uri="mock:before"/> + <enrich variableSend="hello" variableReceive="bye"> + <constant>direct:foo</constant> + </enrich> + <to uri="mock:result"/> + </route> + <route> + <from uri="direct:foo"/> + <transform> + <simple>Bye ${body}</simple> + </transform> + </route> + </camelContext> + <!-- END SNIPPET: example --> + +</beans> diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/enrich.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/enrich.json index 7326f89b55c..e11f1e6a6be 100644 --- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/enrich.json +++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/enrich.json @@ -16,14 +16,16 @@ "description": { "index": 1, "kind": "element", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }, "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime." }, "expression": { "index": 3, "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "java", "joor", "jq", "js", "jsonpath", "language", "method", "mvel", "ognl", "python", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "sec [...] - "aggregationStrategy": { "index": 4, "kind": "attribute", "displayName": "Aggregation Strategy", "required": false, "type": "object", "javaType": "org.apache.camel.AggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the AggregationStrategy to be used to merge the reply from the external service, into a single outgoing message. By default Camel will use the reply from the external service as outgoing message." }, - "aggregationStrategyMethodName": { "index": 5, "kind": "attribute", "displayName": "Aggregation Strategy Method Name", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option can be used to explicit declare the method name to use, when using POJOs as the AggregationStrategy." }, - "aggregationStrategyMethodAllowNull": { "index": 6, "kind": "attribute", "displayName": "Aggregation Strategy Method Allow Null", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "If this option is false then the aggregate method is not used if there was no data to enrich. If this option is true then null values is used as the oldExchange (when no data to enrich), when us [...] - "aggregateOnException": { "index": 7, "kind": "attribute", "displayName": "Aggregate On Exception", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If this option is false then the aggregate method is not used if there was an exception thrown while trying to retrieve the data to enrich from the resource. Setting this option to true allows end us [...] - "shareUnitOfWork": { "index": 8, "kind": "attribute", "displayName": "Share Unit Of Work", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Shares the org.apache.camel.spi.UnitOfWork with the parent and the resource exchange. Enrich will by default not share unit of work between the parent exchange and the resource exchange. This means the resour [...] - "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 producer when uris are reused. Beware that when using dynamic endpoints then it affects how well the cache can be utilized. If each dynamic end [...] - "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": "Ignore the invalidate endpoint exception when try to create a producer with that endpoint" }, - "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 enricher 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 enricher 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 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 o [...] + "aggregationStrategy": { "index": 6, "kind": "attribute", "displayName": "Aggregation Strategy", "required": false, "type": "object", "javaType": "org.apache.camel.AggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the AggregationStrategy to be used to merge the reply from the external service, into a single outgoing message. By default Camel will use the reply from the external service as outgoing message." }, + "aggregationStrategyMethodName": { "index": 7, "kind": "attribute", "displayName": "Aggregation Strategy Method Name", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "This option can be used to explicit declare the method name to use, when using POJOs as the AggregationStrategy." }, + "aggregationStrategyMethodAllowNull": { "index": 8, "kind": "attribute", "displayName": "Aggregation Strategy Method Allow Null", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "If this option is false then the aggregate method is not used if there was no data to enrich. If this option is true then null values is used as the oldExchange (when no data to enrich), when us [...] + "aggregateOnException": { "index": 9, "kind": "attribute", "displayName": "Aggregate On Exception", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If this option is false then the aggregate method is not used if there was an exception thrown while trying to retrieve the data to enrich from the resource. Setting this option to true allows end us [...] + "shareUnitOfWork": { "index": 10, "kind": "attribute", "displayName": "Share Unit Of Work", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Shares the org.apache.camel.spi.UnitOfWork with the parent and the resource exchange. Enrich will by default not share unit of work between the parent exchange and the resource exchange. This means the resou [...] + "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 producer when uris are reused. Beware that when using dynamic endpoints then it affects how well the cache can be utilized. If each dynamic en [...] + "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": "Ignore the invalidate endpoint exception when try to create a producer with that endpoint" }, + "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 enricher 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 enricher is starting up." } } } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/EnrichDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/EnrichDefinition.java index 8f8baa14f2a..7b94d4e0bf2 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/EnrichDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/EnrichDefinition.java @@ -39,6 +39,10 @@ public class EnrichDefinition extends ExpressionNode implements AggregationStrat @XmlTransient private AggregationStrategy aggregationStrategyBean; + @XmlAttribute + private String variableSend; + @XmlAttribute + private String variableReceive; @XmlAttribute @Metadata(javaType = "org.apache.camel.AggregationStrategy") private String aggregationStrategy; @@ -93,6 +97,30 @@ public class EnrichDefinition extends ExpressionNode implements AggregationStrat // Fluent API // ------------------------------------------------------------------------- + /** + * 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 EnrichDefinition 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 EnrichDefinition variableSend(String variableSend) { + setVariableSend(variableSend); + return this; + } + /** * Sets the AggregationStrategy to be used to merge the reply from the external service, into a single outgoing * message. By default Camel will use the reply from the external service as outgoing message. @@ -296,6 +324,22 @@ public class EnrichDefinition extends ExpressionNode implements AggregationStrat this.aggregateOnException = aggregateOnException; } + 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 getShareUnitOfWork() { return shareUnitOfWork; } diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/Enricher.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/Enricher.java index d0ac88b9624..bb8350971ec 100644 --- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/Enricher.java +++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/Enricher.java @@ -54,6 +54,8 @@ public class Enricher extends AsyncProcessorSupport implements IdAware, RouteIdA private String routeId; private final Expression expression; private final String uri; + private String variableSend; + private String variableReceive; private AggregationStrategy aggregationStrategy; private boolean aggregateOnException; private boolean shareUnitOfWork; @@ -107,6 +109,22 @@ public class Enricher extends AsyncProcessorSupport implements IdAware, RouteIdA return sendDynamicProcessor.getEndpointUtilizationStatistics(); } + 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 void setAggregationStrategy(AggregationStrategy aggregationStrategy) { this.aggregationStrategy = aggregationStrategy; } @@ -166,6 +184,21 @@ public class Enricher extends AsyncProcessorSupport implements IdAware, RouteIdA @Override public boolean process(final Exchange exchange, final AsyncCallback callback) { final Exchange resourceExchange = createResourceExchange(exchange, ExchangePattern.InOut); + + // 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; + return sendDynamicProcessor.process(resourceExchange, new AsyncCallback() { @Override public void done(boolean doneSync) { @@ -181,6 +214,12 @@ public class Enricher extends AsyncProcessorSupport implements IdAware, RouteIdA Exchange aggregatedExchange = aggregationStrategy.aggregate(exchange, resourceExchange); if (aggregatedExchange != null) { + if (variableReceive != null) { + // result should be stored in variable instead of message body + Object value = aggregatedExchange.getMessage().getBody(); + ExchangeHelper.setVariable(exchange, variableReceive, value); + aggregatedExchange.getMessage().setBody(originalBody); + } // copy aggregation result onto original exchange (preserving pattern) copyResultsWithoutCorrelationId(exchange, aggregatedExchange); // handover any synchronization (if unit of work is not shared) @@ -248,6 +287,7 @@ public class Enricher extends AsyncProcessorSupport implements IdAware, RouteIdA this.sendDynamicProcessor.setIgnoreInvalidEndpoint(ignoreInvalidEndpoint); this.sendDynamicProcessor.setAllowOptimisedComponents(allowOptimisedComponents); this.sendDynamicProcessor.setAutoStartupComponents(autoStartupComponents); + this.sendDynamicProcessor.setVariableSend(variableSend); // create a per processor exchange factory this.processorExchangeFactory = getCamelContext().getCamelContextExtension() diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/PollEnricher.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/PollEnricher.java index ca029a6525a..21759c73f24 100644 --- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/PollEnricher.java +++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/PollEnricher.java @@ -67,8 +67,8 @@ public class PollEnricher extends AsyncProcessorSupport implements IdAware, Rout protected volatile String scheme; private String id; private String routeId; - private AggregationStrategy aggregationStrategy; private String variableReceive; + private AggregationStrategy aggregationStrategy; private final Expression expression; private final String uri; private long timeout; diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/EnrichReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/EnrichReifier.java index 2302628c569..08bcf089987 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/EnrichReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/EnrichReifier.java @@ -56,6 +56,8 @@ public class EnrichReifier extends ExpressionReifier<EnrichDefinition> { } Enricher enricher = new Enricher(exp, uri); + enricher.setVariableSend(parseString(definition.getVariableSend())); + enricher.setVariableReceive(parseString(definition.getVariableReceive())); enricher.setShareUnitOfWork(parseBoolean(definition.getShareUnitOfWork(), false)); enricher.setIgnoreInvalidEndpoint(parseBoolean(definition.getIgnoreInvalidEndpoint(), false)); enricher.setAggregateOnException(parseBoolean(definition.getAggregateOnException(), false)); diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/EnrichVariableTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/EnrichVariableTest.java new file mode 100644 index 00000000000..a0e1e53f7a3 --- /dev/null +++ b/core/camel-core/src/test/java/org/apache/camel/processor/EnrichVariableTest.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 EnrichVariableTest 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.sendBody("direct:send", "World"); + + 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.sendBody("direct:receive", "World"); + + 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.sendBody("direct:sendAndReceive", "World"); + + 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") + .enrich().constant("direct:foo").variableSend("hello") + .to("mock:result"); + + from("direct:receive") + .enrich().constant("direct:foo").variableReceive("bye") + .to("mock:after") + .setBody(simple("${variable:bye}")) + .to("mock:result"); + + from("direct:sendAndReceive") + .setVariable("hello", simple("Camel")) + .to("mock:before") + .enrich().constant("direct:foo").variableSend("hello").variableReceive("bye") + .to("mock:result"); + + from("direct:foo") + .transform().simple("Bye ${body}"); + } + }; + } +} diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedEnricherMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedEnricherMBean.java index 773f99c25f6..e8183ab20ea 100644 --- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedEnricherMBean.java +++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedEnricherMBean.java @@ -30,6 +30,12 @@ public interface ManagedEnricherMBean extends ManagedProcessorMBean, ManagedExte mask = true) String getExpression(); + @ManagedAttribute(description = "Variable as the source for the message body to send") + String getVariableSend(); + + @ManagedAttribute(description = "Variable to store the received message body (only body, not headers)") + String getVariableReceive(); + @ManagedAttribute(description = "Sets the maximum size used by the ProducerCache which is used to cache and reuse producers") Integer getCacheSize(); diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedEnricher.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedEnricher.java index 76f9a07a53a..cd7cec862c8 100644 --- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedEnricher.java +++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedEnricher.java @@ -89,6 +89,16 @@ public class ManagedEnricher extends ManagedProcessor implements ManagedEnricher return uri; } + @Override + public String getVariableSend() { + return processor.getVariableSend(); + } + + @Override + public String getVariableReceive() { + return processor.getVariableReceive(); + } + @Override public Integer getCacheSize() { return processor.getCacheSize(); 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 6a4f5892c57..a976bf9ba52 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 @@ -408,6 +408,8 @@ public class ModelParser extends BaseParser { case "cacheSize": def.setCacheSize(val); break; case "ignoreInvalidEndpoint": def.setIgnoreInvalidEndpoint(val); break; case "shareUnitOfWork": def.setShareUnitOfWork(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 29a3ac921fe..dafa67a7831 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 @@ -1250,6 +1250,8 @@ public class ModelWriter extends BaseWriter { throws IOException { startElement(name); doWriteProcessorDefinitionAttributes(def); + doWriteAttribute("variableReceive", def.getVariableReceive()); + doWriteAttribute("variableSend", def.getVariableSend()); doWriteAttribute("cacheSize", def.getCacheSize()); doWriteAttribute("aggregationStrategy", def.getAggregationStrategy()); doWriteAttribute("ignoreInvalidEndpoint", def.getIgnoreInvalidEndpoint()); 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 974cebf1f05..7d60741bd7b 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 @@ -1250,6 +1250,8 @@ public class ModelWriter extends BaseWriter { throws IOException { startElement(name); doWriteProcessorDefinitionAttributes(def); + doWriteAttribute("variableReceive", def.getVariableReceive()); + doWriteAttribute("variableSend", def.getVariableSend()); doWriteAttribute("cacheSize", def.getCacheSize()); doWriteAttribute("aggregationStrategy", def.getAggregationStrategy()); doWriteAttribute("ignoreInvalidEndpoint", def.getIgnoreInvalidEndpoint()); 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 7ef2c0a270e..b6116965d2a 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 @@ -5041,7 +5041,9 @@ public final class ModelDeserializers extends YamlDeserializerSupport { @YamlProperty(name = "id", type = "string", description = "Sets the id of this node", displayName = "Id"), @YamlProperty(name = "ignoreInvalidEndpoint", type = "boolean", description = "Ignore the invalidate endpoint exception when try to create a producer with that endpoint", displayName = "Ignore Invalid Endpoint"), @YamlProperty(name = "inheritErrorHandler", type = "boolean"), - @YamlProperty(name = "shareUnitOfWork", type = "boolean", description = "Shares the org.apache.camel.spi.UnitOfWork with the parent and the resource exchange. Enrich will by default not share unit of work between the parent exchange and the resource exchange. This means the resource exchange has its own individual unit of work.", displayName = "Share Unit Of Work") + @YamlProperty(name = "shareUnitOfWork", type = "boolean", description = "Shares the org.apache.camel.spi.UnitOfWork with the parent and the resource exchange. Enrich will by default not share unit of work between the parent exchange and the resource exchange. This means the resource exchange has its own individual unit of work.", displayName = "Share Unit Of Work"), + @YamlProperty(name = "variableReceive", type = "string", 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 current org.apache.camel.Message .", displayName = "Variable Receive"), + @YamlProperty(name = "variableSend", type = "string", 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 current org.apache.camel.Message .", displayName = "Variable Send") } ) public static class EnrichDefinitionDeserializer extends YamlDeserializerBase<EnrichDefinition> { @@ -5119,6 +5121,16 @@ public final class ModelDeserializers extends YamlDeserializerSupport { target.setShareUnitOfWork(val); break; } + case "variableReceive": { + String val = asText(node); + target.setVariableReceive(val); + break; + } + case "variableSend": { + String val = asText(node); + target.setVariableSend(val); + break; + } case "id": { String val = asText(node); target.setId(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 bafd77a84db..8737486cc97 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 @@ -1324,6 +1324,16 @@ "title" : "Share Unit Of Work", "description" : "Shares the org.apache.camel.spi.UnitOfWork with the parent and the resource exchange. Enrich will by default not share unit of work between the parent exchange and the resource exchange. This means the resource exchange has its own individual unit of work." }, + "variableReceive" : { + "type" : "string", + "title" : "Variable Receive", + "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 current org.apache.camel.Message ." + }, + "variableSend" : { + "type" : "string", + "title" : "Variable Send", + "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 current org.apache.camel.Message ." + }, "constant" : { }, "csimple" : { }, "datasonnet" : { }, diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/EnrichVariableTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/EnrichVariableTest.groovy new file mode 100644 index 00000000000..3a889dfa05d --- /dev/null +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/EnrichVariableTest.groovy @@ -0,0 +1,264 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.dsl.yaml + +import org.apache.camel.component.mock.MockEndpoint +import org.apache.camel.dsl.yaml.support.YamlTestSupport + +class EnrichVariableTest extends YamlTestSupport { + + def "enrichVariable send"() { + setup: + loadRoutes ''' + - route: + from: + uri: direct:send + steps: + - setVariable: + name: hello + simple: + expression: Camel + - to: + uri: mock:before + - enrich: + expression: + constant: "direct:foo" + variableSend: hello + - to: + uri: mock:result + - route: + from: + uri: direct:receive + steps: + - enrich: + expression: + constant: "direct:foo" + variableReceive: bye + - to: + uri: mock:after + - setBody: + simple: + expression: "${variable:bye}" + - to: + uri: mock:result + - route: + from: + uri: direct:sendAndReceive + steps: + - setVariable: + name: hello + simple: + expression: Camel + - to: + uri: mock:before + - enrich: + expression: + constant: "direct:foo" + variableReceive: bye + variableSend: hello + - to: + uri: mock:result + - route: + from: + uri: direct:foo + steps: + - transform: + simple: + expression: "Bye ${body}" + ''' + + withMock('mock:before') { + expectedBodiesReceived 'World' + expectedVariableReceived("hello", "Camel") + } + withMock('mock:result') { + expectedBodiesReceived 'Bye Camel' + expectedVariableReceived("hello", "Camel") + } + + when: + context.start() + + withTemplate { + to('direct:send').withBody('World').send() + } + + then: + MockEndpoint.assertIsSatisfied(context) + } + + + def "enrichVariable receive"() { + setup: + loadRoutes ''' + - route: + from: + uri: direct:send + steps: + - setVariable: + name: hello + simple: + expression: Camel + - to: + uri: mock:before + - enrich: + expression: + constant: "direct:foo" + variableSend: hello + - to: + uri: mock:result + - route: + from: + uri: direct:receive + steps: + - enrich: + expression: + constant: "direct:foo" + variableReceive: bye + - to: + uri: mock:after + - setBody: + simple: + expression: "${variable:bye}" + - to: + uri: mock:result + - route: + from: + uri: direct:sendAndReceive + steps: + - setVariable: + name: hello + simple: + expression: Camel + - to: + uri: mock:before + - enrich: + expression: + constant: "direct:foo" + variableReceive: bye + variableSend: hello + - to: + uri: mock:result + - route: + from: + uri: direct:foo + steps: + - transform: + simple: + expression: "Bye ${body}" + ''' + + withMock('mock:after') { + expectedBodiesReceived 'World' + expectedVariableReceived("bye", "Bye World") + } + withMock('mock:result') { + expectedBodiesReceived 'Bye World' + expectedVariableReceived("bye", "Bye World") + } + + when: + context.start() + + withTemplate { + to('direct:receive').withBody('World').send() + } + + then: + MockEndpoint.assertIsSatisfied(context) + } + + def "enrichVariable sendAndReceive"() { + setup: + loadRoutes ''' + - route: + from: + uri: direct:send + steps: + - setVariable: + name: hello + simple: + expression: Camel + - to: + uri: mock:before + - enrich: + expression: + constant: "direct:foo" + variableSend: hello + - to: + uri: mock:result + - route: + from: + uri: direct:receive + steps: + - enrich: + expression: + constant: "direct:foo" + variableReceive: bye + - to: + uri: mock:after + - setBody: + simple: + expression: "${variable:bye}" + - to: + uri: mock:result + - route: + from: + uri: direct:sendAndReceive + steps: + - setVariable: + name: hello + simple: + expression: Camel + - to: + uri: mock:before + - enrich: + expression: + constant: "direct:foo" + variableReceive: bye + variableSend: hello + - to: + uri: mock:result + - route: + from: + uri: direct:foo + steps: + - transform: + simple: + expression: "Bye ${body}" + ''' + + withMock('mock:before') { + expectedBodiesReceived 'World' + expectedVariableReceived("hello", "Camel") + } + withMock('mock:result') { + expectedBodiesReceived 'World' + expectedVariableReceived("bye", "Bye Camel") + } + + when: + context.start() + + withTemplate { + to('direct:sendAndReceive').withBody('World').send() + } + + then: + MockEndpoint.assertIsSatisfied(context) + } +}