diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml index 40e3303c5cb..b36152d2572 100644 --- a/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-autoconfigure/pom.xml @@ -25,6 +25,16 @@ spring-boot + + com.atomikos + transactions-jdbc + true + + + com.atomikos + transactions-jta + true + com.fasterxml.jackson.core jackson-databind @@ -80,6 +90,11 @@ velocity true + + org.codehaus.btm + btm + true + org.codehaus.groovy groovy-templates diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jta/AtomikosJtaConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jta/AtomikosJtaConfiguration.java new file mode 100644 index 00000000000..65ee8083f5c --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jta/AtomikosJtaConfiguration.java @@ -0,0 +1,120 @@ +/* + * Copyright 2012-2014 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.jta; + +import java.io.File; +import java.util.Properties; + +import javax.transaction.TransactionManager; +import javax.transaction.UserTransaction; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationHome; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jta.XAConnectionFactoryWrapper; +import org.springframework.boot.jta.XADataSourceWrapper; +import org.springframework.boot.jta.atomikos.AtomikosDependsOnBeanFactoryPostProcessor; +import org.springframework.boot.jta.atomikos.AtomikosProperties; +import org.springframework.boot.jta.atomikos.AtomikosXAConnectionFactoryWrapper; +import org.springframework.boot.jta.atomikos.AtomikosXADataSourceWrapper; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.jta.JtaTransactionManager; +import org.springframework.util.StringUtils; + +import com.atomikos.icatch.config.UserTransactionService; +import com.atomikos.icatch.config.UserTransactionServiceImp; +import com.atomikos.icatch.jta.UserTransactionManager; + +/** + * JTA Configuration for Atomikos. + * + * @author Josh Long + * @author Phillip Webb + * @since 1.2.0 + */ +@Configuration +@ConditionalOnClass(UserTransactionManager.class) +@ConditionalOnMissingBean(PlatformTransactionManager.class) +class AtomikosJtaConfiguration { + + @Autowired + private JtaProperties jtaProperties; + + @Bean + @ConditionalOnMissingBean + @ConfigurationProperties(prefix = JtaProperties.PREFIX) + public AtomikosProperties atomikosProperties() { + return new AtomikosProperties(); + } + + @Bean(initMethod = "init", destroyMethod = "shutdownForce") + @ConditionalOnMissingBean + public UserTransactionService userTransactionService( + AtomikosProperties atomikosProperties) { + Properties properties = new Properties(); + properties.setProperty("com.atomikos.icatch.log_base_dir", getLogBaseDir()); + properties.putAll(atomikosProperties.asProperties()); + return new UserTransactionServiceImp(properties); + } + + private String getLogBaseDir() { + if (StringUtils.hasLength(this.jtaProperties.getLogDir())) { + return this.jtaProperties.getLogDir(); + } + File home = new ApplicationHome().getDir(); + return new File(home, "transaction-logs").getAbsolutePath(); + } + + @Bean(initMethod = "init", destroyMethod = "close") + @ConditionalOnMissingBean + public UserTransactionManager atomikosTransactionManager( + UserTransactionService userTransactionService) throws Exception { + UserTransactionManager manager = new UserTransactionManager(); + manager.setStartupTransactionService(false); + manager.setForceShutdown(true); + return manager; + } + + @Bean + @ConditionalOnMissingBean + public XADataSourceWrapper xaDataSourceWrapper() { + return new AtomikosXADataSourceWrapper(); + } + + @Bean + @ConditionalOnMissingBean + public XAConnectionFactoryWrapper xaConnectionFactoryWrapper() { + return new AtomikosXAConnectionFactoryWrapper(); + } + + @Bean + @ConditionalOnMissingBean + public static AtomikosDependsOnBeanFactoryPostProcessor atomikosDependsOnBeanFactoryPostProcessor() { + return new AtomikosDependsOnBeanFactoryPostProcessor(); + } + + @Bean + public JtaTransactionManager transactionManager(UserTransaction userTransaction, + TransactionManager transactionManager) { + return new JtaTransactionManager(userTransaction, transactionManager); + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jta/BitronixJtaConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jta/BitronixJtaConfiguration.java new file mode 100644 index 00000000000..6a3407a5e49 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jta/BitronixJtaConfiguration.java @@ -0,0 +1,109 @@ +/* + * Copyright 2012-2014 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.jta; + +import java.io.File; + +import javax.transaction.TransactionManager; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationHome; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jta.XAConnectionFactoryWrapper; +import org.springframework.boot.jta.XADataSourceWrapper; +import org.springframework.boot.jta.bitronix.BitronixDependentBeanFactoryPostProcessor; +import org.springframework.boot.jta.bitronix.BitronixXAConnectionFactoryWrapper; +import org.springframework.boot.jta.bitronix.BitronixXADataSourceWrapper; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.jta.JtaTransactionManager; +import org.springframework.util.StringUtils; + +import bitronix.tm.TransactionManagerServices; +import bitronix.tm.jndi.BitronixContext; + +/** + * JTA Configuration for Bitronix. + * + * @author Josh Long + * @author Phillip Webb + * @since 1.2.0 + */ +@Configuration +@ConditionalOnClass(BitronixContext.class) +@ConditionalOnMissingBean(PlatformTransactionManager.class) +class BitronixJtaConfiguration { + + @Autowired + private JtaProperties jtaProperties; + + @Bean + @ConditionalOnMissingBean + @ConfigurationProperties(prefix = JtaProperties.PREFIX) + public bitronix.tm.Configuration bitronixConfiguration(JtaProperties xxx) { + bitronix.tm.Configuration config = TransactionManagerServices.getConfiguration(); + config.setServerId("spring-boot-jta-bitronix"); + File logBaseDir = getLogBaseDir(); + config.setLogPart1Filename(new File(logBaseDir, "part1.btm").getAbsolutePath()); + config.setLogPart2Filename(new File(logBaseDir, "part2.btm").getAbsolutePath()); + config.setDisableJmx(true); + return config; + } + + private File getLogBaseDir() { + if (StringUtils.hasLength(this.jtaProperties.getLogDir())) { + return new File(this.jtaProperties.getLogDir()); + } + File home = new ApplicationHome().getDir(); + return new File(home, "transaction-logs"); + } + + @Bean + @ConditionalOnMissingBean + public TransactionManager bitronixTransactionManager( + bitronix.tm.Configuration configuration) { + // Inject configuration to force ordering + return TransactionManagerServices.getTransactionManager(); + } + + @Bean + @ConditionalOnMissingBean + public XADataSourceWrapper xaDataSourceWrapper() { + return new BitronixXADataSourceWrapper(); + } + + @Bean + @ConditionalOnMissingBean + public XAConnectionFactoryWrapper xaConnectionFactoryWrapper() { + return new BitronixXAConnectionFactoryWrapper(); + } + + @Bean + @ConditionalOnMissingBean + public static BitronixDependentBeanFactoryPostProcessor atomikosDependsOnBeanFactoryPostProcessor() { + return new BitronixDependentBeanFactoryPostProcessor(); + } + + @Bean + public JtaTransactionManager transactionManager(TransactionManager transactionManager) { + return new JtaTransactionManager(transactionManager); + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jta/JtaAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jta/JtaAutoConfiguration.java new file mode 100644 index 00000000000..803d4c55e2b --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jta/JtaAutoConfiguration.java @@ -0,0 +1,36 @@ +/* + * Copyright 2012-2014 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.jta; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Import; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for JTA. + * + * @author Josh Long + * @author Phillip Webb + * @since 1.2.0 + */ +@ConditionalOnClass(javax.transaction.Transaction.class) +@Import({ BitronixJtaConfiguration.class, AtomikosJtaConfiguration.class }) +@EnableConfigurationProperties(JtaProperties.class) +public class JtaAutoConfiguration { + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jta/JtaProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jta/JtaProperties.java new file mode 100644 index 00000000000..02fda641e9a --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jta/JtaProperties.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2014 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.jta; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.transaction.jta.JtaTransactionManager; + +/** + * External configuration properties for a {@link JtaTransactionManager} created by + * Spring. All {@literal spring.jta.} properties are also applied to the appropriate + * vendor specific configuration. + * + * @author Josh Long + * @author Phillip Webb + * @since 1.2.0 + */ +@ConfigurationProperties(prefix = JtaProperties.PREFIX, ignoreUnknownFields = true) +public class JtaProperties { + + public static final String PREFIX = "spring.jta"; + + private String logDir; + + public void setLogDir(String logDir) { + this.logDir = logDir; + } + + public String getLogDir() { + return this.logDir; + } + +} diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 8f1ba96768d..f2f147692ee 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -25,6 +25,7 @@ org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\ org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.hornetq.HornetQAutoConfiguration,\ +org.springframework.boot.autoconfigure.jta.JtaAutoConfiguration,\ org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchAutoConfiguration,\ org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchDataAutoConfiguration,\ org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\ 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 new file mode 100644 index 00000000000..f07097a6b26 --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jta/JtaAutoConfigurationTests.java @@ -0,0 +1,107 @@ +/* + * Copyright 2012-2014 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.jta; + +import javax.transaction.TransactionManager; +import javax.transaction.UserTransaction; + +import org.junit.After; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.boot.jta.XAConnectionFactoryWrapper; +import org.springframework.boot.jta.XADataSourceWrapper; +import org.springframework.boot.jta.atomikos.AtomikosDependsOnBeanFactoryPostProcessor; +import org.springframework.boot.jta.atomikos.AtomikosProperties; +import org.springframework.boot.jta.bitronix.BitronixDependentBeanFactoryPostProcessor; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.jta.JtaTransactionManager; + +import com.atomikos.icatch.config.UserTransactionService; +import com.atomikos.icatch.jta.UserTransactionManager; + +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link JtaAutoConfiguration}. + * + * @author Josh Long + * @author Phillip Webb + */ +public class JtaAutoConfigurationTests { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private AnnotationConfigApplicationContext context; + + @After + public void closeContext() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void customPatformTransactionManager() throws Exception { + this.context = new AnnotationConfigApplicationContext( + CustomTransactionManagerConfig.class, JtaAutoConfiguration.class); + this.thrown.expect(NoSuchBeanDefinitionException.class); + this.context.getBean(JtaTransactionManager.class); + } + + @Test + public void atomikosSanityCheck() throws Exception { + this.context = new AnnotationConfigApplicationContext(JtaProperties.class, + AtomikosJtaConfiguration.class); + this.context.getBean(AtomikosProperties.class); + this.context.getBean(UserTransactionService.class); + this.context.getBean(UserTransactionManager.class); + this.context.getBean(UserTransaction.class); + this.context.getBean(XADataSourceWrapper.class); + this.context.getBean(XAConnectionFactoryWrapper.class); + this.context.getBean(AtomikosDependsOnBeanFactoryPostProcessor.class); + this.context.getBean(JtaTransactionManager.class); + } + + @Test + public void bitronixSanityCheck() throws Exception { + this.context = new AnnotationConfigApplicationContext(JtaProperties.class, + BitronixJtaConfiguration.class); + this.context.getBean(bitronix.tm.Configuration.class); + this.context.getBean(TransactionManager.class); + this.context.getBean(XADataSourceWrapper.class); + this.context.getBean(XAConnectionFactoryWrapper.class); + this.context.getBean(BitronixDependentBeanFactoryPostProcessor.class); + this.context.getBean(JtaTransactionManager.class); + } + + @Configuration + public static class CustomTransactionManagerConfig { + + @Bean + public PlatformTransactionManager transactionManager() { + return mock(PlatformTransactionManager.class); + } + + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java index 1e6734d164e..d68309630f0 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/AbstractJpaAutoConfigurationTests.java @@ -17,11 +17,12 @@ package org.springframework.boot.autoconfigure.orm.jpa; import java.lang.reflect.Field; -import java.util.Collections; +import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; +import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform; import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -228,8 +229,10 @@ public abstract class AbstractJpaAutoConfigurationTests { factoryBean.setJpaVendorAdapter(adapter); factoryBean.setDataSource(dataSource); factoryBean.setPersistenceUnitName("manually-configured"); - factoryBean.setJpaPropertyMap(Collections.singletonMap("configured", - "manually")); + Map properties = new HashMap(); + properties.put("configured", "manually"); + properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE); + factoryBean.setJpaPropertyMap(properties); return factoryBean; } } diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/XAConnectionFactoryWrapper.java b/spring-boot/src/main/java/org/springframework/boot/jta/XAConnectionFactoryWrapper.java new file mode 100644 index 00000000000..4680fb5c9a9 --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/jta/XAConnectionFactoryWrapper.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-2014 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.jta; + +import javax.jms.ConnectionFactory; +import javax.jms.XAConnectionFactory; +import javax.transaction.TransactionManager; + +/** + * Strategy interface used to wrap a JMS {@link XAConnectionFactory} enrolling it with a + * JTA {@link TransactionManager}. + * + * @author Phillip Webb + * @since 1.2.0 + */ +public interface XAConnectionFactoryWrapper { + + /** + * Wrap the specific {@link XAConnectionFactory} and enroll it with a JTA + * {@link TransactionManager}. + * @param connectionFactory the connection factory to wrap + * @return the wrapped connection factory + */ + ConnectionFactory wrapConnectionFactory(XAConnectionFactory connectionFactory) + throws Exception; + +} diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/XADataSourceWrapper.java b/spring-boot/src/main/java/org/springframework/boot/jta/XADataSourceWrapper.java new file mode 100644 index 00000000000..1ee8d818b72 --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/jta/XADataSourceWrapper.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-2014 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.jta; + +import javax.sql.DataSource; +import javax.sql.XADataSource; +import javax.transaction.TransactionManager; + +/** + * Strategy interface used to wrap a JMS {@link XADataSource} enrolling it with a JTA + * {@link TransactionManager}. + * + * @author Phillip Webb + * @since 1.2.0 + */ +public interface XADataSourceWrapper { + + /** + * Wrap the specific {@link XADataSource} and enroll it with a JTA + * {@link TransactionManager}. + * @param dataSource the data source to wrap + * @return the wrapped data source + */ + DataSource wrapDataSource(XADataSource dataSource) throws Exception; + +} diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosXAConnectionFactoryWrapper.java b/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosXAConnectionFactoryWrapper.java new file mode 100644 index 00000000000..c370bb945bd --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosXAConnectionFactoryWrapper.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-2014 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.jta.atomikos; + +import javax.jms.ConnectionFactory; +import javax.jms.XAConnectionFactory; + +import org.springframework.boot.jta.XAConnectionFactoryWrapper; + +/** + * {@link XAConnectionFactoryWrapper} that uses an {@link AtomikosConnectionFactoryBean} + * to wrap a {@link XAConnectionFactory}. + * + * @author Phillip Webb + * @since 1.2.0 + */ +public class AtomikosXAConnectionFactoryWrapper implements XAConnectionFactoryWrapper { + + @Override + public ConnectionFactory wrapConnectionFactory(XAConnectionFactory connectionFactory) { + AtomikosConnectionFactoryBean bean = new AtomikosConnectionFactoryBean(); + bean.setXaConnectionFactory(connectionFactory); + return bean; + } + +} diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosXADataSourceWrapper.java b/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosXADataSourceWrapper.java new file mode 100644 index 00000000000..28fc7f778bc --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/jta/atomikos/AtomikosXADataSourceWrapper.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-2014 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.jta.atomikos; + +import javax.sql.XADataSource; + +import org.springframework.boot.jta.XADataSourceWrapper; + +/** + * {@link XADataSourceWrapper} that uses an {@link AtomikosDataSourceBean} to wrap a + * {@link XADataSource}. + * + * @author Phillip Webb + * @since 1.2.0 + */ +public class AtomikosXADataSourceWrapper implements XADataSourceWrapper { + + @Override + public AtomikosDataSourceBean wrapDataSource(XADataSource dataSource) + throws Exception { + AtomikosDataSourceBean bean = new AtomikosDataSourceBean(); + bean.setXaDataSource(dataSource); + return bean; + } + +} diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/BitronixXAConnectionFactoryWrapper.java b/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/BitronixXAConnectionFactoryWrapper.java new file mode 100644 index 00000000000..6a539c9a0ca --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/BitronixXAConnectionFactoryWrapper.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-2014 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.jta.bitronix; + +import javax.jms.ConnectionFactory; +import javax.jms.XAConnectionFactory; + +import org.springframework.boot.jta.XAConnectionFactoryWrapper; + +/** + * {@link XAConnectionFactoryWrapper} that uses a Bitronix + * {@link PoolingConnectionFactoryBean} to wrap a {@link XAConnectionFactory}. + * + * @author Phillip Webb + * @since 1.2.0 + */ +public class BitronixXAConnectionFactoryWrapper implements XAConnectionFactoryWrapper { + + @Override + public ConnectionFactory wrapConnectionFactory(XAConnectionFactory connectionFactory) { + PoolingConnectionFactoryBean pool = new PoolingConnectionFactoryBean(); + pool.setConnectionFactory(connectionFactory); + return pool; + } + +} diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/BitronixXADataSourceWrapper.java b/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/BitronixXADataSourceWrapper.java new file mode 100644 index 00000000000..2edd1a07bff --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/BitronixXADataSourceWrapper.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-2014 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.jta.bitronix; + +import javax.sql.XADataSource; + +import org.springframework.boot.jta.XADataSourceWrapper; + +/** + * {@link XADataSourceWrapper} that uses a Bitronix {@link PoolingDataSourceBean} to wrap + * a {@link XADataSource}. + * + * @author Phillip Webb + * @since 1.2.0 + */ +public class BitronixXADataSourceWrapper implements XADataSourceWrapper { + + @Override + public PoolingDataSourceBean wrapDataSource(XADataSource dataSource) throws Exception { + PoolingDataSourceBean pool = new PoolingDataSourceBean(); + pool.setDataSource(dataSource); + return pool; + } + +} diff --git a/spring-boot/src/test/java/org/springframework/boot/jta/atomikos/AtomikosXAConnectionFactoryWrapperTests.java b/spring-boot/src/test/java/org/springframework/boot/jta/atomikos/AtomikosXAConnectionFactoryWrapperTests.java new file mode 100644 index 00000000000..3745522fd66 --- /dev/null +++ b/spring-boot/src/test/java/org/springframework/boot/jta/atomikos/AtomikosXAConnectionFactoryWrapperTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2014 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.jta.atomikos; + +import javax.jms.ConnectionFactory; +import javax.jms.XAConnectionFactory; + +import org.junit.Test; + +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.sameInstance; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link AtomikosXAConnectionFactoryWrapper}. + * + * @author Phillip Webb + */ +public class AtomikosXAConnectionFactoryWrapperTests { + + @Test + public void wrap() { + XAConnectionFactory connectionFactory = mock(XAConnectionFactory.class); + AtomikosXAConnectionFactoryWrapper wrapper = new AtomikosXAConnectionFactoryWrapper(); + ConnectionFactory wrapped = wrapper.wrapConnectionFactory(connectionFactory); + assertThat(wrapped, instanceOf(AtomikosConnectionFactoryBean.class)); + assertThat(((AtomikosConnectionFactoryBean) wrapped).getXaConnectionFactory(), + sameInstance(connectionFactory)); + } + +} diff --git a/spring-boot/src/test/java/org/springframework/boot/jta/atomikos/AtomikosXADataSourceWrapperTests.java b/spring-boot/src/test/java/org/springframework/boot/jta/atomikos/AtomikosXADataSourceWrapperTests.java new file mode 100644 index 00000000000..c2d6e56a5fb --- /dev/null +++ b/spring-boot/src/test/java/org/springframework/boot/jta/atomikos/AtomikosXADataSourceWrapperTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2014 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.jta.atomikos; + +import javax.sql.DataSource; +import javax.sql.XADataSource; + +import org.junit.Test; + +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.sameInstance; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link AtomikosXADataSourceWrapper}. + * + * @author Phillip Webb + */ +public class AtomikosXADataSourceWrapperTests { + + @Test + public void wrap() throws Exception { + XADataSource dataSource = mock(XADataSource.class); + AtomikosXADataSourceWrapper wrapper = new AtomikosXADataSourceWrapper(); + DataSource wrapped = wrapper.wrapDataSource(dataSource); + assertThat(wrapped, instanceOf(AtomikosDataSourceBean.class)); + assertThat(((AtomikosDataSourceBean) wrapped).getXaDataSource(), + sameInstance(dataSource)); + } + +} diff --git a/spring-boot/src/test/java/org/springframework/boot/jta/bitronix/BitronixXAConnectionFactoryWrapperTests.java b/spring-boot/src/test/java/org/springframework/boot/jta/bitronix/BitronixXAConnectionFactoryWrapperTests.java new file mode 100644 index 00000000000..fca543971b5 --- /dev/null +++ b/spring-boot/src/test/java/org/springframework/boot/jta/bitronix/BitronixXAConnectionFactoryWrapperTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2014 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.jta.bitronix; + +import javax.jms.ConnectionFactory; +import javax.jms.XAConnectionFactory; + +import org.junit.Test; + +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.sameInstance; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link BitronixXAConnectionFactoryWrapper}. + * + * @author Phillip Webb + */ +public class BitronixXAConnectionFactoryWrapperTests { + + @Test + public void wrap() { + XAConnectionFactory connectionFactory = mock(XAConnectionFactory.class); + BitronixXAConnectionFactoryWrapper wrapper = new BitronixXAConnectionFactoryWrapper(); + ConnectionFactory wrapped = wrapper.wrapConnectionFactory(connectionFactory); + assertThat(wrapped, instanceOf(PoolingConnectionFactoryBean.class)); + assertThat(((PoolingConnectionFactoryBean) wrapped).getConnectionFactory(), + sameInstance(connectionFactory)); + } + +} diff --git a/spring-boot/src/test/java/org/springframework/boot/jta/bitronix/BitronixXADataSourceWrapperTests.java b/spring-boot/src/test/java/org/springframework/boot/jta/bitronix/BitronixXADataSourceWrapperTests.java new file mode 100644 index 00000000000..abea4324404 --- /dev/null +++ b/spring-boot/src/test/java/org/springframework/boot/jta/bitronix/BitronixXADataSourceWrapperTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2014 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.jta.bitronix; + +import javax.sql.DataSource; +import javax.sql.XADataSource; + +import org.junit.Test; + +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.sameInstance; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link BitronixXADataSourceWrapper}. + * + * @author Phillip Webb + */ +public class BitronixXADataSourceWrapperTests { + + @Test + public void wrap() throws Exception { + XADataSource dataSource = mock(XADataSource.class); + BitronixXADataSourceWrapper wrapper = new BitronixXADataSourceWrapper(); + DataSource wrapped = wrapper.wrapDataSource(dataSource); + assertThat(wrapped, instanceOf(PoolingDataSourceBean.class)); + assertThat(((PoolingDataSourceBean) wrapped).getDataSource(), + sameInstance(dataSource)); + } + +}