SAS 9.1.3 Integration Technologies » Developer's Guide


Developing Java Clients
Installation and JRE Requirements
Security
Using the IOM Server
Using the Java Connection Factory
Connecting with Directly Supplied Server Attributes
Connecting with Server Attributes Read from a SAS Metadata Server
Connecting with Server Attributes Read from an LDAP Server
Connecting with Server Attributes Read from the Information Service
Language Service Example
Logging Java Connection Factory Activities
Using Failover
Using Load Balancing
Using Connection Pooling
Pooling with Directly Supplied Server Attributes
Pooling with Server Attributes Read from a Metadata Server
Pooling with Server Attributes Read from the Information Service
Returning Connections to the Java Connection Factory
Using Java CORBA Stubs for IOM Objects
Getting a JDBC Connection Object
Using the Java Workspace Factory
Using SAS Foundation Services
IOM and CORBA Class Documentation
Java Clients

Pooling with Directly Supplied Server Attributes

With just a few changes to the example program in Connecting with Directly Supplied Server Attributes, you can use the Java Connection Factory to manage a pool of connections to an IOM server rather than a single factory-managed connection.

When set up for connection pooling, the Java Connection Factory tries to fulfill each client's requests for connections by using an existing connection to an IOM server. This is less time consuming than creating a new connection. Behind the scenes, the Java Connection Factory keeps a configurable number of connections alive at all times. For connection pooling to work properly, you must notify the Java Connection Factory when you are finished using a connection by calling close() on a factory-managed connection. For more details, see Returning Connections to the Java Connection Factory. When a client uses an object, it has exclusive access to the connection serving that object. When the client is finished using the object, the object is closed before the connection is returned to the pool. These actions help preserve the performance and security of the single connection case.

To create a pool:

  1. Create the servers.
  2. Create the puddles.

You can maintain performance standards by spreading a pool of connections over more than one server and then setting an upper limit on the number of connections that each server can contribute to the pool. To specify multiple servers, provide a separate Server object for each server that is to participate in the pool. You can specify the following properties for each server (Server object) in addition to the other server properties described earlier.

MaxClients
specifies the maximum number of connections that the pool will be allowed to make to the server at one time. Factors you should consider when determining a value for this field include the number and type of processors on the machine, the amount of memory present, the type of clients that will be requesting objects, and the number of different pools the server participates in. This property is optional. The default value is 10.

RecycleActivationLimit
specifies the number of times a connection to the server will be reused in a pool before it is disconnected ("recycled"). If the value is 0, then there will be no limit on the number of times a connection to the server can be reused. This property is optional. The default value is 0.

ServerRunForever
must be either true or false. If the value is false, then unallocated live connections will be disconnected after a period of time (determined by the value of ServerShutdownAfter) unless they are allocated to a user before that period of time passes. Otherwise, unallocated live connections will remain alive indefinitely. This property is optional. The default value is true.

ServerShutdownAfter
specifies the period of time, in minutes, that an unallocated live connection will wait to be allocated to a user before shutting down. This property is optional and it is ignored if the value of ServerRunForever is true. The value must not be less than 0, and it must not be greater than 1440 (the number of minutes in a day). The default value is 3. If the value is 0, then a connection returned to a pool by a user will be disconnected immediately unless another user is waiting for a connection from the pool.

A pool consists of one or more puddles (Puddle objects). A puddle is an association of one or more IOM servers with exactly one IOM login. In addition to the information about the servers that participate in a connection pool, you must specify information in order to create the puddles. You provide this information to the Java Connection Factory on the Puddle object. Here is a list of the properties that can be specified:

Credential
specifies the login credential object that is associated with the puddle.

MinSize
specifies the minimum number of connections that the Java Connection Factory can maintain for a puddle (after the initial startup period). This number includes both the connections that are in use and the connections that are idle. This property is optional. The default value is 0.

MinAvail
specifies the minimum number of idle connections that the Java Connection Factory can maintain for a puddle. This number includes only the connections that are idle. This property is optional. The default value is 0.

