Solved

Code to change connection pooling

Posted on 2002-07-05
7
663 Views
Last Modified: 2010-05-18
I've got this servlet from a WAS3.5 application using connection pooling.  WAS4.0 no longer supports com.ibm.servlet.connmgr.  I'd like to see the equivalent of this coded for WAS 4.0 preferably with Oracle connection pooling, but IBM is ok.  IBM has  a .pdf file at
http://www-3.ibm.com/software/webservers/appserv/whitepapers/connection_pool.pdf
and Oracle has it's at
http://technet.oracle.com/docs/products/oracle8i/doc_library/817_doc/java.817/a83724/connpoc2.htm

import java.io.*;
import java.util.*;
import com.ibm.eNetwork.ECL.*;
import com.objectspace.jgl.*;


/*
 * CSUHIBMConnectionBroker -- A broker for IBM 3270 connections.
 *
 * Creates and manages a pool of 3270 connections.
 *
 * At init time the max number of 3270 connections are established
 * along with timeout limits for age and idleness.
 *
 * Every five minutes the connections are validated.  As connections
 * exceed the maximum idle time they are removed from the connection
 * pool.  As connections exceed the maximum age they are disconnected
 * and restarted.
 *
 */


public class CSUHIBMConnectionBroker implements Observer, Runnable,
  CSUHIBMConstants
{
  private static final int MAX_NUMBER_OF_CONNECT_ATTEMPTS = 5;
  private static final int TIME_TO_WAIT_AFTER_INIT_FAILS = 10000;
  private static final int MILLISECONDS_TO_WAIT_IF_ALL_CONNECTIONS_ARE_BUSY = 600;

  private static final String className = "CSUHIBMConnectionBroker";
 
  private int connsInUse;               //
  private int minConns;                 // the minimum number of connections that are allowed
  private int maxConns;                 // the maximum number of connections that are allowed
  private long maxConnAge;              // the maximum age that a connection can reach
  private long maxConnIdleTime;         // the maximum time that a connection can be idle
  private long checkConnTime;           // elapsed time before the connections are checked by the housekeeping thread
  private long timeOutValue;            //

  private Properties connectionProperties;    // property object for the CSUHMainframe objects
  private MainframeQueue closedQueue;         //
  private MainframeQueue availableQueue;      //
 
  private CSUHAlarm timer;                      // the CSUHAlarm used to shut off and start registration
  private Thread runner;                        // the housekeeping thread
  private String userName;                      // the user name for the mainframe account
  private String passWord;                      // the password for the mainframe account
  private boolean regStatus;                    //
  private boolean forever;                      //

  // Matt: added these next two lines 03082001 for using the new csuh.properties file
  // see init() method below
  private static Properties config = new Properties();
  private static File configfile = new File("/ws/csuhcode/csuh.properties");

  private static String selectEnvironment;            
  private static String debug;            
  private static String currentTerm;            
  private static String useFakeMainframe;            
  private static String lookupOnly;            

  private static CSUHIBMConnectionBroker onlyInstance = null;

  private CSUHIBMConnectionBroker()
  {
    init();
  }


  public static CSUHIBMConnectionBroker instance()
  {
    if (onlyInstance == null)
      onlyInstance = new CSUHIBMConnectionBroker();

    return onlyInstance;
  }


  public void init()
  {
 
    System.out.print("Loading " + className + "...");

    maxConns = 15;
    minConns = 5;
    maxConnAge = (350 * 60 * 1000);
    maxConnIdleTime = (30 * 60 * 1000);
    checkConnTime = (15 * 60 * 1000);
    timeOutValue = (60 * 1000);

    try    
    { config.load(new FileInputStream(configfile)); }
    catch (Exception e)
    { System.err.println("CSUHIBMConnectionBroker: cannot read csuh.properties: " + e); }

    if(config.getProperty("environment").equalsIgnoreCase("test"))
    { selectEnvironment = "m"; }  // HAYWDTST
    else
    { selectEnvironment = "l"; }  // HAYWDPRD
   
    if(config.getProperty("debug").equalsIgnoreCase("yes"))
    { debug = "yes"; }
    else
    { debug = "no"; }
   
    if(config.getProperty("fakeMainframe").equalsIgnoreCase("yes"))
    {
      useFakeMainframe = "yes";
      System.out.println("Using fake mainframe responses.");
    }
    else
    { useFakeMainframe = "no"; }

    if(config.getProperty("lookup_only").equalsIgnoreCase("yes"))
    {
      lookupOnly = "yes";
      System.out.println("Starting in lookup-only mode.");
    }
    else
    { lookupOnly = "no"; }
   
   
    currentTerm = config.getProperty("myinfoterm");

    userName = config.getProperty("ztlkuser");
    passWord = config.getProperty("ztlkpass");
   
    availableQueue = new MainframeQueue();
    closedQueue = new MainframeQueue();

    regStatus  = false;
    forever = false;

    connectionProperties = new Properties();
    connectionProperties.put(ECLSession.SESSION_HOST, "sail.csuhayward.edu");
    connectionProperties.put(ECLSession.SESSION_HOST_PORT, "23");
    connectionProperties.put(ECLSession.SESSION_TYPE, ECLSession.SESSION_TYPE_3270_STR);
    connectionProperties.put(ECLSession.SESSION_AUTOCONNECT, ECLSession.SESSION_OFF);
    connectionProperties.put(ECLSession.SESSION_AUTORECONNECT, ECLSession.SESSION_OFF);

    if (runner == null)
    {
      runner = new Thread(this);
      runner.start();             // matt: run() method now starts
      timer = new CSUHAlarm(this);
    }

    System.out.println(className + " loaded.");
  }



  public void run()
  {
    long age;
    long idleTime;
    boolean closeConnection;
    boolean restartConnection;
    CSUHMainframe ibmMainframe;


    //switch (checkCurrentTime())
    switch (1)
    {    // 1 = ON here
   
      case OFF:
        regStatus = false;
        forever = false;
        break;
   
      case ON:
        if (bringUpAllConnections() == true)
        {
          regStatus = true;
          forever = true;
        }
        else
        {
          regStatus = false;
          forever = false;
        }
        break;
   
      case WAIT_TO_RUN:
        if (bringUpAllConnections() == true)
        {
          try
          {
            Thread.sleep(syncTime());
          }
          catch (InterruptedException ie) { }
          regStatus = true;
          forever = true;
        }
        else
        {
          regStatus = false;
          forever = false;
        }
        break;
    }


    while (forever)
    {

      try
      { Thread.sleep(checkConnTime); }
      catch (InterruptedException ie) { }

      for (int i = availableQueue.size(); (regStatus == true) && (i > 0); i--)
      {
        closeConnection = false;
        restartConnection = false;
       
        try
        { ibmMainframe = availableQueue.pop(); }
        catch (InvalidOperationException invalidOp)
        { break; }

        age = System.currentTimeMillis() - ibmMainframe.getCreateDate();
        idleTime = System.currentTimeMillis() - ibmMainframe.getLastUsedDate();        

        if (age > maxConnAge)
        { restartConnection = true; }

        if ((restartConnection == false) && (idleTime > maxConnIdleTime))
        {
          if (availableQueue.size() > minConns)
          { closeConnection = true; }
        }

        if ((closeConnection == false) && (restartConnection == false))
        {
          if (ibmMainframe.checkConnection() == true)
          { availableQueue.push(ibmMainframe); }
          else
          { closeConnection = true; }
        }
       
        if ((closeConnection == true) || (restartConnection == true))
        {
          try
          { ibmMainframe.logoff(); }
          catch (ECLErr ibmError) { }
          catch (CSUHMainframeException mainframeError) { }

          closeConn(ibmMainframe);

          if (restartConnection == true)
          {
            for (int j = 0; j < MAX_NUMBER_OF_CONNECT_ATTEMPTS; j++)
            {
              try
              {
                ibmMainframe = closedQueue.pop();
                openExistingConn(ibmMainframe);
                availableQueue.push(ibmMainframe);
                break;
              }
              catch(Exception e)
              {
                try
                {
                  Thread.sleep(TIME_TO_WAIT_AFTER_INIT_FAILS);
                }
                catch(InterruptedException ie) { }
              }
            }    
          }
        }
      }
    } // end of while loop
  } // end of run
 

  public CSUHMainframe getConnection() throws CSUHIBMBrokerException
  {
    boolean gotAConn = false;
    CSUHMainframe ibmMainframe = null;


    for (int i = 0; (gotAConn == false) && (i < MAX_NUMBER_OF_CONNECT_ATTEMPTS); i++)
    {

      try
      {
         ibmMainframe = availableQueue.pop();
         gotAConn = true;
      }
      catch (InvalidOperationException invalidOp) { }
 
      if ((gotAConn == false) && (closedQueue.isEmpty() == false))
      {
        try
        {
          ibmMainframe = closedQueue.pop();
          openExistingConn(ibmMainframe);
          gotAConn = true;
        }
        catch (InvalidOperationException invalidOp) { }
        catch (ECLErr ibmError) { }
        catch (CSUHMainframeException mainframeError) {closeConn(ibmMainframe);}
      }

      if ((gotAConn == true) && (ibmMainframe.checkConnection() == true))
      {
        ibmMainframe.setLastUsedDate(System.currentTimeMillis());
        incrementConnsInUse();
        incrementConnsInUse();
      }
      else
      {
        if (ibmMainframe != null)
        {
          closeConn(ibmMainframe);
          gotAConn = false;
        }
        try
        {
          Thread.sleep(MILLISECONDS_TO_WAIT_IF_ALL_CONNECTIONS_ARE_BUSY);
        }
        catch(InterruptedException ie) { }
      }
    }
 

    if (gotAConn == false)
    {
      throw new CSUHIBMBrokerException("All of the connections to the mainframe are currently in use.");
    }
    return ibmMainframe;
 
  } // end of getConnection


  public void freeConnection(CSUHMainframe ibmMainframe)
  {

    try
    {
      ibmMainframe.sendString(CLEAR_KEY);

      if (ibmMainframe.checkConnection() == true)
      {
        availableQueue.push(ibmMainframe);
      }
      else
      {
        throw new CSUHIBMBrokerException("checkConnection reported a faulty connection.");
      }
    }
    catch(Exception e)
    {
      closeConn(ibmMainframe); { }
    }
  } // end of freeConnection


  public boolean getRegistrationStatus()
  {
    return regStatus;
  }


  public void destroy()
  {

    timer.stopCSUHAlarm();

    regStatus = false;
    forever = false;
    if (runner.isAlive() == true)  // matt: returns true if thread started, and run() still going
    {
      try
      {
        runner.interrupt();
        runner.join(30000);
      }
      catch(InterruptedException ie) { }
    }

    closeDownAllConnections();
 
  } // end of destroy
 

  public void update(Observable obj, Object arg)
  {

    switch (((Integer)arg).intValue())
    {
      case OFF:
        regStatus = false;
        forever = false;
        if (runner.isAlive() == true)
        {
          try
          {
            runner.interrupt();
            runner.join();
          }
          catch(InterruptedException ie) { }
        }
        closeDownAllConnections();
        break;
      case ON:
        if (runner.isAlive() == false)
        {
          runner = new Thread(this);
          runner.start();
        }
        break;
    }
  }  


  // Matt: added 03071002 for a better OO way
  public static String getMainframeEnvironment()
  {
    if(selectEnvironment.equalsIgnoreCase("m"))
      { return "test"; }
    else { return "prod"; }
  }

  public static boolean getDebugSetting()
  {
    if(debug.equalsIgnoreCase("yes"))
      { return true; }
    else { return false; }
  }

  public static boolean getFakeMainframeSetting()
  {
    if(useFakeMainframe.equalsIgnoreCase("yes"))
      { return true; }
    else { return false; }
  }

  public static boolean getLookupSetting()
  {
    if(lookupOnly.equalsIgnoreCase("yes"))
      { return true; }
    else { return false; }
  }


  public static String getTerm()
  { return currentTerm; }

  private void closeDownAllConnections()
  {
    CSUHMainframe ibmMainframe = null;

    while (availableQueue.isEmpty() == false)
    {
      try
      {
        ibmMainframe = availableQueue.pop();
        ibmMainframe.logoff();
        closeConn(ibmMainframe);
      }
      catch (InvalidOperationException invalidOp) { }
      catch (ECLErr e) { }
      catch (CSUHMainframeException mainframeError) { }
    }
  }


  private boolean bringUpAllConnections()
  {
    long beginTime = System.currentTimeMillis();
    boolean connected = false;
    boolean sentinel = false;

    closedQueue.clear();
    availableQueue.clear();

    for (int i = 0; i < maxConns; connected = false, i++)
    {
      for (int j = 0; (connected == false) && (j < MAX_NUMBER_OF_CONNECT_ATTEMPTS); j++)
      {
        try
        {
          availableQueue.push(openNewConn(Integer.toString(i)));
          connected = true;
          sentinel = true;
        }
        catch(Exception e)
        {
          try
          {
            Thread.sleep(TIME_TO_WAIT_AFTER_INIT_FAILS);
          }
          catch(InterruptedException ie) { }
        }
      }
    }

    return sentinel;
  }


  private void closeConn(CSUHMainframe ibmMainframe)
  {
    ibmMainframe.closeConnection();
    closedQueue.push(ibmMainframe);
  } // end of closeConn


  private void openExistingConn(CSUHMainframe ibmMainframe) throws CSUHMainframeException, ECLErr
  {
    long beginTime = System.currentTimeMillis();

    ibmMainframe.refreshConnection(connectionProperties);
    ibmMainframe.startCommunication();
    ibmMainframe.login(userName, passWord, selectEnvironment);

    if (ibmMainframe.checkConnection() == true)
    {
      ibmMainframe.setLastUsedDate(System.currentTimeMillis());
      ibmMainframe.setCreateDate(System.currentTimeMillis());
    }
    else
    {
      throw new CSUHMainframeException("checkConnection reported a faulty connection.");
    }
  }


  private CSUHMainframe openNewConn(String id) throws CSUHMainframeException, ECLErr
  {
    CSUHMainframe ibmMainframe;
    long beginTime = System.currentTimeMillis();

    ibmMainframe = new CSUHMainframe(connectionProperties, timeOutValue, id);
    ibmMainframe.startCommunication();
    ibmMainframe.login(userName, passWord, selectEnvironment);

    if (ibmMainframe.checkConnection() == true)
    {
      ibmMainframe.setLastUsedDate(System.currentTimeMillis());
      ibmMainframe.setCreateDate(System.currentTimeMillis());
    }
    else
    {
      throw new CSUHMainframeException("checkConnection reported a faulty connection.");
    }
    return ibmMainframe;
  }


  private int checkCurrentTime()
  {
    GregorianCalendar myCal = new GregorianCalendar();
    long hour = myCal.get(myCal.HOUR_OF_DAY);
    long minute = myCal.get(myCal.MINUTE);
    long second = myCal.get(myCal.SECOND);
    long dayOfWeek = myCal.get(myCal.DAY_OF_WEEK);
   
    if ((dayOfWeek > 1) && (dayOfWeek <= 7)) // 1=Sunday, 7=Saturday
    {
      if ((hour > 6) && (hour < 19)) // 7 AM - 6:59 PM
      {
        return ON;
      }
      else if (hour == 6) // 6 AM - 6:59 AM
      {
        return WAIT_TO_RUN;
      }
      else
      {
        return OFF;
      }
    }
    else
    {
      return OFF;
    }
  }


  private long syncTime()
  {
    GregorianCalendar myCal = new GregorianCalendar();
    return ((60 - myCal.get(myCal.MINUTE)) * 60 * 1000) - (myCal.get(myCal.SECOND) * 1000);
  }
 
 
  private synchronized int incrementConnsInUse()
  {
    return connsInUse++;
  }


  private synchronized int decrementConnsInUse()
  {
    return connsInUse--;
  }


  private int totalConns()
  {
    return availableQueue.size() + closedQueue.size() + connsInUse;
  }




  class MainframeQueue
  {
 
    private Queue baseQueue;

    MainframeQueue()
    {
      baseQueue = new Queue(new Deque());
    }
   
    void push(CSUHMainframe ibmMainframe)
    {
      baseQueue.push(ibmMainframe);
    }
   
    CSUHMainframe pop()
    {
      return (CSUHMainframe) baseQueue.pop();
    }
   
    boolean isEmpty()
    {
      return baseQueue.isEmpty();
    }
   
    int size()
    {
      return baseQueue.size();
    }
   
    void clear()
    {
      baseQueue.clear();
    }
  }
} // end of CSUHIBMConnectionBroker
0
Comment
Question by:xoxomos
  • 4
  • 3
