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 50c67a6  CAMEL-14191: EIP docs - Add links to last EIP patterns and 
add new pages if missing content
50c67a6 is described below

commit 50c67a6975ebe2eb311400b5f408bc314eb33624
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Wed Nov 20 08:29:24 2019 +0100

    CAMEL-14191: EIP docs - Add links to last EIP patterns and add new pages if 
missing content
---
 .../ROOT/assets/images/eip/CompetingConsumers.gif  | Bin 0 -> 4759 bytes
 .../ROOT/assets/images/eip/MessageDispatcher.gif   | Bin 0 -> 5128 bytes
 .../assets/images/eip/MessageSelectorSolution.gif  | Bin 0 -> 2987 bytes
 .../images/eip/MessagingMapperClassDiagram.gif     | Bin 0 -> 2019 bytes
 .../modules/ROOT/pages/competing-consumers.adoc    | 105 +++++++++++++++++++++
 .../pages/enterprise-integration-patterns.adoc     |   8 +-
 .../modules/ROOT/pages/message-dispatcher.adoc     |  15 +++
 .../modules/ROOT/pages/messaging-mapper.adoc       |  24 +++++
 .../modules/ROOT/pages/selective-consumer.adoc     |  46 +++++++++
 9 files changed, 194 insertions(+), 4 deletions(-)

diff --git 
a/docs/user-manual/modules/ROOT/assets/images/eip/CompetingConsumers.gif 
b/docs/user-manual/modules/ROOT/assets/images/eip/CompetingConsumers.gif
new file mode 100644
index 0000000..5d9c730
Binary files /dev/null and 
b/docs/user-manual/modules/ROOT/assets/images/eip/CompetingConsumers.gif differ
diff --git 
a/docs/user-manual/modules/ROOT/assets/images/eip/MessageDispatcher.gif 
b/docs/user-manual/modules/ROOT/assets/images/eip/MessageDispatcher.gif
new file mode 100644
index 0000000..ae27b08
Binary files /dev/null and 
b/docs/user-manual/modules/ROOT/assets/images/eip/MessageDispatcher.gif differ
diff --git 
a/docs/user-manual/modules/ROOT/assets/images/eip/MessageSelectorSolution.gif 
b/docs/user-manual/modules/ROOT/assets/images/eip/MessageSelectorSolution.gif
new file mode 100644
index 0000000..58447a3
Binary files /dev/null and 
b/docs/user-manual/modules/ROOT/assets/images/eip/MessageSelectorSolution.gif 
differ
diff --git 
a/docs/user-manual/modules/ROOT/assets/images/eip/MessagingMapperClassDiagram.gif
 
b/docs/user-manual/modules/ROOT/assets/images/eip/MessagingMapperClassDiagram.gif
new file mode 100644
index 0000000..00e0b18
Binary files /dev/null and 
b/docs/user-manual/modules/ROOT/assets/images/eip/MessagingMapperClassDiagram.gif
 differ
diff --git a/docs/user-manual/modules/ROOT/pages/competing-consumers.adoc 
b/docs/user-manual/modules/ROOT/pages/competing-consumers.adoc
new file mode 100644
index 0000000..845b39e
--- /dev/null
+++ b/docs/user-manual/modules/ROOT/pages/competing-consumers.adoc
@@ -0,0 +1,105 @@
+[[Competing-Consumers]]
+= Competing Consumers
+
+Camel supports the
+https://www.enterpriseintegrationpatterns.com/patterns/messaging/CompetingConsumers.html[Competing
 Consumers]
