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 2014/10/02 15:58:18 UTC

svn commit: r1628979 - in /tomee/tomee/trunk: arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/cipher/ container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/

Author: rmannibucau
Date: Thu Oct  2 13:58:18 2014
New Revision: 1628979

URL: http://svn.apache.org/r1628979
Log:
TOMEE-1374 TOMEE-1373 unregistring AlternativeDriver + trying to detect we have to create with app loader a datasource

Added:
    tomee/tomee/trunk/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/cipher/
    tomee/tomee/trunk/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/cipher/CipherFromAppTest.java
    tomee/tomee/trunk/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/cipher/MyConstantCipher.java
Modified:
    tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java

Added: tomee/tomee/trunk/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/cipher/CipherFromAppTest.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/cipher/CipherFromAppTest.java?rev=1628979&view=auto
==============================================================================
--- tomee/tomee/trunk/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/cipher/CipherFromAppTest.java (added)
+++ tomee/tomee/trunk/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/cipher/CipherFromAppTest.java Thu Oct  2 13:58:18 2014
@@ -0,0 +1,59 @@
+/*
+ * 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.arquillian.tests.cipher;
+
+import org.apache.openejb.cipher.PasswordCipher;
+import org.apache.openejb.resource.jdbc.managed.local.ManagedDataSource;
+import org.apache.tomee.jdbc.TomEEDataSourceCreator;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Arquillian.class)
+public class CipherFromAppTest {
+    @Deployment
+    public static Archive<?> war() {
+        return ShrinkWrap.create(WebArchive.class, CipherFromAppTest.class.getName() + ".war")
+                .addClass(MyConstantCipher.class)
+                .addAsWebInfResource(new StringAsset(MyConstantCipher.class.getName()), "classes/META-INF/" + PasswordCipher.class.getName() + "/constant")
+                .addAsWebInfResource(new StringAsset("" +
+                        "<resource>" +
+                        "   <Resource type=\"DataSource\" id=\"cipher\">" +
+                        "       PasswordCipher = constant" +
+                        "   </Resource>" +
+                        "</resource>"), "resources.xml");
+    }
+
+    @Resource(name = "cipher")
+    private DataSource ds;
+
+    @Test
+    public void checkPassword() {
+        final DataSource delegate = ManagedDataSource.class.cast(ds).getDelegate();
+        assertEquals(new MyConstantCipher().decrypt(null), TomEEDataSourceCreator.TomEEDataSource.class.cast(delegate).getPoolProperties().getPassword());
+    }
+}

Added: tomee/tomee/trunk/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/cipher/MyConstantCipher.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/cipher/MyConstantCipher.java?rev=1628979&view=auto
==============================================================================
--- tomee/tomee/trunk/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/cipher/MyConstantCipher.java (added)
+++ tomee/tomee/trunk/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/cipher/MyConstantCipher.java Thu Oct  2 13:58:18 2014
@@ -0,0 +1,31 @@
+/*
+ * 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.arquillian.tests.cipher;
+
+import org.apache.openejb.cipher.PasswordCipher;
+
+public class MyConstantCipher implements PasswordCipher {
+    @Override
+    public char[] encrypt(final String plainPassword) {
+        return new char[0];
+    }
+
+    @Override
+    public String decrypt(final char[] encryptedPassword) {
+        return "constant I said";
+    }
+}

Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java?rev=1628979&r1=1628978&r2=1628979&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java (original)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java Thu Oct  2 13:58:18 2014
@@ -17,6 +17,8 @@
 
 package org.apache.openejb.resource.jdbc;
 
+import org.apache.openejb.cipher.PasswordCipherException;
+import org.apache.openejb.cipher.PasswordCipherFactory;
 import org.apache.openejb.loader.IO;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.resource.XAResourceWrapper;
@@ -50,6 +52,8 @@ import java.util.Properties;
 import java.util.TreeMap;
 import java.util.concurrent.TimeUnit;
 
+import static java.util.Arrays.asList;
+
 /**
  * @version $Rev$ $Date$
  */
