Pattern Appendix

There now follows a breakdown of the various Enterprise Integration Patterns that Camel supports

Messaging Systems

Message Channel

Camel supports the Message Channel from the EIP patterns. The Message Channel is an internal implementation detail of the Endpoint interface and all interactions with the Message Channel are via the Endpoint interfaces.

For more details see

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Message

Camel supports the Message from the EIP patterns using the Message interface.

To support various message exchange patterns like one way event messages and request-response messages Camel uses an Exchange interface which is used to handle either oneway messages with a single inbound Message, or request-reply where there is an inbound and outbound message.

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Pipes and Filters

Camel supports the Pipes and Filters from the EIP patterns in various ways.

With Camel you can split your processing across multiple independent Endpoint instances which can then be chained together.

Using Routing Logic

You can create pipelines of logic using multiple Endpoint or Message Translator instances as follows

from("direct:a").pipeline("direct:x", "direct:y", "direct:z", "mock:result");

In the above example we are routing from a single Endpoint to a list of different endpoints specified using URIs. If you find the above a bit confusing, try reading about the Architecture or try the Examples

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Message Router

The Message Router from the EIP patterns allows you to consume from an input destination, evaluate some predicate then choose the right output destination.

The following example shows how to route a request from an input queue:a endpoint to either queue:b, queue:c or queue:d depending on the evaluation of various Predicate expressions

Using the Fluent Builders

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        from("queue:a").choice()
                .when(header("foo").isEqualTo("bar")).to("queue:b")
                .when(header("foo").isEqualTo("cheese")).to("queue:c")
                .otherwise().to("queue:d");
    }
};

Using the Spring XML Extensions

<camelContext id="buildSimpleRouteWithChoice" xmlns="http://activemq.apache.org/camel/schema/spring">
   <route>
     <from uri="queue:a"/>
     <choice>
         <when>
             <predicate>
                <header name="foo"/>
                <isEqualTo value="bar"/>
             </predicate>
             <to uri="queue:b"/>
         </when>
         <when>
             <predicate>
                <header name="foo"/>
                <isEqualTo value="cheese"/>
             </predicate>
             <to uri="queue:c"/>
         </when>
         <otherwise>
             <to uri="queue:d"/>
         </otherwise>
     </choice>
   </route>
</camelContext>

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Message Translator

Camel supports the Message Translator from the EIP patterns by using an artibrary Processor in the routing logic

Using the Fluent Builders

from("direct:start").setBody(body().append(" World!")).to("mock:result");

or you can add your own Processor

from("direct:start").process(new Processor() {
    public void process(Exchange exchange) {
        Message in = exchange.getIn();
        in.setBody(in.getBody(String.class) + " World!");
    }
}).to("mock:result");

For further examples of this pattern in use you could look at one of the JUnit tests

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Message Endpoint

Camel supports the Message Endpoint from the EIP patterns using the Endpoint interface.

When using the DSL to create Routes you typically refer to Message Endpoints by their URIs rather than directly using the Endpoint interface. Its then a responsibility of the CamelContext to create and activate the necessary Endpoint instances using the available Component implementations.

For more details see

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Messaging Channels

Point to Point Channel

Camel supports the Point to Point Channel from the EIP patterns using the following components

  • Queue for in-VM seda based messaging
  • JMS for working with JMS Queues for high performance, clustering and load balancing
  • JPA for using a database as a simple message queue
  • XMPP for point-to-point communication over XMPP (Jabber)

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Publish Subscribe Channel

Camel supports the Publish Subscribe Channel from the EIP patterns using the following components

  • JMS for working with JMS Topics for high performance, clustering and load balancing
  • XMPP when using rooms for group communication

Using Routing Logic

Another option is to explicitly list the publish-subscribe relationship in your routing logic; this keeps the producer and consumer decoupled but lets you control the fine grained routing configuration using the DSL or Xml Configuration.

