View Javadoc

1   package org.apache.jcs.auxiliary.disk.jdbc;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.sql.Connection;
23  import java.sql.DriverManager;
24  import java.sql.SQLException;
25  
26  import org.apache.commons.dbcp.ConnectionFactory;
27  import org.apache.commons.dbcp.DriverManagerConnectionFactory;
28  import org.apache.commons.dbcp.PoolableConnectionFactory;
29  import org.apache.commons.dbcp.PoolingDriver;
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  import org.apache.commons.pool.ObjectPool;
33  import org.apache.commons.pool.impl.GenericObjectPool;
34  
35  /***
36   * This class provides access to the connection pool. It ensures that the various resources that
37   * need to access the tables will be able to use the same pool.
38   * <p>
39   * @author Aaron Smuts
40   */
41  public class JDBCDiskCachePoolAccess
42  {
43      /*** The logger. */
44      private final static Log log = LogFactory.getLog( JDBCDiskCachePoolAccess.class );
45  
46      /*** The defualt Pool Name to which the connetion pool will be keyed. */
47      public static final String DEFAULT_POOL_NAME = "jcs";
48  
49      /*** The name of the pool. */
50      private String poolName = DEFAULT_POOL_NAME;
51  
52      /*** default jdbc driver. */
53      private static final String DRIVER_NAME = "jdbc:apache:commons:dbcp:";
54  
55      // WE SHOULD HAVE A DIFFERENT POOL FOR EACH DB NO REGION
56      // THE SAME TABLE CAN BE USED BY MULTIPLE REGIONS
57      // this.setPoolName( jdbcDiskCacheAttributes.getCacheName() );
58  
59      /***
60       * Configures the pool name to use for the pool access.
61       * <p>
62       * This pool name should be unique to the database. It is used as part of the URL each time we
63       * lookup a conection from the driver manager.
64       * <p>
65       * @param poolName
66       * @param driverName
67       */
68      public JDBCDiskCachePoolAccess( String poolName )
69      {
70          // we can default to jcs if there is only one database in use.
71          if ( poolName != null )
72          {
73              setPoolName( poolName );
74          }
75          else
76          {
77              if ( log.isInfoEnabled() )
78              {
79                  log.info( "The pool name supplied was null.  Using default instead." );
80              }
81          }
82      }
83  
84      /***
85       * Gets a connection from the pool.
86       * <p>
87       * @return Connection
88       * @throws SQLException
89       */
90      public Connection getConnection()
91          throws SQLException
92      {
93          Connection con;
94          try
95          {
96              con = DriverManager.getConnection( getPoolUrl() );
97          }
98          catch ( SQLException e )
99          {
100             log.error( "Problem getting conenction.", e );
101             throw e;
102         }
103 
104         return con;
105     }
106 
107     /***
108      * How many are idle in the pool.
109      * <p>
110      * @return number idle
111      */
112     public int getNumIdleInPool()
113     {
114         int numIdle = 0;
115         try
116         {
117             PoolingDriver driver = (PoolingDriver) DriverManager.getDriver( DRIVER_NAME );
118             ObjectPool connectionPool = driver.getConnectionPool( this.getPoolName() );
119 
120             if ( log.isDebugEnabled() )
121             {
122                 log.debug( connectionPool );
123             }
124             numIdle = connectionPool.getNumIdle();
125         }
126         catch ( Exception e )
127         {
128             log.error( e );
129         }
130         return numIdle;
131     }
132 
133     /***
134      * How many are active in the pool.
135      * <p>
136      * @return number active
137      */
138     public int getNumActiveInPool()
139     {
140         int numActive = 0;
141         try
142         {
143             PoolingDriver driver = (PoolingDriver) DriverManager.getDriver( DRIVER_NAME );
144             ObjectPool connectionPool = driver.getConnectionPool( this.getPoolName() );
145 
146             if ( log.isDebugEnabled() )
147             {
148                 log.debug( connectionPool );
149             }
150             numActive = connectionPool.getNumActive();
151         }
152         catch ( Exception e )
153         {
154             log.error( e );
155         }
156         return numActive;
157     }
158 
159     /***
160      * @throws Exception
161      */
162     public void shutdownDriver()
163         throws Exception
164     {
165         PoolingDriver driver = (PoolingDriver) DriverManager.getDriver( DRIVER_NAME );
166         driver.closePool( this.getPoolName() );
167     }
168 
169     /***
170      * @return Returns the poolUrl.
171      */
172     public String getPoolUrl()
173     {
174         return DRIVER_NAME + this.getPoolName();
175     }
176 
177     /***
178      * @param poolName The poolName to set.
179      */
180     public void setPoolName( String poolName )
181     {
182         this.poolName = poolName;
183     }
184 
185     /***
186      * @return Returns the poolName.
187      */
188     public String getPoolName()
189     {
190         return poolName;
191     }
192 
193     /***
194      * @param connectURI
195      * @param userName
196      * @param password
197      * @param maxActive max connetions
198      * @throws Exception
199      */
200     public void setupDriver( String connectURI, String userName, String password, int maxActive )
201         throws Exception
202     {
203         // First, we'll need a ObjectPool that serves as the
204         // actual pool of connections.
205         // We'll use a GenericObjectPool instance, although
206         // any ObjectPool implementation will suffice.
207         ObjectPool connectionPool = new GenericObjectPool( null, maxActive );
208 
209         // TODO make configurable
210         // By dfault the size is 8!!!!!!!
211         ( (GenericObjectPool) connectionPool ).setMaxIdle( -1 );
212 
213         // Next, we'll create a ConnectionFactory that the
214         // pool will use to create Connections.
215         // We'll use the DriverManagerConnectionFactory,
216         // using the connect string passed in the command line
217         // arguments.
218         // Properties props = new Properties();
219         // props.setProperty( "user", userName );
220         // props.setProperty( "password", password );
221         ConnectionFactory connectionFactory = new DriverManagerConnectionFactory( connectURI, userName, password );
222 
223         // Now we'll create the PoolableConnectionFactory, which wraps
224         // the "real" Connections created by the ConnectionFactory with
225         // the classes that implement the pooling functionality.
226         // PoolableConnectionFactory poolableConnectionFactory =
227         new PoolableConnectionFactory( connectionFactory, connectionPool, null, null, false, true );
228 
229         // Finally, we create the PoolingDriver itself...
230         Class.forName( "org.apache.commons.dbcp.PoolingDriver" );
231         PoolingDriver driver = (PoolingDriver) DriverManager.getDriver( DRIVER_NAME );
232 
233         // ...and register our pool with it.
234         driver.registerPool( this.getPoolName(), connectionPool );
235 
236         // Now we can just use the connect string
237         // "jdbc:apache:commons:dbcp:jcs"
238         // to access our pool of Connections.
239     }
240 
241     /***
242      * @throws Exception
243      */
244     public void logDriverStats()
245         throws Exception
246     {
247         PoolingDriver driver = (PoolingDriver) DriverManager.getDriver( DRIVER_NAME );
248         ObjectPool connectionPool = driver.getConnectionPool( this.getPoolName() );
249 
250         if ( connectionPool != null )
251         {
252             if ( log.isDebugEnabled() )
253             {
254                 log.debug( connectionPool );
255             }
256 
257             if ( log.isInfoEnabled() )
258             {
259                 log.info( "NumActive: " + getNumActiveInPool() );
260                 log.info( "NumIdle: " + getNumIdleInPool() );
261             }
262         }
263         else
264         {
265             log.warn( "Could not find pool." );
266         }
267     }
268 }