You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ma...@apache.org on 2009/09/05 19:14:08 UTC

svn commit: r811682 - in /jackrabbit/sandbox/JCR-1456/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/persistence/db/ main/java/org/apache/jackrabbit/core/util/db/ test/java/org/apache/jackrabbit/core/util/db/

Author: martijnh
Date: Sat Sep  5 17:14:08 2009
New Revision: 811682

URL: http://svn.apache.org/viewvc?rev=811682&view=rev
Log:
JCR-1456 Database connection pooling

* Added a simple DataSource registry to the ConnectionFactory
* Removed getConnection method from the ConnectionFactory

Added:
    jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/
    jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/ConnectionFactoryTest.java   (with props)
    jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/TestAll.java   (with props)
Modified:
    jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/db/SimpleDbPersistenceManager.java
    jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionFactory.java

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/db/SimpleDbPersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/db/SimpleDbPersistenceManager.java?rev=811682&r1=811681&r2=811682&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/db/SimpleDbPersistenceManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/db/SimpleDbPersistenceManager.java Sat Sep  5 17:14:08 2009
@@ -180,7 +180,7 @@
      * @see DatabasePersistenceManager#getConnection()
      */
     protected Connection getConnection() throws RepositoryException, SQLException {
-        return ConnectionFactory.getConnection(driver, url, user, password);
+        return ConnectionFactory.getDataSource(driver, url, user, password).getConnection();
     }
 
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionFactory.java?rev=811682&r1=811681&r2=811682&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionFactory.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionFactory.java Sat Sep  5 17:14:08 2009
@@ -19,6 +19,8 @@
 import java.lang.reflect.Field;
 import java.sql.Connection;
 import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.jcr.RepositoryException;
 import javax.naming.Context;
