How to use multiple JMSComponent in Camel to integrate Routes with different brokers

In this article we will learn how to use multiple Camel JMSComponent objects to bridge messages between two brokers.

In order to perform integration between two different brokers with Camel, you need to define multiple JMSComponent objects: just add 2 methods and give each method a different name, the name of the method is the bean id by default in spring when using @Bean. For example, in this @Configuration class we are defining a JMSComponent (named “activemq”) to integrate with Artemis MQ and another named “wmq” to integrate with IBM MQ:

import com.ibm.mq.jms.*;
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.apache.camel.component.jms.JmsComponent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter;
@Configuration public class AppConfig {
  @Bean public JmsComponent activemq() throws Exception {

    // Create the connectionfactory which will be used to connect to Artemis         

    ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory();
    cf.setBrokerURL("tcp://localhost:61616");
    cf.setUser("admin");
    cf.setPassword("admin");

    // Create the Camel JMS component and wire it to our Artemis connectionfactory         

    JmsComponent jms = new JmsComponent();
    jms.setConnectionFactory(cf);
    return jms;
  }
  @Bean public JmsComponent wmq() {
    JmsComponent jmsComponent = new JmsComponent();
    jmsComponent.setConnectionFactory(mqQueueConnectionFactory());
    return jmsComponent;
  }
  @Bean public MQQueueConnectionFactory mqQueueConnectionFactory() {
    MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
    mqQueueConnectionFactory.setHostName("localhost");
    try {
      mqQueueConnectionFactory.setTransportType(1);
      mqQueueConnectionFactory.setChannel("EXTAPP.SRVCONN");
      mqQueueConnectionFactory.setPort(1414);
      mqQueueConnectionFactory.setQueueManager("QMGRSCORE");
    } catch (Exception e) {
      e.printStackTrace();
    }
    return mqQueueConnectionFactory;
  }
  @Bean public UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter(MQQueueConnectionFactory mqQueueConnectionFactory) {
    UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter = new UserCredentialsConnectionFactoryAdapter();
    userCredentialsConnectionFactoryAdapter.setUsername("username");
    userCredentialsConnectionFactoryAdapter.setPassword("password");
    userCredentialsConnectionFactoryAdapter.setTargetConnectionFactory(mqQueueConnectionFactory);
    return userCredentialsConnectionFactoryAdapter;
  }
}

Also, please note that also @Bean has an id/name attribute you can set also instead of using the method name. With the above JMSComponent objects, you can now reference them in your Routes as in the following example:

package com.sample;

import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;

@Component
public class CamelArtemisRouteBuilder extends RouteBuilder {
  public void configure() throws Exception {
    from("timer:mytimer?period=5000")
        .routeId("generate-route")
        .transform(constant("HELLO from Camel!"))
        .to("activemq:queue:QueueIN");
    from("activemq:queue:QueueIN")
        .routeId("receive-route")
        .log("Received a message - ${body} - sending to outbound queue")
        .to("wmq:queue:QueueOUT?exchangePattern=InOnly");
  }
}