/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.jms;
import javax.jms.ConnectionFactory;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.pool.PooledConnectionFactory;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerConfigUtils;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerEndpoint;
import org.springframework.jms.config.SimpleJmsListenerContainerFactory;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.transaction.jta.JtaTransactionManager;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link JmsAutoConfiguration}.
*
* @author Greg Turnquist
* @author Stephane Nicoll
* @author Aurélien Leboulanger
*/
public class JmsAutoConfigurationTests {
private static final String ACTIVEMQ_EMBEDDED_URL = "vm://localhost?broker.persistent=false";
private static final String ACTIVEMQ_NETWORK_URL = "tcp://localhost:61616";
private AnnotationConfigApplicationContext context;
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void testDefaultJmsConfiguration() {
load(TestConfiguration.class);
ActiveMQConnectionFactory connectionFactory = this.context
.getBean(ActiveMQConnectionFactory.class);
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
JmsMessagingTemplate messagingTemplate = this.context
.getBean(JmsMessagingTemplate.class);
assertThat(connectionFactory).isEqualTo(jmsTemplate.getConnectionFactory());
assertThat(messagingTemplate.getJmsTemplate()).isEqualTo(jmsTemplate);
assertThat(((ActiveMQConnectionFactory) jmsTemplate.getConnectionFactory())
.getBrokerURL()).isEqualTo(ACTIVEMQ_EMBEDDED_URL);
assertThat(this.context.containsBean("jmsListenerContainerFactory")).isTrue();
}
@Test
public void testConnectionFactoryBackOff() {
load(TestConfiguration2.class);
assertThat(this.context.getBean(ActiveMQConnectionFactory.class).getBrokerURL())
.isEqualTo("foobar");
}
@Test
public void testJmsTemplateBackOff() {
load(TestConfiguration3.class);
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
assertThat(jmsTemplate.getPriority()).isEqualTo(999);
}
@Test
public void testJmsMessagingTemplateBackOff() {
load(TestConfiguration5.class);
JmsMessagingTemplate messagingTemplate = this.context
.getBean(JmsMessagingTemplate.class);
assertThat(messagingTemplate.getDefaultDestinationName()).isEqualTo("fooBar");
}
@Test
public void testJmsTemplateBackOffEverything() {
this.context = createContext(TestConfiguration2.class, TestConfiguration3.class,
TestConfiguration5.class);
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
assertThat(jmsTemplate.getPriority()).isEqualTo(999);
assertThat(this.context.getBean(ActiveMQConnectionFactory.class).getBrokerURL())
.isEqualTo("foobar");
JmsMessagingTemplate messagingTemplate = this.context
.getBean(JmsMessagingTemplate.class);
assertThat(messagingTemplate.getDefaultDestinationName()).isEqualTo("fooBar");
assertThat(messagingTemplate.getJmsTemplate()).isEqualTo(jmsTemplate);
}
@Test
public void testEnableJmsCreateDefaultContainerFactory() {
load(EnableJmsConfiguration.class);
JmsListenerContainerFactory<?> jmsListenerContainerFactory = this.context.getBean(
"jmsListenerContainerFactory", JmsListenerContainerFactory.class);
assertThat(jmsListenerContainerFactory.getClass())
.isEqualTo(DefaultJmsListenerContainerFactory.class);
}
@Test
public void testJmsListenerContainerFactoryBackOff() {
this.context = createContext(TestConfiguration6.class,
EnableJmsConfiguration.class);
JmsListenerContainerFactory<?> jmsListenerContainerFactory = this.context.getBean(
"jmsListenerContainerFactory", JmsListenerContainerFactory.class);
assertThat(jmsListenerContainerFactory.getClass())
.isEqualTo(SimpleJmsListenerContainerFactory.class);
}
@Test
public void testJmsListenerContainerFactoryWithCustomSettings() {
load(EnableJmsConfiguration.class, "spring.jms.listener.autoStartup=false",
"spring.jms.listener.acknowledgeMode=client",
"spring.jms.listener.concurrency=2",
"spring.jms.listener.maxConcurrency=10");
JmsListenerContainerFactory<?> jmsListenerContainerFactory = this.context.getBean(
"jmsListenerContainerFactory", JmsListenerContainerFactory.class);
assertThat(jmsListenerContainerFactory.getClass())
.isEqualTo(DefaultJmsListenerContainerFactory.class);
DefaultMessageListenerContainer listenerContainer = ((DefaultJmsListenerContainerFactory) jmsListenerContainerFactory)
.createListenerContainer(mock(JmsListenerEndpoint.class));
assertThat(listenerContainer.isAutoStartup()).isFalse();
assertThat(listenerContainer.getSessionAcknowledgeMode())
.isEqualTo(Session.CLIENT_ACKNOWLEDGE);
assertThat(listenerContainer.getConcurrentConsumers()).isEqualTo(2);
assertThat(listenerContainer.getMaxConcurrentConsumers()).isEqualTo(10);
}
@Test
public void testDefaultContainerFactoryWithJtaTransactionManager() {
this.context = createContext(TestConfiguration7.class,
EnableJmsConfiguration.class);
JmsListenerContainerFactory<?> jmsListenerContainerFactory = this.context.getBean(
"jmsListenerContainerFactory", JmsListenerContainerFactory.class);
assertThat(jmsListenerContainerFactory.getClass())
.isEqualTo(DefaultJmsListenerContainerFactory.class);
DefaultMessageListenerContainer listenerContainer = ((DefaultJmsListenerContainerFactory) jmsListenerContainerFactory)
.createListenerContainer(mock(JmsListenerEndpoint.class));
assertThat(listenerContainer.isSessionTransacted()).isFalse();
assertThat(new DirectFieldAccessor(listenerContainer)
.getPropertyValue("transactionManager"))
.isSameAs(this.context.getBean(JtaTransactionManager.class));
}
@Test
public void testDefaultContainerFactoryNonJtaTransactionManager() {
this.context = createContext(TestConfiguration8.class,
EnableJmsConfiguration.class);
JmsListenerContainerFactory<?> jmsListenerContainerFactory = this.context.getBean(
"jmsListenerContainerFactory", JmsListenerContainerFactory.class);
assertThat(jmsListenerContainerFactory.getClass())
.isEqualTo(DefaultJmsListenerContainerFactory.class);
DefaultMessageListenerContainer listenerContainer = ((DefaultJmsListenerContainerFactory) jmsListenerContainerFactory)
.createListenerContainer(mock(JmsListenerEndpoint.class));
assertThat(listenerContainer.isSessionTransacted()).isTrue();
assertThat(new DirectFieldAccessor(listenerContainer)
.getPropertyValue("transactionManager")).isNull();
}
@Test
public void testDefaultContainerFactoryNoTransactionManager() {
this.context = createContext(EnableJmsConfiguration.class);
JmsListenerContainerFactory<?> jmsListenerContainerFactory = this.context.getBean(
"jmsListenerContainerFactory", JmsListenerContainerFactory.class);
assertThat(jmsListenerContainerFactory.getClass())
.isEqualTo(DefaultJmsListenerContainerFactory.class);
DefaultMessageListenerContainer listenerContainer = ((DefaultJmsListenerContainerFactory) jmsListenerContainerFactory)
.createListenerContainer(mock(JmsListenerEndpoint.class));
assertThat(listenerContainer.isSessionTransacted()).isTrue();
assertThat(new DirectFieldAccessor(listenerContainer)
.getPropertyValue("transactionManager")).isNull();
}
@Test
public void testDefaultContainerFactoryWithMessageConverters() {
this.context = createContext(MessageConvertersConfiguration.class,
EnableJmsConfiguration.class);
JmsListenerContainerFactory<?> jmsListenerContainerFactory = this.context.getBean(
"jmsListenerContainerFactory", JmsListenerContainerFactory.class);
assertThat(jmsListenerContainerFactory.getClass())
.isEqualTo(DefaultJmsListenerContainerFactory.class);
DefaultMessageListenerContainer listenerContainer = ((DefaultJmsListenerContainerFactory) jmsListenerContainerFactory)
.createListenerContainer(mock(JmsListenerEndpoint.class));
assertThat(listenerContainer.getMessageConverter())
.isSameAs(this.context.getBean("myMessageConverter"));
}
@Test
public void testCustomContainerFactoryWithConfigurer() {
this.context = doLoad(
new Class<?>[] { TestConfiguration9.class, EnableJmsConfiguration.class },
"spring.jms.listener.autoStartup=false");
assertThat(this.context.containsBean("jmsListenerContainerFactory")).isTrue();
JmsListenerContainerFactory<?> jmsListenerContainerFactory = this.context.getBean(
"customListenerContainerFactory", JmsListenerContainerFactory.class);
assertThat(jmsListenerContainerFactory)
.isInstanceOf(DefaultJmsListenerContainerFactory.class);
DefaultMessageListenerContainer listenerContainer = ((DefaultJmsListenerContainerFactory) jmsListenerContainerFactory)
.createListenerContainer(mock(JmsListenerEndpoint.class));
assertThat(listenerContainer.getCacheLevel())
.isEqualTo(DefaultMessageListenerContainer.CACHE_CONSUMER);
assertThat(listenerContainer.isAutoStartup()).isFalse();
}
@Test
public void testJmsTemplateWithMessageConverter() {
load(MessageConvertersConfiguration.class);
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
assertThat(jmsTemplate.getMessageConverter())
.isSameAs(this.context.getBean("myMessageConverter"));
}
@Test
public void testJmsTemplateWithDestinationResolver() {
load(DestinationResolversConfiguration.class);
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
assertThat(jmsTemplate.getDestinationResolver())
.isSameAs(this.context.getBean("myDestinationResolver"));
}
@Test
public void testJmsTemplateFullCustomization() {
load(MessageConvertersConfiguration.class,
"spring.jms.template.default-destination=testQueue",
"spring.jms.template.delivery-delay=500",
"spring.jms.template.delivery-mode=non-persistent",
"spring.jms.template.priority=6", "spring.jms.template.time-to-live=6000",
"spring.jms.template.receive-timeout=2000");
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
assertThat(jmsTemplate.getMessageConverter())
.isSameAs(this.context.getBean("myMessageConverter"));
assertThat(jmsTemplate.isPubSubDomain()).isFalse();
assertThat(jmsTemplate.getDefaultDestinationName()).isEqualTo("testQueue");
assertThat(jmsTemplate.getDeliveryDelay()).isEqualTo(500);
assertThat(jmsTemplate.getDeliveryMode()).isEqualTo(1);
assertThat(jmsTemplate.getPriority()).isEqualTo(6);
assertThat(jmsTemplate.getTimeToLive()).isEqualTo(6000);
assertThat(jmsTemplate.isExplicitQosEnabled()).isTrue();
assertThat(jmsTemplate.getReceiveTimeout()).isEqualTo(2000);
}
@Test
public void testPubSubDisabledByDefault() {
load(TestConfiguration.class);
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
assertThat(jmsTemplate.isPubSubDomain()).isFalse();
}
@Test
public void testJmsTemplatePostProcessedSoThatPubSubIsTrue() {
load(TestConfiguration4.class);
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
assertThat(jmsTemplate.isPubSubDomain()).isTrue();
}
@Test
public void testPubSubDomainActive() {
load(TestConfiguration.class, "spring.jms.pubSubDomain:true");
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
DefaultMessageListenerContainer defaultMessageListenerContainer = this.context
.getBean(DefaultJmsListenerContainerFactory.class)
.createListenerContainer(mock(JmsListenerEndpoint.class));
assertThat(jmsTemplate.isPubSubDomain()).isTrue();
assertThat(defaultMessageListenerContainer.isPubSubDomain()).isTrue();
}
@Test
public void testPubSubDomainOverride() {
load(TestConfiguration.class, "spring.jms.pubSubDomain:false");
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
ActiveMQConnectionFactory connectionFactory = this.context
.getBean(ActiveMQConnectionFactory.class);
assertThat(jmsTemplate).isNotNull();
assertThat(jmsTemplate.isPubSubDomain()).isFalse();
assertThat(connectionFactory).isNotNull();
assertThat(connectionFactory).isEqualTo(jmsTemplate.getConnectionFactory());
}
@Test
public void testActiveMQOverriddenStandalone() {
load(TestConfiguration.class, "spring.activemq.inMemory:false");
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
ActiveMQConnectionFactory connectionFactory = this.context
.getBean(ActiveMQConnectionFactory.class);
assertThat(jmsTemplate).isNotNull();
assertThat(connectionFactory).isNotNull();
assertThat(connectionFactory).isEqualTo(jmsTemplate.getConnectionFactory());
assertThat(((ActiveMQConnectionFactory) jmsTemplate.getConnectionFactory())
.getBrokerURL()).isEqualTo(ACTIVEMQ_NETWORK_URL);
}
@Test
public void testActiveMQOverriddenRemoteHost() {
load(TestConfiguration.class,
"spring.activemq.brokerUrl:tcp://remote-host:10000");
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
ActiveMQConnectionFactory connectionFactory = this.context
.getBean(ActiveMQConnectionFactory.class);
assertThat(jmsTemplate).isNotNull();
assertThat(connectionFactory).isNotNull();
assertThat(connectionFactory).isEqualTo(jmsTemplate.getConnectionFactory());
assertThat(((ActiveMQConnectionFactory) jmsTemplate.getConnectionFactory())
.getBrokerURL()).isEqualTo("tcp://remote-host:10000");
}
@Test
public void testActiveMQOverriddenPool() {
load(TestConfiguration.class, "spring.activemq.pool.enabled:true");
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
PooledConnectionFactory pool = this.context
.getBean(PooledConnectionFactory.class);
assertThat(jmsTemplate).isNotNull();
assertThat(pool).isNotNull();
assertThat(pool).isEqualTo(jmsTemplate.getConnectionFactory());
ActiveMQConnectionFactory factory = (ActiveMQConnectionFactory) pool
.getConnectionFactory();
assertThat(factory.getBrokerURL()).isEqualTo(ACTIVEMQ_EMBEDDED_URL);
}
@Test
public void testActiveMQOverriddenPoolAndStandalone() {
load(TestConfiguration.class, "spring.activemq.pool.enabled:true",
"spring.activemq.inMemory:false");
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
PooledConnectionFactory pool = this.context
.getBean(PooledConnectionFactory.class);
assertThat(jmsTemplate).isNotNull();
assertThat(pool).isNotNull();
assertThat(pool).isEqualTo(jmsTemplate.getConnectionFactory());
ActiveMQConnectionFactory factory = (ActiveMQConnectionFactory) pool
.getConnectionFactory();
assertThat(factory.getBrokerURL()).isEqualTo(ACTIVEMQ_NETWORK_URL);
}
@Test
public void testActiveMQOverriddenPoolAndRemoteServer() {
load(TestConfiguration.class, "spring.activemq.pool.enabled:true",
"spring.activemq.brokerUrl:tcp://remote-host:10000");
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
PooledConnectionFactory pool = this.context
.getBean(PooledConnectionFactory.class);
assertThat(jmsTemplate).isNotNull();
assertThat(pool).isNotNull();
assertThat(pool).isEqualTo(jmsTemplate.getConnectionFactory());
ActiveMQConnectionFactory factory = (ActiveMQConnectionFactory) pool
.getConnectionFactory();
assertThat(factory.getBrokerURL()).isEqualTo("tcp://remote-host:10000");
}
@Test
public void enableJmsAutomatically() throws Exception {
load(NoEnableJmsConfiguration.class);
AnnotationConfigApplicationContext ctx = this.context;
ctx.getBean(JmsListenerConfigUtils.JMS_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME);
ctx.getBean(JmsListenerConfigUtils.JMS_LISTENER_ENDPOINT_REGISTRY_BEAN_NAME);
}
private AnnotationConfigApplicationContext createContext(
Class<?>... additionalClasses) {
return doLoad(additionalClasses);
}
private void load(Class<?> config, String... environment) {
this.context = doLoad(new Class<?>[] { config }, environment);
}
private AnnotationConfigApplicationContext doLoad(Class<?>[] configs,
String... environment) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(configs);
applicationContext.register(ActiveMQAutoConfiguration.class,
JmsAutoConfiguration.class);
EnvironmentTestUtils.addEnvironment(applicationContext, environment);
applicationContext.refresh();
return applicationContext;
}
@Configuration
protected static class TestConfiguration {
}
@Configuration
protected static class TestConfiguration2 {
@Bean
ConnectionFactory connectionFactory() {
return new ActiveMQConnectionFactory() {
{
setBrokerURL("foobar");
}
};
}
}
@Configuration
protected static class TestConfiguration3 {
@Bean
JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
jmsTemplate.setPriority(999);
return jmsTemplate;
}
}
@Configuration
protected static class TestConfiguration4 implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (bean.getClass().isAssignableFrom(JmsTemplate.class)) {
JmsTemplate jmsTemplate = (JmsTemplate) bean;
jmsTemplate.setPubSubDomain(true);
}
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
}
@Configuration
protected static class TestConfiguration5 {
@Bean
JmsMessagingTemplate jmsMessagingTemplate(JmsTemplate jmsTemplate) {
JmsMessagingTemplate messagingTemplate = new JmsMessagingTemplate(
jmsTemplate);
messagingTemplate.setDefaultDestinationName("fooBar");
return messagingTemplate;
}
}
@Configuration
protected static class TestConfiguration6 {
@Bean
JmsListenerContainerFactory<?> jmsListenerContainerFactory(
ConnectionFactory connectionFactory) {
SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
return factory;
}
}
@Configuration
protected static class TestConfiguration7 {
@Bean
JtaTransactionManager transactionManager() {
return mock(JtaTransactionManager.class);
}
}
@Configuration
protected static class TestConfiguration8 {
@Bean
DataSourceTransactionManager transactionManager() {
return mock(DataSourceTransactionManager.class);
}
}
@Configuration
protected static class MessageConvertersConfiguration {
@Bean
@Primary
public MessageConverter myMessageConverter() {
return mock(MessageConverter.class);
}
@Bean
public MessageConverter anotherMessageConverter() {
return mock(MessageConverter.class);
}
}
@Configuration
protected static class DestinationResolversConfiguration {
@Bean
@Primary
public DestinationResolver myDestinationResolver() {
return mock(DestinationResolver.class);
}
@Bean
public DestinationResolver anotherDestinationResolver() {
return mock(DestinationResolver.class);
}
}
@Configuration
protected static class TestConfiguration9 {
@Bean
JmsListenerContainerFactory<?> customListenerContainerFactory(
DefaultJmsListenerContainerFactoryConfigurer configurer,
ConnectionFactory connectionFactory) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
factory.setCacheLevel(DefaultMessageListenerContainer.CACHE_CONSUMER);
return factory;
}
}
@Configuration
@EnableJms
protected static class EnableJmsConfiguration {
}
@Configuration
protected static class NoEnableJmsConfiguration {
}
}