Using the Fluent Builders

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        from("queue:a").to("queue:b", "queue:c", "queue:d");
    }
};

Using the Spring XML Extensions

<camelContext id="buildStaticRecipientList" xmlns="http://activemq.apache.org/camel/schema/spring">
   <route>
     <from uri="queue:a"/>
     <to>
        <uri>queue:b</uri>
        <uri>queue:c</uri>
        <uri>queue:d</uri>
     </to>
   </route>
</camelContext>

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Dead Letter Channel

Camel supports the Dead Letter Channel from the EIP patterns using the DeadLetterChannel processor which is an Error Handler.

Redelivery

It is common for a temporary outage or database deadlock to cause a message to fail to process; but the chances are if its tried a few more times with some time delay then it will complete fine. So we typically wish to use some kind of redelivery policy to decide how many times to try redeliver a message and how long to wait before redelivery attempts.

The RedeliveryPolicy defines how the message is to be redelivered. You can customize things like

  • how many times a message is attempted to be redelivered before it is considered a failure and sent to the dead letter channel
  • the initial redelivery timeout
  • whether or not exponential backoff is used (i.e. the time between retries increases using a backoff multiplier)
  • whether to use collision avoidence to add some randomness to the timings

Once all attempts at redelivering the message fails then the message is forwarded to the dead letter queue.

Redelivery header

When a message is redelivered the DeadLetterChannel will append a customizable header to the message to indicate how many times its been redelivered. The default value is org.apache.camel.redeliveryCount.

Configuring via the DSL

The following example shows how to configure the Dead Letter Channel configuration using the DSL

RouteBuilder<Exchange> builder = new RouteBuilder<Exchange>() {
    public void configure() {
        errorHandler(deadLetterChannel("queue:errors"));

        from("queue:a").to("queue:b");
    }
};

You can also configure the RedeliveryPolicy as this example shows

RouteBuilder<Exchange> builder = new RouteBuilder<Exchange>() {
    public void configure() {
        errorHandler(deadLetterChannel("queue:errors").maximumRedeliveries(2).useExponentialBackOff());

        from("queue:a").to("queue:b");
    }
};

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Guaranteed Delivery

Camel supports the Guaranteed Delivery from the EIP patterns using the following components

  • File for using file systems as a persistent store of messages
  • JMS when using persistent delivery (the default) for working with JMS Queues and Topics for high performance, clustering and load balancing
  • JPA for using a database as a persistence layer

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Message Bus

Camel supports the Message Bus from the EIP patterns. You could view Camel as a Message Bus itself as it allows producers and consumers to be decoupled.

Folks often assume that a Message Bus is a JMS though so you may wish to refer to the JMS component for traditional MOM support.

Also worthy of node is the XMPP component for supporting messaging over XMPP (Jabber)

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Message Routing

Content Based Router

The Content Based Router from the EIP patterns allows you to route messages to the correct destination based on the contents of the message exchanges.

The following example shows how to route a request from an input queue:a endpoint to either queue:b, queue:c or queue:d depending on the evaluation of various Predicate expressions

Using the Fluent Builders

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        from("queue:a").choice()
                .when(header("foo").isEqualTo("bar")).to("queue:b")
                .when(header("foo").isEqualTo("cheese")).to("queue:c")
                .otherwise().to("queue:d");
    }
};

Using the Spring XML Extensions

<camelContext id="buildSimpleRouteWithChoice" xmlns="http://activemq.apache.org/camel/schema/spring">
   <route>
     <from uri="queue:a"/>
     <choice>
         <when>
             <predicate>
                <header name="foo"/>
                <isEqualTo value="bar"/>
             </predicate>
             <to uri="queue:b"/>
         </when>
         <when>
             <predicate>
                <header name="foo"/>
                <isEqualTo value="cheese"/>
             </predicate>
             <to uri="queue:c"/>
         </when>
         <otherwise>
             <to uri="queue:d"/>
         </otherwise>
     </choice>
   </route>
