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();
+ }
+}