org.apache.avalon.excalibur.datasource.cluster
Class DefaultHashedDataSourceCluster

java.lang.Object
  extended byorg.apache.avalon.framework.logger.AbstractLogEnabled
      extended byorg.apache.avalon.excalibur.datasource.cluster.AbstractDataSourceCluster
          extended byorg.apache.avalon.excalibur.datasource.cluster.DefaultHashedDataSourceCluster
All Implemented Interfaces:
Component, Configurable, DataSourceComponent, Disposable, HashedDataSourceCluster, Initializable, LogEnabled, Serviceable, ThreadSafe

public class DefaultHashedDataSourceCluster
extends AbstractDataSourceCluster
implements HashedDataSourceCluster

The DefaultHashedDataSourceCluster requires that the user specify an object or a hashCode which will be used consistantly select a member DataSource form a cluster for each connection request. Calls to getConnection() will throw an exception. Components which make use of this class must call either the getConnectionForHashObject( Object hashObject) or the getConnectionForHashCode( int hashCode ) methods instead.

This form of Clustering is useful in cases where data can be reliably accessed in a repeatable manner. For example a web site's visitor information could be accessed by using a String containing the visitor's username as a hashObject. This would allow visitor information to be spread across several database servers.

The Configuration for a 2 database cluster is like this:

   <datasources>
     <hashed-cluster name="mydb-cluster" size="2">
       <dbpool index="0">mydb-0</dbpool>
       <dbpool index="1">mydb-1</dbpool>
     </hashed-cluster>
   </datasources>
   <cluster-datasources>
     <jdbc name="mydb-0">
       <pool-controller min="1" max="10"/>
       <auto-commit>true</auto-commit>
       <driver>com.database.jdbc.JdbcDriver</driver>
       <dburl>jdbc:driver://host0/mydb</dburl>
       <user>username</user>
       <password>password</password>
     </jdbc>
     <jdbc name="mydb-1">
       <pool-controller min="1" max="10"/>
       <auto-commit>true</auto-commit>
       <driver>com.database.jdbc.JdbcDriver</driver>
       <dburl>jdbc:driver://host1/mydb</dburl>
       <user>username</user>
       <password>password</password>
     </jdbc>
   </cluster-datasources>
 
With the following roles declaration:
   <role name="org.apache.avalon.excalibur.datasource.DataSourceComponentSelector"
     shorthand="datasources"
     default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector">
     <hint shorthand="jdbc" class="org.apache.avalon.excalibur.datasource.JdbcDataSource"/>
     <hint shorthand="j2ee" class="org.apache.avalon.excalibur.datasource.J2eeDataSource"/>
     <hint shorthand="hashed-cluster"
       class="org.apache.avalon.excalibur.datasource.cluster.DefaultHashedDataSourceCluster"/>
   </role>
   <role name="org.apache.avalon.excalibur.datasource.DataSourceComponentClusterSelector"
       shorthand="cluster-datasources"
       default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector">
     <hint shorthand="jdbc" class="org.apache.avalon.excalibur.datasource.JdbcDataSource"/>
     <hint shorthand="j2ee" class="org.apache.avalon.excalibur.datasource.J2eeDataSource"/>
   </role>
 
A hashed-cluster definition enforces that the configuration specify a size. This size must equal the number of datasources referenced as being members of the cluster. Any datasource can be a member of the cluster.

The hashed-cluster can be obtained in the same manner as a non-clustered datasource. The only difference is in how it is used. The HashedDataSourceCluster requires that the caller provide an object or a hashCode to use when requesting a connection.

The following code demonstrates a change that can be made to database enabled components so that they will be able to work with both HashedDataSourceCluster DataSources and regular DataSources.

old:

   Connection connection = m_dataSource.getConnection();
 
new:
   Connection connection;
   if ( m_dataSource instanceof HashedDataSourceCluster )
   {
     connection = ((HashedDataSourceCluster)m_dataSource).getConnectionForHashObject( hashObject );
   }
   else
   {
     connection = m_dataSource.getConnection();
   }
 

