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 8a53999  CAMEL-16861: Cleanup and update EIP docs
8a53999 is described below

commit 8a53999bcd06968ba069ca1af207d53d0398d020
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Wed Sep 15 15:34:08 2021 +0200

    CAMEL-16861: Cleanup and update EIP docs
---
 .../main/docs/modules/eips/pages/choice-eip.adoc   | 172 +++++++++++++--------
 1 file changed, 109 insertions(+), 63 deletions(-)

diff --git 
a/core/camel-core-engine/src/main/docs/modules/eips/pages/choice-eip.adoc 
b/core/camel-core-engine/src/main/docs/modules/eips/pages/choice-eip.adoc
index a2dfab4..d3c542b 100644
--- a/core/camel-core-engine/src/main/docs/modules/eips/pages/choice-eip.adoc
+++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/choice-eip.adoc
@@ -26,88 +26,134 @@ The Choice EIP supports 2 options which are listed below:
 |===
 // eip options: END
 
-== Examples
+== Example
 
 The following example shows how to route a request from an input
 *seda:a* endpoint to either *seda:b*, *seda:c* or *seda:d* depending on
-the evaluation of various xref:latest@manual:ROOT:predicate.adoc[Predicate] 
expressions
+the evaluation of various xref:latest@manual:ROOT:predicate.adoc[Predicate].
+
+The Camel xref:components:languages:simple-language.adoc[Simple] language
+is great to use with the Choice EIP when routing is based on the content of 
the message,
+such as checking message headers.
 
 [source,java]
 ----
-RouteBuilder builder = new RouteBuilder() {
-    public void configure() {
-        from("direct:a")
-            .choice()
-                .when(simple("${header.foo} == 'bar'"))
-                    .to("direct:b")
-                .when(simple("${header.foo} == 'cheese'"))
-                    .to("direct:c")
-                .otherwise()
-                    .to("direct:d");
-    }
-};
+from("direct:a")
+    .choice()
+        .when(simple("${header.foo} == 'bar'"))
+            .to("direct:b")
+        .when(simple("${header.foo} == 'cheese'"))
+            .to("direct:c")
+        .otherwise()
+            .to("direct:d");
+----
+
+And the same example using XML DSL:
 
+[source,xml]
+----
+<route>
+    <from uri="direct:a"/>
+    <choice>
+        <when>
+            <simple>${header.foo} == 'bar'</simple>
+            <to uri="direct:b"/>
+        </when>
+        <when>
+            <simple>${header.foo} == 'cheese'</simple>
+            <to uri="direct:c"/>
+        </when>
+        <otherwise>
+            <to uri="direct:d"/>
+        </otherwise>
+    </choice>
+</route>
 ----
 
+=== Why can I not use otherwise in Java DSL
 
-And the same example using XML:
+When using the Choice EIP in the Java DSL you may have a situation where the 
compiler will not accept
+`when()` or `otherwise()` statements.
 
-[source,xml]
+For example as shown in the route below where we use the
+xref:loadBalance-eip.adoc[Load Balancer] inside the
+xref:content-based-router-eip.adoc[Content Based Router] in the first when:
+
+*Code will not compile*
+
+[source,java]
 ----
-<camelContext xmlns="http://camel.apache.org/schema/spring";>
-    <route>
-        <from uri="direct:a"/>
-        <choice>
-            <when>
-                <simple>${header.foo} == 'bar'</simple>
-                <to uri="direct:b"/>
-            </when>
-            <when>
-                <simple>${header.foo} == 'cheese'</simple>
-                <to uri="direct:c"/>
-            </when>
-            <otherwise>
-                <to uri="direct:d"/>
-            </otherwise>
-        </choice>
-    </route>
-</camelContext>
+from("direct:start")
+    .choice()
+        .when(body().contains("Camel"))
+            .loadBalance().roundRobin().to("mock:foo").to("mock:bar")
+        .otherwise()
+            .to("mock:result");
 ----
 
-== Usage of endChoice and end
-Usage of `endChoice` is not mandatory. However, It should be used whenever you 
want to return back control to `choice()` dsl so that you can add subsequent 
`when` and `otherwise` to the choice dsl.
-If you want to end entire `choice()` block use `end()`.
+Well the first issue is that the xref:loadBalance-eip.adoc[Load Balancer]
+uses the additional routing to know what to use in the load balancing.
+In this example that would be the:
 
-=== Example
+[source,java]
+----
+.to("mock:foo").to("mock:bar")
+----
+
+To indicate when the balancing stops, you should use `.end()` to denote
+the end. So the route is updates as follows:
+
+*Code will still not compile*
 
 [source,java]
 ----
+from("direct:start")
+    .choice()
+        .when(body().contains("Camel"))
+            .loadBalance().roundRobin().to("mock:foo").to("mock:bar").end()
+        .otherwise()
+            .to("mock:result");
+----
+
+However, the code will still not compile.
+
+The reason is we have stretched how far we can take the good old Java language 
in terms of
+xref:latest@manual:ROOT:dsl.adoc[DSL]. In a more dynamic or modern language 
such as Kotlin or Groovy
+you would be able to let it be stack based, so the `.end()` will pop the last 
type of the
+stack, and you would return to the scope of the
+xref:{eip-vc}:eips:content-based-router-eip.adoc[Content Based Router].
+
+That's not doable in Java. So we need to help Java a bit, which you do by
+using `.endChoice()`, which tells Camel to "pop the stack" and return
+to the scope of the xref:{eip-vc}:eips:content-based-router-eip.adoc[Content 
Based
+Router].
 
-    @Override
-    protected RouteBuilder createRouteBuilder() throws Exception {
-        return new RouteBuilder() {
-            @Override
-            public void configure() throws Exception {
-                from("direct:start")
-                    .choice()
-                        .when(body().contains("Camel"))
-                        .multicast()
-                            .to("mock:foo")
-                            .to("mock:bar")
-                        .endChoice() //we need to use endChoice to tell Java 
DSL to return scope back to the choice DSL.
-                        .otherwise() 
-                            .to("mock:result");
-            }
-        };
-    }
-    
+*Code compiles*
+
+[source,java]
+----
+from("direct:start")
+    .choice()
+        .when(body().contains("Camel"))
+            
.loadBalance().roundRobin().to("mock:foo").to("mock:bar").endChoice()
+        .otherwise()
+            .to("mock:result");
 ----
 
-Another example is explained in the TIP below.
+You only need to use `.endChoice()` when using certain
+xref:{eip-vc}:eips:enterprise-integration-patterns.adoc[EIP]s which often have 
additional
+methods to configure or as part of the EIP itself. For example the
+xref:split-eip.adoc[Splitter] EIP has a sub-route which denotes the
+routing of each _splitted_ message. You would also have to use
+`.endChoice()` to indicate the end of the sub-route and to return
+to the xref:{eip-vc}:eips:content-based-router-eip.adoc[Content Based Router].
+
+==== Still problems
+
+If there are still problems, then you can split your route into multiple
+routes, and link them together using the 
xref:components::direct-component.adoc[Direct]
+component.
 
-[TIP]
-====
-See 
xref:latest@manual:faq:why-can-i-not-use-when-or-otherwise-in-a-java-camel-route.adoc[Why
-can I not use when or otherwise in a Java Camel route] if you have
-problems with the Java DSL, accepting using `when` or `otherwise`.
-====
+There can be some combinations of 
xref:{eip-vc}:eips:enterprise-integration-patterns.adoc[EIP]s
+that can hit limits in how far we can take the fluent builder DSL with
+generics you can do in Java programming language.

Reply via email to