7 Comments
 
LVL 92

Expert Comment

by:objects
ID: 7133224
That code doesn't really do any handling of connection pooling, it simply returns a IBMConnMgr instance for getting connections.
What exactly is it you want?

0
 

Author Comment

by:xoxomos
ID: 7133243
You're right.  I think this is the pooling code.  I want to see what code would look like using Oracle connection pooling.  Doesn't have to be completely working, just what direction coding changes should take.
0
 

Author Comment

by:xoxomos
ID: 7133306
What's happening is, I have a bunch of servlets running under Websphere 3 that i attempted to run under Websphere 4.  Eventually i came across the documentation that the com.ibm.servlet package from Visual Age 4 that is deprecated in 3 is no longer supported in 4.  I'm looking at the Oracle and IBM sites that dealing  with connection pooling trying to get an idea how to go about making the change that will allow them to run under Websphere 4.
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 92

Accepted Solution

by:
objects earned 500 total points
ID: 7133326
Oracles connection pooling uses the JDBC Optional API and is pretty straight forward.
Just create connection data source:

OracleConnectionPoolDataSource ds =
  new OracleConnectionPoolDataSource();

Set the attributes for the pool:

ds.setURL(url)
ds.setUser(user);
ds.setPassword(pass);


Then to get a connection:

