You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jl...@apache.org on 2016/12/03 16:56:23 UTC

[29/50] tomee git commit: Wrap XAConnection's underlying connections to ensure they go back into the pool. Add tests for XA functionality. Ensure connections are created correctly for XA datasource when using InitialSize.

Wrap XAConnection's underlying connections to ensure they go back into the pool. Add tests for XA functionality. Ensure connections are created correctly for XA datasource when using InitialSize.


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/9e19d4a4
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/9e19d4a4
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/9e19d4a4

Branch: refs/heads/tomee-1.7.x
Commit: 9e19d4a441109ffb0583fdb365d32a03e9a062c2
Parents: 75ac9b4
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Wed Aug 10 00:29:59 2016 +0100
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Wed Aug 10 00:29:59 2016 +0100

----------------------------------------------------------------------
 .../jdbc/managed/local/ManagedConnection.java   | 36 +++++++-
 .../openejb/resource/jdbc/XADataSourceTest.java | 24 ++++-
 examples/xa-datasource/pom.xml                  |  4 +-
 .../superbiz/injection/jpa/MoviesXATest.java    | 95 +-------------------
 .../tomee/jdbc/TomEEDataSourceCreator.java      | 34 +++++--
 .../tomee/jdbc/TomcatXADataSourceTest.java      | 23 ++++-
 6 files changed, 109 insertions(+), 107 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/9e19d4a4/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedConnection.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedConnection.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedConnection.java