To specify multiple puddles, provide a separate Puddle object for each puddle that is to participate in the pool. You can then make a connection factory configuration with the list of puddles. For more details about supplying pooling and puddle information directly in the source code, refer to the Java API class documentation for the Java Connection Service.

Example

The following example demonstrates how to specify server properties to the Java Connection Factory and obtain four object references using only two connections to IOM servers. In this example, the pool consists of a puddle with 2 servers. For information about how to use the object reference, see Language Service Example.

The last part of this example shows how to dispose of an object reference. For details about this procedure, see Returning Connections to the Java Connection Factory.

import java.util.HashSet;
import java.util.Set;
import com.sas.iom.SAS.IWorkspace;
import com.sas.iom.SAS.IWorkspaceHelper;
import com.sas.services.connection.BridgeServer;
import com.sas.services.connection.Cluster;
import com.sas.services.connection.ConnectionFactoryAdminInterface;
import com.sas.services.connection.ConnectionFactoryConfiguration;
import com.sas.services.connection.ConnectionFactoryInterface;
import com.sas.services.connection.ConnectionFactoryManager;
import com.sas.services.connection.ConnectionInterface;
import com.sas.services.connection.Credential;
import com.sas.services.connection.LoadBalancingCluster;
import com.sas.services.connection.ManualConnectionFactoryConfiguration;
import com.sas.services.connection.PasswordCredential;
import com.sas.services.connection.Puddle;
import com.sas.services.connection.Server;
import org.omg.CORBA.Object;


// identify the IOM servers
String classID = Server.CLSID_SAS;
int port = 5310;
String domain = "unx";
Server server0 = new BridgeServer(classID,"serv1.unx.abc.com",port,domain);
Server server1 = new BridgeServer(classID,"serv2.unx.abc.com",port,domain);
Server[] servers = {server0,server1};
Cluster cluster = new LoadBalancingCluster(servers);

// create a login for these servers
Credential login = new PasswordCredential("adm1","adm1pass",domain);

// create a set of users allowed to use the connections to the servers
Credential user1 = new PasswordCredential("use1","use1pass");
Credential user2 = new PasswordCredential("use2","use2pass");
Set authorizedLogins = new HashSet(2);
authorizedLogins.add(user1);
authorizedLogins.add(user2);

// make a puddle with the servers
Puddle puddle = new Puddle(cluster,login);
puddle.setUserCredentials(authorizedLogins);

// make a connection factory configuration with the puddle
ConnectionFactoryConfiguration cxfConfig =
   new ManualConnectionFactoryConfiguration(puddle);

// get a connection factory that matches the configuration
ConnectionFactoryManager cxfManager = new ConnectionFactoryManager();
ConnectionFactoryInterface cxf =
    cxfManager.getFactory(cxfConfig);            /* Use a private factory */
//  cxfManager.getConnectionFactory(cxfConfig);  /* Use a shared factory  */


// get connections
ConnectionInterface cx1 = cxf.getConnection(user1);
Object obj1 = cx1.getObject();
IWorkspace iWorkspace1 = IWorkspaceHelper.narrow(obj1);
System.out.println(iWorkspace1.UniqueIdentifier());
ConnectionInterface cx2 = cxf.getConnection(user2);
Object obj2 = cx2.getObject();
IWorkspace iWorkspace2 = IWorkspaceHelper.narrow(obj2);
System.out.println(iWorkspace2.UniqueIdentifier());

< insert iWorkspace1 and iWorkspace2 usage code here >

cx1.close();
cx2.close();

ConnectionInterface cx3 = cxf.getConnection(user1);
Object obj3 = cx3.getObject();
IWorkspace iWorkspace3 = IWorkspaceHelper.narrow(obj3);
ConnectionInterface cx4 = cxf.getConnection(user1);
CORBA.Object obj4 = cx4.getObject();
IWorkspace iWorkspace4 = IWorkspaceHelper.narrow(obj4);

< insert iWorkspace3 and iWorkspace4 usage code here >

cx3.close();
cx4.close();

// tell the factory that it can destroy unused connections
admin.shutdown();
In an effort to make the previous example more readable, we have removed most of the code structuring elements. The example will not compile as it is shown.