Author: rmannibucau Date: Tue Apr 8 17:25:15 2014 New Revision: 1585786 URL: http://svn.apache.org/r1585786 Log: TOMEE-1172 jta datasource wrapper for custom datasources
Added: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/JTADataSourceWrapperFactoryTest.java - copied, changed from r1585779, tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/JtaFailOverRouterTest.java Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=1585786&r1=1585785&r2=1585786&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java Tue Apr 8 17:25:15 2014 @@ -104,6 +104,7 @@ import org.apache.openejb.quartz.Schedul import org.apache.openejb.resource.GeronimoConnectionManagerFactory; import org.apache.openejb.resource.PropertiesFactory; import org.apache.openejb.resource.jdbc.DataSourceFactory; +import org.apache.openejb.resource.jdbc.managed.JTADataSourceWrapperFactory; import org.apache.openejb.resource.jdbc.managed.local.ManagedDataSource; import org.apache.openejb.spi.ApplicationServer; import org.apache.openejb.spi.ContainerSystem; @@ -2298,7 +2299,9 @@ public class Assembler extends Assembler url = prop.getProperty("jdbcUrl"); } if (url == null) { - logger.info("can't find url for " + serviceInfo.id + " will not monitor it"); + if (!JTADataSourceWrapperFactory.class.getName().equals(serviceInfo.className)) { + logger.info("can't find url for " + serviceInfo.id + " will not monitor it"); + } } else { final String host = extractHost(url); if (host != null) { Added: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java?rev=1585786&view=auto ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java (added) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java Tue Apr 8 17:25:15 2014 @@ -0,0 +1,68 @@ +/* + * 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.managed; + +import org.apache.openejb.assembler.classic.Assembler; +import org.apache.openejb.loader.SystemInstance; +import org.apache.openejb.resource.jdbc.DataSourceFactory; +import org.apache.openejb.resource.jdbc.pool.DataSourceCreator; +import org.apache.openejb.spi.ContainerSystem; + +import javax.naming.NamingException; +import javax.sql.DataSource; + +public class JTADataSourceWrapperFactory { + private String serviceId; + private String delegate = "datasource"; + private String dataSourceCreator = "dbcp-alternative"; + private boolean logSql = false; + + public DataSource create() { + final DataSourceCreator creator = DataSourceFactory.creator(dataSourceCreator, logSql); + DataSource ds = creator.managed(serviceId, findDelegate()); + DataSourceFactory.setCreatedWith(creator, ds); + if (logSql) { + ds = DataSourceFactory.makeItLogging(ds); + } + return ds; + } + + private DataSource findDelegate() { + try { + return DataSource.class.cast(SystemInstance.get().getComponent(ContainerSystem.class).getJNDIContext() + .lookup(Assembler.OPENEJB_RESOURCE_JNDI_PREFIX + delegate)); + } catch (final NamingException e) { + throw new IllegalArgumentException("'" + delegate + "' not found", e); + } + } + + public void setServiceId(final String serviceId) { + this.serviceId = serviceId; + } + + public void setDelegate(final String delegate) { + this.delegate = delegate; + } + + public void setDataSourceCreator(final String dataSourceCreator) { + this.dataSourceCreator = dataSourceCreator; + } + + public void setLogSql(final boolean logSql) { + this.logSql = logSql; + } +} Copied: tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/JTADataSourceWrapperFactoryTest.java (from r1585779, tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/JtaFailOverRouterTest.java) URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/JTADataSourceWrapperFactoryTest.java?p2=tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/JTADataSourceWrapperFactoryTest.java&p1=tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/JtaFailOverRouterTest.java&r1=1585779&r2=1585786&rev=1585786&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/JtaFailOverRouterTest.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/JTADataSourceWrapperFactoryTest.java Tue Apr 8 17:25:15 2014 @@ -16,8 +16,11 @@ */ package org.apache.openejb.resource.jdbc; +import org.apache.openejb.assembler.classic.OpenEjbConfiguration; +import org.apache.openejb.assembler.classic.ResourceInfo; import org.apache.openejb.junit.ApplicationComposer; -import org.apache.openejb.resource.jdbc.router.FailOverRouter; +import org.apache.openejb.loader.SystemInstance; +import org.apache.openejb.resource.jdbc.managed.local.ManagedDataSource; import org.apache.openejb.testing.Configuration; import org.apache.openejb.testing.Module; import org.apache.openejb.testng.PropertiesBuilder; @@ -25,76 +28,75 @@ import org.junit.Test; import org.junit.runner.RunWith; import javax.annotation.Resource; -import javax.ejb.EJB; -import javax.ejb.Singleton; import javax.sql.DataSource; -import java.sql.Connection; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; import java.sql.SQLException; import java.util.Properties; -import static org.apache.openejb.resource.jdbc.FailOverRouters.datasource; -import static org.apache.openejb.resource.jdbc.FailOverRouters.url; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; @RunWith(ApplicationComposer.class) -public class JtaFailOverRouterTest { - @EJB - private JtaWrapper wrapper; +public class JTADataSourceWrapperFactoryTest { + @Resource(name = "jta") + private DataSource jta; + + @Resource(name = "raw") + private DataSource raw; @Test public void test() throws SQLException { - int i = 2; - for (int it = 0; it < 6; it++) { - wrapper.inTx("jdbc:hsqldb:mem:fo" + i); - i = 1 + (i % 2); + assertNotNull(raw); + assertNotNull(jta); + assertThat(jta, instanceOf(ManagedDataSource.class)); + + boolean found = false; + for (final ResourceInfo ri : SystemInstance.get().getComponent(OpenEjbConfiguration.class).facilities.resources) { + if (ri.id.equals("jta")) { + found = true; + assertTrue(ri.types.contains("DataSource")); // otherwise jpa integration is broken + break; + } } + assertTrue(found); } @Configuration public Properties configuration() { - return datasource(datasource(new PropertiesBuilder(), "fo1"), "fo2") - .property("fo1.JtaManaged", "true") - .property("fo2.JtaManaged", "true") - .property("router", "new://Resource?class-name=" + FailOverRouter.class.getName()) - .property("router.datasourceNames", "fo1,fo2") - .property("router.strategy", "reverse") - .property("routedDs", "new://Resource?provider=RoutedDataSource&type=DataSource") - .property("routedDs.router", "router") + return new PropertiesBuilder() + .p("raw", "new://Resource?class-name=" + MyDataSourceFactory.class.getName() + "&factory-name=create") + + .p("jta", "new://Resource?type=DataSource&class-name=org.apache.openejb.resource.jdbc.managed.JTADataSourceWrapperFactory&factory-name=create") + .p("jta.delegate", "raw") .build(); } @Module public Class<?>[] classes() { - return new Class<?>[] { JtaWrapper.class }; + return new Class<?>[] {}; } - @Singleton - public static class JtaWrapper { - @Resource(name = "routedDs") - private DataSource ds; - - public void inTx(final String url) { - Connection firstConnection = null; - try { - firstConnection = ds.getConnection(); - assertEquals(url, url(firstConnection)); - for (int i = 0; i < 1; i++) { // 4 is kind of random, > 2 is enough - final Connection anotherConnection = ds.getConnection(); - assertEquals(firstConnection, anotherConnection); // in tx so should be the same ds and if the ds is JtaManaged same anotherConnection - assertEquals(url, url(anotherConnection)); - } - } catch (final SQLException e) { - fail(e.getMessage()); - } finally { - try { - if (firstConnection != null) { - firstConnection.close(); - } - } catch (final Exception e) { - // no-op - } - } + public static class MyDataSourceFactory { + public DataSource create() { + return DataSource.class.cast( + Proxy.newProxyInstance( + Thread.currentThread().getContextClassLoader(), + new Class<?>[] { DataSource.class}, + new InvocationHandler() { + @Override + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + if ("hashCode".equals(method.getName())) { + return 0; + } + return null; + } + } + ) + ); } } }