index 1e2edfe..bb24f0f 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedConnection.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedConnection.java
@@ -23,6 +23,7 @@ import org.apache.openejb.util.Logger;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.Wrapper;
@@ -164,7 +165,7 @@ public class ManagedConnection implements InvocationHandler {
                 (key.user == null ? XADataSource.class.cast(key.ds).getXAConnection() : XADataSource.class.cast(key.ds).getXAConnection(key.user, key.pwd));
         if (XAConnection.class.isInstance(connection)) {
             xaConnection = XAConnection.class.cast(connection);
-            delegate = xaConnection.getConnection();
+            delegate = wrapDelegate(xaConnection, xaConnection.getConnection());
             xaResource = xaConnection.getXAResource();
         } else {
             delegate = Connection.class.cast(connection);
@@ -173,6 +174,13 @@ public class ManagedConnection implements InvocationHandler {
         return connection;
     }
 
+    private Connection wrapDelegate(final XAConnection xaConnection, final Connection connection) {
+        return (Connection) Proxy.newProxyInstance(
+                Thread.currentThread().getContextClassLoader(),
+                new Class<?>[] { Connection.class },
+                new XAConnectionWrapper(xaConnection, connection));
+    }
+
     protected void setAutoCommit(final boolean value) throws SQLException {
         if (delegate == null) {
             newConnection();
@@ -233,8 +241,8 @@ public class ManagedConnection implements InvocationHandler {
     private static class ClosingSynchronization implements Synchronization {
         private final Connection connection;
 
-        public ClosingSynchronization(final Connection delegate) {
-            this.connection = delegate;
+        public ClosingSynchronization(final Connection connection) {
+            this.connection = connection;
         }
 
         @Override
@@ -285,4 +293,24 @@ public class ManagedConnection implements InvocationHandler {
             return hash;
         }
     }
-}
\ No newline at end of file
+
+    private class XAConnectionWrapper implements InvocationHandler {
+        private final XAConnection xaConnection;
+        private final Connection delegate;
+
+        public XAConnectionWrapper(final XAConnection xaConnection, final Connection delegate) {
+            this.xaConnection = xaConnection;
+            this.delegate = delegate;
+        }
+
+        @Override
+        public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+            if ("close".equals(method.getName()) && (args == null || args.length == 0)) {
+                xaConnection.close();
+                return null;
+            } else {
+                return method.invoke(delegate, args);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/9e19d4a4/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/XADataSourceTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/XADataSourceTest.java b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/XADataSourceTest.java
index d01407a..25016b4 100644
--- a/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/XADataSourceTest.java
+++ b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/XADataSourceTest.java
@@ -33,25 +33,37 @@ import org.junit.runner.RunWith;
 import javax.ejb.EJB;
 import javax.ejb.EJBException;
 import javax.ejb.Singleton;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
 import javax.persistence.Entity;
 import javax.persistence.EntityManager;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
 import javax.persistence.PersistenceContext;
 import java.io.File;
+import java.lang.management.ManagementFactory;
 import java.util.Properties;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
 
 @RunWith(ApplicationComposer.class)
 public class XADataSourceTest {
+
+    private static final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
     @EJB
     private XAEJB ejb;
 
     @Test
-    public void checkOperationsWork() {
+    public void checkOperationsWork() throws Exception {
         ejb.doSthg();
         ejb.assertPersisted();
         try {
@@ -59,6 +71,16 @@ public class XADataSourceTest {
         } catch (final EJBException ejbEx) {
             assertThat(ejbEx.getCause(), instanceOf(IllegalArgumentException.class));
         }
+
+        assertEquals(0, getActiveConnections("xadbn"));
+        assertEquals(0, getActiveConnections("xadbn2"));
+    }
+
+    private int getActiveConnections(final String dataSourceName)
+            throws MalformedObjectNameException, MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException {
+        final ObjectName objectName = new ObjectName("openejb.management:ObjectType=datasources,DataSource=" + dataSourceName);
+        final Object activeConnectionsAttribute = server.getAttribute(objectName, "numActive");
+        return (int) (Integer) activeConnectionsAttribute;
     }
 
     @Configuration

http://git-wip-us.apache.org/repos/asf/tomee/blob/9e19d4a4/examples/xa-datasource/pom.xml
----------------------------------------------------------------------
diff --git a/examples/xa-datasource/pom.xml b/examples/xa-datasource/pom.xml
index fc46986..f73ec8c 100644
--- a/examples/xa-datasource/pom.xml
+++ b/examples/xa-datasource/pom.xml
@@ -70,9 +70,9 @@
     code is dependent on any OpenEJB classes.
     -->
     <dependency>
-      <groupId>org.apache.tomee</groupId>
+      <groupId>org.apache.openejb</groupId>
       <artifactId>openejb-core</artifactId>
-      <version>4.7.5-SNAPSHOT</version>
+      <version>4.7.5-TT.6</version>
       <scope>test</scope>
     </dependency>
 

http://git-wip-us.apache.org/repos/asf/tomee/blob/9e19d4a4/examples/xa-datasource/src/test/java/org/superbiz/injection/jpa/MoviesXATest.java
----------------------------------------------------------------------
diff --git a/examples/xa-datasource/src/test/java/org/superbiz/injection/jpa/MoviesXATest.java b/examples/xa-datasource/src/test/java/org/superbiz/injection/jpa/MoviesXATest.java
index 995a8cb..56ee0c6 100644
--- a/examples/xa-datasource/src/test/java/org/superbiz/injection/jpa/MoviesXATest.java
+++ b/examples/xa-datasource/src/test/java/org/superbiz/injection/jpa/MoviesXATest.java
@@ -48,7 +48,7 @@ public class MoviesXATest {
         final PersistenceUnit unit = new PersistenceUnit("movie-unit");
         unit.setJtaDataSource("movieDatabase");
         unit.setNonJtaDataSource("movieDatabaseUnmanaged");
-        unit.setProperty("openjpa.jdbc.SynchronizeMappings", "buildSchema");
+        unit.setProperty("openjpa.jdbc.SynchronizeMappings", "buildSchema(foreignKeys=true,schemaAction='dropDB,add')");
         unit.addClass(Movie.class);
         return unit;
     }
@@ -70,6 +70,7 @@ public class MoviesXATest {
         p.put("movieDatabase.UserName", "admin");
         p.put("movieDatabase.Password", "admin");
         p.put("movieDatabase.MaxActive", "128");
+        p.put("movieDatabase.InitialSize", "2");
         p.put("movieDatabase.MaxIdle", "25");
         p.put("movieDatabase.MinIdle", "10");
         p.put("movieDatabase.AccessToUnderlyingConnectionAllowed", "true");
@@ -88,6 +89,7 @@ public class MoviesXATest {
         p.put("movieDatabaseUnmanaged.UserName", "admin");
         p.put("movieDatabaseUnmanaged.Password", "admin");
         p.put("movieDatabaseUnmanaged.JtaManaged", "false");
+        p.put("movieDatabaseUnmanaged.InitialSize", "2");
         p.put("movieDatabaseUnmanaged.MaxActive", "128");
         p.put("movieDatabaseUnmanaged.MaxIdle", "25");
         p.put("movieDatabaseUnmanaged.MinIdle", "10");
@@ -100,97 +102,6 @@ public class MoviesXATest {
         p.put("movieDatabaseUnmanaged.MaxOpenPreparedStatements", "1024");
         p.put("movieDatabaseUnmanaged.ValidationQuery", "values 1");
 
-        /*
-
-        Configuration for MS SQL Server
-
-        p.put("movieDatabaseXA", "new://Resource?type=javax.sql.XADataSource&class-name=com.microsoft.sqlserver.jdbc.SQLServerXADataSource");
-        p.put("movieDatabaseXA.DatabaseName", "moviefun");
-        p.put("movieDatabaseXA.URL", "jdbc:sqlserver://localhost:1433;databaseName=moviefun;SelectMethod=cursor;sendStringParametersAsUnicode=false");
-
-        p.put("movieDatabase", "new://Resource?type=DataSource");
-        p.put("movieDatabase.XaDataSource", "movieDatabaseXA");
-        p.put("movieDatabase.UserName", "sa");
-        p.put("movieDatabase.Password", "XXX");
-        p.put("movieDatabase.JtaManaged", "true");
-        p.put("movieDatabase.MaxActive", "128");
-        p.put("movieDatabase.MaxIdle", "25");
-        p.put("movieDatabase.MinIdle", "10");
-        p.put("movieDatabase.AccessToUnderlyingConnectionAllowed", "true");
-        p.put("movieDatabase.TestOnBorrow", "false");
-        p.put("movieDatabase.TestWhileIdle", "true");
-        p.put("movieDatabase.TimeBetweenEvictionRuns", "1 minute");
-        p.put("movieDatabase.MaxWaitTime", "0 seconds");
-        p.put("movieDatabase.PoolPreparedStatements", "true");
-        p.put("movieDatabase.MaxOpenPreparedStatements", "1024");
-        p.put("movieDatabase.ValidationQuery", "select 1");
-
-        p.put("movieDatabaseUnmanaged", "new://Resource?type=DataSource");
-        p.put("movieDatabaseUnmanaged.LogSql", "true");
-        p.put("movieDatabaseUnmanaged.JdbcDriver", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
-        p.put("movieDatabaseUnmanaged.JdbcUrl", "jdbc:sqlserver://localhost:1433;databaseName=moviefun;SelectMethod=cursor;sendStringParametersAsUnicode=false");
-        p.put("movieDatabaseUnmanaged.UserName", "sa");
-        p.put("movieDatabaseUnmanaged.Password", "XXX");
-        p.put("movieDatabaseUnmanaged.JtaManaged", "false");
-        p.put("movieDatabaseUnmanaged.MaxActive", "128");
-        p.put("movieDatabaseUnmanaged.MaxIdle", "25");
-        p.put("movieDatabaseUnmanaged.MinIdle", "10");
-        p.put("movieDatabaseUnmanaged.AccessToUnderlyingConnectionAllowed", "true");
-        p.put("movieDatabaseUnmanaged.TestOnBorrow", "false");
-        p.put("movieDatabaseUnmanaged.TestWhileIdle", "true");
-        p.put("movieDatabaseUnmanaged.TimeBetweenEvictionRuns", "1 minute");
-        p.put("movieDatabaseUnmanaged.MaxWaitTime", "0 seconds");
-        p.put("movieDatabaseUnmanaged.PoolPreparedStatements", "true");
-        p.put("movieDatabaseUnmanaged.MaxOpenPreparedStatements", "1024");
-        p.put("movieDatabaseUnmanaged.ValidationQuery", "select 1");
-
-        p.put("movieDatabaseXA", "new://Resource?type=javax.sql.XADataSource&class-name=oracle.jdbc.xa.client.OracleXADataSource");
-        p.put("movieDatabaseXA.url", "jdbc:oracle:thin:@//localhost:1521/orcl");
-
-        */
-
-        /*
-
-        Configuration for Oracle
-
-        p.put("movieDatabase", "new://Resource?type=DataSource");
-        p.put("movieDatabase.XaDataSource", "movieDatabaseXA");
-        p.put("movieDatabase.JtaManaged", "true");
-        p.put("movieDatabase.UserName", "system");
-        p.put("movieDatabase.Password", "oracle");
-        p.put("movieDatabase.MaxActive", "128");
-        p.put("movieDatabase.MaxIdle", "25");
-        p.put("movieDatabase.MinIdle", "10");
-        p.put("movieDatabase.AccessToUnderlyingConnectionAllowed", "true");
-        p.put("movieDatabase.TestOnBorrow", "false");
-        p.put("movieDatabase.TestWhileIdle", "true");
-        p.put("movieDatabase.TimeBetweenEvictionRuns", "1 minute");
-        p.put("movieDatabase.MaxWaitTime", "0 seconds");
-        p.put("movieDatabase.PoolPreparedStatements", "true");
-        p.put("movieDatabase.MaxOpenPreparedStatements", "1024");
-        p.put("movieDatabase.ValidationQuery", "select 1 from dual");
-
-        p.put("movieDatabaseUnmanaged", "new://Resource?type=DataSource");
-        p.put("movieDatabaseUnmanaged.LogSql", "true");
-        p.put("movieDatabaseUnmanaged.JdbcDriver", "oracle.jdbc.driver.OracleDriver");
-        p.put("movieDatabaseUnmanaged.JdbcUrl", "jdbc:oracle:thin:@//localhost:1521/orcl");
-        p.put("movieDatabaseUnmanaged.UserName", "system");
-        p.put("movieDatabaseUnmanaged.Password", "oracle");
-        p.put("movieDatabaseUnmanaged.JtaManaged", "false");
-        p.put("movieDatabaseUnmanaged.MaxActive", "128");
-        p.put("movieDatabaseUnmanaged.MaxIdle", "25");
-        p.put("movieDatabaseUnmanaged.MinIdle", "10");
-        p.put("movieDatabaseUnmanaged.AccessToUnderlyingConnectionAllowed", "true");
-        p.put("movieDatabaseUnmanaged.TestOnBorrow", "false");
-        p.put("movieDatabaseUnmanaged.TestWhileIdle", "true");
-        p.put("movieDatabaseUnmanaged.TimeBetweenEvictionRuns", "1 minute");
-        p.put("movieDatabaseUnmanaged.MaxWaitTime", "0 seconds");
-        p.put("movieDatabaseUnmanaged.PoolPreparedStatements", "true");
-        p.put("movieDatabaseUnmanaged.MaxOpenPreparedStatements", "1024");
-        p.put("movieDatabaseUnmanaged.ValidationQuery", "select 1 from dual");
-
-        */
-
         System.out.println("Using db: " + db);
 
         return p;

http://git-wip-us.apache.org/repos/asf/tomee/blob/9e19d4a4/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java b/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java
index 73b6043..4ca7529 100644
--- a/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java
+++ b/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java
@@ -40,13 +40,16 @@ import org.apache.tomcat.jdbc.pool.PooledConnection;
 import javax.management.ObjectName;
 import javax.sql.CommonDataSource;
 import javax.sql.DataSource;
+import javax.sql.XAConnection;
 import javax.sql.XADataSource;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
+import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.Map;
 import java.util.Properties;
+import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
 public class TomEEDataSourceCreator extends PoolDataSourceCreator {
@@ -80,17 +83,17 @@ public class TomEEDataSourceCreator extends PoolDataSourceCreator {
 
         updateProperties(prop, converted, driver);
         final PoolConfiguration config = build(PoolProperties.class, converted);
-        final TomEEDataSource ds = build(TomEEDataSource.class, new TomEEDataSource(config, name), converted);
-
         final String xa = String.class.cast(properties.remove("XaDataSource"));
         if (xa != null) {
-            cleanProperty(ds, "xadatasource");
-
             final XADataSource xaDs = XADataSourceResource.proxy(Thread.currentThread().getContextClassLoader(), xa);
-            ds.setDataSource(xaDs);
+            final TomEEDataSource instance = new TomEEDataSource(config, name, xaDs);
+            return build(TomEEDataSource.class, instance, converted);
+
+        } else {
+            final TomEEDataSource instance = new TomEEDataSource(config, name);
+            return build(TomEEDataSource.class, instance, converted);
         }
 
-        return ds;
     }
 
     private void updateProperties(final SuperProperties properties, final Properties converted, final String driver) {
@@ -215,7 +218,15 @@ public class TomEEDataSourceCreator extends PoolDataSourceCreator {
         }
 
         public TomEEDataSource(final PoolConfiguration poolConfiguration, final String name) {
+            this(poolConfiguration, name, null);
+        }
+
+        public TomEEDataSource(final PoolConfiguration poolConfiguration, final String name, final XADataSource xaDs) {
             super(readOnly(poolConfiguration));
+            if (xaDs != null) {
+                this.setDataSource(xaDs);
+            }
+
             try { // just to force the pool to be created and be able to register the mbean
                 createPool();
                 initJmx(name);
@@ -297,6 +308,16 @@ public class TomEEDataSourceCreator extends PoolDataSourceCreator {
                 }
             }
         }
+
+        @Override
+        public Connection getConnection() throws SQLException {
+            return super.getConnection();
+        }
+
+        @Override
+        public Connection getConnection(final String username, final String password) throws SQLException {
+            return super.getConnection(username, password);
+        }
     }
 
     private static class ReadOnlyConnectionpool implements InvocationHandler {
@@ -330,6 +351,7 @@ public class TomEEDataSourceCreator extends PoolDataSourceCreator {
         @Override
         protected PooledConnection create(final boolean incrementCounter) {
             final PooledConnection con = super.create(incrementCounter);
+
             if (getPoolProperties().getDataSource() == null) { // using driver
                 // init driver with TCCL
                 ClassLoader cl = Thread.currentThread().getContextClassLoader();

http://git-wip-us.apache.org/repos/asf/tomee/blob/9e19d4a4/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatXADataSourceTest.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatXADataSourceTest.java b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatXADataSourceTest.java
index f44b0bb..68892e5 100644
--- a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatXADataSourceTest.java
+++ b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatXADataSourceTest.java
@@ -27,17 +27,27 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import javax.annotation.Resource;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
 import javax.sql.DataSource;
+import java.lang.management.ManagementFactory;
 import java.sql.Connection;
-import java.sql.SQLException;
 import java.util.Properties;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
 
 @RunWith(ApplicationComposer.class)
 public class TomcatXADataSourceTest {
+    private static final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
     @Resource(name = "xadb")
     private DataSource ds;
 
@@ -70,12 +80,21 @@ public class TomcatXADataSourceTest {
     }
 
     @Test
-    public void check() throws SQLException {
+    public void check() throws Exception {
         assertNotNull(ds);
         final Connection c = ds.getConnection();
         assertNotNull(c);
         assertThat(c.getMetaData().getConnection(), instanceOf(JDBCXAConnectionWrapper.class));
         c.close();
 
+        assertEquals(0, getActiveConnections("xadb"));
+    }
+
+
+    private int getActiveConnections(final String dataSourceName)
+            throws MalformedObjectNameException, MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException {
+        final ObjectName objectName = new ObjectName("openejb.management:ObjectType=datasources,DataSource=" + dataSourceName);
+        final Object activeConnectionsAttribute = server.getAttribute(objectName, "Active");
+        return (int) (Integer) activeConnectionsAttribute;
     }
 }