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 9817b197b0a62cb48f84a8ba951615900f9890db Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Apr 24 20:49:53 2025 +0200 CAMEL-22018: camel-core - Exchange.getVariables should include message headers --- .../src/main/java/org/apache/camel/Exchange.java | 4 +- .../bean/BeanWithVariablesAndBodyInject3Test.java | 34 ++++++++-- .../org/apache/camel/language/VariableTest.java | 4 ++ .../org/apache/camel/util/ExchangeHelperTest.java | 6 +- .../camel/support/ExchangeVariableRepository.java | 76 ++++++---------------- 5 files changed, 55 insertions(+), 69 deletions(-) diff --git a/core/camel-api/src/main/java/org/apache/camel/Exchange.java b/core/camel-api/src/main/java/org/apache/camel/Exchange.java index 19a3e34e072..9d0a5a7272f 100644 --- a/core/camel-api/src/main/java/org/apache/camel/Exchange.java +++ b/core/camel-api/src/main/java/org/apache/camel/Exchange.java @@ -532,9 +532,9 @@ public interface Exchange extends VariableAware { Object removeVariable(String name); /** - * Returns the variables from the current exchange (read-only) + * Returns the variables from the current exchange * - * @return the variables from the current exchange in a Map (read-only). + * @return the variables from the current exchange in a Map */ Map<String, Object> getVariables(); diff --git a/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithVariablesAndBodyInject3Test.java b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithVariablesAndBodyInject3Test.java index c203450e75c..8245be4b409 100644 --- a/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithVariablesAndBodyInject3Test.java +++ b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithVariablesAndBodyInject3Test.java @@ -26,29 +26,48 @@ import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.spi.Registry; import org.junit.jupiter.api.Test; -public class BeanWithVariablesAndBodyInject3Test extends ContextTestSupport { +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +public class BeanWithVariablesAndBodyInject3Test extends ContextTestSupport { private final MyBean myBean = new MyBean(); @Override protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { - from("direct:start") - .setVariable("cheese", constant("gauda")) - .to("bean:myBean?method=doSomething").to("mock:finish"); + from("direct:start").to("bean:myBean?method=doSomething").to("mock:finish"); } }; } @Test - public void testVariables() throws Exception { + public void testInOnly() throws Exception { MockEndpoint end = getMockEndpoint("mock:finish"); - end.expectedBodiesReceived("Hello 1"); + end.expectedBodiesReceived("Hello!"); sendBody("direct:start", "Test Input"); assertMockEndpointsSatisfied(); + + assertNotNull(end.getExchanges().get(0).getIn().getBody()); + assertEquals("Hello!", end.getExchanges().get(0).getIn().getBody()); + } + + @Test + public void testInOut() throws Exception { + MockEndpoint end = getMockEndpoint("mock:finish"); + end.expectedBodiesReceived("Hello!"); + end.expectedVariableReceived("out", 123); + + String out = template.requestBody("direct:start", "Test Input", String.class); + assertEquals("Hello!", out); + + assertMockEndpointsSatisfied(); + + assertNotNull(end.getExchanges().get(0).getIn().getBody()); + assertEquals("Hello!", end.getExchanges().get(0).getIn().getBody()); + assertEquals(123, end.getExchanges().get(0).getVariable("out")); } @Override @@ -61,7 +80,8 @@ public class BeanWithVariablesAndBodyInject3Test extends ContextTestSupport { public static class MyBean { public String doSomething(@Body String body, @Variables Map<String, Object> variables) { - return "Hello " + variables.size(); + variables.put("out", 123); + return "Hello!"; } } } diff --git a/core/camel-core/src/test/java/org/apache/camel/language/VariableTest.java b/core/camel-core/src/test/java/org/apache/camel/language/VariableTest.java index 9998653af15..de57895162a 100644 --- a/core/camel-core/src/test/java/org/apache/camel/language/VariableTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/language/VariableTest.java @@ -66,6 +66,10 @@ public class VariableTest extends LanguageTestSupport { assertEquals("Hello Again", map.get("myOtherKey")); assertEquals("abc", map.get("header:myKey.foo")); assertEquals(123, map.get("header:myKey.bar")); + + exchange.removeVariable("header:myKey"); + map = exchange.getVariables(); + assertEquals(1, map.size()); } @Test diff --git a/core/camel-core/src/test/java/org/apache/camel/util/ExchangeHelperTest.java b/core/camel-core/src/test/java/org/apache/camel/util/ExchangeHelperTest.java index 575982b3774..564049ac924 100644 --- a/core/camel-core/src/test/java/org/apache/camel/util/ExchangeHelperTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/util/ExchangeHelperTest.java @@ -158,10 +158,8 @@ public class ExchangeHelperTest extends ContextTestSupport { assertSame(exchange.getMessage(), map.get("response")); assertSame(exchange.getIn().getHeaders(), map.get("headers")); assertSame(exchange.getIn().getHeaders(), map.get("header")); - Map vars = (Map) map.get("variable"); - assertEquals(exchange.getVariables().size(), vars.size()); - vars = (Map) map.get("variables"); - assertEquals(exchange.getVariables().size(), vars.size()); + assertSame(exchange.getVariables(), map.get("variable")); + assertSame(exchange.getVariables(), map.get("variables")); assertSame(exchange.getIn().getBody(), map.get("body")); assertSame(exchange.getContext(), map.get("camelContext")); } diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ExchangeVariableRepository.java b/core/camel-support/src/main/java/org/apache/camel/support/ExchangeVariableRepository.java index 0c7be28ac71..ff21700260d 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/ExchangeVariableRepository.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/ExchangeVariableRepository.java @@ -16,10 +16,9 @@ */ package org.apache.camel.support; -import java.util.Collections; -import java.util.HashMap; +import java.util.HashSet; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Set; import org.apache.camel.CamelContext; import org.apache.camel.Exchange; @@ -33,8 +32,6 @@ import org.apache.camel.util.StringHelper; */ final class ExchangeVariableRepository extends AbstractVariableRepository { - private final Map<String, Object> headers = new ConcurrentHashMap<>(8); - public ExchangeVariableRepository(CamelContext camelContext) { setCamelContext(camelContext); // ensure its started @@ -43,28 +40,6 @@ final class ExchangeVariableRepository extends AbstractVariableRepository { void copyFrom(ExchangeVariableRepository source) { setVariables(source.getVariables()); - this.headers.putAll(source.headers); - } - - @Override - public Map<String, Object> getVariables() { - Map<String, Object> answer; - if (headers.isEmpty()) { - answer = super.getVariables(); - } else { - answer = new HashMap<>(super.getVariables()); - // flatten headers - headers.forEach((k, v) -> { - answer.put("header:" + k, v); - }); - } - return Collections.unmodifiableMap(answer); - } - - @Override - public void setVariables(Map<String, Object> map) { - super.setVariables(map); - this.headers.clear(); } @Override @@ -79,54 +54,43 @@ final class ExchangeVariableRepository extends AbstractVariableRepository { prefix = prefix + "."; // we want all headers for a given variable Map<String, Object> map = new CaseInsensitiveMap(); - for (Map.Entry<String, Object> entry : headers.entrySet()) { + for (Map.Entry<String, Object> entry : getVariables().entrySet()) { String key = entry.getKey(); - if (key.startsWith(prefix)) { + if (key.startsWith(name + ".")) { key = StringHelper.after(key, prefix); map.put(key, entry.getValue()); } } return map; - } else { - return headers.get(prefix); } } return super.getVariable(name); } - @Override - public void setVariable(String name, Object value) { - String id = StringHelper.before(name, ":"); - if ("header".equals(id)) { - name = StringHelper.after(name, ":"); - if (value != null) { - // avoid the NullPointException - headers.put(name, value); - } else { - // if the value is null, we just remove the key from the map - headers.remove(name); - } - } else { - super.setVariable(name, value); - } - } - @Override public Object removeVariable(String name) { String id = StringHelper.before(name, ":"); if ("header".equals(id)) { - name = StringHelper.after(name, ":"); - return headers.remove(name); + String prefix = StringHelper.after(name, ":"); + if (prefix == null || prefix.isBlank()) { + throw new IllegalArgumentException("Variable " + name + " must have header key"); + } + if (!prefix.contains(".")) { + // we want to remove all headers for a given variable + Set<String> toRemove = new HashSet<>(); + for (Map.Entry<String, Object> entry : getVariables().entrySet()) { + String key = entry.getKey(); + if (key.startsWith(name + ".")) { + toRemove.add(key); + } + } + toRemove.forEach(super::removeVariable); + return null; + } } return super.removeVariable(name); } - @Override - public void clear() { - super.clear(); - headers.clear(); - } - @Override public String getId() { return "exchange";