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

[49/50] tomee git commit: TOMEE-1964 always return false for isSameResource when required on a XADataSource

TOMEE-1964 always return false for isSameResource when required on a XADataSource


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

Branch: refs/heads/tomee-1.7.x
Commit: 1b222cabd659ed661830ec4e11e995cadc556e48
Parents: d39d1bc
Author: rmannibucau <rm...@apache.org>
Authored: Thu Nov 3 19:26:39 2016 +0100
Committer: rmannibucau <rm...@apache.org>
Committed: Thu Nov 3 19:26:39 2016 +0100

----------------------------------------------------------------------
 .../openejb/config/ConfigurationFactory.java    |   5 +-
 .../resource/jdbc/DataSourceFactory.java        |  15 ++-
 .../jdbc/xa/IsDifferentXaDataSourceWrapper.java | 107 +++++++++++++++++++
 .../jdbc/XADataSourceIsDifferentTest.java       |  87 +++++++++++++++
 4 files changed, 211 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/1b222cab/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
index f5dd8ba..a348da3 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
@@ -1778,8 +1778,9 @@ public class ConfigurationFactory implements OpenEjbConfigurationFactory {
                         }
                     } else {
                         final String trim = String.valueOf(value).trim();
-                        if (ids.contains(trim)) {
-                            refs.add(trim);
+                        final String id = (trim.startsWith("@") || trim.startsWith("$")) && trim.length() > 1 ? trim.substring(1) : trim;
+                        if (ids.contains(id)) {
+                            refs.add(id);
                         }
                     }
                 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/1b222cab/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java
index be23efa..e0db5e3 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java
@@ -77,6 +77,8 @@ public class DataSourceFactory {
     public static final String GLOBAL_FLUSH_PROPERTY = "openejb.jdbc.flushable";
     public static final String POOL_PROPERTY = "openejb.datasource.pool";
     public static final String DATA_SOURCE_CREATOR_PROP = "DataSourceCreator";
+    public static final String XA_GLOBAL_FORCE_DIFFERENT = "openejb.datasource.xa.force-different-xaresource";
+    public static final String XA_FORCE_DIFFERENT = "XAForceDifferent";
     public static final String HANDLER_PROPERTY = "TomEEProxyHandler";
     public static final String GLOBAL_HANDLER_PROPERTY = "openejb.jdbc.handler";
 
@@ -105,6 +107,7 @@ public class DataSourceFactory {
         final String handler = SystemInstance.get().getOptions().get(GLOBAL_HANDLER_PROPERTY, (String) properties.remove(HANDLER_PROPERTY));
         boolean flushable = SystemInstance.get().getOptions().get(GLOBAL_FLUSH_PROPERTY,
             "true".equalsIgnoreCase((String) properties.remove(FLUSHABLE_PROPERTY)));
+        final String forceDifferent = SystemInstance.get().getOptions().get(XA_GLOBAL_FORCE_DIFFERENT, String.class.cast(properties.remove(XA_FORCE_DIFFERENT)));
 
         convert(properties, maxWaitTime, "maxWaitTime", "maxWait");
         convert(properties, timeBetweenEvictionRuns, "timeBetweenEvictionRuns", "timeBetweenEvictionRunsMillis");
@@ -175,8 +178,18 @@ public class DataSourceFactory {
                     recipe.setProperty("url", properties.getProperty("JdbcUrl"));
                 }
 
-                final CommonDataSource dataSource = (CommonDataSource) recipe.create();
+                CommonDataSource dataSource = (CommonDataSource) recipe.create();
                 final boolean isDs = DataSource.class.isInstance(dataSource);
+                if (!isDs && XADataSource.class.isInstance(dataSource) && forceDifferent != null) {
+                    try {
+                        dataSource = CommonDataSource.class.cast(Thread.currentThread().getContextClassLoader()
+                                        .loadClass("true".equals(forceDifferent) ? "org.apache.openejb.resource.jdbc.xa.IsDifferentXaDataSourceWrapper" : forceDifferent)
+                                        .getConstructor(XADataSource.class)
+                                        .newInstance(dataSource));
+                    } catch (InvocationTargetException | ClassNotFoundException | NoSuchMethodException e) {
+                        throw new IllegalArgumentException(e);
+                    }
+                }
 
                 if (managed) {
                     if (isDs && usePool(properties)) {

http://git-wip-us.apache.org/repos/asf/tomee/blob/1b222cab/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/xa/IsDifferentXaDataSourceWrapper.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/xa/IsDifferentXaDataSourceWrapper.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/xa/IsDifferentXaDataSourceWrapper.java
new file mode 100644
index 0000000..e15e8cb
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/xa/IsDifferentXaDataSourceWrapper.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.openejb.resource.jdbc.xa;
+
+import javax.sql.XAConnection;
+import javax.sql.XADataSource;
+import javax.transaction.xa.XAResource;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.logging.Logger;
+
+public class IsDifferentXaDataSourceWrapper implements XADataSource {
+    private static final Class<?>[] API_CONNECTION = {XAConnection.class};
+    private static final Class<?>[] API_RESOURCE = {XAResource.class};
+    private final XADataSource delegate;
+
+    public IsDifferentXaDataSourceWrapper(final XADataSource delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public XAConnection getXAConnection() throws SQLException {
+        return wrap(delegate.getXAConnection());
+    }
+
+    @Override
+    public XAConnection getXAConnection(final String user, final String password) throws SQLException {
+        return wrap(delegate.getXAConnection(user, password));
+    }
+
+    private XAConnection wrap(final XAConnection xaConnection) {
+        return XAConnection.class.cast(Proxy.newProxyInstance(xaConnection.getClass().getClassLoader(), API_CONNECTION, new InvocationHandler() {
+            @Override
+            public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+                if ("getXAResource".equals(method.getName())) {
+                    try {
+                        final Object xaResource = method.invoke(xaConnection, args);
+                        return Proxy.newProxyInstance(xaResource.getClass().getClassLoader(), API_RESOURCE, new InvocationHandler() {
+                            @Override
+                            public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+                                if ("isSameRM".equals(method.getName())) {
+                                    return false; // that's the goal!
+                                }
+                                try {
+                                    return method.invoke(xaResource, args);
+                                } catch (final InvocationTargetException ite) {
+                                    throw ite.getCause();
+                                }
+                            }
+                        });
+                    } catch (final InvocationTargetException ite) {
+                        throw ite.getCause();
+                    }
+                }
+                try {
+                    return method.invoke(xaConnection, args);
+                } catch (final InvocationTargetException ite) {
+                    throw ite.getCause();
+                }
+            }
+        }));
+    }
+
+    @Override
+    public PrintWriter getLogWriter() throws SQLException {
+        return delegate.getLogWriter();
+    }
+
+    @Override
+    public void setLogWriter(final PrintWriter out) throws SQLException {
+        delegate.setLogWriter(out);
+    }
+
+    @Override
+    public void setLoginTimeout(final int seconds) throws SQLException {
+        delegate.setLoginTimeout(seconds);
+    }
+
+    @Override
+    public int getLoginTimeout() throws SQLException {
+        return delegate.getLoginTimeout();
+    }
+
+    @Override
+    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+        return delegate.getParentLogger();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1b222cab/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/XADataSourceIsDifferentTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/XADataSourceIsDifferentTest.java b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/XADataSourceIsDifferentTest.java
new file mode 100644
index 0000000..9ab23bd
--- /dev/null
+++ b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/XADataSourceIsDifferentTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.openejb.resource.jdbc;
+
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.loader.Files;
+import org.apache.openejb.resource.jdbc.dbcp.DbcpDataSourceCreator;
+import org.apache.openejb.resource.jdbc.pool.DataSourceCreator;
+import org.apache.openejb.resource.jdbc.xa.IsDifferentXaDataSourceWrapper;
+import org.apache.openejb.testing.Configuration;
+import org.apache.openejb.testing.Module;
+import org.hsqldb.jdbc.pool.JDBCXADataSource;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.annotation.Resource;
+import javax.sql.XADataSource;
+import javax.transaction.UserTransaction;
+import java.io.File;
+import java.util.Properties;
+
+import static org.junit.Assert.assertFalse;
+
+@RunWith(ApplicationComposer.class)
+public class XADataSourceIsDifferentTest {
+    @Resource
+    private UserTransaction ut;
+
+    @Resource(name = "xaFacade")
+    private XADataSource ds;
+
+    @Test
+    public void run() throws Exception {
+        ut.begin();
+        try {
+            assertFalse(ds.getXAConnection().getXAResource().isSameRM(ds.getXAConnection().getXAResource()));
+        } finally {
+            ut.commit();
+        }
+    }
+
+    @Configuration
+    public Properties config() {
+        final File file = new File("target/test/xa/howl");
+        if (file.isDirectory()) {
+            Files.delete(file);
+        }
+
+        final Properties p = new Properties();
+        p.put(DataSourceCreator.class.getName(), DbcpDataSourceCreator.class.getName()); // default dbcp pool supports xaDataSource config, not our proxy layer
+
+        p.put("txMgr", "new://TransactionManager?type=TransactionManager");
+        p.put("txMgr.txRecovery", "true");
+        p.put("txMgr.logFileDir", "target/test/xa/howl");
+
+        p.put("xa", "new://Resource?class-name=" + JDBCXADataSource.class.getName());
+        p.put("xa.url", "jdbc:hsqldb:mem:xa");
+        p.put("xa.user", "sa");
+        p.put("xa.password", "");
+        p.put("xa.SkipImplicitAttributes", "true"); // conflict with connectionProperties
+
+        p.put("xaFacade", "new://Resource?class-name=" + IsDifferentXaDataSourceWrapper.class.getName() + "&constructor=delegate");
+        p.put("xaFacade.delegate", "@xa");
+
+        return p;
+    }
+
+    @Module
+    public EjbJar app() throws Exception {
+        return new EjbJar();
+    }
+}