+from the xref:enterprise-integration-patterns.adoc[EIP patterns] book.
+
+Camel supports the Competing Consumers from the EIP patterns directly from 
components that can do this.
+For example from SEDA, JMS, Kafka, and various AWS components.
+
+image::eip/CompetingConsumers.gif[image]
+
+- SEDA for SEDA based concurrent processing using a thread pool
+- JMS for distributed SEDA based concurrent processing with queues which 
support reliable load balancing, failover and clustering.
+
+For components which does not allow concurrent consumers, then Camel allows to 
route from the consumer
+to a thread-pool which can then further process the message concurrently,
+which then simulates a _quasi like_ competing consumers.
+
+== Competing Consumers with JMS
+
+To enable Competing Consumers you just need to set the `concurrentConsumers` 
property on the JMS endpoint.
+
+For example
+
+[source,java]
+----
+from("jms:MyQueue?concurrentConsumers=5")
+  .to("bean:someBean");
+----
+
+or in XML DSL
+
+[source,xml]
+----
+<route>
+  <from uri="jms:MyQueue?concurrentConsumers=5"/>
+  <to uri="bean:someBean"/>
+</route>
+----
+
+== Competing Consumers with Thread Pool
+
+You can simulate competing consumers by using a thread pool which then 
continue processing the messages concurrently.
+Then the single thread consumer can quickly continue and pickup new messages 
to process and offload them to the thread-pool
+(and its task queue).
+
+Suppose we have this simple route where we poll a folder for new files,
+process the files and afterwards move the files to a backup folder when 
complete.
+
+[source,java]
+----
+from("file://inbox?move=../backup-${date:now:yyyyMMdd}")
+  .to("bean:calculateBean");
+----
+
+The route is synchronous and there is only a single consumer running at any 
given time.
+This scenario is well known and it doesn't affect thread safety as we only 
have one active thread
+involved at any given time.
+
+Now imagine that the inbox folder is filled with filers quicker than we can 
process.
+So we want to speed up this process. How can we do this?
+
+Well we could try adding a 2nd route with the same route path.
+Well that doesn't work so well as we have competing consumers for the same 
files.
+That requires however that we use file locking so we wont have two consumers 
compete for the same file.
+By default Camel support this with its file locking option on the file 
component.
+
+But what if the component doesn't support this, or its not possible to add a 
2nd consumer
+for the same endpoint? And yes its a bit of a hack and the route logic code is 
duplicated.
+And what if we need more, then we need to add a 3rd, a 4th and so on.
+
+What if the processing of the file itself is the bottleneck? That is the 
calculateBean is slow.
+So how can we process messages with this bean concurrently?
+
+Yeah we can use the xref:threads-eip.adoc[Threads EIP], so if we insert it in 
the route we get:
+
+[source,java]
+----
+from("file://inbox?move=../backup-${date:now:yyyyMMdd}")
+  .threads(10)
+  .to("bean:calculateBean");
+----
+
+So by inserting `threads(10)` we have instructed Camel that from this point 
forward in the route
+it should use a thread pool with up till 10 concurrent threads.
+So when the file consumer delivers a message to the threads, then the threads 
take it from there
+and the file consumer can return and continue to poll the next file.
+
+By leveraging this fact we can still use a single file consumer to poll new 
files.
+And polling a directory to just grab the file handle is very fast.
+And we wont have problem with file locking, sorting, filtering and whatnot.
+And at the same time we can leverage the fact that we can process the file 
messages concurrently
+by the calculate bean.
+
+Here at the end lets take a closer look what happens with the synchronous 
thread and the
+asynchronous thread. The synchronous thread hands over the exchange to the new 
asynchronous thread and as
+such the synchronous thread completes. The asynchronous thread is then routing 
and processing the message.
+And when this thread finishes it will take care of the file completion 
strategy to move the file
+into the backup folder. This is an important note, that the on completion is 
done by the asynchronous thread.
+
+This ensures the file is not moved before the file is processed successfully. 
Suppose the calculate bean
+could not process one of the files. If it was the asynchronous thread that 
should do the on completion strategy
+then the file would have been moved to early into the backup folder. By 
handing over this to the asynchronous
+thread we do it after we have processed the message completely
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 776988d..5b897da 100644
--- a/docs/user-manual/modules/ROOT/pages/enterprise-integration-patterns.adoc
+++ b/docs/user-manual/modules/ROOT/pages/enterprise-integration-patterns.adoc
@@ -220,7 +220,7 @@ semantically equivalent, but arrive in a different format?
 [width="100%",cols="10%,10%,80%",]
 |=======================================================================
 |
-|Messaging Mapper |How do you move data
+|xref:messaging-mapper.adoc[Messaging Mapper] |How do you move data
 between domain objects and the messaging infrastructure while keeping
 the two independent of each other?
 
@@ -233,15 +233,15 @@ a|image::eip/PollingConsumerIcon.gif[image]
 consume a message when the application is ready?
 
 a|image::eip/CompetingConsumersIcon.gif[image]
-|Competing Consumers |How can a messaging
+|xref:competing-consumers.adoc[Competing Consumers] |How can a messaging
 client process multiple messages concurrently?
 
 a|image::eip/MessageDispatcherIcon.gif[image]
-|Message Dispatcher |How can multiple
+|xref:message-dispatcher.adoc[Message Dispatcher] |How can multiple
 consumers on a single channel coordinate their message processing?
 
 a|image::eip/MessageSelectorIcon.gif[image]
-|Selective Consumer |How can a message
+|xref:selective-consumer.adoc[Selective Consumer] |How can a message
 consumer select which messages it wishes to receive?
 
 a|image::eip/DurableSubscriptionIcon.gif[image]
