You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2016/09/01 15:30:56 UTC
svn commit: r1758793 - in /aries/trunk/tx-control:
tx-control-itests/src/test/java/org/apache/aries/tx/control/itests/
tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/connection/impl/
Author: timothyjward
Date: Thu Sep 1 15:30:56 2016
New Revision: 1758793
URL: http://svn.apache.org/viewvc?rev=1758793&view=rev
Log:
[tx-control] Ensure that XA Connections are released by the JDBCResourceProvider
Modified:
aries/trunk/tx-control/tx-control-itests/src/test/java/org/apache/aries/tx/control/itests/AbstractTransactionTest.java
aries/trunk/tx-control/tx-control-itests/src/test/java/org/apache/aries/tx/control/itests/ConnectionLifecycleTest.java
aries/trunk/tx-control/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/connection/impl/XAConnectionWrapper.java
Modified: aries/trunk/tx-control/tx-control-itests/src/test/java/org/apache/aries/tx/control/itests/AbstractTransactionTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-itests/src/test/java/org/apache/aries/tx/control/itests/AbstractTransactionTest.java?rev=1758793&r1=1758792&r2=1758793&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-itests/src/test/java/org/apache/aries/tx/control/itests/AbstractTransactionTest.java (original)
+++ aries/trunk/tx-control/tx-control-itests/src/test/java/org/apache/aries/tx/control/itests/AbstractTransactionTest.java Thu Sep 1 15:30:56 2016
@@ -30,8 +30,10 @@ import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
+import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Properties;
@@ -114,6 +116,11 @@ public abstract class AbstractTransactio
});
}
+ protected Map<String, Object> resourceProviderConfig() {
+ // No extra information by default
+ return new HashMap<>();
+ }
+
public boolean isConfigured() {
return System.getProperties().containsKey(CONFIGURED_PROVIDER_PROPERTY);
}
@@ -156,7 +163,8 @@ public abstract class AbstractTransactio
DataSourceFactory dsf = getService(DataSourceFactory.class, 5000);
- return resourceProviderFactory.getProviderFor(dsf, jdbc, null).getResource(txControl);
+ return resourceProviderFactory.getProviderFor(dsf, jdbc, resourceProviderConfig())
+ .getResource(txControl);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@@ -172,6 +180,9 @@ public abstract class AbstractTransactio
System.out.println("Configuring connection provider with pid " + pid);
+ resourceProviderConfig().entrySet().stream()
+ .forEach(e -> jdbc.put(e.getKey(), e.getValue()));
+
org.osgi.service.cm.Configuration config = cm.createFactoryConfiguration(
pid, "?");
config.update((Hashtable)jdbc);
Modified: aries/trunk/tx-control/tx-control-itests/src/test/java/org/apache/aries/tx/control/itests/ConnectionLifecycleTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-itests/src/test/java/org/apache/aries/tx/control/itests/ConnectionLifecycleTest.java?rev=1758793&r1=1758792&r2=1758793&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-itests/src/test/java/org/apache/aries/tx/control/itests/ConnectionLifecycleTest.java (original)
+++ aries/trunk/tx-control/tx-control-itests/src/test/java/org/apache/aries/tx/control/itests/ConnectionLifecycleTest.java Thu Sep 1 15:30:56 2016
@@ -26,8 +26,14 @@ import static org.junit.Assert.fail;
import java.sql.ResultSet;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import java.util.function.Predicate;
+import java.util.stream.Collectors;
import org.junit.Assume;
import org.junit.Test;
@@ -47,6 +53,22 @@ import org.osgi.service.transaction.cont
@ExamReactorStrategy(PerClass.class)
public class ConnectionLifecycleTest extends AbstractTransactionTest {
+ private static final long LIFETIME = 30000;
+
+ private static final int CONNECTIONS = 17;
+
+ @Override
+ protected Map<String, Object> resourceProviderConfig() {
+ // Set a short lifecycle for pooled connections and force a non-standard number
+ Map<String, Object> config = new HashMap<>();
+ config.put(JDBCConnectionProviderFactory.IDLE_TIMEOUT, LIFETIME/2);
+ config.put(JDBCConnectionProviderFactory.CONNECTION_LIFETIME, LIFETIME);
+ config.put(JDBCConnectionProviderFactory.MAX_CONNECTIONS, CONNECTIONS);
+ config.put(JDBCConnectionProviderFactory.MIN_CONNECTIONS, CONNECTIONS);
+
+ return config;
+ }
+
@Test
public void testStopOfTxControlBundle() {
doBundleStoppingTest(b -> b.getSymbolicName().contains("tx-control-service"),
@@ -55,41 +77,36 @@ public class ConnectionLifecycleTest ext
@Test
public void testStopOfJDBCBundle() {
- doBundleStoppingTest(b -> b.getSymbolicName().contains("tx-control-provider-jdbc"),
+ doBundleStoppingTest(b -> b.getSymbolicName().contains("tx-control-provider-jdbc"),
"There was a problem getting hold of a database connection");
}
private void doBundleStoppingTest(Predicate<Bundle> p, String exceptionMessage) {
- txControl.required(() -> connection.createStatement()
- .execute("Insert into TEST_TABLE values ( 'Hello World!' )"));
+ txControl.required(
+ () -> connection.createStatement().execute("Insert into TEST_TABLE values ( 'Hello World!' )"));
assertEquals("Hello World!", txControl.notSupported(() -> {
- ResultSet rs = connection.createStatement()
- .executeQuery("Select * from TEST_TABLE");
+ ResultSet rs = connection.createStatement().executeQuery("Select * from TEST_TABLE");
rs.next();
return rs.getString(1);
}));
-
-
- List<Bundle> toStop = Arrays.stream(context.getBundles())
- .filter(p)
- .collect(toList());
-
+
+ List<Bundle> toStop = Arrays.stream(context.getBundles()).filter(p).collect(toList());
+
System.out.println(toStop);
-
+
try {
- toStop.stream()
- .forEach(b -> {
- System.out.println("Stopping " + b.getSymbolicName());
- try {
- b.stop();
- } catch (BundleException e) {}
- });
-
+ toStop.stream().forEach(b -> {
+ System.out.println("Stopping " + b.getSymbolicName());
+ try {
+ b.stop();
+ } catch (BundleException e) {
+ }
+ });
+
try {
assertEquals("Hello World!", txControl.notSupported(() -> {
- ResultSet rs = connection.createStatement()
- .executeQuery("Select * from TEST_TABLE");
+ ResultSet rs = connection.createStatement().executeQuery("Select * from TEST_TABLE");
rs.next();
return rs.getString(1);
}));
@@ -101,47 +118,43 @@ public class ConnectionLifecycleTest ext
assertEquals(exceptionMessage, te.getMessage());
}
} finally {
- toStop.stream()
- .forEach(b -> {
- try {
- b.start();
- } catch (BundleException e) {}
- });
+ toStop.stream().forEach(b -> {
+ try {
+ b.start();
+ } catch (BundleException e) {
+ }
+ });
}
}
@Test
public void testDeleteOfConfig() throws Exception {
Assume.assumeTrue("Not a configuration test", isConfigured());
-
-
- txControl.required(() -> connection.createStatement()
- .execute("Insert into TEST_TABLE values ( 'Hello World!' )"));
+
+ txControl.required(
+ () -> connection.createStatement().execute("Insert into TEST_TABLE values ( 'Hello World!' )"));
assertEquals("Hello World!", txControl.notSupported(() -> {
- ResultSet rs = connection.createStatement()
- .executeQuery("Select * from TEST_TABLE");
+ ResultSet rs = connection.createStatement().executeQuery("Select * from TEST_TABLE");
rs.next();
return rs.getString(1);
}));
-
-
+
ConfigurationAdmin cm = getService(ConfigurationAdmin.class, 5000);
-
- Configuration[] configurations = cm.listConfigurations(
- "(service.factoryPid=org.apache.aries.tx.control.jdbc.*)");
-
+
+ Configuration[] configurations = cm
+ .listConfigurations("(service.factoryPid=org.apache.aries.tx.control.jdbc.*)");
+
assertNotNull(configurations);
assertEquals(1, configurations.length);
-
+
configurations[0].delete();
-
+
Thread.sleep(2000);
-
+
try {
assertEquals("Hello World!", txControl.notSupported(() -> {
- ResultSet rs = connection.createStatement()
- .executeQuery("Select * from TEST_TABLE");
+ ResultSet rs = connection.createStatement().executeQuery("Select * from TEST_TABLE");
rs.next();
return rs.getString(1);
}));
@@ -155,35 +168,31 @@ public class ConnectionLifecycleTest ext
@Test
public void testUpdateOfConfig() throws Exception {
Assume.assumeTrue("Not a configuration test", isConfigured());
-
-
- txControl.required(() -> connection.createStatement()
- .execute("Insert into TEST_TABLE values ( 'Hello World!' )"));
+
+ txControl.required(
+ () -> connection.createStatement().execute("Insert into TEST_TABLE values ( 'Hello World!' )"));
assertEquals("Hello World!", txControl.notSupported(() -> {
- ResultSet rs = connection.createStatement()
- .executeQuery("Select * from TEST_TABLE");
+ ResultSet rs = connection.createStatement().executeQuery("Select * from TEST_TABLE");
rs.next();
return rs.getString(1);
}));
-
-
+
ConfigurationAdmin cm = getService(ConfigurationAdmin.class, 5000);
-
- Configuration[] configurations = cm.listConfigurations(
- "(service.factoryPid=org.apache.aries.tx.control.jdbc.*)");
-
+
+ Configuration[] configurations = cm
+ .listConfigurations("(service.factoryPid=org.apache.aries.tx.control.jdbc.*)");
+
assertNotNull(configurations);
assertEquals(1, configurations.length);
-
+
configurations[0].update();
-
+
Thread.sleep(2000);
-
+
try {
assertEquals("Hello World!", txControl.notSupported(() -> {
- ResultSet rs = connection.createStatement()
- .executeQuery("Select * from TEST_TABLE");
+ ResultSet rs = connection.createStatement().executeQuery("Select * from TEST_TABLE");
rs.next();
return rs.getString(1);
}));
@@ -193,32 +202,27 @@ public class ConnectionLifecycleTest ext
assertEquals("There was a problem getting hold of a database connection", swe.getCause().getMessage());
}
}
-
+
@Test
public void testReleaseOfFactoryService() {
Assume.assumeFalse("Not a factory test", isConfigured());
-
- txControl.required(() -> connection.createStatement()
- .execute("Insert into TEST_TABLE values ( 'Hello World!' )"));
+
+ txControl.required(
+ () -> connection.createStatement().execute("Insert into TEST_TABLE values ( 'Hello World!' )"));
assertEquals("Hello World!", txControl.notSupported(() -> {
- ResultSet rs = connection.createStatement()
- .executeQuery("Select * from TEST_TABLE");
+ ResultSet rs = connection.createStatement().executeQuery("Select * from TEST_TABLE");
rs.next();
return rs.getString(1);
}));
-
-
- trackers.stream()
- .filter(t -> t.getService() instanceof JDBCConnectionProviderFactory)
- .findFirst()
- .get().close();;
-
-
+
+ trackers.stream().filter(t -> t.getService() instanceof JDBCConnectionProviderFactory).findFirst().get()
+ .close();
+ ;
+
try {
assertEquals("Hello World!", txControl.notSupported(() -> {
- ResultSet rs = connection.createStatement()
- .executeQuery("Select * from TEST_TABLE");
+ ResultSet rs = connection.createStatement().executeQuery("Select * from TEST_TABLE");
rs.next();
return rs.getString(1);
}));
@@ -228,4 +232,58 @@ public class ConnectionLifecycleTest ext
assertEquals("There was a problem getting hold of a database connection", swe.getCause().getMessage());
}
}
+
+ @Test
+ public void testPoolLifecycle() throws Exception {
+ Set<String> allIds = new TreeSet<>();
+
+ for(int i = 0; i < 100; i++) {
+ Set<String> ids = txControl.notSupported(() -> {
+ Set<String> sessionIds = new HashSet<>();
+
+ ResultSet rs = connection.createStatement()
+ .executeQuery("Select ID, SESSION_START from INFORMATION_SCHEMA.SESSIONS");
+ while(rs.next()) {
+ String connectionId = rs.getString(1);
+ if(connectionId.length() == 1) {
+ connectionId = "0" + connectionId;
+ }
+ sessionIds.add(connectionId + "-"
+ + rs.getString(2));
+ }
+ return sessionIds;
+ });
+
+ Set<String> newIds = ids.stream()
+ .filter(id -> !allIds.contains(id))
+ .collect(Collectors.toSet());
+
+ allIds.addAll(ids);
+ System.out.println("Currently there are " + ids.size() + " connections");
+ System.out.println("In total there have been " + allIds.size() + " connections");
+
+ int currentConnections = ids.size();
+
+ if(currentConnections > CONNECTIONS) {
+ if((currentConnections - newIds.size()) <= CONNECTIONS) {
+ System.out.println("The number of connections is too high at " + currentConnections +
+ ", but " + newIds.size() + " new connections have just been added. The previous connections may be in the process of being closed and so this loop will not fail.");
+ } else {
+ fail("Too many sessions " + currentConnections);
+ }
+ }
+
+ Thread.sleep(500);
+ }
+
+ int size = allIds.size();
+ if(size <= CONNECTIONS + 1) {
+ assertEquals("Expected 34 sessions, but found " + size + " " + allIds, 34, size);
+ } else if(size <= (2 * CONNECTIONS)) {
+ System.out.println("We really should have 34 sessions, but " + size +
+ " is probably enough ");
+ } else {
+ fail("There should not need to be more than " + (2 * CONNECTIONS) + " connections");
+ }
+ }
}
Modified: aries/trunk/tx-control/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/connection/impl/XAConnectionWrapper.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/connection/impl/XAConnectionWrapper.java?rev=1758793&r1=1758792&r2=1758793&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/connection/impl/XAConnectionWrapper.java (original)
+++ aries/trunk/tx-control/tx-control-provider-jdbc-xa/src/main/java/org/apache/aries/tx/control/jdbc/xa/connection/impl/XAConnectionWrapper.java Thu Sep 1 15:30:56 2016
@@ -31,8 +31,11 @@ public class XAConnectionWrapper extends
private final Connection connection;
private final XAResource xaResource;
+
+ private final XAConnection xaConnection;
public XAConnectionWrapper(XAConnection xaConnection) throws SQLException {
+ this.xaConnection = xaConnection;
this.connection = xaConnection.getConnection();
this.xaResource = xaConnection.getXAResource();
}
@@ -45,4 +48,11 @@ public class XAConnectionWrapper extends
public XAResource getXaResource() {
return xaResource;
}
+
+ @Override
+ public void close() throws SQLException {
+ xaConnection.close();
+ }
+
+
}