Solved

Code to change connection pooling

Posted on 2002-07-05
7
675 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

707 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