</camelContext>

For further examples of this pattern in use you could look at the junit test case

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Message Filter

The Message Filter from the EIP patterns allows you to filter messages

The following example shows how to create a Message Filter route consuming messages from an endpoint called queue:a which if the Predicate is true will be dispatched to queue:b

Using the Fluent Builders

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        from("queue:a").filter(header("foo").isEqualTo("bar")).to("queue:b");
    }
};

You can of course use many different Predicate languages such as XPath, XQuery, SQL or various Scripting Languages. Here is an XPath example

from("direct:start").filter(
        xpath("/person[@name='James']")
).to("mock:result");

Using the Spring XML Extensions

<camelContext id="buildSimpleRouteWithHeaderPredicate" xmlns="http://activemq.apache.org/camel/schema/spring">
   <route>
     <from uri="queue:a"/>
     <filter>
         <predicate>
            <header name="foo"/>
            <isEqualTo value="bar"/>
         </predicate>
     </filter>
     <to uri="queue:b"/>
   </route>
</camelContext>

For further examples of this pattern in use you could look at the junit test case

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Recipient List

The Recipient List from the EIP patterns allows you to route messages to a number of destinations.

Static Receipient List

The following example shows how to route a request from an input queue:a endpoint to a static list of destinations

Using the Fluent Builders

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        from("queue:a").to("queue:b", "queue:c", "queue:d");
    }
};

Using the Spring XML Extensions

<camelContext id="buildStaticRecipientList" xmlns="http://activemq.apache.org/camel/schema/spring">
   <route>
     <from uri="queue:a"/>
     <to>
        <uri>queue:b</uri>
        <uri>queue:c</uri>
        <uri>queue:d</uri>
     </to>
   </route>
</camelContext>

Dynamic Recipient List

Usually one of the main resons for using the Recipient List pattern is that the list of recipients is dynamic and calculated at runtime. The following example demostrates how to create a dynamic recipient list using an Expression (which in this case it extracts a named header value dynamically) to calculate the list of endpoints which are either of type Endpoint or are converted to a String and then resolved using the endpoint URIs.

Using the Fluent Builders

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        from("queue:a").recipientList(header("foo"));
    }
};

The above assumes that the header contains a list of endpoint URIs. The following takes a single string header and tokenizes it

from("direct:a").recipientList(header("recipientListHeader").tokenize(","));

Using the Spring XML Extensions

<camelContext id="buildDynamicRecipientList" xmlns="http://activemq.apache.org/camel/schema/spring">
   <route>
     <from uri="queue:a"/>
     <recipientList>
     	<recipients>
          <header name="foo"/>
        </recipients>
     </recipientList>
   </route>
</camelContext>

For further examples of this pattern in use you could look at one of the junit test case

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Splitter

The Splitter from the EIP patterns allows you split a message into a number of pieces and process them individually

Example

The following example shows how to take a request from the queue:a endpoint the split it into pieces using an Expression, then forward each piece to queue:b

Using the Fluent Builders

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        from("queue:a").splitter(bodyAs(String.class).tokenize("\n")).to("queue:b");
    }
};

The splitter can use any Expression language so you could use any of the Languages Supported such as XPath, XQuery, SQL or one of the Scripting Languages to perform the split. e.g.

from("activemq:my.queue").splitter(xpath("//foo/bar")).to("file://some/directory")

Using the Spring XML Extensions

<camelContext id="buildSplitter" xmlns="http://activemq.apache.org/camel/schema/spring">
       <route>
         <from uri="queue:a"/>
         <splitter>
         	<recipients>
	            <bodyAs class="java.lang.String"/>
	            <tokenize token="
"/>
         	</recipients>
         </splitter>
         <to uri="queue:b"/>
       </route>
    </camelContext>

For further examples of this pattern in use you could look at one of the junit test case

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Resequencer

