diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/NarayanaJtaConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/NarayanaJtaConfiguration.java index 0fa78ffac45..ac243d57f10 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/NarayanaJtaConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/NarayanaJtaConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * 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. @@ -22,7 +22,6 @@ import javax.transaction.UserTransaction; import com.arjuna.ats.jbossatx.jta.RecoveryManagerService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.jta.XAConnectionFactoryWrapper; @@ -42,15 +41,20 @@ import org.springframework.transaction.jta.JtaTransactionManager; /** * JTA Configuration for Narayana. * - * @author Gytis Trikleris + * @author Gytis Trikleris + * @since 1.4.0 */ @Configuration -@ConditionalOnClass({ JtaTransactionManager.class, com.arjuna.ats.jta.UserTransaction.class }) +@ConditionalOnClass({ JtaTransactionManager.class, + com.arjuna.ats.jta.UserTransaction.class }) @ConditionalOnMissingBean(PlatformTransactionManager.class) public class NarayanaJtaConfiguration { - @Autowired - private JtaProperties jtaProperties; + private final JtaProperties jtaProperties; + + public NarayanaJtaConfiguration(JtaProperties jtaProperties) { + this.jtaProperties = jtaProperties; + } @Bean @ConditionalOnMissingBean @@ -60,53 +64,57 @@ public class NarayanaJtaConfiguration { @Bean @ConditionalOnMissingBean - public NarayanaConfigurationBean narayanaConfigurationBean(NarayanaProperties narayanaProperties) { + public NarayanaConfigurationBean narayanaConfiguration( + NarayanaProperties properties) { if (this.jtaProperties.getLogDir() != null) { - narayanaProperties.setLogDir(this.jtaProperties.getLogDir()); + properties.setLogDir(this.jtaProperties.getLogDir()); } - if (this.jtaProperties.getTransactionManagerId() != null) { - narayanaProperties.setTransactionManagerId(this.jtaProperties.getTransactionManagerId()); + properties.setTransactionManagerId( + this.jtaProperties.getTransactionManagerId()); } - - return new NarayanaConfigurationBean(narayanaProperties); + return new NarayanaConfigurationBean(properties); } @Bean - @DependsOn("narayanaConfigurationBean") + @DependsOn("narayanaConfiguration") @ConditionalOnMissingBean public UserTransaction narayanaUserTransaction() { return com.arjuna.ats.jta.UserTransaction.userTransaction(); } @Bean - @DependsOn("narayanaConfigurationBean") + @DependsOn("narayanaConfiguration") @ConditionalOnMissingBean public TransactionManager narayanaTransactionManager() { return com.arjuna.ats.jta.TransactionManager.transactionManager(); } @Bean - @DependsOn("narayanaConfigurationBean") + @DependsOn("narayanaConfiguration") public RecoveryManagerService narayanaRecoveryManagerService() { return new RecoveryManagerService(); } @Bean - public NarayanaRecoveryManagerBean narayanaRecoveryManagerBean(RecoveryManagerService recoveryManagerService) { + public NarayanaRecoveryManagerBean narayanaRecoveryManager( + RecoveryManagerService recoveryManagerService) { return new NarayanaRecoveryManagerBean(recoveryManagerService); } @Bean - public JtaTransactionManager transactionManager(UserTransaction userTransaction, TransactionManager transactionManager) { + public JtaTransactionManager transactionManager(UserTransaction userTransaction, + TransactionManager transactionManager) { return new JtaTransactionManager(userTransaction, transactionManager); } @Bean @ConditionalOnMissingBean(XADataSourceWrapper.class) - public XADataSourceWrapper xaDataSourceWrapper(NarayanaRecoveryManagerBean narayanaRecoveryManagerBean, + public XADataSourceWrapper xaDataSourceWrapper( + NarayanaRecoveryManagerBean narayanaRecoveryManagerBean, NarayanaProperties narayanaProperties) { - return new NarayanaXADataSourceWrapper(narayanaRecoveryManagerBean, narayanaProperties); + return new NarayanaXADataSourceWrapper(narayanaRecoveryManagerBean, + narayanaProperties); } @Bean @@ -121,9 +129,12 @@ public class NarayanaJtaConfiguration { @Bean @ConditionalOnMissingBean(XAConnectionFactoryWrapper.class) - public NarayanaXAConnectionFactoryWrapper xaConnectionFactoryWrapper(TransactionManager transactionManager, - NarayanaRecoveryManagerBean narayanaRecoveryManagerBean, NarayanaProperties narayanaProperties) { - return new NarayanaXAConnectionFactoryWrapper(transactionManager, narayanaRecoveryManagerBean, narayanaProperties); + public NarayanaXAConnectionFactoryWrapper xaConnectionFactoryWrapper( + TransactionManager transactionManager, + NarayanaRecoveryManagerBean narayanaRecoveryManagerBean, + NarayanaProperties narayanaProperties) { + return new NarayanaXAConnectionFactoryWrapper(transactionManager, + narayanaRecoveryManagerBean, narayanaProperties); } } diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index 597ac18d134..3de1f716d79 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -100,6 +100,7 @@ 1.1.6 2.2.10 3.3.0.Final + 7.3.0.Final 2.0.6 2.8.1 2.22.2 @@ -124,6 +125,7 @@ 1.10.19 2.14.2 5.1.38 + 5.3.2.Final 1.9.22 2.0.0 9.4.1208.jre7 @@ -174,8 +176,6 @@ 9f96c74 0.30 1.6.3 - 5.3.2.Final - 7.3.0.Final 3.2.1 @@ -401,11 +401,6 @@ spring-boot-starter-jta-bitronix 1.4.0.BUILD-SNAPSHOT - - org.springframework.boot - spring-boot-starter-jta-narayana - 1.4.0.BUILD-SNAPSHOT - org.springframework.boot spring-boot-starter-undertow @@ -436,6 +431,11 @@ spring-boot-starter-mustache 1.4.0.BUILD-SNAPSHOT + + org.springframework.boot + spring-boot-starter-jta-narayana + 1.4.0.BUILD-SNAPSHOT + org.springframework.boot spring-boot-starter-remote-shell @@ -1740,11 +1740,36 @@ javassist ${javassist.version} + + org.jboss + jboss-transaction-spi + ${jboss-transaction-spi.version} + org.jboss.logging jboss-logging ${jboss-logging.version} + + org.jboss.narayana.jta + jdbc + ${narayana.version} + + + org.jboss.narayana.jta + jms + ${narayana.version} + + + org.jboss.narayana.jta + jta + ${narayana.version} + + + org.jboss.narayana.jts + narayana-jts-integration + ${narayana.version} + org.jdom jdom2 @@ -2219,31 +2244,6 @@ wsdl4j ${wsdl4j.version} - - org.jboss.narayana.jta - jta - ${narayana.version} - - - org.jboss.narayana.jta - jdbc - ${narayana.version} - - - org.jboss.narayana.jta - jms - ${narayana.version} - - - org.jboss.narayana.jts - narayana-jts-integration - ${narayana.version} - - - org.jboss - jboss-transaction-spi - ${jboss-transaction-spi.version} - 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 e8e42ffd589..20f9b7d7a18 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -716,17 +716,17 @@ content into your application; rather pick only the properties that you need. spring.jta.bitronix.properties.warn-about-zero-resource-transaction=true # Log a warning for transactions executed without a single enlisted resource. # NARAYANA - spring.jta.narayana.one-phase-commit=true # Enable or disable one phase commit optimisation spring.jta.narayana.default-timeout=60 # Set default transaction timeout in seconds + spring.jta.narayana.expiry-scanners=com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner # List of ExpiryScanner implementations + spring.jta.narayana.one-phase-commit=true # Enable or disable one phase commit optimisation spring.jta.narayana.periodic-recovery-period=120 # Set interval in which periodic recovery scans are performed in seconds spring.jta.narayana.recovery-backoff-period=10 # Set back off period between first and second phases of the recovery scan in seconds - spring.jta.narayana.xa-resource-orphan-filters=com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter,com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter # List of XAResourceOrphanFilter implementations - spring.jta.narayana.recovery-modules=com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule,com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule # List of RecoveryModule implementations - spring.jta.narayana.expiry-scanners=com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner # List of ExpiryScanner implementations spring.jta.narayana.recovery-db-user= # Database username to be used by recovery manager spring.jta.narayana.recovery-db-pass= # Database password to be used by recovery manager spring.jta.narayana.recovery-jms-user= # JMS username to be used by recovery manager spring.jta.narayana.recovery-jms-pass= # JMS password to be used by recovery manager + spring.jta.narayana.recovery-modules=com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule,com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule # List of RecoveryModule implementations + spring.jta.narayana.xa-resource-orphan-filters=com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter,com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter # List of XAResourceOrphanFilter implementations # EMBEDDED MONGODB ({sc-spring-boot-autoconfigure}/mongo/embedded/EmbeddedMongoProperties.{sc-ext}[EmbeddedMongoProperties]) spring.mongodb.embedded.features=SYNC_DELAY # Comma-separated list of features to enable. diff --git a/spring-boot-samples/spring-boot-sample-jta-narayana/pom.xml b/spring-boot-samples/spring-boot-sample-jta-narayana/pom.xml index 4d7d9c32c62..eac68e382d6 100644 --- a/spring-boot-samples/spring-boot-sample-jta-narayana/pom.xml +++ b/spring-boot-samples/spring-boot-sample-jta-narayana/pom.xml @@ -1,57 +1,56 @@ - - 4.0.0 - - spring-boot-samples - org.springframework.boot - 1.4.0.BUILD-SNAPSHOT - - spring-boot-sample-jta-narayana - Spring Boot Narayana JTA Sample - Spring Boot Narayana JTA Sample - http://projects.spring.io/spring-boot/ - - ${basedir}/../.. - - - - org.springframework - spring-jms - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-jta-narayana - - - org.springframework.boot - spring-boot-starter-hornetq - - - org.hornetq - hornetq-jms-server - - - com.h2database - h2 - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - \ No newline at end of file + + 4.0.0 + + spring-boot-samples + org.springframework.boot + 1.4.0.BUILD-SNAPSHOT + + spring-boot-sample-jta-narayana + Spring Boot Narayana JTA Sample + Spring Boot Narayana JTA Sample + http://projects.spring.io/spring-boot/ + + ${basedir}/../.. + + + + org.springframework + spring-jms + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-jta-narayana + + + org.springframework.boot + spring-boot-starter-hornetq + + + org.hornetq + hornetq-jms-server + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/Account.java b/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/Account.java index f588e09f722..ddada8120cd 100644 --- a/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/Account.java +++ b/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/Account.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. diff --git a/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/AccountRepository.java b/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/AccountRepository.java index eb8ec8e9801..ebf3ef4deba 100644 --- a/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/AccountRepository.java +++ b/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/AccountRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. diff --git a/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/AccountService.java b/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/AccountService.java index 72f0d756d46..4333fdae4a1 100644 --- a/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/AccountService.java +++ b/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/AccountService.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. diff --git a/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/Messages.java b/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/Messages.java index 90ff54fb1bd..7ccf4218b54 100644 --- a/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/Messages.java +++ b/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/Messages.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. diff --git a/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/SampleNarayanaApplication.java b/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/SampleNarayanaApplication.java index 9585d14489e..29054ef91cb 100644 --- a/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/SampleNarayanaApplication.java +++ b/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/SampleNarayanaApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. @@ -26,7 +26,8 @@ import org.springframework.context.ApplicationContext; public class SampleNarayanaApplication { public static void main(String[] args) throws Exception { - ApplicationContext context = SpringApplication.run(SampleNarayanaApplication.class, args); + ApplicationContext context = SpringApplication + .run(SampleNarayanaApplication.class, args); AccountService service = context.getBean(AccountService.class); AccountRepository repository = context.getBean(AccountRepository.class); service.createAccountAndNotify("josh"); @@ -34,7 +35,8 @@ public class SampleNarayanaApplication { try { // Using username "error" will cause service to throw SampleRuntimeException service.createAccountAndNotify("error"); - } catch (SampleRuntimeException ex) { + } + catch (SampleRuntimeException ex) { // Log message to let test case know that exception was thrown System.out.println(ex.getMessage()); } diff --git a/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/SampleRuntimeException.java b/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/SampleRuntimeException.java index f65d4848971..1e6a697e0b6 100644 --- a/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/SampleRuntimeException.java +++ b/spring-boot-samples/spring-boot-sample-jta-narayana/src/main/java/sample/narayana/SampleRuntimeException.java @@ -1,8 +1,21 @@ +/* + * 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 sample.narayana; -/** - * @author Gytis Trikleris - */ public class SampleRuntimeException extends RuntimeException { public SampleRuntimeException(String message) { diff --git a/spring-boot-samples/spring-boot-sample-jta-narayana/src/test/java/sample/narayana/SampleNarayanaApplicationTests.java b/spring-boot-samples/spring-boot-sample-jta-narayana/src/test/java/sample/narayana/SampleNarayanaApplicationTests.java index 4ec0ab2b85f..df9c59fb3bb 100644 --- a/spring-boot-samples/spring-boot-sample-jta-narayana/src/test/java/sample/narayana/SampleNarayanaApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-jta-narayana/src/test/java/sample/narayana/SampleNarayanaApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. @@ -16,16 +16,18 @@ package sample.narayana; -import org.hamcrest.Matcher; -import org.hamcrest.core.SubstringMatcher; +import org.assertj.core.api.Condition; import org.junit.Rule; import org.junit.Test; -import org.springframework.boot.test.OutputCapture; -import static org.junit.Assert.assertThat; +import org.springframework.boot.test.rule.OutputCapture; + +import static org.assertj.core.api.Assertions.assertThat; /** - * @author Gytis Trikleris + * Basic integration tests for demo application. + * + * @author Gytis Trikleris */ public class SampleNarayanaApplicationTests { @@ -36,25 +38,22 @@ public class SampleNarayanaApplicationTests { public void testTransactionRollback() throws Exception { SampleNarayanaApplication.main(new String[] {}); String output = this.outputCapture.toString(); - assertThat(output, containsString(1, "---->")); - assertThat(output, containsString(1, "----> josh")); - assertThat(output, containsString(2, "Count is 1")); - assertThat(output, containsString(1, "Simulated error")); + assertThat(output).has(substring(1, "---->")); + assertThat(output).has(substring(1, "----> josh")); + assertThat(output).has(substring(2, "Count is 1")); + assertThat(output).has(substring(1, "Simulated error")); } - private Matcher containsString(final int times, String s) { - return new SubstringMatcher(s) { + private Condition substring(final int times, final String substring) { + return new Condition( + "containing '" + substring + "' " + times + " times") { @Override - protected String relationship() { - return "containing " + times + " times"; - } - - @Override - protected boolean evalSubstringOf(String s) { + public boolean matches(String value) { int i = 0; - while (s.contains(this.substring)) { - s = s.substring(s.indexOf(this.substring) + this.substring.length()); + while (value.contains(substring)) { + int beginIndex = value.indexOf(substring) + substring.length(); + value = value.substring(beginIndex); i++; } return i == times; diff --git a/spring-boot-starters/spring-boot-starter-jta-narayana/pom.xml b/spring-boot-starters/spring-boot-starter-jta-narayana/pom.xml index 9b689932e08..c39459c499a 100644 --- a/spring-boot-starters/spring-boot-starter-jta-narayana/pom.xml +++ b/spring-boot-starters/spring-boot-starter-jta-narayana/pom.xml @@ -1,48 +1,47 @@ - - 4.0.0 - - spring-boot-starters - org.springframework.boot - 1.4.0.BUILD-SNAPSHOT - - spring-boot-starter-jta-narayana - Spring Boot Narayana JTA Starter - Spring Boot Narayana JTA Starter - http://projects.spring.io/spring-boot/ - - ${basedir}/../.. - - - - org.springframework.boot - spring-boot-starter - - - org.jboss.narayana.jta - jta - - - org.jboss.narayana.jta - jdbc - - - org.jboss.narayana.jta - jms - - - org.jboss.narayana.jts - narayana-jts-integration - - - org.jboss - jboss-transaction-spi - - - javax.transaction - javax.transaction-api - - - \ No newline at end of file + + 4.0.0 + + spring-boot-starters + org.springframework.boot + 1.4.0.BUILD-SNAPSHOT + + spring-boot-starter-jta-narayana + Spring Boot Narayana JTA Starter + Spring Boot Narayana JTA Starter + http://projects.spring.io/spring-boot/ + + ${basedir}/../.. + + + + org.springframework.boot + spring-boot-starter + + + org.jboss + jboss-transaction-spi + + + org.jboss.narayana.jta + jdbc + + + org.jboss.narayana.jta + jms + + + org.jboss.narayana.jta + jta + + + org.jboss.narayana.jts + narayana-jts-integration + + + javax.transaction + javax.transaction-api + + + diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/DataSourceXAResourceRecoveryHelper.java b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/DataSourceXAResourceRecoveryHelper.java index 6ff48c18f9c..5f33ee29806 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/DataSourceXAResourceRecoveryHelper.java +++ b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/DataSourceXAResourceRecoveryHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * 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. @@ -17,8 +17,6 @@ package org.springframework.boot.jta.narayana; import java.sql.SQLException; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.sql.XAConnection; import javax.sql.XADataSource; @@ -27,34 +25,56 @@ import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; import com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.util.Assert; /** - * XAResourceRecoveryHelper implementation which gets Xids, which needs to be recovered, from the database. + * XAResourceRecoveryHelper implementation which gets XIDs, which needs to be recovered, + * from the database. * - * @author Gytis Trikleris + * @author Gytis Trikleris + * @since 1.4.0 */ -public class DataSourceXAResourceRecoveryHelper implements XAResourceRecoveryHelper, XAResource { +public class DataSourceXAResourceRecoveryHelper + implements XAResourceRecoveryHelper, XAResource { - private static final Logger LOGGER = Logger.getLogger(DataSourceXAResourceRecoveryHelper.class.getName()); + private static final XAResource[] NO_XA_RESOURCES = {}; + + private static final Log logger = LogFactory + .getLog(DataSourceXAResourceRecoveryHelper.class); private final XADataSource xaDataSource; private final String user; - private final String pass; + private final String password; private XAConnection xaConnection; private XAResource delegate; + /** + * Create a new {@link DataSourceXAResourceRecoveryHelper} instance. + * @param xaDataSource the XA data source + */ public DataSourceXAResourceRecoveryHelper(XADataSource xaDataSource) { this(xaDataSource, null, null); } - public DataSourceXAResourceRecoveryHelper(XADataSource xaDataSource, String user, String pass) { + /** + * Create a new {@link DataSourceXAResourceRecoveryHelper} instance. + * @param xaDataSource the XA data source + * @param user the database user or {@code null} + * @param password the database password or {@code null} + */ + public DataSourceXAResourceRecoveryHelper(XADataSource xaDataSource, String user, + String password) { + Assert.notNull(xaDataSource, "XADataSource must not be null"); this.xaDataSource = xaDataSource; this.user = user; - this.pass = pass; + this.password = password; } @Override @@ -67,90 +87,48 @@ public class DataSourceXAResourceRecoveryHelper implements XAResourceRecoveryHel if (connect()) { return new XAResource[] { this }; } - - return new XAResource[0]; - } - - @Override - public Xid[] recover(int i) throws XAException { - try { - return this.delegate.recover(i); - } - finally { - if (i == XAResource.TMENDRSCAN) { - disconnect(); - } - } - } - - @Override - public void start(Xid xid, int i) throws XAException { - this.delegate.start(xid, i); - } - - @Override - public void end(Xid xid, int i) throws XAException { - this.delegate.end(xid, i); - } - - @Override - public int prepare(Xid xid) throws XAException { - return this.delegate.prepare(xid); - } - - @Override - public void commit(Xid xid, boolean b) throws XAException { - this.delegate.commit(xid, b); - } - - @Override - public void rollback(Xid xid) throws XAException { - this.delegate.rollback(xid); - } - - @Override - public boolean isSameRM(XAResource xaResource) throws XAException { - return this.delegate.isSameRM(xaResource); - } - - @Override - public void forget(Xid xid) throws XAException { - this.delegate.forget(xid); - } - - @Override - public int getTransactionTimeout() throws XAException { - return this.delegate.getTransactionTimeout(); - } - - @Override - public boolean setTransactionTimeout(int i) throws XAException { - return this.delegate.setTransactionTimeout(i); + return NO_XA_RESOURCES; } private boolean connect() { - if (this.delegate != null) { - return true; + if (this.delegate == null) { + try { + this.xaConnection = getXaConnection(); + this.delegate = this.xaConnection.getXAResource(); + } + catch (SQLException ex) { + logger.warn("Failed to create connection", ex); + return false; + } } - - try { - this.xaConnection = getXaConnection(); - this.delegate = this.xaConnection.getXAResource(); - } - catch (SQLException e) { - LOGGER.log(Level.WARNING, "Failed to create connection", e); - return false; - } - return true; } + private XAConnection getXaConnection() throws SQLException { + if (this.user == null && this.password == null) { + return this.xaDataSource.getXAConnection(); + } + return this.xaDataSource.getXAConnection(this.user, this.password); + } + + @Override + public Xid[] recover(int flag) throws XAException { + try { + return getDelegate(true).recover(flag); + } + finally { + if (flag == XAResource.TMENDRSCAN) { + disconnect(); + } + } + } + private void disconnect() throws XAException { try { this.xaConnection.close(); } catch (SQLException e) { - LOGGER.log(Level.WARNING, "Failed to close connection", e); + logger.warn("Failed to close connection", e); } finally { this.xaConnection = null; @@ -158,12 +136,55 @@ public class DataSourceXAResourceRecoveryHelper implements XAResourceRecoveryHel } } - private XAConnection getXaConnection() throws SQLException { - if (this.user == null && this.pass == null) { - return this.xaDataSource.getXAConnection(); - } + @Override + public void start(Xid xid, int flags) throws XAException { + getDelegate(true).start(xid, flags); + } - return this.xaDataSource.getXAConnection(this.user, this.pass); + @Override + public void end(Xid xid, int flags) throws XAException { + getDelegate(true).end(xid, flags); + } + + @Override + public int prepare(Xid xid) throws XAException { + return getDelegate(true).prepare(xid); + } + + @Override + public void commit(Xid xid, boolean onePhase) throws XAException { + getDelegate(true).commit(xid, onePhase); + } + + @Override + public void rollback(Xid xid) throws XAException { + getDelegate(true).rollback(xid); + } + + @Override + public boolean isSameRM(XAResource xaResource) throws XAException { + return getDelegate(true).isSameRM(xaResource); + } + + @Override + public void forget(Xid xid) throws XAException { + getDelegate(true).forget(xid); + } + + @Override + public int getTransactionTimeout() throws XAException { + return getDelegate(true).getTransactionTimeout(); + } + + @Override + public boolean setTransactionTimeout(int seconds) throws XAException { + return getDelegate(true).setTransactionTimeout(seconds); + } + + private XAResource getDelegate(boolean required) { + Assert.state(this.delegate != null || !required, + "Connection has not been opened"); + return this.delegate; } } diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaBeanFactoryPostProcessor.java b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaBeanFactoryPostProcessor.java index 8b7a4513d98..7ca2ca5b538 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaBeanFactoryPostProcessor.java +++ b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaBeanFactoryPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * 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. @@ -26,44 +26,54 @@ import org.springframework.core.Ordered; /** * {@link BeanFactoryPostProcessor} to automatically setup correct beans ordering. * - * @author Gytis Trikleris + * @author Gytis Trikleris + * @since 1.4.0 */ -public class NarayanaBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered { +public class NarayanaBeanFactoryPostProcessor + implements BeanFactoryPostProcessor, Ordered { private static final String[] NO_BEANS = {}; private static final int ORDER = Ordered.LOWEST_PRECEDENCE; @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - String[] transactionManagers = beanFactory.getBeanNamesForType(TransactionManager.class, true, false); - String[] recoveryManagers = beanFactory.getBeanNamesForType(NarayanaRecoveryManagerBean.class, true, false); - + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) + throws BeansException { + String[] transactionManagers = beanFactory + .getBeanNamesForType(TransactionManager.class, true, false); + String[] recoveryManagers = beanFactory + .getBeanNamesForType(NarayanaRecoveryManagerBean.class, true, false); addBeanDependencies(beanFactory, transactionManagers, "javax.sql.DataSource"); addBeanDependencies(beanFactory, recoveryManagers, "javax.sql.DataSource"); - addBeanDependencies(beanFactory, transactionManagers, "javax.jms.ConnectionFactory"); + addBeanDependencies(beanFactory, transactionManagers, + "javax.jms.ConnectionFactory"); addBeanDependencies(beanFactory, recoveryManagers, "javax.jms.ConnectionFactory"); } - private void addBeanDependencies(ConfigurableListableBeanFactory beanFactory, String[] beanNames, String dependencyType) { + private void addBeanDependencies(ConfigurableListableBeanFactory beanFactory, + String[] beanNames, String dependencyType) { for (String beanName : beanNames) { addBeanDependencies(beanFactory, beanName, dependencyType); } } - private void addBeanDependencies(ConfigurableListableBeanFactory beanFactory, String beanName, String dependencyType) { - for (String dependentBeanName : getBeanNamesForType(beanFactory, dependencyType)) { + private void addBeanDependencies(ConfigurableListableBeanFactory beanFactory, + String beanName, String dependencyType) { + for (String dependentBeanName : getBeanNamesForType(beanFactory, + dependencyType)) { beanFactory.registerDependentBean(beanName, dependentBeanName); } } - private String[] getBeanNamesForType(ConfigurableListableBeanFactory beanFactory, String type) { + private String[] getBeanNamesForType(ConfigurableListableBeanFactory beanFactory, + String type) { try { return beanFactory.getBeanNamesForType(Class.forName(type), true, false); } catch (ClassNotFoundException ex) { // Ignore - } catch (NoClassDefFoundError ex) { + } + catch (NoClassDefFoundError ex) { // Ignore } return NO_BEANS; diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaConfigurationBean.java b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaConfigurationBean.java index 311a2c503fd..08094c375c6 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaConfigurationBean.java +++ b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaConfigurationBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * 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. @@ -31,16 +31,17 @@ import org.springframework.beans.factory.InitializingBean; /** * Bean that configures Narayana transaction manager. * - * @author Gytis Trikleris + * @author Gytis Trikleris + * @since 1.4.0 */ public class NarayanaConfigurationBean implements InitializingBean { private static final String JBOSSTS_PROPERTIES_FILE_NAME = "jbossts-properties.xml"; - private final NarayanaProperties narayanaProperties; + private final NarayanaProperties properties; public NarayanaConfigurationBean(NarayanaProperties narayanaProperties) { - this.narayanaProperties = narayanaProperties; + this.properties = narayanaProperties; } @Override @@ -48,59 +49,75 @@ public class NarayanaConfigurationBean implements InitializingBean { if (isPropertiesFileAvailable()) { return; } - - setNodeIdentifier(this.narayanaProperties.getTransactionManagerId()); - setObjectStoreDir(this.narayanaProperties.getLogDir()); - setCommitOnePhase(this.narayanaProperties.isOnePhaseCommit()); - setDefaultTimeout(this.narayanaProperties.getDefaultTimeout()); - setPeriodicRecoveryPeriod(this.narayanaProperties.getPeriodicRecoveryPeriod()); - setRecoveryBackoffPeriod(this.narayanaProperties.getRecoveryBackoffPeriod()); - setXaResourceOrphanFilters(this.narayanaProperties.getXaResourceOrphanFilters()); - setRecoveryModules(this.narayanaProperties.getRecoveryModules()); - setExpiryScanners(this.narayanaProperties.getExpiryScanners()); + setNodeIdentifier(this.properties.getTransactionManagerId()); + setObjectStoreDir(this.properties.getLogDir()); + setCommitOnePhase(this.properties.isOnePhaseCommit()); + setDefaultTimeout(this.properties.getDefaultTimeout()); + setPeriodicRecoveryPeriod(this.properties.getPeriodicRecoveryPeriod()); + setRecoveryBackoffPeriod(this.properties.getRecoveryBackoffPeriod()); + setXaResourceOrphanFilters(this.properties.getXaResourceOrphanFilters()); + setRecoveryModules(this.properties.getRecoveryModules()); + setExpiryScanners(this.properties.getExpiryScanners()); } private boolean isPropertiesFileAvailable() { - return Thread.currentThread().getContextClassLoader().getResource(JBOSSTS_PROPERTIES_FILE_NAME) != null; + return Thread.currentThread().getContextClassLoader() + .getResource(JBOSSTS_PROPERTIES_FILE_NAME) != null; } - private void setNodeIdentifier(String nodeIdentifier) throws CoreEnvironmentBeanException { - BeanPopulator.getDefaultInstance(CoreEnvironmentBean.class).setNodeIdentifier(nodeIdentifier); + private void setNodeIdentifier(String nodeIdentifier) + throws CoreEnvironmentBeanException { + getPopulator(CoreEnvironmentBean.class).setNodeIdentifier(nodeIdentifier); } private void setObjectStoreDir(String objectStoreDir) { - BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class).setObjectStoreDir(objectStoreDir); - BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, "communicationStore") + getPopulator(ObjectStoreEnvironmentBean.class).setObjectStoreDir(objectStoreDir); + getPopulator(ObjectStoreEnvironmentBean.class, "communicationStore") + .setObjectStoreDir(objectStoreDir); + getPopulator(ObjectStoreEnvironmentBean.class, "stateStore") .setObjectStoreDir(objectStoreDir); - BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, "stateStore").setObjectStoreDir(objectStoreDir); } private void setCommitOnePhase(boolean isCommitOnePhase) { - BeanPopulator.getDefaultInstance(CoordinatorEnvironmentBean.class).setCommitOnePhase(isCommitOnePhase); + getPopulator(CoordinatorEnvironmentBean.class) + .setCommitOnePhase(isCommitOnePhase); } private void setDefaultTimeout(int defaultTimeout) { - BeanPopulator.getDefaultInstance(CoordinatorEnvironmentBean.class).setDefaultTimeout(defaultTimeout); + getPopulator(CoordinatorEnvironmentBean.class).setDefaultTimeout(defaultTimeout); } private void setPeriodicRecoveryPeriod(int periodicRecoveryPeriod) { - BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).setPeriodicRecoveryPeriod(periodicRecoveryPeriod); + getPopulator(RecoveryEnvironmentBean.class) + .setPeriodicRecoveryPeriod(periodicRecoveryPeriod); } private void setRecoveryBackoffPeriod(int recoveryBackoffPeriod) { - BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).setRecoveryBackoffPeriod(recoveryBackoffPeriod); + getPopulator(RecoveryEnvironmentBean.class) + .setRecoveryBackoffPeriod(recoveryBackoffPeriod); } private void setXaResourceOrphanFilters(List xaResourceOrphanFilters) { - BeanPopulator.getDefaultInstance(JTAEnvironmentBean.class).setXaResourceOrphanFilterClassNames(xaResourceOrphanFilters); + getPopulator(JTAEnvironmentBean.class) + .setXaResourceOrphanFilterClassNames(xaResourceOrphanFilters); } private void setRecoveryModules(List recoveryModules) { - BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).setRecoveryModuleClassNames(recoveryModules); + getPopulator(RecoveryEnvironmentBean.class) + .setRecoveryModuleClassNames(recoveryModules); } private void setExpiryScanners(List expiryScanners) { - BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).setExpiryScannerClassNames(expiryScanners); + getPopulator(RecoveryEnvironmentBean.class) + .setExpiryScannerClassNames(expiryScanners); + } + + private T getPopulator(Class beanClass) { + return BeanPopulator.getDefaultInstance(beanClass); + } + + private T getPopulator(Class beanClass, String name) { + return BeanPopulator.getNamedInstance(beanClass, name); } } diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaDataSourceBean.java b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaDataSourceBean.java index 1421ec499f9..fd5c63f9966 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaDataSourceBean.java +++ b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaDataSourceBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * 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. @@ -29,16 +29,26 @@ import javax.sql.XADataSource; import com.arjuna.ats.internal.jdbc.ConnectionManager; import com.arjuna.ats.jdbc.TransactionalDriver; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; + /** - * {@link DataSource} implementation wrapping {@link XADataSource} and using {@link ConnectionManager} to acquire connections. + * {@link DataSource} implementation wrapping {@link XADataSource} and using + * {@link ConnectionManager} to acquire connections. * - * @author Gytis Trikleris + * @author Gytis Trikleris + * @since 1.4.0 */ public class NarayanaDataSourceBean implements DataSource { private final XADataSource xaDataSource; + /** + * Create a new {@link NarayanaDataSourceBean} instance. + * @param xaDataSource the XA DataSource + */ public NarayanaDataSourceBean(XADataSource xaDataSource) { + Assert.notNull(xaDataSource, "XADataSource must not be null"); this.xaDataSource = xaDataSource; } @@ -46,17 +56,16 @@ public class NarayanaDataSourceBean implements DataSource { public Connection getConnection() throws SQLException { Properties properties = new Properties(); properties.put(TransactionalDriver.XADataSource, this.xaDataSource); - return ConnectionManager.create(null, properties); } @Override - public Connection getConnection(String username, String password) throws SQLException { + public Connection getConnection(String username, String password) + throws SQLException { Properties properties = new Properties(); properties.put(TransactionalDriver.XADataSource, this.xaDataSource); properties.put(TransactionalDriver.userName, username); properties.put(TransactionalDriver.password, password); - return ConnectionManager.create(null, properties); } @@ -91,20 +100,15 @@ public class NarayanaDataSourceBean implements DataSource { if (isWrapperFor(iface)) { return (T) this; } - else if (isWrapperFor(iface, this.xaDataSource.getClass())) { + if (ClassUtils.isAssignableValue(iface, this.xaDataSource)) { return (T) this.xaDataSource; } - throw new SQLException(getClass() + " is not a wrapper for " + iface); } @Override public boolean isWrapperFor(Class iface) throws SQLException { - return isWrapperFor(iface, getClass()); - } - - private boolean isWrapperFor(Class iface, Class wrapperIface) { - return iface.isAssignableFrom(wrapperIface); + return iface.isAssignableFrom(getClass()); } } diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaProperties.java b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaProperties.java index 1962fe43fbb..730d4736cb8 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaProperties.java +++ b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * 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. @@ -22,10 +22,11 @@ import java.util.List; import org.springframework.boot.context.properties.ConfigurationProperties; /** - * Subset of Narayana properties which can be configured via Spring configuration. Use jbossts-properties.xml for complete - * configuration. + * Subset of Narayana properties which can be configured via Spring configuration. Use + * jbossts-properties.xml for complete configuration. * - * @author Gytis Trikleris + * @author Gytis Trikleris + * @since 1.4.0 */ @ConfigurationProperties(prefix = NarayanaProperties.PROPERTIES_PREFIX) public class NarayanaProperties { @@ -56,12 +57,14 @@ public class NarayanaProperties { private int defaultTimeout = 60; /** - * Interval in which periodic recovery scans are performed in seconds. Default: 120 + * Interval in which periodic recovery scans are performed in seconds. Default: + * 120 */ private int periodicRecoveryPeriod = 120; /** - * Back off period between first and second phases of the recovery scan in seconds. Default: 10 + * Back off period between first and second phases of the recovery scan in seconds. + * Default: 10 */ private int recoveryBackoffPeriod = 10; @@ -88,8 +91,11 @@ public class NarayanaProperties { /** * List of orphan filters. Default: *
    - *
  • com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter
  • - *
  • com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter
  • + *
  • com.arjuna.ats.internal.jta.recovery.arjunacore. + * JTATransactionLogXAResourceOrphanFilter
  • + *
  • + * com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter + *
  • *
*/ private List xaResourceOrphanFilters = Arrays.asList( @@ -103,17 +109,19 @@ public class NarayanaProperties { *
  • com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule
  • * */ - private List recoveryModules = Arrays.asList("com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule", + private List recoveryModules = Arrays.asList( + "com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule", "com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule"); /** * List of expiry scanners. Default: *
      - *
    • com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner
    • + *
    • com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner + *
    • *
    */ - private List expiryScanners = Arrays - .asList("com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner"); + private List expiryScanners = Arrays.asList( + "com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner"); public String getLogDir() { return this.logDir; @@ -218,4 +226,5 @@ public class NarayanaProperties { public void setRecoveryJmsPass(String recoveryJmsPass) { this.recoveryJmsPass = recoveryJmsPass; } + } diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaRecoveryManagerBean.java b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaRecoveryManagerBean.java index 62c2f976bd9..3bbb47356b6 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaRecoveryManagerBean.java +++ b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaRecoveryManagerBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * 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. @@ -24,17 +24,20 @@ import com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; /** * Bean to set up Narayana recovery manager. * - * @author Gytis Trikleris + * @author Gytis Trikleris + * @since 1.4.0 */ public class NarayanaRecoveryManagerBean implements InitializingBean, DisposableBean { private final RecoveryManagerService recoveryManagerService; public NarayanaRecoveryManagerBean(RecoveryManagerService recoveryManagerService) { + Assert.notNull(recoveryManagerService, "RecoveryManagerService must not be null"); this.recoveryManagerService = recoveryManagerService; } @@ -50,8 +53,10 @@ public class NarayanaRecoveryManagerBean implements InitializingBean, Disposable this.recoveryManagerService.destroy(); } - void registerXAResourceRecoveryHelper(XAResourceRecoveryHelper xaResourceRecoveryHelper) { - getXARecoveryModule(RecoveryManager.manager()).addXAResourceRecoveryHelper(xaResourceRecoveryHelper); + void registerXAResourceRecoveryHelper( + XAResourceRecoveryHelper xaResourceRecoveryHelper) { + getXARecoveryModule(RecoveryManager.manager()) + .addXAResourceRecoveryHelper(xaResourceRecoveryHelper); } private XARecoveryModule getXARecoveryModule(RecoveryManager recoveryManager) { @@ -60,8 +65,8 @@ public class NarayanaRecoveryManagerBean implements InitializingBean, Disposable return (XARecoveryModule) recoveryModule; } } - - throw new IllegalStateException("XARecoveryModule is not registered with recovery manager"); + throw new IllegalStateException( + "XARecoveryModule is not registered with recovery manager"); } } diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaXAConnectionFactoryWrapper.java b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaXAConnectionFactoryWrapper.java index 06c4f672659..01bdf220c45 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaXAConnectionFactoryWrapper.java +++ b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaXAConnectionFactoryWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. @@ -26,41 +26,57 @@ import org.jboss.narayana.jta.jms.JmsXAResourceRecoveryHelper; import org.jboss.narayana.jta.jms.TransactionHelperImpl; import org.springframework.boot.jta.XAConnectionFactoryWrapper; +import org.springframework.util.Assert; /** - * {@link XAConnectionFactoryWrapper} that uses {@link ConnectionFactoryProxy} to wrap an {@link XAConnectionFactory}. + * {@link XAConnectionFactoryWrapper} that uses {@link ConnectionFactoryProxy} to wrap an + * {@link XAConnectionFactory}. * - * @author Gytis Trikleris + * @author Gytis Trikleris + * @since 1.4.0 */ public class NarayanaXAConnectionFactoryWrapper implements XAConnectionFactoryWrapper { private final TransactionManager transactionManager; - private final NarayanaRecoveryManagerBean narayanaRecoveryManagerBean; + private final NarayanaRecoveryManagerBean recoveryManager; - private final NarayanaProperties narayanaProperties; + private final NarayanaProperties properties; + /** + * Create a new {@link NarayanaXAConnectionFactoryWrapper} instance. + * @param transactionManager the underlying transaction manager + * @param recoveryManager the underlying recovery manager + * @param properties the Narayana properties + */ public NarayanaXAConnectionFactoryWrapper(TransactionManager transactionManager, - NarayanaRecoveryManagerBean narayanaRecoveryManagerBean, NarayanaProperties narayanaProperties) { + NarayanaRecoveryManagerBean recoveryManager, NarayanaProperties properties) { + Assert.notNull(transactionManager, "TransactionManager must not be null"); + Assert.notNull(recoveryManager, "RecoveryManager must not be null"); + Assert.notNull(properties, "Properties must not be null"); this.transactionManager = transactionManager; - this.narayanaRecoveryManagerBean = narayanaRecoveryManagerBean; - this.narayanaProperties = narayanaProperties; + this.recoveryManager = recoveryManager; + this.properties = properties; } @Override - public ConnectionFactory wrapConnectionFactory(XAConnectionFactory xaConnectionFactory) { - this.narayanaRecoveryManagerBean.registerXAResourceRecoveryHelper(getRecoveryHelper(xaConnectionFactory)); - - return new ConnectionFactoryProxy(xaConnectionFactory, new TransactionHelperImpl(this.transactionManager)); + public ConnectionFactory wrapConnectionFactory( + XAConnectionFactory xaConnectionFactory) { + XAResourceRecoveryHelper recoveryHelper = getRecoveryHelper(xaConnectionFactory); + this.recoveryManager.registerXAResourceRecoveryHelper(recoveryHelper); + return new ConnectionFactoryProxy(xaConnectionFactory, + new TransactionHelperImpl(this.transactionManager)); } - private XAResourceRecoveryHelper getRecoveryHelper(XAConnectionFactory xaConnectionFactory) { - if (this.narayanaProperties.getRecoveryJmsUser() == null && this.narayanaProperties.getRecoveryJmsPass() == null) { + private XAResourceRecoveryHelper getRecoveryHelper( + XAConnectionFactory xaConnectionFactory) { + if (this.properties.getRecoveryJmsUser() == null + && this.properties.getRecoveryJmsPass() == null) { return new JmsXAResourceRecoveryHelper(xaConnectionFactory); } - - return new JmsXAResourceRecoveryHelper(xaConnectionFactory, this.narayanaProperties.getRecoveryJmsUser(), - this.narayanaProperties.getRecoveryJmsPass()); + return new JmsXAResourceRecoveryHelper(xaConnectionFactory, + this.properties.getRecoveryJmsUser(), + this.properties.getRecoveryJmsPass()); } } diff --git a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaXADataSourceWrapper.java b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaXADataSourceWrapper.java index 7bb844164f4..e7705be90a7 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaXADataSourceWrapper.java +++ b/spring-boot/src/main/java/org/springframework/boot/jta/narayana/NarayanaXADataSourceWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * 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. @@ -22,38 +22,48 @@ import javax.sql.XADataSource; import com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper; import org.springframework.boot.jta.XADataSourceWrapper; +import org.springframework.util.Assert; /** - * {@link XADataSourceWrapper} that uses {@link NarayanaDataSourceBean} to wrap an {@link XADataSource}. + * {@link XADataSourceWrapper} that uses {@link NarayanaDataSourceBean} to wrap an + * {@link XADataSource}. * - * @author Gytis Trikleris + * @author Gytis Trikleris + * @since 1.4.0 */ public class NarayanaXADataSourceWrapper implements XADataSourceWrapper { - private final NarayanaRecoveryManagerBean narayanaRecoveryManagerBean; + private final NarayanaRecoveryManagerBean recoveryManager; - private final NarayanaProperties narayanaProperties; + private final NarayanaProperties properties; - public NarayanaXADataSourceWrapper(NarayanaRecoveryManagerBean narayanaRecoveryManagerBean, - NarayanaProperties narayanaProperties) { - this.narayanaRecoveryManagerBean = narayanaRecoveryManagerBean; - this.narayanaProperties = narayanaProperties; + /** + * Create a new {@link NarayanaXADataSourceWrapper} instance. + * @param recoveryManager the underlying recovery manager + * @param properties the Narayana properties + */ + public NarayanaXADataSourceWrapper(NarayanaRecoveryManagerBean recoveryManager, + NarayanaProperties properties) { + Assert.notNull(recoveryManager, "RecoveryManager must not be null"); + Assert.notNull(properties, "Properties must not be null"); + this.recoveryManager = recoveryManager; + this.properties = properties; } @Override public DataSource wrapDataSource(XADataSource dataSource) { - this.narayanaRecoveryManagerBean.registerXAResourceRecoveryHelper(getRecoveryHelper(dataSource)); - + XAResourceRecoveryHelper recoveryHelper = getRecoveryHelper(dataSource); + this.recoveryManager.registerXAResourceRecoveryHelper(recoveryHelper); return new NarayanaDataSourceBean(dataSource); } private XAResourceRecoveryHelper getRecoveryHelper(XADataSource dataSource) { - if (this.narayanaProperties.getRecoveryDbUser() == null && this.narayanaProperties.getRecoveryDbPass() == null) { + if (this.properties.getRecoveryDbUser() == null + && this.properties.getRecoveryDbPass() == null) { return new DataSourceXAResourceRecoveryHelper(dataSource); } - - return new DataSourceXAResourceRecoveryHelper(dataSource, this.narayanaProperties.getRecoveryDbUser(), - this.narayanaProperties.getRecoveryDbPass()); + return new DataSourceXAResourceRecoveryHelper(dataSource, + this.properties.getRecoveryDbUser(), this.properties.getRecoveryDbPass()); } } diff --git a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/DataSourceXAResourceRecoveryHelperTests.java b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/DataSourceXAResourceRecoveryHelperTests.java index ab9b74d23cb..06eff9acdda 100644 --- a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/DataSourceXAResourceRecoveryHelperTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/DataSourceXAResourceRecoveryHelperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. @@ -27,14 +27,16 @@ import org.junit.Before; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.times; -import static org.mockito.BDDMockito.verify; -import static org.mockito.BDDMockito.when; +import static org.mockito.BDDMockito.given; import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; /** - * @author Gytis Trikleris + * Tests for {@link DataSourceXAResourceRecoveryHelper}. + * + * @author Gytis Trikleris */ public class DataSourceXAResourceRecoveryHelperTests { @@ -53,8 +55,8 @@ public class DataSourceXAResourceRecoveryHelperTests { this.xaResource = mock(XAResource.class); this.recoveryHelper = new DataSourceXAResourceRecoveryHelper(this.xaDataSource); - when(this.xaDataSource.getXAConnection()).thenReturn(this.xaConnection); - when(this.xaConnection.getXAResource()).thenReturn(this.xaResource); + given(this.xaDataSource.getXAConnection()).willReturn(this.xaConnection); + given(this.xaConnection.getXAResource()).willReturn(this.xaResource); } @Test @@ -67,10 +69,12 @@ public class DataSourceXAResourceRecoveryHelperTests { } @Test - public void shouldCreateConnectionWithCredentialsAndGetXAResource() throws SQLException { - when(this.xaDataSource.getXAConnection(anyString(), anyString())).thenReturn(this.xaConnection); - this.recoveryHelper = new DataSourceXAResourceRecoveryHelper(this.xaDataSource, "username", "password"); - + public void shouldCreateConnectionWithCredentialsAndGetXAResource() + throws SQLException { + given(this.xaDataSource.getXAConnection(anyString(), anyString())) + .willReturn(this.xaConnection); + this.recoveryHelper = new DataSourceXAResourceRecoveryHelper(this.xaDataSource, + "username", "password"); XAResource[] xaResources = this.recoveryHelper.getXAResources(); assertThat(xaResources.length).isEqualTo(1); assertThat(xaResources[0]).isSameAs(this.recoveryHelper); @@ -80,10 +84,9 @@ public class DataSourceXAResourceRecoveryHelperTests { @Test public void shouldFailToCreateConnectionAndNotGetXAResource() throws SQLException { - when(this.xaDataSource.getXAConnection()).thenThrow(new SQLException("Test exception")); - + given(this.xaDataSource.getXAConnection()) + .willThrow(new SQLException("Test exception")); XAResource[] xaResources = this.recoveryHelper.getXAResources(); - assertThat(xaResources.length).isEqualTo(0); verify(this.xaDataSource, times(1)).getXAConnection(); verify(this.xaConnection, times(0)).getXAResource(); @@ -93,15 +96,14 @@ public class DataSourceXAResourceRecoveryHelperTests { public void shouldDelegateRecoverCall() throws XAException { this.recoveryHelper.getXAResources(); this.recoveryHelper.recover(XAResource.TMSTARTRSCAN); - verify(this.xaResource, times(1)).recover(XAResource.TMSTARTRSCAN); } @Test - public void shouldDelegateRecoverCallAndCloseConnection() throws XAException, SQLException { + public void shouldDelegateRecoverCallAndCloseConnection() + throws XAException, SQLException { this.recoveryHelper.getXAResources(); this.recoveryHelper.recover(XAResource.TMENDRSCAN); - verify(this.xaResource, times(1)).recover(XAResource.TMENDRSCAN); verify(this.xaConnection, times(1)).close(); } @@ -110,7 +112,6 @@ public class DataSourceXAResourceRecoveryHelperTests { public void shouldDelegateStartCall() throws XAException { this.recoveryHelper.getXAResources(); this.recoveryHelper.start(null, 0); - verify(this.xaResource, times(1)).start(null, 0); } @@ -118,7 +119,6 @@ public class DataSourceXAResourceRecoveryHelperTests { public void shouldDelegateEndCall() throws XAException { this.recoveryHelper.getXAResources(); this.recoveryHelper.end(null, 0); - verify(this.xaResource, times(1)).end(null, 0); } @@ -126,7 +126,6 @@ public class DataSourceXAResourceRecoveryHelperTests { public void shouldDelegatePrepareCall() throws XAException { this.recoveryHelper.getXAResources(); this.recoveryHelper.prepare(null); - verify(this.xaResource, times(1)).prepare(null); } @@ -134,7 +133,6 @@ public class DataSourceXAResourceRecoveryHelperTests { public void shouldDelegateCommitCall() throws XAException { this.recoveryHelper.getXAResources(); this.recoveryHelper.commit(null, true); - verify(this.xaResource, times(1)).commit(null, true); } @@ -142,7 +140,6 @@ public class DataSourceXAResourceRecoveryHelperTests { public void shouldDelegateRollbackCall() throws XAException { this.recoveryHelper.getXAResources(); this.recoveryHelper.rollback(null); - verify(this.xaResource, times(1)).rollback(null); } @@ -150,7 +147,6 @@ public class DataSourceXAResourceRecoveryHelperTests { public void shouldDelegateIsSameRMCall() throws XAException { this.recoveryHelper.getXAResources(); this.recoveryHelper.isSameRM(null); - verify(this.xaResource, times(1)).isSameRM(null); } @@ -158,7 +154,6 @@ public class DataSourceXAResourceRecoveryHelperTests { public void shouldDelegateForgetCall() throws XAException { this.recoveryHelper.getXAResources(); this.recoveryHelper.forget(null); - verify(this.xaResource, times(1)).forget(null); } @@ -166,7 +161,6 @@ public class DataSourceXAResourceRecoveryHelperTests { public void shouldDelegateGetTransactionTimeoutCall() throws XAException { this.recoveryHelper.getXAResources(); this.recoveryHelper.getTransactionTimeout(); - verify(this.xaResource, times(1)).getTransactionTimeout(); } @@ -174,9 +168,7 @@ public class DataSourceXAResourceRecoveryHelperTests { public void shouldDelegateSetTransactionTimeoutCall() throws XAException { this.recoveryHelper.getXAResources(); this.recoveryHelper.setTransactionTimeout(0); - verify(this.xaResource, times(1)).setTransactionTimeout(0); } } - diff --git a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaBeanFactoryPostProcessorTests.java b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaBeanFactoryPostProcessorTests.java index c0e25db46c6..07f50888c43 100644 --- a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaBeanFactoryPostProcessorTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaBeanFactoryPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * 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. @@ -27,12 +27,14 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.spy; -import static org.mockito.BDDMockito.verify; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; /** - * @author Gytis Trikleris + * Tests for {@link NarayanaBeanFactoryPostProcessor}. + * + * @author Gytis Trikleris */ public class NarayanaBeanFactoryPostProcessorTests { @@ -41,16 +43,17 @@ public class NarayanaBeanFactoryPostProcessorTests { @Test public void setsDependsOn() { DefaultListableBeanFactory beanFactory = spy(new DefaultListableBeanFactory()); - this.context = new AnnotationConfigApplicationContext(beanFactory); this.context.register(Config.class); this.context.refresh(); - - verify(beanFactory).registerDependentBean("narayanaTransactionManager", "dataSource"); - verify(beanFactory).registerDependentBean("narayanaTransactionManager", "connectionFactory"); - verify(beanFactory).registerDependentBean("narayanaRecoveryManagerBean", "dataSource"); - verify(beanFactory).registerDependentBean("narayanaRecoveryManagerBean", "connectionFactory"); - + verify(beanFactory).registerDependentBean("narayanaTransactionManager", + "dataSource"); + verify(beanFactory).registerDependentBean("narayanaTransactionManager", + "connectionFactory"); + verify(beanFactory).registerDependentBean("narayanaRecoveryManagerBean", + "dataSource"); + verify(beanFactory).registerDependentBean("narayanaRecoveryManagerBean", + "connectionFactory"); this.context.close(); } diff --git a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaConfigurationBeanTests.java b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaConfigurationBeanTests.java index e60e82781d0..a09221f8b51 100644 --- a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaConfigurationBeanTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaConfigurationBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. @@ -25,52 +25,63 @@ import com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean; import com.arjuna.ats.arjuna.common.RecoveryEnvironmentBean; import com.arjuna.ats.jta.common.JTAEnvironmentBean; import com.arjuna.common.internal.util.propertyservice.BeanPopulator; - import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; /** - * @author Gytis Trikleris + * Tests for {@link NarayanaConfigurationBean}. + * + * @author Gytis Trikleris */ public class NarayanaConfigurationBeanTests { @Test public void shouldSetDefaultProperties() throws Exception { NarayanaProperties narayanaProperties = new NarayanaProperties(); - NarayanaConfigurationBean narayanaConfigurationBean = new NarayanaConfigurationBean(narayanaProperties); + NarayanaConfigurationBean narayanaConfigurationBean = new NarayanaConfigurationBean( + narayanaProperties); narayanaConfigurationBean.afterPropertiesSet(); - assertThat(BeanPopulator.getDefaultInstance(CoreEnvironmentBean.class).getNodeIdentifier()).isEqualTo("1"); - assertThat(BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class).getObjectStoreDir()) - .isEqualTo("target/tx-object-store"); - assertThat(BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, "communicationStore").getObjectStoreDir()) - .isEqualTo("target/tx-object-store"); - assertThat(BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, "stateStore").getObjectStoreDir()) - .isEqualTo("target/tx-object-store"); - assertThat(BeanPopulator.getDefaultInstance(CoordinatorEnvironmentBean.class).isCommitOnePhase()).isTrue(); - assertThat(BeanPopulator.getDefaultInstance(CoordinatorEnvironmentBean.class).getDefaultTimeout()).isEqualTo(60); - assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).getPeriodicRecoveryPeriod()).isEqualTo(120); - assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).getRecoveryBackoffPeriod()).isEqualTo(10); - + assertThat(BeanPopulator.getDefaultInstance(CoreEnvironmentBean.class) + .getNodeIdentifier()).isEqualTo("1"); + assertThat(BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class) + .getObjectStoreDir()).isEqualTo("target/tx-object-store"); + assertThat(BeanPopulator + .getNamedInstance(ObjectStoreEnvironmentBean.class, "communicationStore") + .getObjectStoreDir()).isEqualTo("target/tx-object-store"); + assertThat(BeanPopulator + .getNamedInstance(ObjectStoreEnvironmentBean.class, "stateStore") + .getObjectStoreDir()).isEqualTo("target/tx-object-store"); + assertThat(BeanPopulator.getDefaultInstance(CoordinatorEnvironmentBean.class) + .isCommitOnePhase()).isTrue(); + assertThat(BeanPopulator.getDefaultInstance(CoordinatorEnvironmentBean.class) + .getDefaultTimeout()).isEqualTo(60); + assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class) + .getPeriodicRecoveryPeriod()).isEqualTo(120); + assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class) + .getRecoveryBackoffPeriod()).isEqualTo(10); List xaResourceOrphanFilters = Arrays.asList( "com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter", "com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter"); - assertThat(BeanPopulator.getDefaultInstance(JTAEnvironmentBean.class).getXaResourceOrphanFilterClassNames()) - .isEqualTo(xaResourceOrphanFilters); + assertThat(BeanPopulator.getDefaultInstance(JTAEnvironmentBean.class) + .getXaResourceOrphanFilterClassNames()) + .isEqualTo(xaResourceOrphanFilters); - List recoveryModules = Arrays.asList("com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule", + List recoveryModules = Arrays.asList( + "com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule", "com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule"); - assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).getRecoveryModuleClassNames()) - .isEqualTo(recoveryModules); + assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class) + .getRecoveryModuleClassNames()).isEqualTo(recoveryModules); - List expiryScanners = Arrays - .asList("com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner"); - assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).getExpiryScannerClassNames()) - .isEqualTo(expiryScanners); + List expiryScanners = Arrays.asList( + "com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner"); + assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class) + .getExpiryScannerClassNames()).isEqualTo(expiryScanners); - assertThat(BeanPopulator.getDefaultInstance(JTAEnvironmentBean.class).getXaResourceRecoveryClassNames()).isEmpty(); + assertThat(BeanPopulator.getDefaultInstance(JTAEnvironmentBean.class) + .getXaResourceRecoveryClassNames()).isEmpty(); } @Test @@ -82,30 +93,44 @@ public class NarayanaConfigurationBeanTests { narayanaProperties.setPeriodicRecoveryPeriod(2); narayanaProperties.setRecoveryBackoffPeriod(3); narayanaProperties.setOnePhaseCommit(false); - narayanaProperties.setXaResourceOrphanFilters(Arrays.asList("test-filter-1", "test-filter-2")); - narayanaProperties.setRecoveryModules(Arrays.asList("test-module-1", "test-module-2")); - narayanaProperties.setExpiryScanners(Arrays.asList("test-scanner-1", "test-scanner-2")); + narayanaProperties.setXaResourceOrphanFilters( + Arrays.asList("test-filter-1", "test-filter-2")); + narayanaProperties + .setRecoveryModules(Arrays.asList("test-module-1", "test-module-2")); + narayanaProperties + .setExpiryScanners(Arrays.asList("test-scanner-1", "test-scanner-2")); - NarayanaConfigurationBean narayanaConfigurationBean = new NarayanaConfigurationBean(narayanaProperties); + NarayanaConfigurationBean narayanaConfigurationBean = new NarayanaConfigurationBean( + narayanaProperties); narayanaConfigurationBean.afterPropertiesSet(); - assertThat(BeanPopulator.getDefaultInstance(CoreEnvironmentBean.class).getNodeIdentifier()).isEqualTo("test-id"); - assertThat(BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class).getObjectStoreDir()) - .isEqualTo("test-dir"); - assertThat(BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, "communicationStore").getObjectStoreDir()) - .isEqualTo("test-dir"); - assertThat(BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, "stateStore").getObjectStoreDir()) - .isEqualTo("test-dir"); - assertThat(BeanPopulator.getDefaultInstance(CoordinatorEnvironmentBean.class).isCommitOnePhase()).isFalse(); - assertThat(BeanPopulator.getDefaultInstance(CoordinatorEnvironmentBean.class).getDefaultTimeout()).isEqualTo(1); - assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).getPeriodicRecoveryPeriod()).isEqualTo(2); - assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).getRecoveryBackoffPeriod()).isEqualTo(3); - assertThat(BeanPopulator.getDefaultInstance(JTAEnvironmentBean.class).getXaResourceOrphanFilterClassNames()) - .isEqualTo(Arrays.asList("test-filter-1", "test-filter-2")); - assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).getRecoveryModuleClassNames()) - .isEqualTo(Arrays.asList("test-module-1", "test-module-2")); - assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).getExpiryScannerClassNames()) - .isEqualTo(Arrays.asList("test-scanner-1", "test-scanner-2")); + assertThat(BeanPopulator.getDefaultInstance(CoreEnvironmentBean.class) + .getNodeIdentifier()).isEqualTo("test-id"); + assertThat(BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class) + .getObjectStoreDir()).isEqualTo("test-dir"); + assertThat(BeanPopulator + .getNamedInstance(ObjectStoreEnvironmentBean.class, "communicationStore") + .getObjectStoreDir()).isEqualTo("test-dir"); + assertThat(BeanPopulator + .getNamedInstance(ObjectStoreEnvironmentBean.class, "stateStore") + .getObjectStoreDir()).isEqualTo("test-dir"); + assertThat(BeanPopulator.getDefaultInstance(CoordinatorEnvironmentBean.class) + .isCommitOnePhase()).isFalse(); + assertThat(BeanPopulator.getDefaultInstance(CoordinatorEnvironmentBean.class) + .getDefaultTimeout()).isEqualTo(1); + assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class) + .getPeriodicRecoveryPeriod()).isEqualTo(2); + assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class) + .getRecoveryBackoffPeriod()).isEqualTo(3); + assertThat(BeanPopulator.getDefaultInstance(JTAEnvironmentBean.class) + .getXaResourceOrphanFilterClassNames()) + .isEqualTo(Arrays.asList("test-filter-1", "test-filter-2")); + assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class) + .getRecoveryModuleClassNames()) + .isEqualTo(Arrays.asList("test-module-1", "test-module-2")); + assertThat(BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class) + .getExpiryScannerClassNames()) + .isEqualTo(Arrays.asList("test-scanner-1", "test-scanner-2")); } } diff --git a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaDataSourceBeanTests.java b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaDataSourceBeanTests.java index 3521a8f1d75..fada25acca9 100644 --- a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaDataSourceBeanTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaDataSourceBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. @@ -30,24 +30,26 @@ import org.junit.Before; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.times; -import static org.mockito.BDDMockito.verify; -import static org.mockito.BDDMockito.when; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; /** - * @author Gytis Trikleris + * Tests for {@link NarayanaDataSourceBean}. + * + * @author Gytis Trikleris */ public class NarayanaDataSourceBeanTests { - private XADataSource mockDataSource; + private XADataSource dataSource; private NarayanaDataSourceBean dataSourceBean; @Before public void before() { - this.mockDataSource = mock(XADataSource.class); - this.dataSourceBean = new NarayanaDataSourceBean(this.mockDataSource); + this.dataSource = mock(XADataSource.class); + this.dataSourceBean = new NarayanaDataSourceBean(this.dataSource); } @Test @@ -62,32 +64,36 @@ public class NarayanaDataSourceBeanTests { @Test public void shouldUnwrapDataSource() throws SQLException { - assertThat(this.dataSourceBean.unwrap(DataSource.class)).isInstanceOf(DataSource.class); - assertThat(this.dataSourceBean.unwrap(DataSource.class)).isSameAs(this.dataSourceBean); + assertThat(this.dataSourceBean.unwrap(DataSource.class)) + .isInstanceOf(DataSource.class); + assertThat(this.dataSourceBean.unwrap(DataSource.class)) + .isSameAs(this.dataSourceBean); } @Test public void shouldUnwrapXaDataSource() throws SQLException { - assertThat(this.dataSourceBean.unwrap(XADataSource.class)).isInstanceOf(XADataSource.class); - assertThat(this.dataSourceBean.unwrap(XADataSource.class)).isSameAs(this.mockDataSource); + assertThat(this.dataSourceBean.unwrap(XADataSource.class)) + .isInstanceOf(XADataSource.class); + assertThat(this.dataSourceBean.unwrap(XADataSource.class)) + .isSameAs(this.dataSource); } @Test public void shouldGetConnectionAndCommit() throws SQLException { Connection mockConnection = mock(Connection.class); XAConnection mockXaConnection = mock(XAConnection.class); - when(mockXaConnection.getConnection()).thenReturn(mockConnection); - when(this.mockDataSource.getXAConnection()).thenReturn(mockXaConnection); + given(mockXaConnection.getConnection()).willReturn(mockConnection); + given(this.dataSource.getXAConnection()).willReturn(mockXaConnection); Properties properties = new Properties(); - properties.put(TransactionalDriver.XADataSource, this.mockDataSource); + properties.put(TransactionalDriver.XADataSource, this.dataSource); Connection connection = this.dataSourceBean.getConnection(); assertThat(connection).isInstanceOf(ConnectionImple.class); connection.commit(); - verify(this.mockDataSource, times(1)).getXAConnection(); + verify(this.dataSource, times(1)).getXAConnection(); verify(mockXaConnection, times(1)).getConnection(); verify(mockConnection, times(1)).commit(); } @@ -98,11 +104,12 @@ public class NarayanaDataSourceBeanTests { String password = "testPassword"; Connection mockConnection = mock(Connection.class); XAConnection mockXaConnection = mock(XAConnection.class); - when(mockXaConnection.getConnection()).thenReturn(mockConnection); - when(this.mockDataSource.getXAConnection(username, password)).thenReturn(mockXaConnection); + given(mockXaConnection.getConnection()).willReturn(mockConnection); + given(this.dataSource.getXAConnection(username, password)) + .willReturn(mockXaConnection); Properties properties = new Properties(); - properties.put(TransactionalDriver.XADataSource, this.mockDataSource); + properties.put(TransactionalDriver.XADataSource, this.dataSource); properties.put(TransactionalDriver.userName, username); properties.put(TransactionalDriver.password, password); @@ -111,7 +118,7 @@ public class NarayanaDataSourceBeanTests { connection.commit(); - verify(this.mockDataSource, times(1)).getXAConnection(username, password); + verify(this.dataSource, times(1)).getXAConnection(username, password); verify(mockXaConnection, times(1)).getConnection(); verify(mockConnection, times(1)).commit(); } diff --git a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaRecoveryManagerBeanTests.java b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaRecoveryManagerBeanTests.java index 5e66bba76d4..f90425ede27 100644 --- a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaRecoveryManagerBeanTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaRecoveryManagerBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. @@ -17,7 +17,6 @@ package org.springframework.boot.jta.narayana; import com.arjuna.ats.jbossatx.jta.RecoveryManagerService; - import org.junit.Before; import org.junit.Test; @@ -26,34 +25,34 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; /** - * @author Gytis Trikleris + * Tests for {@link NarayanaRecoveryManagerBean}. + * + * @author Gytis Trikleris */ public class NarayanaRecoveryManagerBeanTests { - private RecoveryManagerService recoveryManagerService; + private RecoveryManagerService service; - private NarayanaRecoveryManagerBean narayanaRecoveryManagerBean; + private NarayanaRecoveryManagerBean recoveryManager; @Before public void before() { - this.recoveryManagerService = mock(RecoveryManagerService.class); - this.narayanaRecoveryManagerBean = new NarayanaRecoveryManagerBean(this.recoveryManagerService); + this.service = mock(RecoveryManagerService.class); + this.recoveryManager = new NarayanaRecoveryManagerBean(this.service); } @Test public void shouldCreateAndStartRecoveryManagerService() throws Exception { - this.narayanaRecoveryManagerBean.afterPropertiesSet(); - - verify(this.recoveryManagerService, times(1)).create(); - verify(this.recoveryManagerService, times(1)).start(); + this.recoveryManager.afterPropertiesSet(); + verify(this.service, times(1)).create(); + verify(this.service, times(1)).start(); } @Test public void shouldStopAndDestroyRecoveryManagerService() throws Exception { - this.narayanaRecoveryManagerBean.destroy(); - - verify(this.recoveryManagerService, times(1)).stop(); - verify(this.recoveryManagerService, times(1)).destroy(); + this.recoveryManager.destroy(); + verify(this.service, times(1)).stop(); + verify(this.service, times(1)).destroy(); } } diff --git a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaXAConnectionFactoryWrapperTests.java b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaXAConnectionFactoryWrapperTests.java index 6105d5be2a9..e1a8143327d 100644 --- a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaXAConnectionFactoryWrapperTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaXAConnectionFactoryWrapperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. @@ -25,14 +25,16 @@ import org.jboss.narayana.jta.jms.JmsXAResourceRecoveryHelper; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.times; -import static org.mockito.BDDMockito.verify; -import static org.mockito.BDDMockito.when; +import static org.mockito.BDDMockito.given; import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; /** - * @author Gytis Trikleris + * Tests for {@link NarayanaXAConnectionFactoryWrapper}. + * + * @author Gytis Trikleris */ public class NarayanaXAConnectionFactoryWrapperTests { @@ -40,34 +42,36 @@ public class NarayanaXAConnectionFactoryWrapperTests { private TransactionManager transactionManager = mock(TransactionManager.class); - private NarayanaRecoveryManagerBean narayanaRecoveryManagerBean = mock(NarayanaRecoveryManagerBean.class); + private NarayanaRecoveryManagerBean recoveryManager = mock( + NarayanaRecoveryManagerBean.class); - private NarayanaProperties narayanaProperties = mock(NarayanaProperties.class); + private NarayanaProperties properties = mock(NarayanaProperties.class); - private NarayanaXAConnectionFactoryWrapper wrapper = new NarayanaXAConnectionFactoryWrapper(this.transactionManager, - this.narayanaRecoveryManagerBean, this.narayanaProperties); + private NarayanaXAConnectionFactoryWrapper wrapper = new NarayanaXAConnectionFactoryWrapper( + this.transactionManager, this.recoveryManager, this.properties); @Test public void wrap() { - ConnectionFactory wrapped = this.wrapper.wrapConnectionFactory(this.connectionFactory); + ConnectionFactory wrapped = this.wrapper + .wrapConnectionFactory(this.connectionFactory); assertThat(wrapped).isInstanceOf(ConnectionFactoryProxy.class); - verify(this.narayanaRecoveryManagerBean, times(1)) + verify(this.recoveryManager, times(1)) .registerXAResourceRecoveryHelper(any(JmsXAResourceRecoveryHelper.class)); - verify(this.narayanaProperties, times(1)).getRecoveryJmsUser(); - verify(this.narayanaProperties, times(1)).getRecoveryJmsPass(); + verify(this.properties, times(1)).getRecoveryJmsUser(); + verify(this.properties, times(1)).getRecoveryJmsPass(); } @Test public void wrapWithCredentials() { - when(this.narayanaProperties.getRecoveryJmsUser()).thenReturn("userName"); - when(this.narayanaProperties.getRecoveryJmsPass()).thenReturn("password"); - ConnectionFactory wrapped = this.wrapper.wrapConnectionFactory(this.connectionFactory); - + given(this.properties.getRecoveryJmsUser()).willReturn("userName"); + given(this.properties.getRecoveryJmsPass()).willReturn("password"); + ConnectionFactory wrapped = this.wrapper + .wrapConnectionFactory(this.connectionFactory); assertThat(wrapped).isInstanceOf(ConnectionFactoryProxy.class); - verify(this.narayanaRecoveryManagerBean, times(1)) + verify(this.recoveryManager, times(1)) .registerXAResourceRecoveryHelper(any(JmsXAResourceRecoveryHelper.class)); - verify(this.narayanaProperties, times(2)).getRecoveryJmsUser(); - verify(this.narayanaProperties, times(1)).getRecoveryJmsPass(); + verify(this.properties, times(2)).getRecoveryJmsUser(); + verify(this.properties, times(1)).getRecoveryJmsPass(); } } diff --git a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaXADataSourceWrapperTests.java b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaXADataSourceWrapperTests.java index 2b031898fde..aa1ac6f4a68 100644 --- a/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaXADataSourceWrapperTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/jta/narayana/NarayanaXADataSourceWrapperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. @@ -22,48 +22,49 @@ import javax.sql.XADataSource; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.times; -import static org.mockito.BDDMockito.verify; -import static org.mockito.BDDMockito.when; +import static org.mockito.BDDMockito.given; import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; /** - * @author Gytis Trikleris + * Tests for {@link NarayanaXADataSourceWrapper}. + * + * @author Gytis Trikleris */ public class NarayanaXADataSourceWrapperTests { private XADataSource dataSource = mock(XADataSource.class); - private NarayanaRecoveryManagerBean narayanaRecoveryManagerBean = mock(NarayanaRecoveryManagerBean.class); + private NarayanaRecoveryManagerBean recoveryManager = mock( + NarayanaRecoveryManagerBean.class); - private NarayanaProperties narayanaProperties = mock(NarayanaProperties.class); + private NarayanaProperties properties = mock(NarayanaProperties.class); - private NarayanaXADataSourceWrapper wrapper = new NarayanaXADataSourceWrapper(this.narayanaRecoveryManagerBean, - this.narayanaProperties); + private NarayanaXADataSourceWrapper wrapper = new NarayanaXADataSourceWrapper( + this.recoveryManager, this.properties); @Test public void wrap() { DataSource wrapped = this.wrapper.wrapDataSource(this.dataSource); - assertThat(wrapped).isInstanceOf(NarayanaDataSourceBean.class); - verify(this.narayanaRecoveryManagerBean, times(1)) - .registerXAResourceRecoveryHelper(any(DataSourceXAResourceRecoveryHelper.class)); - verify(this.narayanaProperties, times(1)).getRecoveryDbUser(); - verify(this.narayanaProperties, times(1)).getRecoveryDbPass(); + verify(this.recoveryManager, times(1)).registerXAResourceRecoveryHelper( + any(DataSourceXAResourceRecoveryHelper.class)); + verify(this.properties, times(1)).getRecoveryDbUser(); + verify(this.properties, times(1)).getRecoveryDbPass(); } @Test public void wrapWithCredentials() { - when(this.narayanaProperties.getRecoveryDbUser()).thenReturn("userName"); - when(this.narayanaProperties.getRecoveryDbPass()).thenReturn("password"); + given(this.properties.getRecoveryDbUser()).willReturn("userName"); + given(this.properties.getRecoveryDbPass()).willReturn("password"); DataSource wrapped = this.wrapper.wrapDataSource(this.dataSource); - assertThat(wrapped).isInstanceOf(NarayanaDataSourceBean.class); - verify(this.narayanaRecoveryManagerBean, times(1)) - .registerXAResourceRecoveryHelper(any(DataSourceXAResourceRecoveryHelper.class)); - verify(this.narayanaProperties, times(2)).getRecoveryDbUser(); - verify(this.narayanaProperties, times(1)).getRecoveryDbPass(); + verify(this.recoveryManager, times(1)).registerXAResourceRecoveryHelper( + any(DataSourceXAResourceRecoveryHelper.class)); + verify(this.properties, times(2)).getRecoveryDbUser(); + verify(this.properties, times(1)).getRecoveryDbPass(); } }