@@ -36,60 +38,60 @@
 public class ConnectionFactory {
 
     /**
+     * The lock to protect the registry. 
+     */
+    private static final Object lock = new Object();
+
+    /**
+     * The known data sources. The keys in the map are based on driver-url-user combination.
+     */
+    private static final Map<String, DataSource> registry = new HashMap<String, DataSource>();
+
+    /**
      * Utility classes should not have a public or default constructor.
      */
     private ConnectionFactory() {
     }
 
     /**
-     * Open a connection using the specified properties.
-     * The connection can be created using a JNDI Data Source as well. To do that,
-     * the driver class name must reference a javax.naming.Context class
-     * (for example javax.naming.InitialContext), and the URL must be the JNDI URL
-     * (for example java:comp/env/jdbc/Test).
+     * Retrieve a {@code DataSource} for the specified properties.
+     * This can be a JNDI Data Source as well. To do that,
+     * the driver class name must reference a {@code javax.naming.Context} class
+     * (for example {@code javax.naming.InitialContext}), and the URL must be the JNDI URL
+     * (for example {@code java:comp/env/jdbc/Test}).
      *
      * @param driver the JDBC driver or the Context class
      * @param url the database URL
      * @param user the user name
      * @param password the password
-     * @return the connection
+     * @return the {@code DataSource}
      * @throws RepositoryException if the driver could not be loaded
      * @throws SQLException if the connection could not be established
      */
     @SuppressWarnings("unchecked")
-    public static Connection getConnection(
-            String driver, String url, String user, String password)
-            throws RepositoryException, SQLException {
-
-        Class<?> driverClass = getDriverClass(driver);
-        if (driverClass != null
-                && Context.class.isAssignableFrom(driverClass)) {
-            DataSource database = getJndiDataSource((Class<Context>) driverClass, url);
-            if (user == null && password == null) {
-                return database.getConnection();
-            } else {
-                return database.getConnection(user, password);
-            }
-        } else {
-            return getDriverDataSource(driverClass, url, user, password).getConnection();
-        }
-    }
-    
-    @SuppressWarnings("unchecked")
     public static DataSource getDataSource(String driver, String url, String user, String password)
             throws RepositoryException, SQLException    {
-
-        Class<?> driverClass = getDriverClass(driver);
-        if (driverClass != null
-                && Context.class.isAssignableFrom(driverClass)) {
-            DataSource database = getJndiDataSource((Class<Context>) driverClass, url);
-            if (user == null && password == null) {
-                return database;
-            } else {
-                return new DataSourceWrapper(database, user, password);
+        final String key = driver + url + user;
+        synchronized(lock) {
+            DataSource ds = registry.get(key);
+            if (ds == null) {
+                // Create a new pooling data source or lookup the JNDI data source and put it in the registry.
+                Class<?> driverClass = getDriverClass(driver);
+                if (driverClass != null
+                        && Context.class.isAssignableFrom(driverClass)) {
+                    DataSource database = getJndiDataSource((Class<Context>) driverClass, url);
+                    if (user == null && password == null) {
+                        ds = database;
+                    } else {
+                        ds = new DataSourceWrapper(database, user, password);
+                    }
+                } else {
+                    ds = getDriverDataSource(driverClass, url, user, password);
+                }
+                // FIXME: is it good practice to cache JNDI things???
+                registry.put(key, ds);
             }
-        } else {
-            return getDriverDataSource(driverClass, url, user, password);
+            return ds;
         }        
     }
 
@@ -203,7 +205,11 @@
         database.setUrl(url);
         database.setUsername(user);
         database.setPassword(password);
-
+        database.setDefaultAutoCommit(true);
+        database.setTestOnBorrow(true);
+        database.setMaxActive(10);
+//        database.setValidationQuery("select 1");
+        
         return database;
     }
 

Added: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/ConnectionFactoryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/ConnectionFactoryTest.java?rev=811682&view=auto
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/ConnectionFactoryTest.java (added)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/ConnectionFactoryTest.java Sat Sep  5 17:14:08 2009
@@ -0,0 +1,51 @@
+/*
+ * 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.jackrabbit.core.util.db;
+
+import javax.sql.DataSource;
+
+import junit.framework.TestCase;
+
+/**
+ * 
+ */
+public class ConnectionFactoryTest extends TestCase {
+
+    private static final String DERBY_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
+
+    private static final String DERBY_URL = "jdbc:derby:target/connection-factory-test/db;create=true";
+
+    public void testIdentity() throws Exception {
+        DataSource ds1 = ConnectionFactory.getDataSource(DERBY_DRIVER, DERBY_URL, "user", "password");
+        DataSource ds2 = ConnectionFactory.getDataSource(DERBY_DRIVER, DERBY_URL, "user", "password");
+        assertSame(ds1, ds2);
+    }
+
+    public void testIdentity_differentPasswords() throws Exception {
+        DataSource ds1 = ConnectionFactory.getDataSource(DERBY_DRIVER, DERBY_URL, "user", "password");
+        DataSource ds2 = ConnectionFactory.getDataSource(DERBY_DRIVER, DERBY_URL, "user", "password2");
+        assertSame(ds1, ds2);
+    }
+
+    public void testNonIdentity() throws Exception {
+        DataSource ds1 = ConnectionFactory.getDataSource(DERBY_DRIVER, DERBY_URL, "user", "password");
+        DataSource ds2 = ConnectionFactory.getDataSource(DERBY_DRIVER, DERBY_URL, "user2", "password");
+        assertNotSame(ds1, ds2);
+    }
+
+    // TODO: test JNDI config
+}

Propchange: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/ConnectionFactoryTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/TestAll.java?rev=811682&view=auto
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/TestAll.java (added)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/TestAll.java Sat Sep  5 17:14:08 2009
@@ -0,0 +1,38 @@
+/*
+ * 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.jackrabbit.core.util.db;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite that includes all testcases for the util module.
+ */
+public class TestAll extends TestCase {
+
+    /**
+     * Returns a test suite that executes all tests inside this package.
+     *
+     * @return a test suite that executes all tests inside this package
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite("Database utility tests");
+        suite.addTestSuite(ConnectionFactoryTest.class);
+        return suite;
+    }
+}

Propchange: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/db/TestAll.java
------------------------------------------------------------------------------
    svn:eol-style = native