The Resequencer from the EIP patterns allows you to reorganise messages based on some comparator. By default in Camel we use an Expression to create the comparator; so that you can compare by a message header or the body or a piece of a message etc.

The following example shows how to reorder the messages so that they are sorted in order of the body() expression. That is messages are collected into a batch (either by a maximum number of messages per batch or using a timeout) then they are sorted in order and then sent out to their output.

Using the Fluent Builders

from("direct:a").resequencer(body()).to("mock:result");

So the above example will reorder messages from endpoint direct:a in order of their bodies, to the endpoint mock:result. Typically you'd use a header rather than the body to order things; or maybe a part of the body. So you could replace this expression with

resequencer(header("JMSPriority"))

for example to reorder messages using their JMS priority.

You can of course use many different Expression languages such as XPath, XQuery, SQL or various Scripting Languages.

You can also use multiple expressions; so you could for example sort by priority first then some other custom header

resequencer(header("JMSPriority"), header("MyCustomerRating"))

Using the Spring XML Extensions

For further examples of this pattern in use you could look at the junit test case

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Message Transformation

Content Enricher

Camel supports the Content Enricher from the EIP patterns using a Message Translator or by using an artibrary Processor in the routing logic to enrich the message.

Using the Fluent Builders

Here is a simple example using the DSL directly

from("direct:start").setBody(body().append(" World!")).to("mock:result");

In this example we add our own Processor

from("direct:start").process(new Processor() {
    public void process(Exchange exchange) {
        Message in = exchange.getIn();
        in.setBody(in.getBody(String.class) + " World!");
    }
}).to("mock:result");

For further examples of this pattern in use you could look at one of the JUnit tests

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Content Filter

Camel supports the Content Filter from the EIP patterns using a Message Translator or by using an artibrary Processor in the routing logic to filter content from the inbound message.

A common way to filter messages is to use an Expression in the DSL like XQuery, SQL or one of the supported Scripting Languages.

Using the Fluent Builders

Here is a simple example using the DSL directly

from("direct:start").setBody(body().append(" World!")).to("mock:result");

In this example we add our own Processor

from("direct:start").process(new Processor() {
    public void process(Exchange exchange) {
        Message in = exchange.getIn();
        in.setBody(in.getBody(String.class) + " World!");
    }
}).to("mock:result");

For further examples of this pattern in use you could look at one of the JUnit tests

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Normalizer

Camel supports the Normalizer from the EIP patterns by using a Message Router in front of a number of Message Translator instances.

See Also

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Messaging Endpoints

Messaging Mapper

Camel supports the Messaging Mapper from the EIP patterns by using either Message Translator pattern or the Type Converter module.

See also

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Event Driven Consumer

Camel supports the Event Driven Consumer from the EIP patterns. The default consumer model is event based (i.e. asynchronous) as this means that the Camel container can then manage pooling, threading and concurrency for you in a declarative manner.

The Event Driven Consumer is implemented by consumers implementing the Processor interface which is invoked by the Message Endpoint when a Message is available for processing.

For more details see

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Polling Consumer

Camel supports implementing the Polling Consumer from the EIP patterns using the PollingConsumer interface which can be created via the Endpoint.createPollingConsumer() method.

So in your Java code you can do

Endpoint endpoint = context.getEndpoint("activemq:my.queue");
PollingConsumer consumer = endpoint.createPollingConsumer();
Exchange exchange = consumer.receive();

There are 3 main polling methods on PollingConsumer

Method name Description
receive() Waits until a message is available and then returns it; potentially blocking forever
receive(long) Attempts to receive a message exchange immediately without waiting and returning null if a message exchange is not available yet
receiveNoWait() Attempts to receive a message exchange, waiting up to the given timeout and returning null if no message exchange could be received within the time available

Scheduled Poll Components

Quite a few inbound Camel endpoints use a scheduled poll pattern to receive messages and push them through the Camel processing routes. That is to say externally from the client the endpoint appears to use an Event Driven Consumer but internally a scheduled poll is used to monitor some kind of state or resource and then fire message exchanges.

