This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new 91058c30809 CAMEL-21849: camel-kamelet - Using variableReceive should not loose message body (#17391) 91058c30809 is described below commit 91058c30809390eb86eeb3f280f40aa65f18e9fa Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Fri Mar 7 16:02:29 2025 +0000 CAMEL-21849: camel-kamelet - Using variableReceive should not loose message body (#17391) --- .../kamelet/KameletVariableReceiveTest.java | 66 ++++++++++++++++++++++ .../camel/model/RouteTemplateDefinition.java | 24 ++++++++ .../org/apache/camel/reifier/RouteReifier.java | 13 +++-- 3 files changed, 97 insertions(+), 6 deletions(-) diff --git a/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletVariableReceiveTest.java b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletVariableReceiveTest.java new file mode 100644 index 00000000000..ec3e4585ea2 --- /dev/null +++ b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletVariableReceiveTest.java @@ -0,0 +1,66 @@ +/* + * 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.component.kamelet; + +import java.util.List; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Test; + +/** + * Test that using variable receive in kamelets does not cause original message body to be lost after calling the + * kamelet. + */ +public class KameletVariableReceiveTest extends CamelTestSupport { + + private final Object body = List.of("1", "2"); + + @Test + public void testVariableReceive() throws Exception { + getMockEndpoint("mock:line").expectedMessageCount(1); + getMockEndpoint("mock:line").message(0).variable("myVar").isEqualTo("[1, 2]"); + getMockEndpoint("mock:result").expectedBodiesReceived(body); + + template.sendBody("direct:start", "Hello World"); + + MockEndpoint.assertIsSatisfied(context); + } + + @Override + protected RoutesBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + // this kamelet only manipulates variables + routeTemplate("demo") + .fromV("kamelet:source", "myVar") + .convertVariableTo("myVar", String.class) + .to("mock:line") + .removeVariable("myVar"); + + from("direct:start").routeId("test") + .setBody(constant(body)) + .to("kamelet:demo") + .log("${body}") + .to("mock:result"); + } + }; + } +} diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java index aca502d6311..519cb7245d7 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java @@ -138,6 +138,30 @@ public class RouteTemplateDefinition extends OptionalIdentifiedDefinition<RouteT return route.from(endpoint); } + /** + * Creates an input to the route, and uses a variable to store a copy of the received message body (only body, not + * headers). This is handy for easy access to the received message body via variables. + * + * @param uri the from uri + * @param variableReceive the name of the variable + * @return the builder + */ + public RouteDefinition fromV(@AsEndpointUri String uri, String variableReceive) { + return route.fromV(uri, variableReceive); + } + + /** + * Creates an input to the route, and uses a variable to store a copy of the received message body (only body, not + * headers). This is handy for easy access to the received message body via variables. + * + * @param endpoint the from endpoint + * @param variableReceive the name of the variable + * @return the builder + */ + public RouteDefinition fromV(EndpointConsumerBuilder endpoint, String variableReceive) { + return route.fromV(endpoint, variableReceive); + } + /** * To define the route in the template */ 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 57c709f9d85..cd71e075ec1 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 @@ -474,19 +474,20 @@ public class RouteReifier extends ProcessorReifier<RouteDefinition> { public Object before(Exchange exchange) throws Exception { // move body to variable ExchangeHelper.setVariableFromMessageBodyAndHeaders(exchange, name, exchange.getMessage()); + // remember body + Object body = exchange.getMessage().getBody(); exchange.getMessage().setBody(null); - return null; + return body; } @Override public void after(Exchange exchange, Object data) throws Exception { - // noop + // restore body if body has not been changed + if (data != null && exchange.getMessage().getBody() == null) { + exchange.getMessage().setBody(data); + } } - @Override - public boolean hasState() { - return false; - } } }