Make sure Atomikos default are applied consistently

This commit makes sure to apply Atomikos defaults also adds a test that
validates Atomikos defaults are consistent.

As a side effect of that, `threadedTwoPhaseCommit` is now `false` (which
is effectively what users got with no customization anyway since that
default was changed in Atomikos 3.7

Closes gh-9141
This commit is contained in:
Stephane Nicoll 2017-05-22 15:43:12 +02:00
parent 4cc515054e
commit b61b1f0e08
3 changed files with 81 additions and 39 deletions

View File

@ -724,7 +724,7 @@ content into your application; rather pick only the properties that you need.
spring.jta.atomikos.properties.output-dir= # Directory in which to store the debug log files.
spring.jta.atomikos.properties.serial-jta-transactions=true # Specify if sub-transactions should be joined when possible.
spring.jta.atomikos.properties.service= # Transaction manager implementation that should be started.
spring.jta.atomikos.properties.threaded-two-phase-commit=true # Use different (and concurrent) threads for two-phase commit on the participating resources.
spring.jta.atomikos.properties.threaded-two-phase-commit=false # Use different (and concurrent) threads for two-phase commit on the participating resources.
spring.jta.atomikos.properties.transaction-manager-unique-name= # Transaction manager's unique name.
# BITRONIX

View File

@ -16,9 +16,7 @@
package org.springframework.boot.jta.atomikos;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ -36,8 +34,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "spring.jta.atomikos.properties")
public class AtomikosProperties {
private final Map<String, String> values = new TreeMap<String, String>();
/**
* Transaction manager implementation that should be started.
*/
@ -128,7 +124,7 @@ public class AtomikosProperties {
* Use different (and concurrent) threads for two-phase commit on the participating
* resources.
*/
private boolean threadedTwoPhaseCommit = true;
private boolean threadedTwoPhaseCommit;
/**
* Specifies the transaction manager implementation that should be started. There is
@ -139,7 +135,6 @@ public class AtomikosProperties {
*/
public void setService(String service) {
this.service = service;
set("service", service);
}
public String getService() {
@ -155,7 +150,6 @@ public class AtomikosProperties {
*/
public void setMaxTimeout(long maxTimeout) {
this.maxTimeout = maxTimeout;
set("max_timeout", maxTimeout);
}
public long getMaxTimeout() {
@ -169,7 +163,6 @@ public class AtomikosProperties {
*/
public void setDefaultJtaTimeout(long defaultJtaTimeout) {
this.defaultJtaTimeout = defaultJtaTimeout;
set("default_jta_timeout", defaultJtaTimeout);
}
public long getDefaultJtaTimeout() {
@ -186,7 +179,6 @@ public class AtomikosProperties {
*/
public void setMaxActives(int maxActives) {
this.maxActives = maxActives;
set("max_actives", maxActives);
}
public int getMaxActives() {
@ -202,7 +194,6 @@ public class AtomikosProperties {
*/
public void setEnableLogging(boolean enableLogging) {
this.enableLogging = enableLogging;
set("enable_logging", enableLogging);
}
public boolean isEnableLogging() {
@ -222,7 +213,6 @@ public class AtomikosProperties {
*/
public void setTransactionManagerUniqueName(String uniqueName) {
this.transactionManagerUniqueName = uniqueName;
set("tm_unique_name", uniqueName);
}
public String getTransactionManagerUniqueName() {
@ -239,7 +229,6 @@ public class AtomikosProperties {
*/
public void setSerialJtaTransactions(boolean serialJtaTransactions) {
this.serialJtaTransactions = serialJtaTransactions;
set("serial_jta_transactions", serialJtaTransactions);
}
public boolean isSerialJtaTransactions() {
@ -253,7 +242,6 @@ public class AtomikosProperties {
*/
public void setForceShutdownOnVmExit(boolean forceShutdownOnVmExit) {
this.forceShutdownOnVmExit = forceShutdownOnVmExit;
set("force_shutdown_on_vm_exit", forceShutdownOnVmExit);
}
public boolean isForceShutdownOnVmExit() {
@ -269,7 +257,6 @@ public class AtomikosProperties {
*/
public void setLogBaseName(String logBaseName) {
this.logBaseName = logBaseName;
set("log_base_name", logBaseName);
}
public String getLogBaseName() {
@ -285,7 +272,6 @@ public class AtomikosProperties {
*/
public void setLogBaseDir(String logBaseDir) {
this.logBaseDir = logBaseDir;
set("log_base_dir", logBaseDir);
}
public String getLogBaseDir() {
@ -299,7 +285,6 @@ public class AtomikosProperties {
*/
public void setCheckpointInterval(long checkpointInterval) {
this.checkpointInterval = checkpointInterval;
set("checkpoint_interval", checkpointInterval);
}
public long getCheckpointInterval() {
@ -312,7 +297,6 @@ public class AtomikosProperties {
*/
public void setConsoleLogLevel(AtomikosLoggingLevel consoleLogLevel) {
this.consoleLogLevel = consoleLogLevel;
set("console_log_level", consoleLogLevel);
}
public AtomikosLoggingLevel getConsoleLogLevel() {
@ -326,7 +310,6 @@ public class AtomikosProperties {
*/
public void setOutputDir(String outputDir) {
this.outputDir = outputDir;
set("output_dir", outputDir);
}
public String getOutputDir() {
@ -339,7 +322,6 @@ public class AtomikosProperties {
*/
public void setConsoleFileName(String consoleFileName) {
this.consoleFileName = consoleFileName;
set("console_file_name", consoleFileName);
}
public String getConsoleFileName() {
@ -352,7 +334,6 @@ public class AtomikosProperties {
*/
public void setConsoleFileCount(int consoleFileCount) {
this.consoleFileCount = consoleFileCount;
set("console_file_count", consoleFileCount);
}
public int getConsoleFileCount() {
@ -366,7 +347,6 @@ public class AtomikosProperties {
*/
public void setConsoleFileLimit(int consoleFileLimit) {
this.consoleFileLimit = consoleFileLimit;
set("console_file_limit", consoleFileLimit);
}
public int getConsoleFileLimit() {
@ -384,26 +364,12 @@ public class AtomikosProperties {
*/
public void setThreadedTwoPhaseCommit(boolean threadedTwoPhaseCommit) {
this.threadedTwoPhaseCommit = threadedTwoPhaseCommit;
set("threaded_2pc", threadedTwoPhaseCommit);
}
public boolean isThreadedTwoPhaseCommit() {
return this.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.
@ -411,8 +377,31 @@ public class AtomikosProperties {
*/
public Properties asProperties() {
Properties properties = new Properties();
properties.putAll(this.values);
set(properties, "service", getService());
set(properties, "max_timeout", getMaxTimeout());
set(properties, "default_jta_timeout", getDefaultJtaTimeout());
set(properties, "max_actives", getMaxActives());
set(properties, "enable_logging", isEnableLogging());
set(properties, "tm_unique_name", getTransactionManagerUniqueName());
set(properties, "serial_jta_transactions", isSerialJtaTransactions());
set(properties, "force_shutdown_on_vm_exit", isForceShutdownOnVmExit());
set(properties, "log_base_name", getLogBaseName());
set(properties, "log_base_dir", getLogBaseDir());
set(properties, "checkpoint_interval", getCheckpointInterval());
set(properties, "console_log_level", getConsoleLogLevel());
set(properties, "output_dir", getOutputDir());
set(properties, "console_file_name", getConsoleFileName());
set(properties, "console_file_count", getConsoleFileCount());
set(properties, "console_file_limit", getConsoleFileLimit());
set(properties, "threaded_2pc", isThreadedTwoPhaseCommit());
return properties;
}
private void set(Properties properties, String key, Object value) {
String id = "com.atomikos.icatch." + key;
if (value != null && !properties.containsKey(id)) {
properties.setProperty(id, value.toString());
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 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,14 +16,23 @@
package org.springframework.boot.jta.atomikos;
import java.lang.reflect.Method;
import java.util.Properties;
import org.assertj.core.data.MapEntry;
import org.junit.Test;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
/**
* Tests for ;@link AtomikosProperties}.
* Tests for {@link AtomikosProperties}.
*
* @author Phillip Webb
* @author Stephane Nicoll
*/
public class AtomikosPropertiesTests {
@ -69,6 +78,50 @@ public class AtomikosPropertiesTests {
assertProperty("com.atomikos.icatch.threaded_2pc", "true");
}
@Test
public void testDefaultProperties() {
Properties defaultSettings = loadDefaultSettings();
Properties properties = this.properties.asProperties();
assertThat(properties).contains(defaultOf(defaultSettings,
"com.atomikos.icatch.max_timeout",
"com.atomikos.icatch.default_jta_timeout",
"com.atomikos.icatch.max_actives",
"com.atomikos.icatch.enable_logging",
"com.atomikos.icatch.serial_jta_transactions",
"com.atomikos.icatch.force_shutdown_on_vm_exit",
"com.atomikos.icatch.log_base_name",
"com.atomikos.icatch.checkpoint_interval",
"com.atomikos.icatch.threaded_2pc"));
assertThat(properties).contains(
entry("com.atomikos.icatch.console_log_level", "WARN"),
entry("com.atomikos.icatch.console_file_name", "tm.out"),
entry("com.atomikos.icatch.console_file_count", "1"),
entry("com.atomikos.icatch.console_file_limit", "-1"));
assertThat(properties).hasSize(13);
}
private MapEntry<?, ?>[] defaultOf(Properties defaultSettings, String... keys) {
MapEntry<?, ?>[] entries = new MapEntry[keys.length];
for (int i = 0; i < keys.length; i++) {
String key = keys[i];
entries[i] = entry(key, defaultSettings.get(key));
}
return entries;
}
private Properties loadDefaultSettings() {
try {
Class<?> target = ClassUtils.forName("com.atomikos.icatch.standalone.UserTransactionServiceImp",
getClass().getClassLoader());
Method m = target.getMethod("getDefaultProperties");
m.setAccessible(true);
return (Properties) ReflectionUtils.invokeMethod(m, null);
}
catch (Exception ex) {
throw new IllegalStateException("Failed to get default from Atomikos", ex);
}
}
private void assertProperty(String key, String value) {
assertThat(this.properties.asProperties().getProperty(key)).isEqualTo(value);
}