Add Atomikos support classes
Add support classes for the Atomikos JTA library, including: - A Spring friendly ConnectionFactoryBean and DataSourceBean. - A PostProcessor to apply "depends-on" ordering automatically. - A bindable properties class for type-safe configuration. See gh-947
This commit is contained in:
parent
bacdd5a408
commit
983ec0ebc8
|
|
@ -48,6 +48,7 @@
|
|||
<!-- Third Party -->
|
||||
<activemq.version>5.9.1</activemq.version>
|
||||
<aspectj.version>1.8.2</aspectj.version>
|
||||
<atomikos.version>3.9.3</atomikos.version>
|
||||
<codahale-metrics.version>3.0.2</codahale-metrics.version>
|
||||
<commons-beanutils.version>1.9.2</commons-beanutils.version>
|
||||
<commons-collections.version>3.2.1</commons-collections.version>
|
||||
|
|
@ -85,6 +86,7 @@
|
|||
<jolokia.version>1.2.2</jolokia.version>
|
||||
<json-path.version>0.9.1</json-path.version>
|
||||
<jstl.version>1.2</jstl.version>
|
||||
<jta.version>1.1</jta.version>
|
||||
<junit.version>4.11</junit.version>
|
||||
<liquibase.version>3.0.8</liquibase.version>
|
||||
<log4j.version>1.2.17</log4j.version>
|
||||
|
|
@ -350,6 +352,21 @@
|
|||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atomikos</groupId>
|
||||
<artifactId>transactions-jdbc</artifactId>
|
||||
<version>${atomikos.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atomikos</groupId>
|
||||
<artifactId>transactions-jms</artifactId>
|
||||
<version>${atomikos.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atomikos</groupId>
|
||||
<artifactId>transactions-jta</artifactId>
|
||||
<version>${atomikos.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.codahale.metrics</groupId>
|
||||
<artifactId>metrics-graphite</artifactId>
|
||||
|
|
@ -482,6 +499,11 @@
|
|||
<artifactId>jstl</artifactId>
|
||||
<version>${jstl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.transaction</groupId>
|
||||
<artifactId>jta</artifactId>
|
||||
<version>${jta.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jaxen</groupId>
|
||||
<artifactId>jaxen</artifactId>
|
||||
|
|
|
|||
|
|
@ -34,11 +34,31 @@
|
|||
<artifactId>logback-classic</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atomikos</groupId>
|
||||
<artifactId>transactions-jms</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atomikos</groupId>
|
||||
<artifactId>transactions-jta</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atomikos</groupId>
|
||||
<artifactId>transactions-jdbc</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.jms</groupId>
|
||||
<artifactId>jms-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Spring friendly version of {@link com.atomikos.jms.AtomikosConnectionFactoryBean}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class AtomikosConnectionFactoryBean extends
|
||||
com.atomikos.jms.AtomikosConnectionFactoryBean implements BeanNameAware,
|
||||
InitializingBean, DisposableBean {
|
||||
|
||||
private String beanName;
|
||||
|
||||
@Override
|
||||
public void setBeanName(String name) {
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (!StringUtils.hasLength(getUniqueResourceName())) {
|
||||
setUniqueResourceName(this.beanName);
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Spring friendly version of {@link com.atomikos.jdbc.AtomikosDataSourceBean}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class AtomikosDataSourceBean extends com.atomikos.jdbc.AtomikosDataSourceBean
|
||||
implements BeanNameAware, InitializingBean, DisposableBean {
|
||||
|
||||
private String beanName;
|
||||
|
||||
@Override
|
||||
public void setBeanName(String name) {
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (!StringUtils.hasLength(getUniqueResourceName())) {
|
||||
setUniqueResourceName(this.beanName);
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* 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 java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import com.atomikos.icatch.jta.UserTransactionManager;
|
||||
|
||||
/**
|
||||
* {@link BeanFactoryPostProcessor} to automatically setup the recommended
|
||||
* {@link BeanDefinition#setDependsOn(String[]) dependsOn} settings for <a
|
||||
* href="http://www.atomikos.com/Documentation/SpringIntegration">correct Atomikos
|
||||
* ordering</a>.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class AtomikosDependsOnBeanFactoryPostProcessor implements
|
||||
BeanFactoryPostProcessor, Ordered {
|
||||
|
||||
private static final String[] NO_BEANS = {};
|
||||
|
||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
||||
throws BeansException {
|
||||
String[] transactionManagers = beanFactory.getBeanNamesForType(
|
||||
UserTransactionManager.class, true, false);
|
||||
for (String transactionManager : transactionManagers) {
|
||||
addTransactionManagerDependencies(beanFactory, transactionManager);
|
||||
}
|
||||
addMessageDrivenContainerDependencies(beanFactory, transactionManagers);
|
||||
}
|
||||
|
||||
private void addTransactionManagerDependencies(
|
||||
ConfigurableListableBeanFactory beanFactory, String transactionManager) {
|
||||
BeanDefinition bean = beanFactory.getBeanDefinition(transactionManager);
|
||||
Set<String> dependsOn = new LinkedHashSet<String>(asList(bean.getDependsOn()));
|
||||
int initialSize = dependsOn.size();
|
||||
addDependencies(beanFactory, "javax.jms.ConnectionFactory", dependsOn);
|
||||
addDependencies(beanFactory, "javax.sql.DataSource", dependsOn);
|
||||
if (dependsOn.size() != initialSize) {
|
||||
bean.setDependsOn(dependsOn.toArray(new String[dependsOn.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
private void addMessageDrivenContainerDependencies(
|
||||
ConfigurableListableBeanFactory beanFactory, String[] transactionManagers) {
|
||||
String[] messageDrivenContainers = getBeanNamesForType(beanFactory,
|
||||
"com.atomikos.jms.extra.MessageDrivenContainer");
|
||||
for (String messageDrivenContainer : messageDrivenContainers) {
|
||||
BeanDefinition bean = beanFactory.getBeanDefinition(messageDrivenContainer);
|
||||
Set<String> dependsOn = new LinkedHashSet<String>(asList(bean.getDependsOn()));
|
||||
dependsOn.addAll(asList(transactionManagers));
|
||||
bean.setDependsOn(dependsOn.toArray(new String[dependsOn.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
private void addDependencies(ConfigurableListableBeanFactory beanFactory,
|
||||
String type, Set<String> dependsOn) {
|
||||
dependsOn.addAll(asList(getBeanNamesForType(beanFactory, type)));
|
||||
}
|
||||
|
||||
private String[] getBeanNamesForType(ConfigurableListableBeanFactory beanFactory,
|
||||
String type) {
|
||||
try {
|
||||
return beanFactory.getBeanNamesForType(Class.forName(type), true, false);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Ignore
|
||||
}
|
||||
return NO_BEANS;
|
||||
}
|
||||
|
||||
private List<String> asList(String[] array) {
|
||||
return (array == null ? Collections.<String> emptyList() : Arrays.asList(array));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Logging levels supported by Atomikos.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @see AtomikosProperties
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public enum AtomikosLoggingLevel {
|
||||
|
||||
/**
|
||||
* Debug Level.
|
||||
*/
|
||||
DEBUG,
|
||||
|
||||
/**
|
||||
* Info Level.
|
||||
*/
|
||||
INFO,
|
||||
|
||||
/**
|
||||
* Warning Level.
|
||||
*/
|
||||
WARN
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* 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 java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Bean friendly variant of <a
|
||||
* href="http://www.atomikos.com/Documentation/JtaProperties">Atomikos configuration
|
||||
* properties</a>. Allows for setter based configuration and is amiable to relaxed data
|
||||
* binding.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @see #asProperties()
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class AtomikosProperties {
|
||||
|
||||
private final Map<String, String> values = new TreeMap<String, String>();
|
||||
|
||||
/**
|
||||
* Specifies the transaction manager implementation that should be started. There is
|
||||
* no default value and this must be set. Generally,
|
||||
* {@literal com.atomikos.icatch.standalone.UserTransactionServiceFactory} is the
|
||||
* value you should set.
|
||||
* @param service the service
|
||||
*/
|
||||
public void setService(String service) {
|
||||
set("service", service);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the maximum timeout (in milliseconds) that can be allowed for
|
||||
* transactions. Defaults to {@literal 300000}. This means that calls to
|
||||
* UserTransaction.setTransactionTimeout() with a value higher than configured here
|
||||
* will be max'ed to this value.
|
||||
* @param maxTimeout the max timeout
|
||||
*/
|
||||
public void setMaxTimeout(long maxTimeout) {
|
||||
set("max_timeout", maxTimeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* The default timeout for JTA transactions (optional, defaults to {@literal 10000}
|
||||
* ms).
|
||||
* @param defaultJtaTimeout the default JTA timeout
|
||||
*/
|
||||
public void setDefaultJtaTimeout(long defaultJtaTimeout) {
|
||||
set("default_jta_timeout", defaultJtaTimeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the maximum number of active transactions. Defaults to {@literal 50}. A
|
||||
* negative value means infinite amount. You will get an {@code IllegalStateException}
|
||||
* with error message "Max number of active transactions reached" if you call
|
||||
* {@code UserTransaction.begin()} while there are already n concurrent transactions
|
||||
* running, n being this value.
|
||||
* @param maxActivities the max activities
|
||||
*/
|
||||
public void setMaxActives(int maxActivities) {
|
||||
set("max_actives", maxActivities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies if disk logging should be enabled or not. Defaults to true. It is useful
|
||||
* for JUnit testing, or to profile code without seeing the transaction manager's
|
||||
* activity as a hot spot but this should never be disabled on production or data
|
||||
* integrity cannot be guaranteed.
|
||||
* @param enableLogging if logging is enabled
|
||||
*/
|
||||
public void setEnableLogging(boolean enableLogging) {
|
||||
set("enable_logging", enableLogging);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the transaction manager's unique name. Defaults to the machine's IP
|
||||
* address. If you plan to run more than one transaction manager against one database
|
||||
* you must set this property to a unique value or you might run into duplicate
|
||||
* transaction ID (XID) problems that can be quite subtle (example:
|
||||
* {@literal http://fogbugz.atomikos.com/default.asp?community.6.2225.7}). If multiple
|
||||
* instances need to use the same properties file then the easiest way to ensure
|
||||
* uniqueness for this property is by referencing a system property specified at VM
|
||||
* startup.
|
||||
* @param uniqueName the unique name
|
||||
*/
|
||||
public void setTransactionManagerUniqueName(String uniqueName) {
|
||||
set("tm_unique_name", uniqueName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies if subtransactions should be joined when possible. Defaults to true. When
|
||||
* false, no attempt to call {@code XAResource.start(TM_JOIN)} will be made for
|
||||
* different but related subtransctions. This setting has no effect on resource access
|
||||
* within one and the same transaction. If you don't use subtransactions then this
|
||||
* setting can be ignored.
|
||||
* @param serialJtaTransactions if serial JTA transaction are supported
|
||||
*/
|
||||
public void setSerialJtaTransactions(boolean serialJtaTransactions) {
|
||||
set("serial_jta_transactions", serialJtaTransactions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether VM shutdown should trigger forced shutdown of the transaction
|
||||
* core. Defaults to false.
|
||||
* @param forceShutdownOnVmExit
|
||||
*/
|
||||
public void setForceShutdownOnVmExit(boolean forceShutdownOnVmExit) {
|
||||
set("force_shutdown_on_vm_exit", forceShutdownOnVmExit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the transactions log file base name. Defaults to {@literal tmlog}. The
|
||||
* transactions logs are stored in files using this name appended with a number and
|
||||
* the extension {@literal .log}. At checkpoint, a new transactions log file is
|
||||
* created and the number is incremented.
|
||||
* @param logBaseName the log base name
|
||||
*/
|
||||
public void setLogBaseName(String logBaseName) {
|
||||
set("log_base_name", logBaseName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the directory in which the log files should be stored. Defaults to the
|
||||
* current working directory. This directory should be a stable storage like a SAN,
|
||||
* RAID or at least backed up location. The transactions logs files are as important
|
||||
* as the data themselves to guarantee consistency in case of failures.
|
||||
* @param logBaseDir the log base dir
|
||||
*/
|
||||
public void setLogBaseDir(String logBaseDir) {
|
||||
set("log_base_dir", logBaseDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the interval between checkpoints. A checkpoint reduces the log file size
|
||||
* at the expense of adding some overhead in the runtime. Defaults to {@literal 500}.
|
||||
* @param checkpointInterval the checkpoint interval
|
||||
*/
|
||||
public void setCheckpointInterval(long checkpointInterval) {
|
||||
set("checkpoint_interval", checkpointInterval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the console log level. Defaults to {@link AtomikosLoggingLevel#WARN}.
|
||||
* @param consoleLogLevel the console log level
|
||||
*/
|
||||
public void setConsoleLogLevel(AtomikosLoggingLevel consoleLogLevel) {
|
||||
set("console_log_level", consoleLogLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the directory in which to store the debug log files. Defaults to the
|
||||
* current working directory.
|
||||
* @param outputDir the output dir
|
||||
*/
|
||||
public void setOutputDir(String outputDir) {
|
||||
set("output_dir", outputDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the debug logs file name. Defaults to {@literal tm.out}.
|
||||
* @param consoleFileName the console file name
|
||||
*/
|
||||
public void setConsoleFileName(String consoleFileName) {
|
||||
set("console_file_name", consoleFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies how many debug logs files can be created. Defaults to {@literal 1}.
|
||||
* @param consoleFileCount the console file count
|
||||
*/
|
||||
public void setConsoleFileCount(int consoleFileCount) {
|
||||
set("console_file_count", consoleFileCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies how many bytes can be stored at most in debug logs files. Defaults to
|
||||
* {@literal -1}. Negative values means unlimited.
|
||||
* @param consoleFileLimit the console file limit
|
||||
*/
|
||||
public void setConsoleFileLimit(int consoleFileLimit) {
|
||||
set("console_file_limit", consoleFileLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether or not to use different (and concurrent) threads for two-phase
|
||||
* commit on the participating resources. Setting this to {@literal true} implies that
|
||||
* the commit is more efficient since waiting for acknowledgements is done in
|
||||
* parallel. Defaults to {@literal true}. If you set this to {@literal false}, then
|
||||
* commits will happen in the order that resources are accessed within the
|
||||
* transaction.
|
||||
* @param threadedTwoPhaseCommit if threaded two phase commits should be used
|
||||
*/
|
||||
public void setThreadedTwoPhaseCommit(boolean threadedTwoPhaseCommit) {
|
||||
set("threaded_2pc", threadedTwoPhaseCommit);
|
||||
}
|
||||
|
||||
private void set(String key, Object value) {
|
||||
set("com.atomikos.icatch.", key, value);
|
||||
}
|
||||
|
||||
private void set(String keyPrefix, String key, Object value) {
|
||||
if (value != null) {
|
||||
this.values.put(keyPrefix + key, value.toString());
|
||||
}
|
||||
else {
|
||||
this.values.remove(keyPrefix + key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the properties as a {@link Properties} object that can be used with
|
||||
* Atomikos.
|
||||
* @return the properties
|
||||
*/
|
||||
public Properties asProperties() {
|
||||
Properties properties = new Properties();
|
||||
properties.putAll(this.values);
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Support for the Java Transaction API.
|
||||
*/
|
||||
package org.springframework.boot.jta;
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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.JMSException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link AtomikosConnectionFactoryBean}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class AtomikosConnectionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void beanMethods() throws Exception {
|
||||
MockAtomikosConnectionFactoryBean bean = spy(new MockAtomikosConnectionFactoryBean());
|
||||
bean.setBeanName("bean");
|
||||
bean.afterPropertiesSet();
|
||||
assertThat(bean.getUniqueResourceName(), equalTo("bean"));
|
||||
verify(bean).init();
|
||||
verify(bean, never()).close();
|
||||
bean.destroy();
|
||||
verify(bean).close();
|
||||
}
|
||||
|
||||
private static class MockAtomikosConnectionFactoryBean extends
|
||||
AtomikosConnectionFactoryBean {
|
||||
|
||||
@Override
|
||||
public synchronized void init() throws JMSException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 org.junit.Test;
|
||||
|
||||
import com.atomikos.jdbc.AtomikosSQLException;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link AtomikosDataSourceBean}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class AtomikosDataSourceBeanTests {
|
||||
|
||||
@Test
|
||||
public void beanMethods() throws Exception {
|
||||
MockAtomikosDataSourceBean bean = spy(new MockAtomikosDataSourceBean());
|
||||
bean.setBeanName("bean");
|
||||
bean.afterPropertiesSet();
|
||||
assertThat(bean.getUniqueResourceName(), equalTo("bean"));
|
||||
verify(bean).init();
|
||||
verify(bean, never()).close();
|
||||
bean.destroy();
|
||||
verify(bean).close();
|
||||
}
|
||||
|
||||
private static class MockAtomikosDataSourceBean extends AtomikosDataSourceBean {
|
||||
|
||||
@Override
|
||||
public synchronized void init() throws AtomikosSQLException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* 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 java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
import javax.jms.ConnectionFactory;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.atomikos.icatch.jta.UserTransactionManager;
|
||||
import com.atomikos.jms.extra.MessageDrivenContainer;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link AtomikosDependsOnBeanFactoryPostProcessor}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class AtomikosDependsOnBeanFactoryPostProcessorTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void setsDependsOn() {
|
||||
this.context = new AnnotationConfigApplicationContext(Config.class);
|
||||
assertDependsOn("dataSource");
|
||||
assertDependsOn("connectionFactory");
|
||||
assertDependsOn("userTransactionManager", "dataSource", "connectionFactory");
|
||||
assertDependsOn("messageDrivenContainer", "userTransactionManager");
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
private void assertDependsOn(String bean, String... expected) {
|
||||
BeanDefinition definition = this.context.getBeanDefinition(bean);
|
||||
if (definition.getDependsOn() == null) {
|
||||
assertTrue("No dependsOn expected for " + bean, expected.length == 0);
|
||||
return;
|
||||
}
|
||||
HashSet<String> dependsOn = new HashSet<String>(Arrays.asList(definition
|
||||
.getDependsOn()));
|
||||
assertThat(dependsOn, equalTo(new HashSet<String>(Arrays.asList(expected))));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
return mock(DataSource.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConnectionFactory connectionFactory() {
|
||||
return mock(ConnectionFactory.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserTransactionManager userTransactionManager() {
|
||||
return mock(UserTransactionManager.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageDrivenContainer messageDrivenContainer() {
|
||||
return mock(MessageDrivenContainer.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public static AtomikosDependsOnBeanFactoryPostProcessor atomikosPostProcessor() {
|
||||
return new AtomikosDependsOnBeanFactoryPostProcessor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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 org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for ;@link AtomikosProperties}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class AtomikosPropertiesTests {
|
||||
|
||||
private AtomikosProperties properties = new AtomikosProperties();
|
||||
|
||||
@Test
|
||||
public void testProperties() {
|
||||
this.properties.setService("service");
|
||||
this.properties.setMaxTimeout(1L);
|
||||
this.properties.setDefaultJtaTimeout(2L);
|
||||
this.properties.setMaxActives(3);
|
||||
this.properties.setEnableLogging(true);
|
||||
this.properties.setTransactionManagerUniqueName("uniqueName");
|
||||
this.properties.setSerialJtaTransactions(true);
|
||||
this.properties.setForceShutdownOnVmExit(true);
|
||||
this.properties.setLogBaseName("logBaseName");
|
||||
this.properties.setLogBaseDir("logBaseDir");
|
||||
this.properties.setCheckpointInterval(4);
|
||||
this.properties.setConsoleLogLevel(AtomikosLoggingLevel.WARN);
|
||||
this.properties.setOutputDir("outputDir");
|
||||
this.properties.setConsoleFileName("consoleFileName");
|
||||
this.properties.setConsoleFileCount(5);
|
||||
this.properties.setConsoleFileLimit(6);
|
||||
this.properties.setThreadedTwoPhaseCommit(true);
|
||||
|
||||
assertThat(this.properties.asProperties().size(), equalTo(17));
|
||||
assertProperty("com.atomikos.icatch.service", "service");
|
||||
assertProperty("com.atomikos.icatch.max_timeout", "1");
|
||||
assertProperty("com.atomikos.icatch.default_jta_timeout", "2");
|
||||
assertProperty("com.atomikos.icatch.max_actives", "3");
|
||||
assertProperty("com.atomikos.icatch.enable_logging", "true");
|
||||
assertProperty("com.atomikos.icatch.tm_unique_name", "uniqueName");
|
||||
assertProperty("com.atomikos.icatch.serial_jta_transactions", "true");
|
||||
assertProperty("com.atomikos.icatch.force_shutdown_on_vm_exit", "true");
|
||||
assertProperty("com.atomikos.icatch.log_base_name", "logBaseName");
|
||||
assertProperty("com.atomikos.icatch.log_base_dir", "logBaseDir");
|
||||
assertProperty("com.atomikos.icatch.checkpoint_interval", "4");
|
||||
assertProperty("com.atomikos.icatch.console_log_level", "WARN");
|
||||
assertProperty("com.atomikos.icatch.output_dir", "outputDir");
|
||||
assertProperty("com.atomikos.icatch.console_file_name", "consoleFileName");
|
||||
assertProperty("com.atomikos.icatch.console_file_count", "5");
|
||||
assertProperty("com.atomikos.icatch.console_file_limit", "6");
|
||||
assertProperty("com.atomikos.icatch.threaded_2pc", "true");
|
||||
}
|
||||
|
||||
private void assertProperty(String key, String value) {
|
||||
assertThat(this.properties.asProperties().getProperty(key), equalTo(value));
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue