This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new 1e793ef CAMEL-14191: EIP docs - Add links to last EIP patterns and add new pages if missing content 1e793ef is described below commit 1e793ef2efefa88089b2446de77ed50a3737d516 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Wed Nov 20 06:50:33 2019 +0100 CAMEL-14191: EIP docs - Add links to last EIP patterns and add new pages if missing content --- .../ROOT/assets/images/eip/BroadcastAggregate.gif | Bin 0 -> 4005 bytes .../ROOT/pages/composed-message-processor.adoc | 6 +- .../pages/enterprise-integration-patterns.adoc | 22 ++-- .../modules/ROOT/pages/getting-started.adoc | 35 ++---- .../modules/ROOT/pages/scatter-gather.adoc | 136 +++++++++++++++++++++ 5 files changed, 162 insertions(+), 37 deletions(-) diff --git a/docs/user-manual/modules/ROOT/assets/images/eip/BroadcastAggregate.gif b/docs/user-manual/modules/ROOT/assets/images/eip/BroadcastAggregate.gif new file mode 100644 index 0000000..9387cc4 Binary files /dev/null and b/docs/user-manual/modules/ROOT/assets/images/eip/BroadcastAggregate.gif differ diff --git a/docs/user-manual/modules/ROOT/pages/composed-message-processor.adoc b/docs/user-manual/modules/ROOT/pages/composed-message-processor.adoc index 15c17b9..7571b58 100644 --- a/docs/user-manual/modules/ROOT/pages/composed-message-processor.adoc +++ b/docs/user-manual/modules/ROOT/pages/composed-message-processor.adoc @@ -1,9 +1,9 @@ [[Composed-Message-Processor]] = Composed Message Processor -The -http://www.enterpriseintegrationpatterns.com/MessageRouter.html[Composed -Message Processor] from the xref:enterprise-integration-patterns.adoc[EIP patterns] +Camel supports the +https://www.enterpriseintegrationpatterns.com/patterns/messaging/DistributionAggregate.html[Composed Message Processor] +from the xref:enterprise-integration-patterns.adoc[EIP patterns] book. How can you maintain the overall message flow when processing a message consisting of multiple elements, each of which may require different processing? diff --git a/docs/user-manual/modules/ROOT/pages/enterprise-integration-patterns.adoc b/docs/user-manual/modules/ROOT/pages/enterprise-integration-patterns.adoc index 9046138..393abf5 100644 --- a/docs/user-manual/modules/ROOT/pages/enterprise-integration-patterns.adoc +++ b/docs/user-manual/modules/ROOT/pages/enterprise-integration-patterns.adoc @@ -5,10 +5,8 @@ Camel supports most of the http://www.eaipatterns.com/toc.html[Enterprise Integration Patterns] from the excellent book by Gregor Hohpe and Bobby Woolf. -If you are new to Camel you might want to try the -Getting Started in the -User Guide before attempting to implement these -patterns. +If you are new to Camel you might want to try the xref:getting-started[Getting Started] in the +User Guide before attempting to implement these patterns. [[EnterpriseIntegrationPatterns-MessagingSystems]] == Messaging Systems @@ -139,7 +137,7 @@ consisting of multiple elements, each of which may require different processing? | -|Scatter-Gather |How do you maintain the +|xref:scatter-gather.adoc[Scatter-Gather] |How do you maintain the overall message flow when a message needs to be sent to multiple recipients, each of which may send a reply? @@ -302,11 +300,11 @@ analyze and debug the flow of messages in a loosely coupled system? === EIP Icons The EIP icons library is available as a Visio stencil file adapted to -render the icons with the Camel color : sand. Download it +render the icons with the Camel color. Download it link:{attachmentsdir}/Hohpe_EIP_camel_20150622.zip[here] -for your presentation, functional and technical analysis documents. The -original EIP stencil is also available in -link:{attachmentsdir}/Hohpe_EIP_camel_OpenOffice.zip[OpenOffice -3.x Draw] (thanks to Marco Garbelini) , -http://www.eaipatterns.com/download/EIP_Visio_stencil.zip[Microsoft -Visio], or http://www.graffletopia.com/stencils/137[Omnigraffle]. +for your presentation, functional and technical analysis documents. + +The original EIP stencil is also available in +link:{attachmentsdir}/Hohpe_EIP_camel_OpenOffice.zip[OpenOffice 3.x Draw], +http://www.eaipatterns.com/download/EIP_Visio_stencil.zip[Microsoft Visio], +or http://www.graffletopia.com/stencils/137[Omnigraffle]. diff --git a/docs/user-manual/modules/ROOT/pages/getting-started.adoc b/docs/user-manual/modules/ROOT/pages/getting-started.adoc index 92cf3ce..53e0a03 100644 --- a/docs/user-manual/modules/ROOT/pages/getting-started.adoc +++ b/docs/user-manual/modules/ROOT/pages/getting-started.adoc @@ -9,34 +9,25 @@ Then come back here and you might want to read the following documentation before continuing: * Longer Getting Started Guide -* Find out about xref:enterprise-integration-patterns.adoc[Enterprise -Integration Patterns] and how to implement them with Camel -* Review the Architecture guide to see how to -build Routes using the Java DSL or -Spring based xref:xml-configuration.adoc[Xml -Configuration] +* Find out about xref:enterprise-integration-patterns.adoc[Enterprise Integration Patterns] + and how to implement them with Camel +* Review the Architecture guide to see how to build Routes using the xref:java-dsl[Java DSL] + or xref:xml-configuration.adoc[XML DSL] [[GettingStarted-WorkingwithCamelContextsandRouteBuilders]] == Working with CamelContexts and RouteBuilders To get started with Camel: -1. Create a CamelContext. -2. Optionally, xref:configuring-camel.adoc[configure components or -endpoints]. -3. Add whatever routing rules you wish using the DSL and -RouteBuilder or using -XML Configuration. -4. Start the context. - -When your application is closing you may wish to -stop the context - -When you are ready, why not xref:walk-through-an-example.adoc[Walk -through an Example]? + - And then continue the walk xref:walk-through-another-example.adoc[Walk -through another example] + - And after the walks head over to the tutorials. +1. Create a `CamelContext`. +2. Optionally, xref:configuring-camel.adoc[configure components or endpoints]. +3. Add whatever routing rules you wish using the DSL and `RouteBuilder` or using XML DSL. +4. Start the Camel context. + +When your application is closing you may wish to stop the context + +When you are ready, why not xref:walk-through-an-example.adoc[Walk through an Example]? +And then continue the walk xref:walk-through-another-example.adoc[Walk through another example]. [[GettingStarted-WorkingwithSpring]] == Working with Spring diff --git a/docs/user-manual/modules/ROOT/pages/scatter-gather.adoc b/docs/user-manual/modules/ROOT/pages/scatter-gather.adoc new file mode 100644 index 0000000..3cb5d30 --- /dev/null +++ b/docs/user-manual/modules/ROOT/pages/scatter-gather.adoc @@ -0,0 +1,136 @@ +[[Scatter-Gather]] += Scatter Gather + +Camel supports the +https://www.enterpriseintegrationpatterns.com/patterns/messaging/BroadcastAggregate.html[Scatter Gather] +from the xref:enterprise-integration-patterns.adoc[EIP patterns] book. + +The Scatter Gather from the EIP patterns allows you to route messages to a number of dynamically +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] +and the xref:aggregate-eip[Aggregate] patterns. + +== Sample + +In this example we want to get the best quote for beer from several different vendors. +We use a dynamic Recipient List to get the request for a quote to all vendors and an Aggregator +to pick the best quote out of all the responses. The routes for this are defined as: + +[source,xml] +---- +<camelContext xmlns="http://camel.apache.org/schema/spring"> + <route> + <from uri="direct:start"/> + <recipientList> + <header>listOfVendors</header> + </recipientList> + </route> + + <route> + <from uri="seda:quoteAggregator"/> + <aggregate strategyRef="aggregatorStrategy" completionTimeout="1000"> + <correlationExpression> + <header>quoteRequestId</header> + </correlationExpression> + <to uri="mock:result"/> + </aggregate> + </route> +</camelContext> +---- + +So in the first route you see that the Recipient List is looking at the listOfVendors header +for the list of recipients. So, we need to send a message like + +[source,java] +---- +Map<String, Object> headers = new HashMap<>(); +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: + +[source,java] +---- +public class MyVendor { + private int beerPrice; + + @Produce("seda:quoteAggregator") + private ProducerTemplate quoteAggregator; + + public MyVendor(int beerPrice) { + this.beerPrice = beerPrice; + } + + public void quote(@XPath("/quote_request/@item") String item, Exchange exchange) { + if ("beer".equals(item)) { + exchange.getIn().setBody(beerPrice); + quoteAggregator.send(exchange); + } else { + // ignore no quote + } + } +} +---- + +And are loaded up in Spring XML like: + +[source,xml] +---- +<bean id="aggregatorStrategy" class="org.apache.camel.spring.processor.scattergather.LowestQuoteAggregationStrategy"/> + +<bean id="vendor1" class="org.apache.camel.spring.processor.scattergather.MyVendor"> + <constructor-arg> + <value>1</value> + </constructor-arg> +</bean> + +<bean id="vendor2" class="org.apache.camel.spring.processor.scattergather.MyVendor"> + <constructor-arg> + <value>2</value> + </constructor-arg> +</bean> + +<bean id="vendor3" class="org.apache.camel.spring.processor.scattergather.MyVendor"> + <constructor-arg> + <value>3</value> + </constructor-arg> +</bean> +---- + +Each bean is loaded with a different price for beer. When the message is sent to each bean endpoint, +it will arrive at the `MyVendor.quote` method. This method does a simple check whether this quote +request is for beer and then sets the price of beer on the exchange for retrieval at a later step. +The message is forwarded on to the next step using POJO Producing (see the `@Produce` annotation). + +At the next step we want to take the beer quotes from all vendors and find out which one was the best +(i.e. the lowest!). To do this we use an Aggregator with a custom aggregation strategy. +The Aggregator needs to be able to compare only the messages from this particular quote; +this is easily done by specifying a correlationExpression equal to the value of the quoteRequestId header. +As shown above in the message sending snippet, we set this header to quoteRequest-1. +This correlation value should be unique or you may include responses that are not part of this quote. +To pick the lowest quote out of the set, we use a custom aggregation strategy like + +[source,java] +---- +public class LowestQuoteAggregationStrategy implements AggregationStrategy { + public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { + // the first time we only have the new exchange + if (oldExchange == null) { + return newExchange; + } + + if (oldExchange.getIn().getBody(int.class) < newExchange.getIn().getBody(int.class)) { + return oldExchange; + } else { + return newExchange; + } + } +} +---- +