Since:
4.1
Version:
CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:20 $
Author:
Avalon Development Team

Field Summary
 
Fields inherited from class org.apache.avalon.excalibur.datasource.cluster.AbstractDataSourceCluster
m_size
 
Fields inherited from interface org.apache.avalon.excalibur.datasource.cluster.HashedDataSourceCluster
ROLE
 
Constructor Summary
DefaultHashedDataSourceCluster()
           
 
Method Summary
 java.sql.Connection getConnection()
          Not supported in this component.
 java.sql.Connection getConnectionForHashCode(int hashCode)
          Gets a Connection to a database given a hash code.
 java.sql.Connection getConnectionForHashObject(java.lang.Object hashObject)
          Gets a Connection to a database given a hash object.
 int getIndexForHashCode(int hashCode)
          Gets the index which will be resolved for a given hashCode.
 int getIndexForHashObject(java.lang.Object hashObject)
          Gets the index which will be resolved for a given hashCode.
 
Methods inherited from class org.apache.avalon.excalibur.datasource.cluster.AbstractDataSourceCluster
configure, dispose, getClusterSize, getConnectionForIndex, initialize, service
 
Methods inherited from class org.apache.avalon.framework.logger.AbstractLogEnabled
enableLogging, getLogger, setupLogger, setupLogger, setupLogger
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface org.apache.avalon.excalibur.datasource.cluster.HashedDataSourceCluster
getClusterSize, getConnectionForIndex
 
Methods inherited from interface org.apache.avalon.framework.configuration.Configurable
configure
 

Constructor Detail

DefaultHashedDataSourceCluster

public DefaultHashedDataSourceCluster()
Method Detail

getConnection

public java.sql.Connection getConnection()
                                  throws java.sql.SQLException
Not supported in this component. Will throw a NoValidConnectionException.

Specified by:
getConnection in interface DataSourceComponent
Returns:
Connection a valid connection for you to use
Throws:
java.sql.SQLException

getConnectionForHashObject

public java.sql.Connection getConnectionForHashObject(java.lang.Object hashObject)
                                               throws java.sql.SQLException
Gets a Connection to a database given a hash object.

Specified by:
getConnectionForHashObject in interface HashedDataSourceCluster
Parameters:
hashObject - Object whose hashCode will be used to select which of the Clusted DataSources will be provide a Connection.
Throws:
NoValidConnectionException - when there is no valid Connection wrapper available in the classloader or when the index is not valid.
NoValidConnectionException - when there are no more available Connections in the pool.
java.sql.SQLException

getConnectionForHashCode

public java.sql.Connection getConnectionForHashCode(int hashCode)
                                             throws java.sql.SQLException
Gets a Connection to a database given a hash code.

Specified by:
getConnectionForHashCode in interface HashedDataSourceCluster
Parameters:
hashCode - HashCode which will be used to select which of the Clusted DataSources will be provide a Connection.
Throws:
NoValidConnectionException - when there is no valid Connection wrapper available in the classloader or when the index is not valid.
NoValidConnectionException - when there are no more available Connections in the pool.
java.sql.SQLException

getIndexForHashObject

public int getIndexForHashObject(java.lang.Object hashObject)
Gets the index which will be resolved for a given hashCode. This can be used by user code to optimize the use of DataSource Clusters.

Subclasses can override this method to get different behavior.

By default the index = getIndexForHashCode( hashObject.hashCode() )

Specified by:
getIndexForHashObject in interface HashedDataSourceCluster
Parameters:
hashObject - Object whose hashCode will be used to select which of the Clusted DataSources will be provide a Connection.

getIndexForHashCode

public int getIndexForHashCode(int hashCode)
Gets the index which will be resolved for a given hashCode. This can be used by user code to optimize the use of DataSource Clusters.

Subclasses can override this method to get different behavior.

By default the index = hashCode % getClusterSize()

Specified by:
getIndexForHashCode in interface HashedDataSourceCluster
Parameters:
hashCode - HashCode which will be used to select which of the Clusted DataSources will be provide a Connection.


Copyright © 1997-2005 The Apache Software Foundation. All Rights Reserved.