PooledConnection pc = ds.getPooledConnection();
Connection c = pc.getConnection();
0
 

Author Comment

by:xoxomos
ID: 7133429
OK i'll see.  Do you mean for instance
 private static String poolName   = "JdbcOracle"; // pool name from WebSphere application manager
   private static boolean waitRetry = true; // waitRetry - try again if all connections are busy?
   private static String jdbcDriver = "oracle.jdbc.driver.OracleDriver"; // Java class for the JDBC driver
   private static String url        = "jdbc:oracle:thin:@127.0.0.1:1521:REG"; // database connection url
   private static String user       = "webreg"; // user
   private static String password   = "jackson"; // password

i would instead
ds.setURL(url)
                     ds.setUser(user);
                     ds.setPassword(pass);
??
0
 
LVL 92

Expert Comment

by:objects
ID: 7133453
yes, let me know how you go.

Thanks for the points :)

http://www.objects.com.au/staff/mick
Brainbench MVP for Java 1
http://www.brainbench.com
0
 

Author Comment

by:xoxomos
ID: 7133496
What's happening is, I have a bunch of servlets running under Websphere 3 that i attempted to run under Websphere 4.  Eventually i came across the documentation that the com.ibm.servlet package from Visual Age 4 that is deprecated in 3 is no longer supported in 4.  I'm looking at the Oracle and IBM sites that dealing  with connection pooling trying to get an idea how to go about making the change that will allow them to run under Websphere 4.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now