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 77db847 CAMEL-16861: Cleanup and update EIP docs 77db847 is described below commit 77db8477b20baeb949f83f877082e06a944c24bc Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Mon Oct 18 10:45:33 2021 +0200 CAMEL-16861: Cleanup and update EIP docs --- .../docs/modules/eips/pages/scatter-gather.adoc | 65 ++++++++++++++++------ .../main/docs/modules/eips/pages/script-eip.adoc | 54 +++++++++--------- 2 files changed, 75 insertions(+), 44 deletions(-) diff --git a/core/camel-core-engine/src/main/docs/modules/eips/pages/scatter-gather.adoc b/core/camel-core-engine/src/main/docs/modules/eips/pages/scatter-gather.adoc index aa63dfa..07b3809 100644 --- a/core/camel-core-engine/src/main/docs/modules/eips/pages/scatter-gather.adoc +++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/scatter-gather.adoc @@ -9,37 +9,54 @@ specified recipients and re-aggregate the responses back into a single message. image::eip/BroadcastAggregate.gif[image] -With Camel this pattern is implemented by using the xref:recipientList-eip.adoc[Recipient List] -which comes with aggregation built-in. This is often the simplest solution. However, there can -be some complex use-cases where you would need not use the built-in aggregator, and instead -use the more powerful xref:aggregate-eip.adoc[Aggregate] EIP for aggregation. +In Camel the Scatter Gather EIP is supported in two different synchronous modes. -== Using only Recipient List +- request/reply mode, where the re-aggregated response message continues being routed synchronously +after the Scatter Gather is complete. -In the following example we want to call two HTTP services and gather their responses into a single message. +- one-way mode, where the response message is being routed asynchronous separately from +the incoming message thread. + +== Request/Reply vs One-Way messaging modes + +In Camel the request/reply mode is done by using only the xref:recipientList-eip.adoc[Recipient List] +which comes with aggregation built-in (which is often the simplest solution). + +The request/reply mode refers to the fact that the response message, is tied synchronously +to the incoming message (that would wait), until the response message is ready, and then continue being routed. +This allows for xref:requestReply-eip.adoc[Request Reply] messaging style. + +The one-way mode refers to the fact that the response message, is not tied to the incoming message (which will continue). +And the response message (when its ready) will continue being routed independently of the incoming message. +This only allows for xref:event-message.adoc[Event Message] messaging style. + +In the one-way mode, then you combine the xref:recipientList-eip.adoc[Recipient List] and xref:aggregate-eip.adoc[Aggregate] EIPs +together as the Scatter Gather EIP solution. + +== Using Recipient List only + +In the following example we want to call two HTTP services and gather their responses into a single message, +as the response: [source,xml] ---- <routes> <route> - <from uri="direct:start"/> + <from uri="servlet:cheese"/> <recipientList strategyRef="cheeseAggregator"> <constant>http:server1,http:server2</header> </recipientList> - <to uri="mock:result"/> + <to uri="log:response"/> </route> </routes> ---- -The example is kept basic, - -TODO: Simple example -TODO: sync vs async messaging +This is a basic example that only uses basic functionality of the xref:recipientList-eip.adoc[Recipient List]. +For more details how the aggregation works, see the xref:recipientList-eip.adoc[Recipient List] documentation. - -== Using both Recipient List and Aggregator EIP +== Using Recipient List and Aggregate EIP In this example we want to get the best quote for beer from several vendors. @@ -65,7 +82,7 @@ The routes for this are defined as: <correlationExpression> <header>quoteRequestId</header> </correlationExpression> - <to uri="mock:result"/> + <to uri="direct:bestBeer"/> </aggregate> </route> @@ -78,14 +95,14 @@ listOfVendors header for the list of recipients. So, we need to send a message l [source,java] ---- Map<String, Object> headers = new HashMap<>(); -headers.put("listOfVendors", "bean:vendor1, bean:vendor2, bean:vendor3"); +headers.put("listOfVendors", "bean:vendor1,bean:vendor2,bean:vendor3"); headers.put("quoteRequestId", "quoteRequest-1"); template.sendBodyAndHeaders("direct:start", "<quote_request item=\"beer\"/>", headers); ---- This message will be distributed to the following Endpoints: bean:vendor1, bean:vendor2, and bean:vendor3. -These are all beans which look like: +These are all Java beans (called via the Camel xref:components::bean-component.adoc[Bean] endpoint), which look like: [source,java] ---- @@ -110,7 +127,7 @@ public class MyVendor { } ---- -And are loaded up in XML like: +And are loaded up in XML like this: [source,xml] ---- @@ -168,3 +185,15 @@ public class LowestQuoteAggregationStrategy implements AggregationStrategy { } ---- +And finally the aggregator will assemble the response message with the best beer price (the lowest). +Notice how the aggregator has timeout built-in, meaning that if one or more of the beer vendors does +not respond, then the aggregator will discard those _late_ responses, and send out a message with the _best price so far_. + +The message is then continued to another route via the `direct:bestBeer` endpoint. + +== See Also + +The Scatter Gather EIP is a composite pattern that is built by exiting EIPs: + +- xref:recipientList-eip.adoc[Recipient List] +- xref:aggregate-eip.adoc[Aggregate] diff --git a/core/camel-core-engine/src/main/docs/modules/eips/pages/script-eip.adoc b/core/camel-core-engine/src/main/docs/modules/eips/pages/script-eip.adoc index 0fc348a..550e3ca 100644 --- a/core/camel-core-engine/src/main/docs/modules/eips/pages/script-eip.adoc +++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/script-eip.adoc @@ -1,16 +1,18 @@ = Script EIP :doctitle: Script :shortname: script -:description: Executes a script from a language which does not change the message body. +:d<scription: Executes a script from a language which does not change the message body. :since: :supportlevel: Stable -Is used to execute a script which does not change the message (by default). +The Script EIP is used for executing a coding script. + +image::eip/MessagingGatewayIcon.gif[image] + This is useful when you need to invoke some logic that are not in Java code such as JavaScript, -Groovy or any of the other Languages. The message body is not changed (by default) however the scripting -context has access to the current Exchange and can essentially change the message or headers directly. -But the return value from the script is discarded and not used. -If the return value should be used as a changed message body then use xref:message-translator.adoc[Message Translator] EIP instead. +Groovy or any of the other Languages. + +NOTE: The returned value from the script is discarded and not used. If the returned value should be set as the new message body, then use the xref:message-translator.adoc[Message Translator] EIP instead. == Options @@ -18,32 +20,31 @@ If the return value should be used as a changed message body then use xref:messa include::partial$eip-options.adoc[] // eip options: END -== Samples -The route below will read the file contents and validate them against a regular expression. +== Using Script EIP + +The route below will read the file contents and call a groovy script [source,java] ---- -from("file://inbox") - .script().groovy("// some groovy code goes here") - .to("bean:MyServiceBean.processLine"); +from("file:inbox") + .script().groovy("some groovy code goes here") + .to("bean:myServiceBean.processLine"); ---- -And from XML its easy as well +And from XML: [source,xml] ---- <route> - <from uri="file://inbox"/> + <from uri="file:inbox"/> <script> - <groovy>// some groovy code goes here</groovy> + <groovy>some groovy code goes here</groovy> </script> - <beanRef ref="myServiceBean" method="processLine"/> + <to uri="bean:myServiceBean.processLine"/> </route> - -<bean id="myServiceBean" class="com.mycompany.MyServiceBean"/> ---- -Mind that you can use _CDATA_ in XML if the groovy scrip uses `< >` etc +Mind that you can use _CDATA_ in XML if the script uses `< >` etc: [source,xml] ---- @@ -52,27 +53,28 @@ Mind that you can use _CDATA_ in XML if the groovy scrip uses `< >` etc <script> <groovy><![CDATA[ some groovy script here that can be multiple lines and whatnot ]]></groovy> </script> - <beanRef ref="myServiceBean" method="processLine"/> + <to uri="bean:myServiceBean.processLine"/> </route> - -<bean id="myServiceBean" class="com.mycompany.MyServiceBean"/> ---- -== Using external script files +=== Scripting Context + +The scripting context has access to the current `Exchange` and can essentially change the message or headers directly. + +=== Using external script files + You can refer to external script files instead of inlining the script. For example to load a groovy script from the classpath you need to prefix the value with `resource:` as shown: [source,xml] ---- <route> - <from uri="file://inbox"/> + <from uri="file:inbox"/> <script> <groovy>resource:classpath:com/foo/myscript.groovy</groovy> </script> - <beanRef ref="myServiceBean" method="processLine"/> + <to uri="bean:myServiceBean.processLine"/> </route> - -<bean id="myServiceBean" class="com.mycompany.MyServiceBean"/> ---- You can also refer to the script from the file system with `file:` instead of `classpath:`