diff --git a/docs/user-manual/modules/ROOT/pages/message-dispatcher.adoc 
b/docs/user-manual/modules/ROOT/pages/message-dispatcher.adoc
new file mode 100644
index 0000000..c858e0a
--- /dev/null
+++ b/docs/user-manual/modules/ROOT/pages/message-dispatcher.adoc
@@ -0,0 +1,15 @@
+[[Message-Dispatcher]]
+= Message Dispatcher
+
+Camel supports the
+https://www.enterpriseintegrationpatterns.com/patterns/messaging/MessageDispatcher.html[Message
 Dispatcher]
+from the xref:enterprise-integration-patterns.adoc[EIP patterns] book.
+
+Camel supports the Message Dispatcher from the EIP patterns using various 
approaches.
+
+image::eip/MessageDispatcher.gif[image]
+
+You can use a component like JMS with selectors to implement a 
xref:selective-consumer.adoc[Selective Consumer]
+as the Message Dispatcher implementation. Or you can use an 
xref:message-endpoint.adoc[Message Endpoint]
+as the Message Dispatcher itself and then use a 
xref:content-based-router-eip.adoc[Content Based Router]
+as the Message Dispatcher.
diff --git a/docs/user-manual/modules/ROOT/pages/messaging-mapper.adoc 
b/docs/user-manual/modules/ROOT/pages/messaging-mapper.adoc
new file mode 100644
index 0000000..ec53021
--- /dev/null
+++ b/docs/user-manual/modules/ROOT/pages/messaging-mapper.adoc
@@ -0,0 +1,24 @@
+[[Messaging-Mapper]]
+= Messaging Mapper
+
+Camel supports the
+https://www.enterpriseintegrationpatterns.com/patterns/messaging/MessagingMapper.html[Messaging
 Mapper]
+from the xref:enterprise-integration-patterns.adoc[EIP patterns] book.
+
+How do you move data between domain objects and the messaging infrastructure 
while keeping the two independent of each other?
+
+image::eip/MessagingMapperClassDiagram.gif[image]
+
+Create a separate Messaging Mapper that contains the mapping logic between the 
messaging infrastructure and the domain objects.
+Neither the objects nor the infrastructure have knowledge of the Messaging 
Mapper's existence.
+
+The Messaging Mapper accesses one or more domain objects and converts them 
into a message as required by the messaging channel.
+It also performs the opposite function, creating or updating domain objects 
based on incoming messages.
+Since the Messaging Mapper is implemented as a separate class that references 
the domain object(s)
+and the messaging layer, neither layer is aware of the other. The layers don't 
even know about the Messaging Mapper.
+
+With Camel this pattern is often implemented directly via Camel components 
that provides
+xref:type-converter[Type Converter]'s from the messaging infrastructure to 
common Java types or
+Java Objects representing the data model of the component in question. 
Combining this with the
+xref:message-translator.adoc[Message Translator] to have the Messaging Mapper 
EIP pattern.
+
diff --git a/docs/user-manual/modules/ROOT/pages/selective-consumer.adoc 
b/docs/user-manual/modules/ROOT/pages/selective-consumer.adoc
new file mode 100644
index 0000000..a1f8c5f
--- /dev/null
+++ b/docs/user-manual/modules/ROOT/pages/selective-consumer.adoc
@@ -0,0 +1,46 @@
+[[Selective-Consumer]]
+= Selective Consumer
+
+Camel supports the
+https://www.enterpriseintegrationpatterns.com/patterns/messaging/MessageSelector.html[Selective
 Consumer]
+from the xref:enterprise-integration-patterns.adoc[EIP patterns] book.
+
+The Selective Consumer from the EIP patterns can be implemented in two ways
+
+image::eip/MessageSelectorSolution.gif[image]
+
+== Selective Consumer using Components
+
+The first solution is to provide a Message Selector to the underlying URIs 
when creating your consumer.
+For example when using JMS you can specify a selector parameter so that the 
message broker will only deliver messages matching your criteria.
+
+[source,java]
+----
+from("activemq:queue:hello?selector=color='red'")
+  .to("bean:red");
+----
+
+== Selective Consumer using Filter pattern
+
+The other approach is to use a xref:filter-eip.adoc[Message Filter] which is 
applied;
+then if the filter matches the message your consumer is invoked as shown in 
the following example.
+
+[source,java]
+----
+from("seda:a")
+    .filter(header("foo").isEqualTo("bar"))
+        .process(myProcessor);
+----
+
+And in XML
+
+[source,xml]
+----
+<route>
+    <from uri="seda:a"/>
+    <filter>
+        <simple>${header.foo} == 'bar'</xpath>
+        <process ref="myProcessor"/>
+    </filter>
+</route>
+----
\ No newline at end of file

Reply via email to