This post is relevant for developers who are aware of Apache Camel and use its JMS component to consume from a JMS broker. We are only discussing the message consumption part here. I'm assuming you are conversant with Camel's terminology of routes, endpoints, processors and EIPs. If not, following is a good place to start:
Link ---> Apache Camel Home
Ever wondered what happens underneath when a Camel consumer route is defined to take messages from a JMS endpoint ? This post is an attempt to explain how Camel integrates with JMS via Spring APIs and how the business logic defined in a Camel route is invoked ?
Following is a simplified sequence diagram showing the set-up process which will eventually lead to message consumption from JMS broker.
Creation of JMS endpoints in a camel context is initiated by definition (via Java/XML DSL). A JMS endpoint takes a number of configurable attributes as seen here Camel JMS Component.
As soon as context is bootstrapped, if it finds a JMS endpoint defined in a "from" clause, the Camel machinery will try to create a consumer endpoint (JMSEndpoint and JMSConsumer instance) which internally refers to a DefaultMessageListenerContainer instance.
The container IS-A specialization of Spring's well known DefaultMessageListenerContainer. The initialization process also internally installs a javax.jms.MessageListener impl via EndpointMessageListener which comes from Camel API.
EndpointMessageListener is the entry point from where our business route definition will be invoked later on.
Another important thing which happens is the specification of task executor which is a cached thread pool by default. On this pool all the message consumption and "onMessage" call back will happen.
As soon as the JMSConsumer will start (auto start by deafult), it will post N number of AsyncMessageListenerInvoker instances on the task execution pool. These instances are obviously Runnables.
Also N = no. of concurrent consumers which we had specified in endpoint configuration
From here Spring will take over...
AsynMsgListenerInvoker IS-A Runnable which was posted on the task executor. It keeps polling the JMS broker via the message listener container (because container IS-A polling consumer as well, see the 1st diagram).
As soon as a message is received, the EndpointMessageListener is invoked which has a reference to the first Processor in route definition hence triggering the business logic.
We must appreciate the fact that "onMessage" is invoked in a try-catch block which captures all Throwables. That means Spring always has an opportunity to deal with issues which remained un-handled in our business route.
Should there be any exceptions caught by Spring, it will rollback the JMS transaction if session was transacted. In case of no errors, the transaction will be committed. In case of non-transacted sessions, no rollback/commit takes place.
In any case, if there is an error, the "onMessage" handler of EndpointMessageListener will invoke route specific ErrorHandler (in sync or async manner), and will propagate back to Spring which will catch it and deal with it.
This discussion shows the points in time when a JMS commit or rollback actually takes place and how Spring gracefully deals with errors.
Link ---> Apache Camel Home
Ever wondered what happens underneath when a Camel consumer route is defined to take messages from a JMS endpoint ? This post is an attempt to explain how Camel integrates with JMS via Spring APIs and how the business logic defined in a Camel route is invoked ?
Following is a simplified sequence diagram showing the set-up process which will eventually lead to message consumption from JMS broker.
Creation of JMS endpoints in a camel context is initiated by definition (via Java/XML DSL). A JMS endpoint takes a number of configurable attributes as seen here Camel JMS Component.
As soon as context is bootstrapped, if it finds a JMS endpoint defined in a "from" clause, the Camel machinery will try to create a consumer endpoint (JMSEndpoint and JMSConsumer instance) which internally refers to a DefaultMessageListenerContainer instance.
The container IS-A specialization of Spring's well known DefaultMessageListenerContainer. The initialization process also internally installs a javax.jms.MessageListener impl via EndpointMessageListener which comes from Camel API.
EndpointMessageListener is the entry point from where our business route definition will be invoked later on.
Another important thing which happens is the specification of task executor which is a cached thread pool by default. On this pool all the message consumption and "onMessage" call back will happen.
As soon as the JMSConsumer will start (auto start by deafult), it will post N number of AsyncMessageListenerInvoker instances on the task execution pool. These instances are obviously Runnables.
Also N = no. of concurrent consumers which we had specified in endpoint configuration
From here Spring will take over...
AsynMsgListenerInvoker IS-A Runnable which was posted on the task executor. It keeps polling the JMS broker via the message listener container (because container IS-A polling consumer as well, see the 1st diagram).
As soon as a message is received, the EndpointMessageListener is invoked which has a reference to the first Processor in route definition hence triggering the business logic.
We must appreciate the fact that "onMessage" is invoked in a try-catch block which captures all Throwables. That means Spring always has an opportunity to deal with issues which remained un-handled in our business route.
Should there be any exceptions caught by Spring, it will rollback the JMS transaction if session was transacted. In case of no errors, the transaction will be committed. In case of non-transacted sessions, no rollback/commit takes place.
In any case, if there is an error, the "onMessage" handler of EndpointMessageListener will invoke route specific ErrorHandler (in sync or async manner), and will propagate back to Spring which will catch it and deal with it.
This discussion shows the points in time when a JMS commit or rollback actually takes place and how Spring gracefully deals with errors.
Comments
Post a Comment