@@ -64,6 +68,8 @@ public class DataSourceFactory {
     public static final String POOL_PROPERTY = "openejb.datasource.pool";
     public static final String DATA_SOURCE_CREATOR_PROP = "DataSourceCreator";
 
+    private static final Map<CommonDataSource, AlternativeDriver> driverByDataSource = new HashMap<CommonDataSource, AlternativeDriver>();
+
     private static final Map<CommonDataSource, DataSourceCreator> creatorByDataSource = new HashMap<CommonDataSource, DataSourceCreator>();
     private static final Map<String, String> KNOWN_CREATORS = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER) {{
         put("simple", "org.apache.openejb.resource.jdbc.SimpleDataSourceCreator"); // use user provided DS, pooling not supported
@@ -114,23 +120,37 @@ public class DataSourceFactory {
 
         final String jdbcUrl = properties.getProperty("JdbcUrl");
 
+        final AlternativeDriver driver;
         if (Driver.class.isAssignableFrom(impl) && jdbcUrl != null) {
             try {
-                final AlternativeDriver driver = new AlternativeDriver((Driver) impl.newInstance(), jdbcUrl);
+                driver = new AlternativeDriver((Driver) impl.newInstance(), jdbcUrl);
                 driver.register();
             } catch (final SQLException e) {
                 throw new IllegalStateException(e);
             }
+        } else {
+            driver = null;
         }
 
         final boolean logSql = SystemInstance.get().getOptions().get(GLOBAL_LOG_SQL_PROPERTY,
             "true".equalsIgnoreCase((String) properties.remove(LOG_SQL_PROPERTY)));
         final DataSourceCreator creator = creator(properties.remove(DATA_SOURCE_CREATOR_PROP), logSql);
 
-        final boolean useContainerLoader = "true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.resources.use-container-loader", "true")) && (impl == null || impl.getClassLoader() == DataSourceFactory.class.getClassLoader());
+        boolean useContainerLoader = "true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.resources.use-container-loader", "true")) && (impl == null || impl.getClassLoader() == DataSourceFactory.class.getClassLoader());
         final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
         if (useContainerLoader) {
-            Thread.currentThread().setContextClassLoader(DataSourceFactory.class.getClassLoader());
+            final ClassLoader containerLoader = DataSourceFactory.class.getClassLoader();
+            Thread.currentThread().setContextClassLoader(containerLoader);
+            try {
+                useContainerLoader = basicChecksThatDataSourceCanBeCreatedFromContainerLoader(properties, containerLoader);
+            } finally {
+                Thread.currentThread().setContextClassLoader(oldLoader);
+            }
+            if (useContainerLoader) {
+                Thread.currentThread().setContextClassLoader(containerLoader);
+            } else {
+                LOGGER.info("Can't use container loader to create datasource " + name + " so using application one");
+            }
         }
 
         try {
@@ -178,6 +198,9 @@ public class DataSourceFactory {
 
             // ds and creator are associated here, not after the proxying of the next if if active
             setCreatedWith(creator, ds);
+            if (driver != null) {
+                driverByDataSource.put(ds, driver);
+            }
 
             if (logSql) {
                 ds = makeItLogging(ds);
@@ -194,6 +217,34 @@ public class DataSourceFactory {
         }
     }
 
+    private static boolean basicChecksThatDataSourceCanBeCreatedFromContainerLoader(final Properties properties, final ClassLoader containerLoader) {
+        // check basic some classes can be loaded from container otherwise don't force it
+        try {
+            for (final String property : asList("JdbcDriver", "driverClassName")) {
+                final String value = properties.getProperty(property);
+                if (value != null) {
+                    Class.forName(value, false, containerLoader);
+                }
+            }
+        } catch (final ClassNotFoundException cnfe) {
+            return false;
+        } catch (final NoClassDefFoundError cnfe) {
+            return false;
+        }
+
+        // also password cipher can be loaded from apps
+        try {
+            final String cipher = properties.getProperty("PasswordCipher");
+            if (cipher != null && !"PlainText".equals(cipher) && !"Static3DES".equals(cipher)) {
+                PasswordCipherFactory.getPasswordCipher(cipher);
+            }
+        } catch (final PasswordCipherException cnfe) {
+            return false;
+        }
+
+        return true;
+    }
+
     private static CommonDataSource makeFlushable(final CommonDataSource ds, final FlushableDataSourceHandler.FlushConfig flushConfig) {
         return (CommonDataSource) Proxy.newProxyInstance(
             Thread.currentThread().getContextClassLoader(),
@@ -334,6 +385,11 @@ public class DataSourceFactory {
         }
         final DataSourceCreator remove = creatorByDataSource.remove(instance);
         remove.destroy(instance);
+
+        final AlternativeDriver driver = driverByDataSource.remove(instance);
+        if (driver != null) {
+            driver.deregister();
+        }
     }
 
     // remove proxy added by us in front of the datasource returned by the creator