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 2013/04/26 08:16:15 UTC
svn commit: r1476058 - in
/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc:
RoutedDataSource.java router/ConnectionProvider.java
router/FailOverRouter.java
Author: rmannibucau
Date: Fri Apr 26 06:16:15 2013
New Revision: 1476058
URL: http://svn.apache.org/r1476058
Log:
TOMEE-912 reworking FailoverRouter to get rid of ConnectionProvider and better handling set/get
Removed:
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/router/ConnectionProvider.java
Modified:
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/RoutedDataSource.java
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/router/FailOverRouter.java
Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/RoutedDataSource.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/RoutedDataSource.java?rev=1476058&r1=1476057&r2=1476058&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/RoutedDataSource.java (original)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/RoutedDataSource.java Fri Apr 26 06:16:15 2013
@@ -17,7 +17,6 @@
package org.apache.openejb.resource.jdbc;
import org.apache.openejb.loader.SystemInstance;
-import org.apache.openejb.resource.jdbc.router.ConnectionProvider;
import org.apache.openejb.resource.jdbc.router.Router;
import org.apache.openejb.spi.ContainerSystem;
import org.apache.openejb.util.reflection.Reflections;
@@ -108,17 +107,11 @@ public class RoutedDataSource implements
}
public Connection getConnection() throws SQLException {
- if (ConnectionProvider.class.isInstance(getDelegate())) {
- return ConnectionProvider.class.cast(getDelegate()).getConnection();
- }
return getTargetDataSource().getConnection();
}
public Connection getConnection(String username, String password)
throws SQLException {
- if (ConnectionProvider.class.isInstance(getDelegate())) {
- return ConnectionProvider.class.cast(getDelegate()).getConnection(username, password);
- }
return getTargetDataSource().getConnection(username, password);
}
Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/router/FailOverRouter.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/router/FailOverRouter.java?rev=1476058&r1=1476057&r2=1476058&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/router/FailOverRouter.java (original)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/router/FailOverRouter.java Fri Apr 26 06:16:15 2013
@@ -21,50 +21,26 @@ import org.apache.openejb.util.Logger;
import javax.naming.NamingException;
import javax.sql.DataSource;
-import java.sql.Connection;
-import java.sql.SQLException;
+import javax.sql.XADataSource;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
-public class FailOverRouter extends AbstractRouter implements ConnectionProvider {
+public class FailOverRouter extends AbstractRouter {
private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB_SERVER, FailOverRouter.class);
-
+ private final AtomicReference<DataSource> facade = new AtomicReference<DataSource>();
+ private final Collection<DataSource> dataSources = new CopyOnWriteArrayList<DataSource>();
private String delimiter = ",";
private String datasourceNames = "";
- private Collection<DataSource> dataSources = new CopyOnWriteArrayList<DataSource>();
-
@Override
public DataSource getDataSource() {
- for (final DataSource ds : dataSources) {
- return ds;
- }
- throw new IllegalStateException("No datasource configured");
- }
-
- @Override
- public Connection getConnection() throws SQLException {
- for (final DataSource ds : dataSources) {
- try {
- return ds.getConnection();
- } catch (final SQLException e) {
- // no-op
- }
- }
- throw new SQLException("Can't connect to any datasources of " + dataSources);
- }
-
- @Override
- public Connection getConnection(String user, String pwd) throws SQLException {
- for (final DataSource ds : dataSources) {
- try {
- return ds.getConnection(user, pwd);
- } catch (final SQLException e) {
- // no-op
- }
- }
- throw new SQLException("Can't connect to any datasources of " + dataSources);
+ return facade.get();
}
public void setDatasourceNames(final String datasourceNames) {
@@ -78,6 +54,7 @@ public class FailOverRouter extends Abst
}
private void initDataSources() {
+ dataSources.clear();
for (final String ds : datasourceNames.split(Pattern.quote(delimiter))) {
try {
final Object o = getOpenEJBResource(ds.trim());
@@ -89,6 +66,25 @@ public class FailOverRouter extends Abst
LOGGER.error("Can't find datasource '" + ds + "'", error);
}
}
+
+ initFacade();
+ }
+
+ private void initFacade() {
+ Class<?> clazz = DataSource.class;
+ int xads = 0;
+ for (final DataSource ds : dataSources) {
+ if (XADataSource.class.isInstance(ds)) {
+ xads++;
+ }
+ }
+ if (xads > 0 && xads == dataSources.size()) {
+ clazz = XADataSource.class;
+ }
+
+ facade.set(DataSource.class.cast(Proxy.newProxyInstance(
+ Thread.currentThread().getContextClassLoader(),
+ new Class<?>[]{ clazz }, new FacadeHandler(dataSources))));
}
public Collection<DataSource> getDataSources() {
@@ -98,5 +94,47 @@ public class FailOverRouter extends Abst
public void updateDataSources(final Collection<DataSource> ds) {
dataSources.clear();
dataSources.addAll(ds);
+ initFacade();
+ }
+
+ private static class FacadeHandler implements InvocationHandler {
+ private final Collection<DataSource> delegates;
+
+ public FacadeHandler(final Collection<DataSource> dataSources) {
+ this.delegates = dataSources;
+ }
+
+ @Override
+ public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+ if (Object.class.equals(method.getDeclaringClass())) {
+ if ("toString".equals(method.getName())) {
+ return "DataSourceFacade" + delegates;
+ }
+ if ("hashCode".equals(method.getName())) {
+ return delegates.hashCode();
+ }
+ if ("equals".equals(method.getName())) {
+ return method.invoke(this, args);
+ }
+ }
+
+ int ex = 0;
+ for (final DataSource ds : delegates) {
+ try {
+ if (method.getName().startsWith("set")) {
+ method.invoke(ds, args);
+ } else if (method.getName().startsWith("get")) {
+ return method.invoke(ds, args); // return the first one succeeding
+ }
+ } catch (final InvocationTargetException ite) {
+ ex++;
+ if (ex == delegates.size()) { // all failed so throw the exception
+ throw ite.getCause();
+ }
+ }
+ }
+
+ return null;
+ }
}
}