diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml index cc9eee48c4..a553dbd422 100644 --- a/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-autoconfigure/pom.xml @@ -428,6 +428,11 @@ test-jar test + + com.atomikos + transactions-jms + test + org.apache.tomcat.embed tomcat-embed-websocket diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jta/JtaAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jta/JtaAutoConfigurationTests.java index 2ce09e6f76..ed6e250890 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jta/JtaAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jta/JtaAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -20,8 +20,16 @@ import java.io.File; import java.net.InetAddress; import java.net.UnknownHostException; +import javax.jms.ConnectionFactory; +import javax.jms.TemporaryQueue; +import javax.jms.XAConnection; +import javax.jms.XAConnectionFactory; +import javax.jms.XASession; +import javax.sql.DataSource; +import javax.sql.XADataSource; import javax.transaction.TransactionManager; import javax.transaction.UserTransaction; +import javax.transaction.xa.XAResource; import org.junit.After; import org.junit.Before; @@ -33,9 +41,12 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jta.XAConnectionFactoryWrapper; import org.springframework.boot.jta.XADataSourceWrapper; +import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean; import org.springframework.boot.jta.atomikos.AtomikosDependsOnBeanFactoryPostProcessor; import org.springframework.boot.jta.atomikos.AtomikosProperties; import org.springframework.boot.jta.bitronix.BitronixDependentBeanFactoryPostProcessor; +import org.springframework.boot.jta.bitronix.PoolingConnectionFactoryBean; +import org.springframework.boot.jta.bitronix.PoolingDataSourceBean; import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -46,6 +57,7 @@ import org.springframework.util.FileSystemUtils; import com.atomikos.icatch.config.UserTransactionService; import com.atomikos.icatch.jta.UserTransactionManager; +import com.atomikos.jms.AtomikosConnectionFactoryBean; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -53,6 +65,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Tests for {@link JtaAutoConfiguration}. @@ -176,6 +189,66 @@ public class JtaAutoConfigurationTests { assertTrue(epochFile.isFile()); } + @Test + public void atomikosConnectionFactoryPoolConfiguration() { + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, + "spring.jta.atomikos.connectionfactory.minPoolSize:5", + "spring.jta.atomikos.connectionfactory.maxPoolSize:10"); + this.context.register(JtaPropertiesConfiguration.class, + AtomikosJtaConfiguration.class, PoolConfiguration.class); + this.context.refresh(); + AtomikosConnectionFactoryBean connectionFactory = this.context + .getBean(AtomikosConnectionFactoryBean.class); + assertThat(connectionFactory.getMinPoolSize(), is(equalTo(5))); + assertThat(connectionFactory.getMaxPoolSize(), is(equalTo(10))); + } + + @Test + public void bitronixConnectionFactoryPoolConfiguration() { + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, + "spring.jta.bitronix.connectionfactory.minPoolSize:5", + "spring.jta.bitronix.connectionfactory.maxPoolSize:10"); + this.context.register(JtaPropertiesConfiguration.class, + BitronixJtaConfiguration.class, PoolConfiguration.class); + this.context.refresh(); + PoolingConnectionFactoryBean connectionFactory = this.context + .getBean(PoolingConnectionFactoryBean.class); + assertThat(connectionFactory.getMinPoolSize(), is(equalTo(5))); + assertThat(connectionFactory.getMaxPoolSize(), is(equalTo(10))); + } + + @Test + public void atomikosDataSourcePoolConfiguration() { + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, + "spring.jta.atomikos.datasource.minPoolSize:5", + "spring.jta.atomikos.datasource.maxPoolSize:10"); + this.context.register(JtaPropertiesConfiguration.class, + AtomikosJtaConfiguration.class, PoolConfiguration.class); + this.context.refresh(); + AtomikosDataSourceBean dataSource = this.context + .getBean(AtomikosDataSourceBean.class); + assertThat(dataSource.getMinPoolSize(), is(equalTo(5))); + assertThat(dataSource.getMaxPoolSize(), is(equalTo(10))); + } + + @Test + public void bitronixDataSourcePoolConfiguration() { + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, + "spring.jta.bitronix.datasource.minPoolSize:5", + "spring.jta.bitronix.datasource.maxPoolSize:10"); + this.context.register(JtaPropertiesConfiguration.class, + BitronixJtaConfiguration.class, PoolConfiguration.class); + this.context.refresh(); + PoolingDataSourceBean dataSource = this.context + .getBean(PoolingDataSourceBean.class); + assertThat(dataSource.getMinPoolSize(), is(equalTo(5))); + assertThat(dataSource.getMaxPoolSize(), is(equalTo(10))); + } + @Configuration @EnableConfigurationProperties(JtaProperties.class) public static class JtaPropertiesConfiguration { @@ -192,4 +265,29 @@ public class JtaAutoConfigurationTests { } + @Configuration + public static class PoolConfiguration { + + @Bean + public ConnectionFactory pooledConnectionFactory( + XAConnectionFactoryWrapper wrapper) throws Exception { + XAConnectionFactory connectionFactory = mock(XAConnectionFactory.class); + XAConnection connection = mock(XAConnection.class); + XASession session = mock(XASession.class); + TemporaryQueue queue = mock(TemporaryQueue.class); + XAResource resource = mock(XAResource.class); + when(connectionFactory.createXAConnection()).thenReturn(connection); + when(connection.createXASession()).thenReturn(session); + when(session.createTemporaryQueue()).thenReturn(queue); + when(session.getXAResource()).thenReturn(resource); + return wrapper.wrapConnectionFactory(connectionFactory); + } + + @Bean + public DataSource pooledDataSource(XADataSourceWrapper wrapper) throws Exception { + XADataSource dataSource = mock(XADataSource.class); + return wrapper.wrapDataSource(dataSource); + } + } + } diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 976d9ac0a2..29e34e793d 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -270,6 +270,72 @@ content into your application; rather pick only the properties that you need. spring.jta.log-dir= # transaction log dir spring.jta.*= # technology specific configuration + # ATOMIKOS + spring.jta.atomikos.connectionfactory.borrow-connection-timeout=30 # Timeout, in seconds, for borrowing connections from the pool + spring.jta.atomikos.connectionfactory.ignore-session-transacted-flag=true # Whether or not to ignore the transacted flag when creating session + spring.jta.atomikos.connectionfactory.local-transaction-mode=false # Whether or not local transactions are desired + spring.jta.atomikos.connectionfactory.maintenance-interval=60 # The time, in seconds, between runs of the pool's maintenance thread + spring.jta.atomikos.connectionfactory.max-idle-time=60 # The time, in seconds, after which connections are cleaned up from the pool + spring.jta.atomikos.connectionfactory.max-lifetime=0 # The time, in seconds, that a connection can be pooled for before being destroyed. 0 denotes no limit. + spring.jta.atomikos.connectionfactory.max-pool-size=1 # The maximum size of the pool + spring.jta.atomikos.connectionfactory.min-pool-size=1 # The minimum size of the pool + spring.jta.atomikos.connectionfactory.reap-timeout=0 # The reap timeout, in seconds, for borrowed connections. 0 denotes no limit. + spring.jta.atomikos.connectionfactory.unique-resource-name=jmsConnectionFactory # The unique name used to identify the resource during recovery + spring.jta.atomikos.datasource.borrow-connection-timeout=30 # Timeout, in seconds, for borrowing connections from the pool + spring.jta.atomikos.datasource.default-isolation-level= # Default isolation level of connections provided by the pool + spring.jta.atomikos.datasource.login-timeout= # Timeout, in seconds, for establishing a database connection + spring.jta.atomikos.datasource.maintenance-interval=60 # The time, in seconds, between runs of the pool's maintenance thread + spring.jta.atomikos.datasource.max-idle-time=60 # The time, in seconds, after which connections are cleaned up from the pool + spring.jta.atomikos.datasource.max-lifetime=0 # The time, in seconds, that a connection can be pooled for before being destroyed. 0 denotes no limit. + spring.jta.atomikos.datasource.max-pool-size=1 # The maximum size of the pool + spring.jta.atomikos.datasource.min-pool-size=1 # The minimum size of the pool + spring.jta.atomikos.datasource.reap-timeout=0 # The reap timeout, in seconds, for borrowed connections. 0 denotes no limit. + spring.jta.atomikos.datasource.test-query= # SQL query or statement used to validate a connection before returning it + spring.jta.atomikos.datasource.unique-resource-name=dataSource # The unique name used to identify the resource during recovery + + # BITRONIX + spring.jta.bitronix.connectionfactory.acquire-increment=1 # Number of connections to create when growing the pool + spring.jta.bitronix.connectionfactory.acquisition-interval=1 # Time, in seconds, to wait before trying to acquire a connection again after an invalid connection was acquired + spring.jta.bitronix.connectionfactory.acquisition-timeout=30 # Timeout, in seconds, for acquiring connections from the pool + spring.jta.bitronix.connectionfactory.allow-local-transactions=true # Whether or not the transaction manager should allow mixing XA and non-XA transactions + spring.jta.bitronix.connectionfactory.apply-transaction-timeout=false # Whether or not the transaction timeout should be set on the XAResource when it is enlisted + spring.jta.bitronix.connectionfactory.automatic-enlisting-enabled=true # Whether or not resources should be enlisted and delisted automatically + spring.jta.bitronix.connectionfactory.cache-producers-consumers=true # Whether or not produces and consumers should be cached + spring.jta.bitronix.connectionfactory.defer-connection-release=true # Whether or not the provider can run many transactions on the same connection and supports transaction interleaving + spring.jta.bitronix.connectionfactory.ignore-recovery-failures=false # Whether or not recovery failures should be ignored + spring.jta.bitronix.connectionfactory.max-idle-time=60 # The time, in seconds, after which connections are cleaned up from the pool + spring.jta.bitronix.connectionfactory.max-pool-size=10 # The maximum size of the pool. 0 denotes no limit + spring.jta.bitronix.connectionfactory.min-pool-size=0 # The minimum size of the pool + spring.jta.bitronix.connectionfactory.password= # The password to use to connect to the JMS provider + spring.jta.bitronix.connectionfactory.share-transaction-connections=false # Whether or not connections in the ACCESSIBLE state can be shared within the context of a transaction + spring.jta.bitronix.connectionfactory.test-connections=true # Whether or not connections should be tested when acquired from the pool + spring.jta.bitronix.connectionfactory.two-pc-ordering-position=1 # The postion that this resource should take during two-phase commit (always first is Integer.MIN_VALUE, always last is Integer.MAX_VALUE) + spring.jta.bitronix.connectionfactory.unique-name=jmsConnectionFactory # The unique name used to identify the resource during recovery + spring.jta.bitronix.connectionfactory.use-tm-join=true Whether or not TMJOIN should be used when starting XAResources + spring.jta.bitronix.connectionfactory.user= # The user to use to connect to the JMS provider + spring.jta.bitronix.datasource.acquire-increment=1 # Number of connections to create when growing the pool + spring.jta.bitronix.datasource.acquisition-interval=1 # Time, in seconds, to wait before trying to acquire a connection again after an invalid connection was acquired + spring.jta.bitronix.datasource.acquisition-timeout=30 # Timeout, in seconds, for acquiring connections from the pool + spring.jta.bitronix.datasource.allow-local-transactions=true # Whether or not the transaction manager should allow mixing XA and non-XA transactions + spring.jta.bitronix.datasource.apply-transaction-timeout=false # Whether or not the transaction timeout should be set on the XAResource when it is enlisted + spring.jta.bitronix.datasource.automatic-enlisting-enabled=true # Whether or not resources should be enlisted and delisted automatically + spring.jta.bitronix.datasource.cursor-holdability= # The default cursor holdability for connections + spring.jta.bitronix.datasource.defer-connection-release=true # Whether or not the database can run many transactions on the same connection and supports transaction interleaving + spring.jta.bitronix.datasource.enable-jdbc4-connection-test # Whether or not Connection.isValid() is called when acquiring a connection from the pool + spring.jta.bitronix.datasource.ignore-recovery-failures=false # Whether or not recovery failures should be ignored + spring.jta.bitronix.datasource.isolation-level= # The default isolation level for connections + spring.jta.bitronix.datasource.local-auto-commit # The default auto-commit mode for local transactions + spring.jta.bitronix.datasource.login-timeout= # Timeout, in seconds, for establishing a database connection + spring.jta.bitronix.datasource.max-idle-time=60 # The time, in seconds, after which connections are cleaned up from the pool + spring.jta.bitronix.datasource.max-pool-size=10 # The maximum size of the pool. 0 denotes no limit + spring.jta.bitronix.datasource.min-pool-size=0 # The minimum size of the pool + spring.jta.bitronix.datasource.prepared-statement-cache-size=0 # The target size of the prepared statement cache. 0 disables the cache + spring.jta.bitronix.datasource.share-transaction-connections=false # Whether or not connections in the ACCESSIBLE state can be shared within the context of a transaction + spring.jta.bitronix.datasource.test-query # SQL query or statement used to validate a connection before returning it + spring.jta.bitronix.datasource.two-pc-ordering-position=1 # The postion that this resource should take during two-phase commit (always first is Integer.MIN_VALUE, always last is Integer.MAX_VALUE) + spring.jta.bitronix.datasource.unique-name=dataSource # The unique name used to identify the resource during recovery + spring.jta.bitronix.datasource.use-tm-join=true Whether or not TMJOIN should be used when starting XAResources + # SOLR ({sc-spring-boot-autoconfigure}/solr/SolrProperties.{sc-ext}[SolrProperties}]) spring.data.solr.host=http://127.0.0.1:8983/solr spring.data.solr.zk-host= diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/TypeExcludeFilter.java b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/TypeExcludeFilter.java index c5b7c0dab8..3f79d22191 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/TypeExcludeFilter.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/TypeExcludeFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -25,6 +25,7 @@ import javax.lang.model.type.TypeMirror; * Filter to excluded elements that don't make sense to process. * * @author Stephane Nicoll + * @author Andy Wilkinson * @since 1.2.0 */ class TypeExcludeFilter { @@ -32,13 +33,15 @@ class TypeExcludeFilter { private final Set excludes = new HashSet(); public TypeExcludeFilter() { + add("com.zaxxer.hikari.IConnectionCustomizer"); + add("groovy.text.markup.MarkupTemplateEngine"); add("java.io.Writer"); add("java.io.PrintWriter"); add("java.lang.ClassLoader"); add("java.util.concurrent.ThreadFactory"); + add("javax.jms.XAConnectionFactory"); add("javax.sql.DataSource"); - add("com.zaxxer.hikari.IConnectionCustomizer"); - add("groovy.text.markup.MarkupTemplateEngine"); + add("javax.sql.XADataSource"); add("org.apache.tomcat.jdbc.pool.PoolConfiguration"); add("org.apache.tomcat.jdbc.pool.Validator"); add("org.flywaydb.core.api.callback.FlywayCallback"); diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosConnectionFactoryBean.java b/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosConnectionFactoryBean.java index eec80b1f37..fb2115cb2d 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosConnectionFactoryBean.java +++ b/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosConnectionFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -19,15 +19,18 @@ package org.springframework.boot.jta.atomikos; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.util.StringUtils; /** * Spring friendly version of {@link com.atomikos.jms.AtomikosConnectionFactoryBean}. * * @author Phillip Webb + * @author Andy Wilkinson * @since 1.2.0 */ @SuppressWarnings("serial") +@ConfigurationProperties(prefix = "spring.jta.atomikos.connectionfactory") public class AtomikosConnectionFactoryBean extends com.atomikos.jms.AtomikosConnectionFactoryBean implements BeanNameAware, InitializingBean, DisposableBean { diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosDataSourceBean.java b/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosDataSourceBean.java index 1d393a9226..a9440f09c1 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosDataSourceBean.java +++ b/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosDataSourceBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -19,15 +19,18 @@ package org.springframework.boot.jta.atomikos; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.util.StringUtils; /** * Spring friendly version of {@link com.atomikos.jdbc.AtomikosDataSourceBean}. * * @author Phillip Webb + * @author Andy Wilkinson * @since 1.2.0 */ @SuppressWarnings("serial") +@ConfigurationProperties(prefix = "spring.jta.atomikos.datasource") public class AtomikosDataSourceBean extends com.atomikos.jdbc.AtomikosDataSourceBean implements BeanNameAware, InitializingBean, DisposableBean { diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/PoolingConnectionFactoryBean.java b/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/PoolingConnectionFactoryBean.java index 25303995da..50f7a853f2 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/PoolingConnectionFactoryBean.java +++ b/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/PoolingConnectionFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -25,6 +25,7 @@ import javax.jms.XAConnectionFactory; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.util.StringUtils; import bitronix.tm.resource.common.ResourceBean; @@ -37,9 +38,11 @@ import bitronix.tm.resource.jms.PoolingConnectionFactory; * * @author Phillip Webb * @author Josh Long + * @author Andy Wilkinson * @since 1.2.0 */ @SuppressWarnings("serial") +@ConfigurationProperties(prefix = "spring.jta.bitronix.connectionfactory") public class PoolingConnectionFactoryBean extends PoolingConnectionFactory implements BeanNameAware, InitializingBean, DisposableBean { diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/PoolingDataSourceBean.java b/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/PoolingDataSourceBean.java index 03d917fce7..5ae82b4dc8 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/PoolingDataSourceBean.java +++ b/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/PoolingDataSourceBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -28,6 +28,7 @@ import javax.sql.XADataSource; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.util.StringUtils; import bitronix.tm.resource.common.ResourceBean; @@ -40,9 +41,11 @@ import bitronix.tm.resource.jdbc.PoolingDataSource; * * @author Phillip Webb * @author Josh Long + * @author Andy Wilkinson * @since 1.2.0 */ @SuppressWarnings("serial") +@ConfigurationProperties(prefix = "spring.jta.bitronix.datasource") public class PoolingDataSourceBean extends PoolingDataSource implements BeanNameAware, InitializingBean {