Author: sumedha
Date: Tue Dec 18 02:24:18 2007
New Revision: 11377

Log:

connection pooling using DBCP

Added:
   
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBCPConnectionManager.java
   
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/beans/Config.java
   
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/beans/Property.java
Modified:
   trunk/commons/data-services/pom.xml
   
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBConstants.java
   
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBDeployer.java
   
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBUtils.java

Modified: trunk/commons/data-services/pom.xml
==============================================================================
--- trunk/commons/data-services/pom.xml (original)
+++ trunk/commons/data-services/pom.xml Tue Dec 18 02:24:18 2007
@@ -4,7 +4,7 @@
        <modelVersion>4.0.0</modelVersion>
        <groupId>org.wso2.dataservice</groupId>
        <artifactId>wso2data-service</artifactId>
-       <packaging>jar</packaging>
+    <packaging>jar</packaging>
        <version>SNAPSHOT</version>
        <name>WSO2 Data Service</name>
        <url>http://wso2.org</url>
@@ -22,6 +22,17 @@
                 <artifactId>poi</artifactId>
                 <version>${poi.version}</version>
             </dependency>
+            <dependency>
+                <groupId>commons-dbcp</groupId>
+                <artifactId>commons-dbcp</artifactId>                
+                <version>${commons.dbcp.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-pool</groupId>
+                <artifactId>commons-pool</artifactId>                
+                <version>${commons.pool.version}</version>
+            </dependency>         
+            
         </dependencies>
     </dependencyManagement>
 
@@ -98,6 +109,14 @@
             <groupId>org.apache.poi</groupId>
             <artifactId>poi</artifactId>
         </dependency>
+        <dependency>
+            <groupId>commons-dbcp</groupId>
+            <artifactId>commons-dbcp</artifactId>                
+        </dependency>
+        <dependency>
+            <groupId>commons-pool</groupId>
+            <artifactId>commons-pool</artifactId>                
+        </dependency>
        </dependencies>
        
     <scm>
@@ -226,5 +245,7 @@
         <commons.httpclient.version>3.0.1</commons.httpclient.version>
         <opencsv.version>1.8</opencsv.version>
         <poi.version>3.0-FINAL</poi.version>
+        <commons.dbcp.version>1.2.2</commons.dbcp.version>
+        <commons.pool.version>1.3</commons.pool.version>
     </properties>
 </project>

Added: 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBCPConnectionManager.java
==============================================================================
--- (empty file)
+++ 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBCPConnectionManager.java
        Tue Dec 18 02:24:18 2007
@@ -0,0 +1,155 @@
+package org.wso2.ws.dataservice;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.dbcp.ConnectionFactory;
+import org.apache.commons.dbcp.DriverManagerConnectionFactory;
+import org.apache.commons.dbcp.PoolableConnectionFactory;
+import org.apache.commons.dbcp.PoolingDataSource;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.pool.ObjectPool;
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.wso2.ws.dataservice.beans.Config;
+
+public class DBCPConnectionManager {
+       private static final Log log = 
LogFactory.getLog(DBCPConnectionManager.class);
+       public static DataSource datasource = null;
+       private static GenericObjectPool pool = null;
+       
+
+       public static DataSource getDatasource() {
+               return datasource;
+       }
+       public static void setDatasource(DataSource datasource) {
+               DBCPConnectionManager.datasource = datasource;
+       }
+
+       /**
+        * @param config - contains configuration parameters to create 
connection pool
+        */
+       public DBCPConnectionManager(Config config) {
+               try {
+                       connectToDB(config);
+               } catch (Exception e) {
+                       log.error("Error occured connecting to database " +
+                                       "using connection pooling manager", e);
+               }
+       }
+
+
+       protected void finalize() {
+               try {
+                       super.finalize();
+               } catch (Throwable e) {
+                       log.error("Error occured when finalizing.", e);
+               }
+       }
+
+       /**
+        *  @param config - contains connection parameters such as JDBC 
URL,username,password,etc
+        *  
+        */
+       private void connectToDB(Config config) {
+               String driverClass = 
config.getPropertyValue(DBConstants.DRIVER);
+               String jdbcURL = config.getPropertyValue(DBConstants.PROTOCOL);
+               String userName = config.getPropertyValue(DBConstants.USER);
+               String password = config.getPropertyValue(DBConstants.PASSWORD);
+               String minPool = 
config.getPropertyValue(DBConstants.MIN_POOL_SIZE);
+               String maxPool = 
config.getPropertyValue(DBConstants.MAX_POOL_SIZE);
+
+               // set numeric values for min & max pool sizes
+               int minPoolSize = 0; // default values
+               int maxPoolSize = 100; // default values
+               try {
+                       if (minPool != null) {
+                               minPoolSize = 
Integer.valueOf(minPool).intValue();
+                       }
+                       if (maxPool != null) {
+                               maxPoolSize = 
Integer.valueOf(maxPool).intValue();
+                       }
+               } catch (NumberFormatException e) {
+                       log.error("Non-numeric value found for max/min pool 
size", e);
+               }
+
+               try {
+                       java.lang.Class.forName(driverClass).newInstance();
+               } catch (ClassNotFoundException e) {
+                       log.error("Error locating class "+driverClass, e);
+               } catch (InstantiationException e) {
+                       log.error("Error instantiating class "+driverClass, e);
+               } catch (IllegalAccessException e) {
+                       log.error("Illegal access to class "+driverClass, e);
+               }
+
+               try {
+                       DBCPConnectionManager.datasource = 
setupDataSource(jdbcURL,
+                                       userName, password, minPoolSize, 
maxPoolSize);
+               } catch (Exception e) {
+                       log.error("Error occured while creating datasource.", 
e);
+               }
+       }
+
+       /**
+        * Create dataSource object using given parameters
+        */
+       public static DataSource setupDataSource(String connectionURL,
+                       String username, String password, int minIdle, int 
maxActive)
+                       throws Exception {
+               GenericObjectPool connectionPool = new GenericObjectPool(null);
+               connectionPool.setMinIdle(minIdle);
+               connectionPool.setMaxActive(maxActive);
+
+               DBCPConnectionManager.pool = connectionPool;
+               ConnectionFactory connectionFactory = new 
DriverManagerConnectionFactory(
+                               connectionURL, username, password);
+               PoolableConnectionFactory poolableConnectionFactory = new 
PoolableConnectionFactory(
+                               connectionFactory, connectionPool, null, null, 
false, true);
+               PoolingDataSource dataSource = new 
PoolingDataSource(connectionPool);
+               return dataSource;
+       }
+
+       public static void printDriverStats(){
+               ObjectPool connectionPool = DBCPConnectionManager.pool;
+               log.info("NumActive: " + connectionPool.getNumActive());
+               log.info("NumIdle: " + connectionPool.getNumIdle());
+       }
+
+       /**
+        *  getLockedProcessCount - gets the number of currently locked 
processes 
+        *  @return Number of locked processes
+        */
+       public int getLockedProcessCount() {
+               int num_locked_connections = 0;
+               Connection con = null;
+               PreparedStatement pstmt = null;
+               ResultSet rs = null;
+               try {
+                       con = DBCPConnectionManager.datasource.getConnection();
+                       pstmt = con.prepareStatement("SHOW PROCESSLIST");
+                       rs = pstmt.executeQuery();
+                       while (rs.next()) {
+                               if (rs.getString("State") != null
+                                               && 
rs.getString("State").equals("Locked")) {
+                                       num_locked_connections++;
+                               }
+                       }
+                       log.info("Number of locked connections : 
"+num_locked_connections);
+               } catch (Exception e) {
+                       log.error("Error occured while getting 
lockedProcessCount",e);
+               } finally {
+                       try {
+                               rs.close();
+                               pstmt.close();
+                               con.close();
+                       } catch (java.sql.SQLException e) {
+                               log.error("Error closing connection.",e);
+                       }
+               }
+               return num_locked_connections;
+       }
+}
\ No newline at end of file

Modified: 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBConstants.java
==============================================================================
--- 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBConstants.java
  (original)
+++ 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBConstants.java
  Tue Dec 18 02:24:18 2007
@@ -20,6 +20,12 @@
        public static final String PROTOCOL = 
"org.wso2.ws.dataservice.protocol";
        public static final String USER = "org.wso2.ws.dataservice.user";
        public static final String PASSWORD = 
"org.wso2.ws.dataservice.password";
+       public static final String MIN_POOL_SIZE = 
"org.wso2.ws.dataservice.minpoolsize";
+       public static final String MAX_POOL_SIZE = 
"org.wso2.ws.dataservice.maxpoolsize";
+       
+       //Keys for parameters in AxisService
+       public static final String CONNECTION_CONFIG = 
"org.wso2.ws.dataservice.config";
+       
        public static final String CSV_DATASOURCE = "csv_datasource";
        public static final String EXCEL_DATASOURCE = "excel_datasource";
        public static final String JNDI_DATASOURCE = "jndi_datasource";

Modified: 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBDeployer.java
==============================================================================
--- 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBDeployer.java
   (original)
+++ 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBDeployer.java
   Tue Dec 18 02:24:18 2007
@@ -52,6 +52,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ws.commons.schema.utils.NamespaceMap;
+import org.wso2.ws.dataservice.beans.Config;
 
 public class DBDeployer implements Deployer, DeploymentConstants {
     private static final Log log = LogFactory.getLog(DBDeployer.class);
@@ -209,12 +210,16 @@
             // thing is missing we will see an error at Deployment time.
             HashMap props = getProperties(connection);
             ArrayList reqProps = new ArrayList();
-            //Do we really need to populate this list ?
+            //TODO : Do we really need to populate this list ?
             reqProps.add(DBConstants.DRIVER);
             reqProps.add(DBConstants.PROTOCOL);
             reqProps.add(DBConstants.USER);
             reqProps.add(DBConstants.PASSWORD);
             reqProps.add(DBConstants.DB_CONFIG_ELEMENT);
+            
+            //load parameters in <config> section 
+            Config config = getConfigProperties(connection);
+            axisService.addParameter(DBConstants.CONNECTION_CONFIG , config);
 
             for (int i = 0; i < reqProps.size(); i++) {
                 String propName = (String) reqProps.get(i);
@@ -243,7 +248,7 @@
             if(dataSourceType.equals(DBConstants.DATASOURCE_TYPE_RDBMS)){
                 Connection dbConnection;
                 try {
-                    dbConnection = DBUtils.createConnection(axisService);
+                    dbConnection = 
DBUtils.createConnection(axisService.getName(),config);
                     if (dbConnection != null) {
                         axisService.addParameter(DBConstants.DB_CONNECTION, 
dbConnection);
                     } else {
@@ -403,6 +408,11 @@
         return (String) convertionMap.get(sqlType);
     }
 
+
+    /**
+     * @deprecated : use getConfigProperties() instead
+     *  
+     */
     private HashMap getProperties(OMElement confiObj) {
         HashMap props = new HashMap();
         for (Iterator iter = confiObj.getChildrenWithName(new 
QName("property")); iter.hasNext();) {
@@ -413,6 +423,15 @@
         return props;
     }
 
+    private Config getConfigProperties(OMElement confiObj) {
+        Config config = new Config();
+        for (Iterator iter = confiObj.getChildrenWithName(new 
QName("property")); iter.hasNext();) {
+            OMElement element = (OMElement) iter.next();
+            config.addProperty((element.getAttributeValue(new QName("name"))), 
element.getText());
+        }
+        return config;
+    }
+    
     private ArrayList processService(DeploymentFileData currentFile,
                                      AxisServiceGroup axisServiceGroup, 
ConfigurationContext configCtx)
             throws AxisFault {

Modified: 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBUtils.java
==============================================================================
--- 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBUtils.java  
    (original)
+++ 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/DBUtils.java  
    Tue Dec 18 02:24:18 2007
@@ -63,6 +63,7 @@
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.wso2.ws.dataservice.beans.CSVQuery;
+import org.wso2.ws.dataservice.beans.Config;
 import org.wso2.ws.dataservice.beans.ExcelQuery;
 import org.wso2.ws.dataservice.beans.Result;
 
@@ -215,7 +216,8 @@
                     if(log.isDebugEnabled()){
                         log.debug("Database connection is closed.Trying to 
re-establish.");
                     }
-                    return createConnection(axisService);
+                    Config config = 
(Config)axisService.getParameterValue(DBConstants.CONNECTION_CONFIG);
+                    return createConnection(axisService.getName(),config);
                 }else{
                     //existing connection is not closed. Return it.
                     return conn;
@@ -240,11 +242,16 @@
                        }
                        conn = (Connection)dbConnectionParam.getValue();
                        conn = checkDBConnectionStatus(axisService, conn);
+                       
+                       log.info("Using connection object : 
"+Integer.toHexString(conn.hashCode()));
+                       
                        conn.setAutoCommit(false);
                        PreparedStatement preparedStatement =
                                getProcessedPreparedStatement(inputValues, 
params, paramOrder, conn, sqlQuery);
                        int responseCode = -1;
                        ResultSet rs = null;
+                       
+                       DBCPConnectionManager.printDriverStats();
                        if (isDML) {
                                responseCode = 
preparedStatement.executeUpdate();
                        } else {
@@ -363,17 +370,18 @@
                } 
                
                
-//             finally {
-//             try {
-//             if (conn != null) {
-//             conn.commit();
-//             conn.close();
-//             }
-//             } catch (SQLException e) {
-//             log.error(e.getMessage());
-//             throw new AxisFault("Exception occurred while trying to 
commit.", e);
-//             }
-//             }
+               finally {
+                       try {
+                               if (conn != null) {
+                                       conn.commit();
+                                       conn.close();
+                               }
+                       } catch (SQLException e) {
+                               log.error(e.getMessage());
+                               throw new AxisFault(
+                                               "Exception occurred while 
trying to commit.", e);
+                       }
+               }
                return resultElement;
        }
 
@@ -855,18 +863,26 @@
        }
 
 
-       public static Connection createConnection(AxisService axisService) 
throws AxisFault {
+       public static Connection createConnection(String serviceName,Config 
config) throws AxisFault {
                try{
-                       log.info("Creating database connection for 
"+axisService.getName());
+                       log.info("Creating database connection for 
"+serviceName);
                        //Try to load the JDBC driver class. If class not found 
throw an error.
-                       Class.forName((String) 
axisService.getParameterValue(DBConstants.DRIVER)).newInstance();
-                       Connection conn ;
+                       
Class.forName(config.getPropertyValue(DBConstants.DRIVER)).newInstance();
+                       Connection conn = null;
                        Properties props = new Properties();
-                       props.put("user", 
axisService.getParameterValue(DBConstants.USER));
-                       props.put("password", 
axisService.getParameterValue(DBConstants.PASSWORD));
-
-                       conn = DriverManager.getConnection((String) axisService
-                                       
.getParameterValue(DBConstants.PROTOCOL), props);
+                       props.put("user", 
config.getPropertyValue(DBConstants.USER));
+                       props.put("password", 
config.getPropertyValue(DBConstants.PASSWORD));
+                       
+                       
+                       if(config.getPropertyValue(DBConstants.MIN_POOL_SIZE) 
!= null 
+                                       || 
config.getPropertyValue(DBConstants.MAX_POOL_SIZE) != null){
+                               //user has set connection pool size(s). Get 
connection from pooling manager
+                               DBCPConnectionManager dbcpConnectionManager = 
new DBCPConnectionManager(config);
+                               conn = 
dbcpConnectionManager.getDatasource().getConnection();
+                               
+                       }else{
+                               conn = DriverManager.getConnection((String) 
config.getPropertyValue(DBConstants.PROTOCOL), props);
+                       }
                        return conn;
                } catch (SQLException e) {
                        log.error("Error occured while connecting to 
database",e);
@@ -877,12 +893,12 @@
                        throw new AxisFault("JDBC driver not available in 
classpath : "+e.getMessage());
                }
                catch (InstantiationException e) {
-                       log.error("Error occurred during instantiating 
"+(String) axisService.getParameterValue(DBConstants.DRIVER), e);
-                       throw new AxisFault("Error occurred during 
instantiating "+(String) axisService.getParameterValue(DBConstants.DRIVER), e);
+                       log.error("Error occurred during instantiating 
"+config.getPropertyValue(DBConstants.DRIVER), e);
+                       throw new AxisFault("Error occurred during 
instantiating "+config.getPropertyValue(DBConstants.DRIVER), e);
                } 
                catch (IllegalAccessException e) {
-                       log.error("Illegal Access error during loading 
"+(String) axisService.getParameterValue(DBConstants.DRIVER), e);
-                       throw new AxisFault("Illegal Access error during 
loading "+(String) axisService.getParameterValue(DBConstants.DRIVER), e);
+                       log.error("Illegal Access error during loading 
"+config.getPropertyValue(DBConstants.DRIVER), e);
+                       throw new AxisFault("Illegal Access error during 
loading "+config.getPropertyValue(DBConstants.DRIVER), e);
                }
        }
 

Added: 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/beans/Config.java
==============================================================================
--- (empty file)
+++ 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/beans/Config.java
 Tue Dec 18 02:24:18 2007
@@ -0,0 +1,33 @@
+package org.wso2.ws.dataservice.beans;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+public class Config {
+       ArrayList properties = new ArrayList();
+
+       public ArrayList getProperties() {
+               return properties;
+       }
+
+       public void setProperties(ArrayList properties) {
+               this.properties = properties;
+       }
+
+       public void addProperty(String name,String value){
+               Property property = new Property(name,value);
+               properties.add(property);
+       }
+       
+       public String getPropertyValue(String propertyName){
+               Iterator propertyItr = properties.iterator();
+               for (; propertyItr.hasNext();) {
+                       Property property = (Property) propertyItr.next();
+                       if(property.getName().equals(propertyName)){
+                               return property.getValue();
+                       }
+               }
+               return null;
+       }
+
+}

Added: 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/beans/Property.java
==============================================================================
--- (empty file)
+++ 
trunk/commons/data-services/src/main/java/org/wso2/ws/dataservice/beans/Property.java
       Tue Dec 18 02:24:18 2007
@@ -0,0 +1,33 @@
+package org.wso2.ws.dataservice.beans;
+
+/*
+ * Represents property elements in config section.
+ * eg :
+ *   <config>
+ *       <property 
name="org.wso2.ws.dataservice.driver">com.mysql.jdbc.Driver</property>
+ *       <property 
name="org.wso2.ws.dataservice.protocol">jdbc:mysql://localhost:3306/classicmodels</property>
+ *       <property name="org.wso2.ws.dataservice.user">sumedha</property>
+ *       <property name="org.wso2.ws.dataservice.password">sumedha</property>
+ *   </config>  
+ */
+public class Property {
+       private String name;
+       private String value;
+       
+       public Property(String name, String value) {
+               this.name = name;
+               this.value = value;
+       }
+       public String getName() {
+               return name;
+       }
+       public void setName(String name) {
+               this.name = name;
+       }
+       public String getValue() {
+               return value;
+       }
+       public void setValue(String value) {
+               this.value = value;
+       }
+}

_______________________________________________
Commons-dev mailing list
[email protected]
http://wso2.org/cgi-bin/mailman/listinfo/commons-dev

Reply via email to