Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot multiple JMS connections

I'm developing Spring Boot application which must connect to several WebSphere JMS connections with different ports or even ip addresses. I need receive and send messages to different queues.

I took example of connection from this source - https://github.com/lzp4ever/IBM_WebSphere_MQ_Spring_Boot_JMS

But when i add second connectionFactory Spring Boot failes to start, it just don't know which once to use.

My question is How should i configure my config file to listen several queues? Is it good idea connecting SpringBoot app to several different JMS servers?

like image 607
lalilulelo_1986 Avatar asked Mar 27 '18 18:03

lalilulelo_1986


1 Answers

Solution

i just copy and paste same beans(like at git link above) second time and add Bean(name) to separate them. It was not work and then i added new JmsListenerContainerFactory bean to each of my config file.

One of my config file is:

@Bean(name = "mqQueueConnectionFactory2")
public MQQueueConnectionFactory mqQueueConnectionFactory2() {
    MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
    mqQueueConnectionFactory.setHostName(host);
    try {
        mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
        mqQueueConnectionFactory.setCCSID(1208);
        mqQueueConnectionFactory.setChannel(channel);
        mqQueueConnectionFactory.setPort(port);
        mqQueueConnectionFactory.setQueueManager(queueManager);
    } catch (Exception e) {
        logger.error("MQQueueConnectionFactory bean exception", e);
    }
    return mqQueueConnectionFactory;
}

@Bean(name = "userCredentialsConnectionFactoryAdapter2")
UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter2(@Qualifier("mqQueueConnectionFactory2") MQQueueConnectionFactory mqQueueConnectionFactory) {
    UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter = new UserCredentialsConnectionFactoryAdapter();
    userCredentialsConnectionFactoryAdapter.setUsername(username);
    userCredentialsConnectionFactoryAdapter.setPassword(password);
    userCredentialsConnectionFactoryAdapter.setTargetConnectionFactory(mqQueueConnectionFactory);
    return userCredentialsConnectionFactoryAdapter;
}

@Bean(name = "cachingConnectionFactory2")
//@Primary
public CachingConnectionFactory cachingConnectionFactory2(@Qualifier("userCredentialsConnectionFactoryAdapter2") UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter) {
    CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
    cachingConnectionFactory.setTargetConnectionFactory(userCredentialsConnectionFactoryAdapter);
    cachingConnectionFactory.setSessionCacheSize(500);
    cachingConnectionFactory.setReconnectOnException(true);
    return cachingConnectionFactory;
}

@Bean(name = "jmsTransactionManager2")
public PlatformTransactionManager jmsTransactionManager2(@Qualifier("cachingConnectionFactory2") CachingConnectionFactory cachingConnectionFactory) {
    JmsTransactionManager jmsTransactionManager = new JmsTransactionManager();
    jmsTransactionManager.setConnectionFactory(cachingConnectionFactory);
    return jmsTransactionManager;
}

@Bean(name = "jmsOperations2")
public JmsOperations jmsOperations2(@Qualifier("cachingConnectionFactory2") CachingConnectionFactory cachingConnectionFactory) {
    JmsTemplate jmsTemplate = new JmsTemplate(cachingConnectionFactory);
    jmsTemplate.setReceiveTimeout(receiveTimeout);
    return jmsTemplate;
}

@Bean
public JmsListenerContainerFactory<?> myFactory2(@Qualifier("cachingConnectionFactory2") CachingConnectionFactory connectionFactory,
                                                 DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    // This provides all boot's default to this factory, including the message converter
    configurer.configure(factory, connectionFactory);
    // You could still override some of Boot's default if necessary.
    return factory;
}

Then i change my sender code from this:

@Autowired
private JmsOperations jmsOperations;

to this

@Autowired
@Qualifier("jmsOperations2")
private JmsOperations jmsOperations;

also i change my receiver to:

@JmsListener(destination = "${project.queues.uzb.recieve}", containerFactory = "myFactory2")
public void receiveMessage(JMSTextMessage data) {
    
}

it seems to me it worked!!!

But one of my CachingConnectionFactory must be marked as @Primary. If i delete @Primaty from one of my config files then i am gettig this error:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2018-03-28 12:28:37 -


APPLICATION FAILED TO START


Description:

Parameter 1 of method myFactory in com.config.UzbConnection required a bean of type 'org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer' that could not be found.

Action:

Consider defining a bean of type 'org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer' in your configuration.

Thanks

like image 143
lalilulelo_1986 Avatar answered Sep 22 '22 12:09

lalilulelo_1986