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 25fac54 CAMEL-16861: Cleanup and update EIP docs
25fac54 is described below
commit 25fac54ab42f7b8333bc8d63c9752063c9a64aab
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Oct 7 17:42:31 2021 +0200
CAMEL-16861: Cleanup and update EIP docs
---
.../docs/modules/eips/pages/multicast-eip.adoc | 249 ++++++++++++++++-----
1 file changed, 189 insertions(+), 60 deletions(-)
diff --git
a/core/camel-core-engine/src/main/docs/modules/eips/pages/multicast-eip.adoc
b/core/camel-core-engine/src/main/docs/modules/eips/pages/multicast-eip.adoc
index 34acbe9..fe33060 100644
--- a/core/camel-core-engine/src/main/docs/modules/eips/pages/multicast-eip.adoc
+++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/multicast-eip.adoc
@@ -5,10 +5,15 @@
:since:
:supportlevel: Stable
-The Multicast EIP allows to route the same message to a number of endpoints
-and process them in a different way. The main difference between the
-Multicast and Splitter is that Splitter will split the message into
-several pieces but the Multicast will not modify the request message.
+The Multicast EIP allows to route *the same* message to a number of
xref:latest@manual:ROOT:endpoint.adoc[endpoints]
+and process them in a different way.
+
+image::eip/RecipientListIcon.gif[image]
+
+The Multicast EIP has many features and is also used as baseline for
+the xref:recipientList-eip.adoc[Recipient List] and xref:split-eip.adoc[Split]
EIPs.
+For example the Multicast EIP is capable of aggregating each multicasted
message into a single
+_response_ message as the result after the Multicast EIP.
== Options
@@ -16,116 +21,240 @@ several pieces but the Multicast will not modify the
request message.
include::partial$eip-options.adoc[]
// eip options: END
-== Multicast example
+== Exchange properties
+
+The following properties are set on each Exchange that are multicasted:
+
+[width="100%",cols="3,1m,6",options="header"]
+|=======================================================================
+| Property | Type | Description
+| `CamelMulticastIndex` | `int` | An index counter that increases for each
Exchange being multicasted. The counter starts from 0.
+| `MULTICAST_COMPLETE` | `boolean` |Whether or not this Exchange is the last.
+|=======================================================================
+
+== Using Multicast
+
+The following example shows how to take a request from the direct:a
+endpoint, then multicast these request to direct:x, direct:y, and direct:z.
+
+[source,java]
+----
+from("direct:a")
+ .multicast()
+ .to("direct:x")
+ .to("direct:y")
+ .to("direct:z");
+----
+
+And in XML:
+
+[source,xml]
+----
+<route>
+ <from uri="direct:a"/>
+ <multicast>
+ <to uri="direct:b"/>
+ <to uri="direct:c"/>
+ <to uri="direct:d"/>
+ </multicast>
+</route>
+----
-The following example shows how to take a request from the *direct:a*
-endpoint , then multicast these request to *direct:x*, *direct:y*,
-*direct:z*.
+By default, Multicast EIP runs in single threaded mode, which mean
+that the next multicasted message is processed only when the previous is
finished.
+This means that direct:b must be done before Camel will call direct:c and so
on.
-== Using the fluent builder
+=== Multicasting with parallel processing
-By default Multicast invokes each endpoint sequentially. If parallel
-processing is desired, simply use
+You can enable parallel processing with Multicast EIP so each multicasted
message
+is processed by its own thread in parallel.
+
+The example below enabled parallel mode:
[source,java]
----
-from("direct:a").multicast().parallelProcessing().to("direct:x", "direct:y",
"direct:z");
+from("direct:a")
+ .multicast().paralllelProcessing()
+ .to("direct:x")
+ .to("direct:y")
+ .to("direct:z");
+----
+
+And in XML:
+
+[source,xml]
+----
+<route>
+ <from uri="direct:a"/>
+ <multicast parallelProcessing="true">
+ <to uri="direct:b"/>
+ <to uri="direct:c"/>
+ <to uri="direct:d"/>
+ </multicast>
+</route>
----
-In case of using InOut MEP, an AggregationStrategy is used for
-aggregating all reply messages. The default is to only use the latest
-reply message and discard any earlier replies. The aggregation strategy
-is configurable:
+=== Ending a Multicast block
+
+You may want to continue routing the exchange after the Multicast EIP. In Java
DSL you need to use `end()`
+to mark where multicast ends, and where other EIPs can be added to continue
the route.
+
+In the example above then sending to mock:result happens after the Multicast
EIP has finished.
+In other words direct:y, direct:y, and direct:z should be completed first,
before the message
+continues.
+
+[source,java]
+----
+from("direct:a")
+ .multicast().paralllelProcessing()
+ .to("direct:x")
+ .to("direct:y")
+ .to("direct:z")
+ .end()
+ .to("mock:result");
+----
+
+And in XML its intuitive as `</multicast>` marks the end of the block:
+
+[source,xml]
+----
+<route>
+ <from uri="direct:a"/>
+ <multicast parallelProcessing="true">
+ <to uri="direct:b"/>
+ <to uri="direct:c"/>
+ <to uri="direct:d"/>
+ </multicast>
+ <to uri="mock:result"/>
+</route>
+----
+
+=== Aggregating
+
+The `AggregationStrategy` is used for aggregating all the multicasted
exchanges together
+as a single response exchange, that becomes the outgoing exchange after the
Multicast EIP block.
+
+The example now aggregates with the `MyAggregationStrategy` class:
[source,java]
----
from("direct:start")
- .multicast(new MyAggregationStrategy())
- .parallelProcessing().timeout(500).to("direct:a", "direct:b", "direct:c")
+ .multicast(new MyAggregationStrategy()).parallelProcessing().timeout(500)
+ .to("direct:x")
+ .to("direct:y")
+ .to("direct:z")
.end()
.to("mock:result");
----
+And in XML we can refer to the FQN class name with `#class:` syntax as shown
below:
+
+[source,xml]
+----
+<route>
+ <from uri="direct:a"/>
+ <multicast parallelProcessing="true" timeout="5000"
+ strategyRef="#class:com.foo.MyAggregationStrategy">
+ <to uri="direct:b"/>
+ <to uri="direct:c"/>
+ <to uri="direct:d"/>
+ </multicast>
+ <to uri="mock:result"/>
+</route>
+----
+
[NOTE]
====
The Multicast, Recipient List, and Splitter EIPs have special support for
using `AggregationStrategy` with
access to the original input exchange. You may want to use this when you
aggregate messages and
there has been a failure in one of the messages, which you then want to enrich
on the original
-input message and return as response; its the aggregate method with 3 exchange
parameters.
+input message and return as response; it's the aggregate method with 3
exchange parameters.
====
-== Stop processing in case of exception
+=== Stop processing in case of exception
-The mutlicast EIP will by default continue to process
+The Multicast EIP will by default continue to process
the entire exchange even in case one of the
multicasted messages will throw an exception during routing.
+
For example if you want to multicast to 3 destinations and the 2nd
destination fails by an exception. What Camel does by default is to
-process the remainder destinations. You have the chance to remedy or
-handle this in the `AggregationStrategy`.
+process the remainder destinations. You have the chance to deal with the
exception
+when aggregating using an `AggregationStrategy`.
But sometimes you just want Camel to stop and let the exception be
-propagated back, and let the Camel error handler handle it. You can do
-this by specifying that it should stop in case of an
+propagated back, and let the Camel
xref:latest@manual:ROOT:error-handler.adoc[Error Handler]
+handle it. You can do this by specifying that it should stop in case of an
exception occurred. This is done by the `stopOnException` option as
shown below:
[source,java]
----
- from("direct:start")
- .multicast()
- .stopOnException().to("direct:foo", "direct:bar", "direct:baz")
- .end()
- .to("mock:result");
+from("direct:start")
+ .multicast()
+ .stopOnException().to("direct:foo", "direct:bar", "direct:baz")
+ .end()
+ .to("mock:result");
- from("direct:foo").to("mock:foo");
+ from("direct:foo").to("mock:foo");
- from("direct:bar").process(new MyProcessor()).to("mock:bar");
+ from("direct:bar").process(new MyProcessor()).to("mock:bar");
- from("direct:baz").to("mock:baz");
+ from("direct:baz").to("mock:baz");
----
+In the example above, then `MyProcessor` is causing a failure and throws an
exception.
+This means the Multicast EIP will stop after this, and not the last route
(direct:baz).
+
And using XML DSL you specify it as follows:
[source,xml]
----
- <route>
- <from uri="direct:start"/>
- <multicast stopOnException="true">
- <to uri="direct:foo"/>
- <to uri="direct:bar"/>
- <to uri="direct:baz"/>
- </multicast>
- <to uri="mock:result"/>
- </route>
+<routes>
+ <route>
+ <from uri="direct:start"/>
+ <multicast stopOnException="true">
+ <to uri="direct:foo"/>
+ <to uri="direct:bar"/>
+ <to uri="direct:baz"/>
+ </multicast>
+ <to uri="mock:result"/>
+ </route>
- <route>
- <from uri="direct:foo"/>
- <to uri="mock:foo"/>
- </route>
+ <route>
+ <from uri="direct:foo"/>
+ <to uri="mock:foo"/>
+ </route>
- <route>
- <from uri="direct:bar"/>
- <process ref="myProcessor"/>
- <to uri="mock:bar"/>
- </route>
+ <route>
+ <from uri="direct:bar"/>
+ <process ref="myProcessor"/>
+ <to uri="mock:bar"/>
+ </route>
- <route>
- <from uri="direct:baz"/>
- <to uri="mock:baz"/>
- </route>
+ <route>
+ <from uri="direct:baz"/>
+ <to uri="mock:baz"/>
+ </route>
+</routes>
----
-== Using onPrepare to execute custom logic when preparing messages
+=== Preparing the message by deep copying before multicasting
The multicast EIP will copy the source
-exchange and multicast each copy. However the copy
-is a shallow copy, so in case you have mutateable message bodies, then
+exchange and multicast each copy. However, the copy
+is a shallow copy, so in case you have mutable message bodies, then
any changes will be visible by the other copied messages. If you want to
use a deep clone copy then you need to use a custom `onPrepare` which
-allows you to do this using the processor
-interface.
+allows you to create a deep copy of the message body in the `Processor`.
Notice the `onPrepare` can be used for any kind of custom logic which
you would like to execute before the
xref:latest@manual:ROOT:exchange.adoc[Exchange] is
being multicasted.
+
+== See Also
+
+Because Multicast EIP is baseline for
+the xref:recipientList-eip.adoc[Recipient List] and xref:split-eip.adoc[Split]
EIPs,
+then you can find more information in those EIPs about features that is also
available
+with Multicast EIP.