com.ibm.as400.access.ConnectionList Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400 Show documentation
Show all versions of jt400 Show documentation
The Open Source version of the IBM Toolbox for Java
The newest version!
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: ConnectionList.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2003 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// @C1 - 2008-06-06 - Added support for ProfileTokenCredential authentication
// by using AS400ConnectionPoolAuthentication class.
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.util.Vector; // Java 2
import java.io.IOException;
import java.util.Locale; //@B2A
/**
* ConnectionList is a list of connections specific to an IBM i system and userID. The
* connection list is used to create new connections and get connections from the pool.
* The connection list can remove connections that have exceeded inactivity time and
* replace connections that have exceeded the maximum use count or maximum lifetime.
**/
final class ConnectionList
{
// Values returned by checkConnectionExpiration().
// Note: These correspond to MRI text IDs in class MRI2.
private static final String NOT_EXPIRED = null;
private static final String EXPIRED_INACTIVE = "CL_REMUNUSED";
private static final String EXPIRED_MAX_LIFETIME = "CL_REMLIFE";
private static final String EXPIRED_MAX_USE_COUNT = "CL_REMUSECOUNT";
private static final String EXPIRED_MAX_USE_TIME = "CL_REMUSETIME";
private static final String EXPIRED_FAILED_PRETEST = "CL_REMPRETEST";
private String systemName_;
private String userID_;
private ConnectionPoolProperties properties_;
private Log log_;
private Vector connectionList_ = new Vector();
/**
* Construct a ConnectionList object.
* @param systemName The system where the ConnectionList will exist.
* @param userID The name of the user.
* @param properties The properties of the ConnectionList.
**/
ConnectionList(String systemName, String userID, ConnectionPoolProperties properties)
{
if (systemName == null) throw new NullPointerException("systemName");
if (systemName.length() == 0) throw new ExtendedIllegalArgumentException("systemName", ExtendedIllegalArgumentException.LENGTH_NOT_VALID);
if (userID == null) throw new NullPointerException("userID");
if (userID.length() == 0) throw new ExtendedIllegalArgumentException("userID", ExtendedIllegalArgumentException.LENGTH_NOT_VALID);
if (properties == null) throw new NullPointerException("properties");
this.systemName_ = systemName;
this.userID_ = userID;
this.properties_ = properties;
}
/**
* Sees if the specified connection is due for removal.
*
* @param poolItem The pool item.
* @return The MRI textID specifying the type of expiration, or null if not expired.
**/
private String checkConnectionExpiration(PoolItem poolItem)
{
// See if the item has exceeded the maximum inactivity time.
if ((properties_.getMaxInactivity() >= 0) && (poolItem.getInactivityTime() >= properties_.getMaxInactivity()))
return EXPIRED_INACTIVE;
// See if the item has exceeded the maximum use count.
if ((properties_.getMaxUseCount() >= 0) && (poolItem.getUseCount() >= properties_.getMaxUseCount()))
return EXPIRED_MAX_USE_COUNT;
// See if the item has exceeded the maximum lifetime.
if ( (properties_.getMaxLifetime() >= 0) && (poolItem.getLifeSpan() >= properties_.getMaxLifetime()))
return EXPIRED_MAX_LIFETIME;
// See if the item has exceeded the maximum use time.
if ((properties_.getMaxUseTime() >= 0) && (poolItem.getInUseTime() >= properties_.getMaxUseTime()))
return EXPIRED_MAX_USE_TIME;
return NOT_EXPIRED;
}
/**
* Close the connection.
**/
void close()
{
if (log_ != null || Trace.traceOn_) log(ResourceBundleLoader.getText("CL_CLEANUP", new String[] {systemName_, userID_} ));
synchronized (connectionList_)
{
int size = connectionList_.size(); //@A5M
for (int i=0; i 0) && (getConnectionCount() >= properties_.getMaxConnections()))
{
if (log_ != null || Trace.traceOn_) log(ResourceBundleLoader.getText("CL_CLEANUPEXP"));
// see if anything frees up
removeExpiredConnections(poolListeners);
// if that didn't do the trick, try shutting down unused connections
if (getConnectionCount() >= properties_.getMaxConnections())
{
if (log_ != null || Trace.traceOn_) log(ResourceBundleLoader.getText("CL_CLEANUPOLD"));
shutDownOldest();
// if not enough connections were freed, throw an exception!
if (getConnectionCount() >= properties_.getMaxConnections())
throw new ConnectionPoolException(ConnectionPoolException.MAX_CONNECTIONS_REACHED);
}
}
boolean threadUse = properties_.isThreadUsed();
// create a new connection
PoolItem sys = new PoolItem (systemName_, userID_, poolAuth, secure, locale, service, connect, threadUse, socketProperties, ccsid);
// set the item is in use since we are going to return it to caller
sys.setInUse(true);
connectionList_.addElement(sys);
if (poolListeners != null)
{
ConnectionPoolEvent poolEvent = new ConnectionPoolEvent(sys.getAS400Object(), ConnectionPoolEvent.CONNECTION_CREATED);
poolListeners.fireConnectionCreatedEvent(poolEvent);
}
if (log_ != null || Trace.traceOn_) log(ResourceBundleLoader.getText("CL_CREATED", new String[] {systemName_, userID_} ));
return sys;
}
/**
* Return the poolItem in the list that contains this AS400 instance.
*
* @return The matching poolItem.
**/
PoolItem findElement(AS400 systemToFind)
{
synchronized (connectionList_)
{
int size = connectionList_.size();
for (int i=0; i=0; i--)
{
PoolItem p = (PoolItem)connectionList_.elementAt(i);
// Be conservative about removing in-use connections.
if (p.isInUse())
{
// Reclaim an in-use connection, only if its maxUseTime limit is exceeded.
if ((properties_.getMaxUseTime() >= 0) && (p.getInUseTime() >= properties_.getMaxUseTime()))
{
// Limit exceeded, so disconnect and remove the connection.
if (log_ != null || Trace.traceOn_) {
log(ResourceBundleLoader.getText(EXPIRED_MAX_USE_TIME, new String[] {systemName_, userID_} ));
log(Trace.WARNING, "Disconnecting pooled connection (currently in use) because it has exceeded the maximum use time limit of " + properties_.getMaxUseTime() + " milliseconds.");
}
p.getAS400Object().resetAllServices();
connectionList_.removeElementAt(i);
if (poolListeners != null)
{
ConnectionPoolEvent poolEvent = new ConnectionPoolEvent(p.getAS400Object(), ConnectionPoolEvent.CONNECTION_EXPIRED); //@A5C
poolListeners.fireConnectionExpiredEvent(poolEvent);
}
}
}
else if (p.isFailedPretest())
{
// Pool item has failed a connection validity pretest, so disconnect and remove the connection.
if (log_ != null || Trace.traceOn_)
{
log(ResourceBundleLoader.getText(EXPIRED_FAILED_PRETEST, new String[] {systemName_, userID_} ));
log(Trace.DIAGNOSTIC, "Disconnecting pooled connection (not currently in use) because it has failed a validation pretest.");
}
p.getAS400Object().resetAllServices();
connectionList_.removeElementAt(i);
if (poolListeners != null)
{
ConnectionPoolEvent poolEvent = new ConnectionPoolEvent(p.getAS400Object(), ConnectionPoolEvent.CONNECTION_EXPIRED);
poolListeners.fireConnectionExpiredEvent(poolEvent);
}
}
else if ((properties_.getMaxInactivity() >= 0) && (p.getInactivityTime() >= properties_.getMaxInactivity()))
{
// Connection has exceeded the maximum inactivity time, so disconnect and remove the connection.
if (log_ != null || Trace.traceOn_)
{
log(ResourceBundleLoader.getText(EXPIRED_INACTIVE, new String[] {systemName_, userID_} ));
log(Trace.DIAGNOSTIC, "Disconnecting pooled connection (not currently in use) because it has exceeded the maximum inactivity time limit of " + properties_.getMaxInactivity() + " milliseconds.");
}
p.getAS400Object().resetAllServices();
connectionList_.removeElementAt(i);
if (poolListeners != null)
{
ConnectionPoolEvent poolEvent = new ConnectionPoolEvent(p.getAS400Object(), ConnectionPoolEvent.CONNECTION_EXPIRED); //@A5C
poolListeners.fireConnectionExpiredEvent(poolEvent);
}
}
else if ((properties_.getMaxUseCount() >= 0) && (p.getUseCount() >= properties_.getMaxUseCount()))
{
// Connection has exceeded the maximum use count, so disconnect and remove the connection.
if (log_ != null || Trace.traceOn_)
{
log(ResourceBundleLoader.getText(EXPIRED_MAX_USE_COUNT, new String[] {systemName_, userID_} ));
log(Trace.DIAGNOSTIC, "Disconnecting pooled connection (not currently in use) because it has exceeded the maximum use count of " + properties_.getMaxUseCount());
}
p.getAS400Object().resetAllServices();
connectionList_.removeElementAt(i);
if (poolListeners != null)
{
ConnectionPoolEvent poolEvent = new ConnectionPoolEvent(p.getAS400Object(), ConnectionPoolEvent.CONNECTION_EXPIRED); //@A5C //@B2C
poolListeners.fireConnectionExpiredEvent(poolEvent);
}
}
else if ( (properties_.getMaxLifetime() >= 0) && (p.getLifeSpan() >= properties_.getMaxLifetime()))
{
// Connection has exceeded the maximum lifetime, so disconnect and remove the connection.
if (log_ != null || Trace.traceOn_)
{
log(ResourceBundleLoader.getText(EXPIRED_MAX_LIFETIME, new String[] {systemName_, userID_} ));
log(Trace.DIAGNOSTIC, "Disconnecting pooled connection (not currently in use) because it has exceeded the maximum lifetime limit of " + properties_.getMaxLifetime() + " milliseconds.");
}
p.getAS400Object().resetAllServices();
connectionList_.removeElementAt(i);
if (poolListeners != null)
{
ConnectionPoolEvent poolEvent = new ConnectionPoolEvent(p.getAS400Object(), ConnectionPoolEvent.CONNECTION_EXPIRED); //@A5C //@B2C
poolListeners.fireConnectionExpiredEvent(poolEvent);
}
}
}//end 'for' loop
}//@B1A end synchronized
}
/**
* Removes the connection from the pool if it is due for removal.
*
* @param poolItem The pool item.
* @param poolListeners The pool listeners to which events will be fired.
* @return true if the pool item was found and removed from the pool; false otherwise.
* @exception AS400SecurityException If a security error occured.
* @exception IOException If a communications error occured.
**/
boolean removeIfExpired(PoolItem poolItem, ConnectionPoolEventSupport poolListeners)
{
if (connectionList_.isEmpty())
return false;
boolean connectionIsExpired = false;
String expirationStatus = null;
synchronized (connectionList_)
{
expirationStatus = checkConnectionExpiration(poolItem);
if (expirationStatus == NOT_EXPIRED) {} // do nothing
else {
connectionList_.removeElement(poolItem);
connectionIsExpired = true;
}
}
// Now that we're out of the sync block (and the connection has been removed from connectionList_), disconnect the connection.
if (connectionIsExpired)
{
if ((log_ != null || Trace.traceOn_) && expirationStatus != null)
log(ResourceBundleLoader.getText(expirationStatus, new String[] {systemName_, userID_} ));
if (poolListeners != null)
{
ConnectionPoolEvent poolEvent = new ConnectionPoolEvent(poolItem.getAS400Object(), ConnectionPoolEvent.CONNECTION_EXPIRED);
poolListeners.fireConnectionExpiredEvent(poolEvent);
}
if (Trace.traceOn_)
log(Trace.DIAGNOSTIC, "Disconnecting pooled connection (not currently in use) because it has expired.");
poolItem.getAS400Object().resetAllServices();
}
return connectionIsExpired;
}
/**
* New method to work with AS400ConnectionPool.removeFromPool().
**/
boolean removeUnusedElements()
{
synchronized (connectionList_)
{
if (connectionList_.size() > 0)
{
int size = connectionList_.size();
if (size == 0)
return false;
// incrementally search the list, looking for elements that are not in
// use to remove
for (int numToCheck = size - 1; numToCheck >= 0; numToCheck--)
{
PoolItem item = (PoolItem)connectionList_.elementAt(numToCheck);
if (!item.isInUse())
{
if (Trace.traceOn_) log(Trace.DIAGNOSTIC, "Disconnecting pooled connection (not currently in use) because removeFromPool() was called.");
item.getAS400Object().resetAllServices();
connectionList_.removeElementAt(numToCheck);
}
}
}
}
return true;
}
/**
* Remove the pool item in the list that contains this AS400 instance.
* The caller takes responsibility for subsequently calling resetAllServices().
* Called by AS400ConnectionPool.
**/
void removeElement(AS400 systemToFind)
{
synchronized(connectionList_)
{
int size = connectionList_.size();
for (int i=0; i 0)
{
long t = 0;
int size = connectionList_.size();
for (int i=0; i t || oldest == 0)
{
oldest = i;
t = item.getInactivityTime();
}
}
}
//only disconnect oldest item if it is not in use
PoolItem item = (PoolItem)connectionList_.elementAt(oldest);
if (!item.isInUse())
{
if (Trace.traceOn_)
log(Trace.DIAGNOSTIC, "Disconnecting pooled connection (not currently in use) during removal of oldest unallocated connections.");
item.getAS400Object().resetAllServices();
connectionList_.removeElementAt(oldest);
if (log_ != null || Trace.traceOn_)
log(ResourceBundleLoader.getText("CL_REMOLDCOMP", new String[] {systemName_, userID_} ));
}
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy