This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch camel-4.10.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.10.x by this push:
new c0bfa10e164 [4.10.x] CAMEL-21958: camel-core: Java DSL. Fix
endChoice() to reuse end() and scope to current/nearest choice (#17778)
c0bfa10e164 is described below
commit c0bfa10e16461bb4ba4e2f4fbb4921201fd13a08
Author: Peter Palaga <[email protected]>
AuthorDate: Wed Apr 16 18:24:09 2025 +0200
[4.10.x] CAMEL-21958: camel-core: Java DSL. Fix endChoice() to reuse end()
and scope to current/nearest choice (#17778)
* CAMEL-21958: camel-core: Java DSL. Fix endChoice() to reuse end() and
scope to current/nearest choice. (#17761)
* CAMEL-21958: camel-core: Java DSL. Fix endChoice() to reuse end() and
scope to current/nearest choice.
* CAMEL-21958: camel-core: Java DSL. Fix endChoice() to reuse end() and
scope to current/nearest choice.
---------
Co-authored-by: Claus Ibsen <[email protected]>
---
.../processor/SpringNestedChoiceIssueTest.xml | 2 +-
.../org/apache/camel/model/ChoiceDefinition.java | 5 ++
.../apache/camel/model/ProcessorDefinition.java | 24 +++----
.../camel/processor/NestedChoiceIssueTest.java | 10 ++-
.../processor/NestedChoiceOtherwiseIssueTest.java | 82 ++++++++++++++++++++++
.../processor/TripleNestedChoiceIssueTest.java | 10 ++-
.../async/AsyncNestedTripleChoiceIssueTest.java | 4 +-
7 files changed, 119 insertions(+), 18 deletions(-)
diff --git
a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/SpringNestedChoiceIssueTest.xml
b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/SpringNestedChoiceIssueTest.xml
index 1534c773b38..6174e512f8b 100644
---
a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/SpringNestedChoiceIssueTest.xml
+++
b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/SpringNestedChoiceIssueTest.xml
@@ -26,7 +26,7 @@
<camelContext xmlns="http://camel.apache.org/schema/spring">
<jmxAgent id="jmx" disabled="true"/>
- <route>
+ <route id="route1">
<from uri="direct:start"/>
<choice>
<when>
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/model/ChoiceDefinition.java
b/core/camel-core-model/src/main/java/org/apache/camel/model/ChoiceDefinition.java
index 4d771dda24e..64e2dd5abc7 100644
---
a/core/camel-core-model/src/main/java/org/apache/camel/model/ChoiceDefinition.java
+++
b/core/camel-core-model/src/main/java/org/apache/camel/model/ChoiceDefinition.java
@@ -186,6 +186,11 @@ public class ChoiceDefinition extends
NoOutputDefinition<ChoiceDefinition> {
* @return the builder
*/
public ChoiceDefinition otherwise() {
+ if (this.otherwise != null) {
+ throw new IllegalArgumentException(
+ "Cannot add a 2nd otherwise to this choice: " + this
+ + ". If you have nested choice
then you may need to end().endChoice() to go back to parent choice.");
+ }
OtherwiseDefinition answer = new OtherwiseDefinition();
addClause(answer);
return this;
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
b/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
index 6917ea436af..2020877f452 100644
---
a/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
+++
b/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
@@ -41,7 +41,6 @@ import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Expression;
import org.apache.camel.LoggingLevel;
-import org.apache.camel.NamedNode;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
import org.apache.camel.builder.DataFormatClause;
@@ -1089,25 +1088,24 @@ public abstract class ProcessorDefinition<Type extends
ProcessorDefinition<Type>
public ChoiceDefinition endChoice() {
ProcessorDefinition<?> def = this;
- // are we nested choice?
- if (def.getParent() instanceof ChoiceDefinition cho) {
+ // are we already a choice
+ if (def instanceof ChoiceDefinition cho) {
return cho;
}
+ // end and find the choice
+ def = end();
+ if (def instanceof RouteDefinition) {
+ // okay that was too far down so go back up
+ def = this;
+ }
+
// are we already a choice?
if (def instanceof ChoiceDefinition choice) {
return choice;
- }
-
- // okay end this and get back to the choice
- def = end();
- NamedNode p = def.getParent();
- if ("when".equals(p.getShortName())) {
- return (ChoiceDefinition) p;
- } else if ("otherwise".equals(p.getShortName())) {
- return (ChoiceDefinition) p;
} else {
- return (ChoiceDefinition) def;
+ throw new IllegalArgumentException(
+ "Cannot endChoice() to find current/parent choice DSL. If
you have nested choice then you may need to end().endChoice() to go back to
parent choice.");
}
}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/NestedChoiceIssueTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/NestedChoiceIssueTest.java
index b46a21e2a19..c91ea223d30 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/NestedChoiceIssueTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/NestedChoiceIssueTest.java
@@ -18,8 +18,11 @@ package org.apache.camel.processor;
import org.apache.camel.ContextTestSupport;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.support.PluginHelper;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
public class NestedChoiceIssueTest extends ContextTestSupport {
@Test
@@ -46,6 +49,11 @@ public class NestedChoiceIssueTest extends
ContextTestSupport {
@Test
public void testNestedChoiceLow() throws Exception {
+ String xml =
PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context,
+ context.getRouteDefinition("route1"));
+ assertNotNull(xml);
+ log.info(xml);
+
getMockEndpoint("mock:low").expectedMessageCount(1);
getMockEndpoint("mock:med").expectedMessageCount(0);
getMockEndpoint("mock:big").expectedMessageCount(0);
@@ -62,7 +70,7 @@ public class NestedChoiceIssueTest extends ContextTestSupport
{
public void configure() {
from("direct:start").choice().when(header("foo").isGreaterThan(1)).choice().when(header("foo").isGreaterThan(5))
.to("mock:big").otherwise().to("mock:med")
- .endChoice().otherwise().to("mock:low").end();
+ .end().endChoice().otherwise().to("mock:low").end();
}
};
}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/NestedChoiceOtherwiseIssueTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/NestedChoiceOtherwiseIssueTest.java
new file mode 100644
index 00000000000..a938e488760
--- /dev/null
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/NestedChoiceOtherwiseIssueTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.apache.camel.support.PluginHelper;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class NestedChoiceOtherwiseIssueTest extends ContextTestSupport {
+
+ @Test
+ public void testNestedChoiceOtherwise() throws Exception {
+ String xml =
PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context,
+ context.getRouteDefinition("myRoute"));
+ assertNotNull(xml);
+ log.info(xml);
+
+ getMockEndpoint("mock:foo").expectedMessageCount(1);
+ getMockEndpoint("mock:bar").expectedMessageCount(0);
+ getMockEndpoint("mock:other").expectedMessageCount(0);
+ getMockEndpoint("mock:other2").expectedMessageCount(0);
+ template.sendBodyAndHeader("direct:start", "Hello World", "foo", 10);
+ assertMockEndpointsSatisfied();
+
+ resetMocks();
+ getMockEndpoint("mock:foo").expectedMessageCount(0);
+ getMockEndpoint("mock:bar").expectedMessageCount(1);
+ getMockEndpoint("mock:other").expectedMessageCount(1);
+ getMockEndpoint("mock:other2").expectedMessageCount(0);
+ template.sendBodyAndHeader("direct:start", "Hello World", "bar", 11);
+ assertMockEndpointsSatisfied();
+
+ resetMocks();
+ getMockEndpoint("mock:foo").expectedMessageCount(0);
+ getMockEndpoint("mock:bar").expectedMessageCount(0);
+ getMockEndpoint("mock:other").expectedMessageCount(1);
+ getMockEndpoint("mock:other2").expectedMessageCount(1);
+ template.sendBodyAndHeader("direct:start", "Hello World", "cheese",
12);
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("direct:start").routeId("myRoute")
+ .errorHandler(noErrorHandler())
+ .choice()
+ .when(header("foo"))
+ .to("mock:foo")
+ .otherwise()
+ .to("mock:other")
+ .choice()
+ .when(header("bar"))
+ .to("mock:bar")
+ .endChoice()
+ .otherwise()
+ .to("mock:other2")
+ .end()
+ .end();
+ }
+ };
+ }
+}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/TripleNestedChoiceIssueTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/TripleNestedChoiceIssueTest.java
index c06cfb6eba4..17b469ae04a 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/TripleNestedChoiceIssueTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/TripleNestedChoiceIssueTest.java
@@ -18,8 +18,11 @@ package org.apache.camel.processor;
import org.apache.camel.ContextTestSupport;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.support.PluginHelper;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
public class TripleNestedChoiceIssueTest extends ContextTestSupport {
@Test
@@ -60,6 +63,11 @@ public class TripleNestedChoiceIssueTest extends
ContextTestSupport {
@Test
public void testNestedChoiceLow() throws Exception {
+ String xml =
PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context,
+ context.getRouteDefinition("route1"));
+ assertNotNull(xml);
+ log.info(xml);
+
getMockEndpoint("mock:low").expectedMessageCount(1);
getMockEndpoint("mock:med").expectedMessageCount(0);
getMockEndpoint("mock:big").expectedMessageCount(0);
@@ -77,7 +85,7 @@ public class TripleNestedChoiceIssueTest extends
ContextTestSupport {
public void configure() {
from("direct:start").choice().when(header("foo").isGreaterThan(1)).choice().when(header("foo").isGreaterThan(5))
.choice().when(header("foo").isGreaterThan(10))
-
.to("mock:verybig").otherwise().to("mock:big").endChoice().otherwise().to("mock:med").endChoice()
+
.to("mock:verybig").otherwise().to("mock:big").end().endChoice().otherwise().to("mock:med").end().endChoice()
.otherwise().to("mock:low").end();
}
};
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/async/AsyncNestedTripleChoiceIssueTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/async/AsyncNestedTripleChoiceIssueTest.java
index 036bc7ac99c..8f8a284662f 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/async/AsyncNestedTripleChoiceIssueTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/async/AsyncNestedTripleChoiceIssueTest.java
@@ -79,8 +79,8 @@ public class AsyncNestedTripleChoiceIssueTest extends
ContextTestSupport {
from("direct:start").choice().when(header("foo").isGreaterThan(1)).to("async:bye:camel").choice()
.when(header("foo").isGreaterThan(5)).to("async:bye:camel2")
-
.choice().when(header("foo").isGreaterThan(7)).to("mock:verybig").otherwise().to("mock:big").endChoice()
- .otherwise().to("mock:med").endChoice().otherwise()
+
.choice().when(header("foo").isGreaterThan(7)).to("mock:verybig").otherwise().to("mock:big").end().endChoice()
+
.otherwise().to("mock:med").end().endChoice().otherwise()
.to("mock:low").end();
}
};