Since this a such a common pattern, polling components can extend the ScheduledPollConsumer base class which makes it simpler to implement this pattern.

There is also the Quartz Component which provides scheduled delivery of messages using the Quartz enterprise scheduler.

For more details see

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Competing Consumers

Camel supports the Competing Consumers from the EIP patterns using a few different components.

You can use the following components to implement competing consumers:-

  • Queue 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.

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Message Dispatcher

Camel supports the Message Dispatcher from the EIP patterns using various approaches.

You can use a component like JMS with selectors to implement a Selective Consumer as the Message Dispatcher implementation. Or you can use an Endpoint as the Message Dispatcher itself and then use a Content Based Router as the Message Dispatcher.

See Also

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Selective Consumer

The Selective Consumer from the EIP patterns can be implemented in two ways

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.

The other approach is to use a Message Filter which is applied; then if the filter matches the message your consumer is invoked as shown in the following example

Using the Fluent Builders

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        from("queue:a").filter(header("foo").isEqualTo("bar")).process(myProcessor);
    }
};

Using the Spring XML Extensions

<camelContext id="buildCustomProcessorWithFilter" xmlns="http://activemq.apache.org/camel/schema/spring">
   <route>
     <from uri="queue:a"/>
     <filter>
       <predicate>
         <header name="foo"/>
         <isEqualTo value="bar"/>
       </predicate>
     </filter>
     <process ref="#myProcessor"/>
   </route>
</camelContext>

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Durable Subscriber

Camel supports the Durable Subscriber from the EIP patterns using the JMS component which supports publish & subscribe using Topics with support for non-durable and durable subscribers.

Another alternative is to combine the Message Dispatcher or Content Based Router with File or JPA components for durable subscribers then something like Queue for non-durable.

See Also

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Idempotent Consumer

The Idempotent Consumer from the EIP patterns is used to filter out duplicate messages.

This pattern is implemented using the IdempotentConsumer class. This uses an Expression to calculate a unique message ID string for a given message exchange; this ID can then be looked up in the MessageIdRepository to see if it has been seen before; if it has the message is consumed; if its not then the message is processed and the ID is added to the repository.

The Idempotent Consumer essentially acts like a Message Filter to filter out duplicates.

Using the Fluent Builders

The following example will use the header myMessageId to filter out duplicates

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        from("queue:a").idempotentConsumer(
                header("myMessageId"), memoryMessageIdRepository(200)
        ).to("queue:b");
    }
};

The above example will use an in-memory based MessageIdRepository which can easily run out of memory and doesn't work in a clustered environment. So you might prefer to use the JPA based implementation which uses a database to store the message IDs which have been processed

return new SpringRouteBuilder() {
    public void configure() {
        from("direct:start").idempotentConsumer(
                header("messageId"),
                jpaMessageIdRepository(bean(JpaTemplate.class), "myProcessorName")
        ).to("mock:result");
    }
};

In the above example we are using the header messageId to filter out duplicates and using the collection myProcessorName to indicate the Message ID Repository to use. This name is important as you could process the same message by many different processors; so each may require its own logical Message ID Repository.

Using the Spring XML Extensions

<camelContext id="buildCustomProcessorWithFilter" xmlns="http://activemq.apache.org/camel/schema/spring">
   <route>
     <from uri="queue:a"/>
     <filter>
       <predicate>
         <header name="foo"/>
         <isEqualTo value="bar"/>
       </predicate>
     </filter>
     <process ref="#myProcessor"/>
   </route>
</camelContext>

For further examples of this pattern in use you could look at the junit test case

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Transactional Client

Camel recommends supporting the Transactional Client from the EIP patterns using spring transactions.

Transaction Oriented Endpoints (Camel Toes) like JMS support using a transaction for both inbound and outbound message exchanges. Endpoints that support transactions will participate in the current transaction context that they are called from.

