In this article we will learn how to route JMS messages to IBM MQ broker using a Camel Route.
IBM MQ provides these messaging and queuing capabilities across multiple modes of operation: point-to-point ; publish/subscribe. You can easily integrate with this messaging provider by using the camel JMSComponent by setting the MQQueueConnectionFactory properties either in configuration or using Java DSL.
Let’s check how to write a Java DSL class which defines the JmsComponent named “mq” which takes the MQQueueConnectionFactory from Class variable:
import org.apache.camel.component.jms.JmsComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.connection.JmsTransactionManager;
import org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import com.ibm.msg.client.wmq.WMQConstants;
@Configuration
@EnableTransactionManagement
public class JmsConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(JmsConfiguration.class);
private String host = "localhost";
private int port = 1414;
private String queueManager = "QM1";
private String channel = "DEV.APP.SVRCONN";
private String username = "app";
private String password = "";
private long receiveTimeout = 2000;
@Bean
public JmsComponent mq() {
JmsComponent jmsComponent = new JmsComponent();
jmsComponent.setConnectionFactory(mqQueueConnectionFactory());
return jmsComponent;
}
@Bean
public MQQueueConnectionFactory mqQueueConnectionFactory() {
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
mqQueueConnectionFactory.setHostName(host);
try {
mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
mqQueueConnectionFactory.setChannel(channel);
mqQueueConnectionFactory.setPort(port);
mqQueueConnectionFactory.setQueueManager(queueManager);
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
return mqQueueConnectionFactory;
}
@Bean
public UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter(
MQQueueConnectionFactory mqQueueConnectionFactory) {
UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter =
new UserCredentialsConnectionFactoryAdapter();
userCredentialsConnectionFactoryAdapter.setUsername(username);
userCredentialsConnectionFactoryAdapter.setPassword(password);
userCredentialsConnectionFactoryAdapter.setTargetConnectionFactory(mqQueueConnectionFactory);
return userCredentialsConnectionFactoryAdapter;
}
@Bean
@Primary
public CachingConnectionFactory cachingConnectionFactory(
UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter) {
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
cachingConnectionFactory.setTargetConnectionFactory(userCredentialsConnectionFactoryAdapter);
cachingConnectionFactory.setSessionCacheSize(500);
cachingConnectionFactory.setReconnectOnException(true);
return cachingConnectionFactory;
}
@Bean
public PlatformTransactionManager jmsTransactionManager(
CachingConnectionFactory cachingConnectionFactory) {
JmsTransactionManager jmsTransactionManager = new JmsTransactionManager();
jmsTransactionManager.setConnectionFactory(cachingConnectionFactory);
return jmsTransactionManager;
}
}
In order to use the JMSComponent, you can implement a simple Route like this:
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
@Component
public class CamelRouteBuilder extends RouteBuilder {
public void configure() throws Exception {
from("timer:mytimer?period=5000")
.routeId("generate-route")
.transform(constant("HELLO from Camel!"))
.to("mq:queue:DEV.QUEUE.1");
}
}
In order to use the JMSComponent with IBM MQ, you need to add both dependencies to your project:
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jms</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.1.0.5</version>
</dependency>
On the other hand, if you prefer, you can stick to Spring XML configuration to define your IBM MQ Connection Factory and Route:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route id="timer">
<from uri="timer://foo?fixedRate=true&period=10000"/>
<setBody>
<simple>${date:now:yyyy-MM-dd'T'HH:mm:ss}</simple>
</setBody>
<log message="SENDING MESSAGE"/>
<to uri="mq:queue:DEV.QUEUE.1"/>
<log message="SENT MESSAGE"/>
</route>
<route id="get">
<from uri="mq:queue:DEV.QUEUE.1"/>
<log message="GOT MESSAGE with headers: ${in.headers}"/>
<log message="GOT MESSAGE with Body ${in.body}"/>
</route>
</camelContext>
<bean id="mqConnectionFactory" class="com.ibm.mq.jms.MQConnectionFactory">
<property name="hostName" value="localhost"/>
<property name="port" value="1414"/>
<property name="queueManager" value="QM1"/>
<property name="channel" value="DEV.APP.SVRCONN"/>
<property name="transportType" value="1"/>
<property name="shareConvAllowed" value="0"/>
</bean>
<bean id="mqcredential" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="targetConnectionFactory" ref="mqConnectionFactory"/>
<property name="username" value="app"/>
<property name="password" value=""/>
</bean>
<bean id="mq" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="mqcredential"/>
<property name="maxConcurrentConsumers" value="1"/>
<property name="cacheLevelName" value="CACHE_CONSUMER"/>
</bean>
</beans>
Found the article helpful? if so please follow us on Socials