You should use the SpringRouteBuilder to setup the routes since you will need to setup the spring context with the TransactionTemplates that will define the transaction manager configuration and policies.

For inbound endpoint to be transacted, they normally need to be configured to use a Spring PlatformTransactionManager. In the case of the JMS component, this can be done by looking it up in the spring context.

You first define needed object in the spring configuration.

<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
    <property name="connectionFactory" ref="jmsConnectionFactory" />
  </bean>
  
  <bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="tcp://localhost:61616"/>
  </bean>

Then you look them up and use them to create the JmsComponent.

PlatformTransactionManager transactionManager = (PlatformTransactionManager) spring.getBean("jmsTransactionManager");
  ConnectionFactory connectionFactory = (ConnectionFactory) spring.getBean("jmsConnectionFactory");
  JmsComponent component = JmsComponent.jmsComponentTransacted(connectionFactory, transactionManager);
  component.getConfiguration().setConcurrentConsumers(1);
  ctx.addComponent("activemq", component);

Transaction Policies

Outbound endpoints will automatically enlist in the current transaction context. But what if you do not want your outbound endpoint to enlist in the same transaction as your inbound endpoint? The solution is to add a Transaction Policy to the processing route. You first have to define transaction policies that you will be using. The policies use a spring TransactionTemplate to declare the transaction demarcation use. So you will need to add something like the following to your spring xml:

<bean id="PROPAGATION_REQUIRED" class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager" ref="jmsTransactionManager"/>
  </bean>
  
  <bean id="PROPAGATION_NOT_SUPPORTED" class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager" ref="jmsTransactionManager"/>
    <property name="propagationBehaviorName" value="PROPAGATION_NOT_SUPPORTED"/>
  </bean>

  <bean id="PROPAGATION_REQUIRES_NEW" class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager" ref="jmsTransactionManager"/>
    <property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW"/>
  </bean>

Then in your SpringRouteBuilder, you just need to create new SpringTransactionPolicy objects for each of the templates.

public void configure() {
   ...
   Policy requried = new SpringTransactionPolicy(bean(TransactionTemplate.class, "PROPAGATION_REQUIRED"));
   Policy notsupported = new SpringTransactionPolicy(bean(TransactionTemplate.class, "PROPAGATION_NOT_SUPPORTED"));
   Policy requirenew = new SpringTransactionPolicy(bean(TransactionTemplate.class, "PROPAGATION_REQUIRES_NEW"));
   ...
}

Once created, you can use the Policy objects in your processing routes:

// Send to bar in a new transaction
   from("activemq:queue:foo").policy(requirenew).to("activemq:queue:bar");

   // Send to bar without a transaction.
   from("activemq:queue:foo").policy(notsupported ).to("activemq:queue:bar");

See Also

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Messaging Gateway

Camel has several endpoint components that support the Messaging Gateway from the EIP patterns.

Components like Bean, CXF and Pojo provide a a way to bind a Java interface to the message exchange.

See Also

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Service Activator

Camel has several endpoint components that support the Service Activator from the EIP patterns.

Components like Bean, CXF and Pojo provide a a way to bind the message exchange to a Java interface/service.

See Also

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

System Management

Wire Tap

The Wire Tap from the EIP patterns allows you to route messages to a separate tap location before it is forwarded to the ultimate destination.

The following example shows how to route a request from an input queue:a endpoint to the wire tap location queue:tap before it is received by queue:b

Using the Fluent Builders

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        from("queue:a").to("queue:tap", "queue:b");
    }
};

Using the Spring XML Extensions

<camelContext id="buildWireTap" xmlns="http://activemq.apache.org/camel/schema/spring">
   <route>
     <from uri="queue:a"/>
     <to>
        <uri>queue:tap</uri>
        <uri>queue:b</uri>
     </to>
   </route>
</camelContext>

Using This Pattern

If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.

Graphic Design By Hiram