|
Foundation |
|
| |||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
Interface Summary | |
---|---|
ConnectionFactoryAdminInterface | The administrator's interface to a connection factory. |
ConnectionFactoryEventListener | An interface implemented by factory users who want to be notified of important events such as factory shutdown. |
ConnectionFactoryInterface | User interface for connection factories. |
ConnectionFactoryShellInterface | Methods common to all connection factory interfaces. |
ConnectionInterface | The factory-managed connection handle. |
ConnectionMetadataInterface | Information about the connection. |
Class Summary | |
---|---|
BridgeServer | A description of an IOM bridge protocol server. |
Cluster | A base class representing a cluster of IOM servers. |
ConnectionFactoryConfiguration | The base class for all connection factory configurations. |
ConnectionFactoryEvent | A class used to notify factory users of important events such as factory shutdown. |
ConnectionFactoryManager | A factory of connection factories. |
Credential | A base class for credentials that can be used to authenticate and authorize use of a connection factory. |
FailoverCluster | A failover cluster of IOM servers. |
LoadBalancingCluster | A load balancing cluster of IOM servers. |
ManualConnectionFactoryConfiguration | A connection factory configuration in which the servers, clusters, and puddles that the factory is to connect to are explicitly described. |
PasswordCredential | Login credentials for an IOM server. |
Puddle | A description of a puddle of IOM clusters. |
SecurityPackageCredential | A credential to use when requesting a security-package-authenticated connection to a server. |
Server | A base class for describing IOM servers. |
TCPIPServer | A base class to describe IOM servers that communicate with clients using a TCP/IP application protocol. |
TrustedPeerCredential | A credential to use when requesting a trusted peer connection to a server. |
XMLConfigurationBuilder | Converts XML configuration files produced by the Integration Technologies
Configuration tool (ITConfig) into a ManualConnectionFactoryConfiguration
object. |
Exception Summary | |
---|---|
ConnectionFactoryException | The base class for all connection service exceptions. |
ConnectionTimeoutException | The connection factory throws a timeout exception when a connection request could not be completed before an administrative time limit expired. |
CredentialsException | Base class for exceptions thrown to indicate that something is wrong with credentials presented during a connection request. |
FatalConnectionFactoryException | A exception that is so severe that a factory which throws this exception can no longer be used. |
LoginException | The connection factory throws a login exception when a connection request cannot be granted because the connecting client cannot be authenticated or authorized. |
WrongCredentialsException | The connection factory throws a wrong credentials exception when a connection request cannot be granted because the credentials presented with the connection request were not from an authetication domain supported by the connection factory. |
Service for making and managing connections to IOM servers.
There is also a simple manager of connection factories. The connection factory manager allows a user to obtain a connection factory with a desired configuration without needing to know whether or not such a factory already exists.
Connection factories are not remotable so they cannot be deployed or located via the discovery service.
The connection service supports only IOM Bridge Protocol. The basic steps for obtaining a connection to an IOM server are listed below:
The code fragments introduced in these basic steps are compiled into a simple, complete sample program here. The code fragments do not include exception handling for brevity.
More advanced topics are also covered:
Throughout this document, server refers to either an IOM Bridge server or an IOM object spawner configured to start a server. From the client's point of view, the server and spawner behave exactly the same so there is no point in distinguishing one from the other.
The simplest style of connection factory configuration is manual configuration. To create a manual configuration object, you must provide, at a minimum, the type of IOM server, the address of the machine hosting the server, and the port on which the server is listening for connections.
The manual configuration style can also be used to configure a factory for more advanced connection management. More discussion and examples are available in the encryption, failover, load balancing, and connection pooling sections.
Also, more sophisticated configuration styles are discussed in the alternate configuration styles section.
Here is an example of a connection factory configuration that would tell a connection factory how to connect to a workspace server (or spawner) on host foo.bar.abc.com at port 1234:
String classID = Server.CLSID_SAS; String host = "foo.bar.abc.com"; int port = 1234; Server server = new BridgeServer(classID,host,port); ConnectionFactoryConfiguration cxfConfig = new ManualConnectionFactoryConfiguration(server); |
This design allows more than one factory user to share a single connection factory without a great deal of coordination on the part of the factory users. While connection factory sharing can greatly reduce resource usage, it also has the potential to create some complicated factory lifetime problems. These tradeoffs are discussed in detail in the factory sharing section.
If you do not want your connection factory to be shared with other factory users, or if you are just getting started with the connection service, and you don't want to worry about factory sharing yet, then you should create a factory manager for your own use. Here is a code fragment that shows how to create a connection factory manager. There's not much to it:
ConnectionFactoryManager cxfManager = new ConnectionFactoryManager(); |
As previously discussed, the connection factory manager maintains a set of connection factories, and, if one of these connection factories matches your configuration, that factory it returned. Otherwise, the connection factory manager creates a new connection factory and returns it. In this simple example, however, let's assume that the manager has not previosly created any factories.
ConnectionFactoryConfiguration cxfConfig = ... ConnectionFactoryInterface cxf = cxfManager.getFactory(cxfConfig); |
The simplest way to associate an identity with a connection is to provide a user name and a password that are valid on the server. Here is an example:
ConnectionFactoryInterface cxf = ... String userName = "myName"; String password = "mySecret"; ConnectionInterface cx = cxf.getConnection(userName,password); |
The connection factory is bundled with the classes necessary to narrow a generic interface reference to a workspace server reference. Narrowing to other server interfaces will require additional software packages.
Here is sample code describing how to narrow to a workspace server interface:
ConnectionInterface cx = ... org.omg.CORBA.Object obj = cx.getObject(); com.sas.iom.SAS.IWorkspace iWorkspace = com.sas.iom.SAS.IWorkspaceHelper.narrow(obj); ... |
Reference information for the workspace server interface can be found here.
ConnectionInterface cx = ... ... cx.close(); |
Factory destruction can be accomplished by calling the
shutdown()
and destroy()
methods
on the factory administration interface.
The administration interface is obtained by calling
getAdminInterface()
on the factory.
The shutdown()
and destroy()
methods
are more alike than they are different. Both cause a factory to
release its resources and remove itself from its manager's
factory set. Also, both cause a factory to disallow further
connection requests. However, shutdown()
is somewhat
less forceful than destroy()
. When
shutdown()
is called, any connections that have been
allocated to users and have not yet been returned to the factory
are allowed to remain open until they are returned. On the other
hand, when destroy()
is called, all open connections
are immediately destroyed even if they are currently allocated to
users.
shutdown()
and destory()
can be used in combination.
Some applications may want to call shutdown()
and then allow a
period of time to pass to allow users to destroy any outstanding connections
before calling destory()
.
In some cases it may be desirable to delay the destruction of a connection factory to allow the factory to be reused or shared. See the section on factory sharing for more details.
Here is an example of how to call shutdown()
and
destory()
.
ConnectionFactoryInterface cxf = ... ... cxf.getAdminInterface().shutdown(); ... cxf.getAdminInterface().destroy(); |
import com.sas.iom.SAS.IWorkspace; import com.sas.iom.SAS.IWorkspaceHelper; import com.sas.services.connection.*; public class SimpleExampleProgram { public static void main(String[] argv) { // create a connection factory configuration String classID = Server.CLSID_SAS; String host = "foo.bar.abc.com"; int port = 1234; Server server = new BridgeServer(classID,host,port); ConnectionFactoryConfiguration cxfConfig = new ManualConnectionFactoryConfiguration(server); ConnectionFactoryManager cxfManager = new ConnectionFactoryManager(); ConnectionFactoryInterface cxf = null; ConnectionInterface cx = null; try { // create a connection factory that matches the configuration cxf = cxfManager.getFactory(cxfConfig); // get a connection from the factory String userName = "myName"; String password = "mySecret"; cx = cxf.getConnection(userName,password); } catch (ConnectionFactoryException cfe) { cfe.printStackTrace(); System.exit(1); } // narrow and use the connection org.omg.CORBA.Object obj = cx.getObject(); IWorkspace iWorkspace = IWorkspaceHelper.narrow(obj); // use the connection // destroy the connection cx.close(); // destroy the connection factory cxf.getAdminInterface().destroy(); } } |
ConnectionFactoryManager.getFactory()
use the
java.util.logging
package
to write log messages. Two different logger names are
used depending on the type of message.
Messages related to connection management are logged
in a logger named com.sas.services.connection
. Events
that cause messages to be logged in this logger include allocations,
deallocations, creations, and destructions. Most messages logged
in this logger are logged at Level.FINE
. Of course,
error messages are logged at Level.SEVERE
, and warnings
are logged at Level.WARNING
.
Messages related to connection usage are logged
in a logger named com.sas.iom.orb
. All
IOM Bridge protocol-level communication between protocol
peers is traced in this logger. Connection initialization
tracing messages are logged at Level.FINE
.
Protocol packet tracing messages are logged at
Level.FINER
. Messages tracing the exchange
of raw bytes between peers is logged at
Level.FINEST
. Logs that include messages
from this logger can be extremely verbose.
Messages logged in either logger are prefixed with a tag
that indicates the individual connection factory manager,
connection factory, or connection to which it relates. For
example, all messages related to invocation number 3 of
getFactory()
on instance number 2 of
ConnectionFactoryManager
are prefixed with the
tag (m2,g3)
. If that invocation is successful,
a log message will indicate what unique tracking number the
connection factory manager assigned to the resulting connection
factory, say f5
. Then all messages related to
invocation number 11 of getConnection()
on that
connection factory are prefixed with the tag
(f5,rB)
.
It is best to manipulate the Connection Service loggers
using a logging.properties
file. The default
file is located in the jre/lib
directory of a
Java installation. The path to an alternate file can be
specified as the value of Java system property
java.util.logging.config.file
. The
java.util.logging
API can also be used to
manipulate loggers at runtime. However, that approach
sometimes requires security permissions.
Here is a quick example of the properties needed in
the logging.properties
file to print
connection factory messages in the console.
handlers = java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.level = FINE java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter com.sas.services.connection.level = ALL |
Note that connection factories created by calling
getFactory()
on a subclass of
ConnectionFactoryManager
might use a different
logging subsystem. For example, connection factories
created by calling
PlatformConnectionFactoryManager.getFactory()
use the Logging Service from Foundation Services.
SAS has implemented a fifth encryption algorithm called SASPROPRIETARY. Support for this algorithm is included in the IOM server and connection factory with no additional licensing or installation requirements. However, this implementation is slower and more easily defeated than the RSA implementations.
To take advantage of encrypted connections to approriately configured
IOM servers through the connection factory, use the encryption
attributes on the BridgeServer
class. Here is an
example of a configuration which will encrypt all information passed
between the client and server using RC2 if it is available on the
server, or SASPROPRIETARY if RC2 is not available. If the IOM server
is not configured to support encryption, then the connection will
fail.
String classID = Server.CLSID_SAS; String host = "foo.bar.abc.com"; int port = 1234; String cryptoAlgorithms = BridgeServer.ENCRYPTION_ALGORITHM_RC2 + "," + BridgeServer.ENCRYPTION_ALGORITHM_SASPROPRIETARY; BridgeServer server = new BridgeServer(classID,host,port,cryptoPolicy,cryptoAlgorithms,cryptoContent); server.setEncryptionPolicy(BridgeServer.ENCRYPTION_POLICY_REQUIRED); server.setEncryptionAlgorithms(cryptoAlgorithms); ConnectionFactoryConfiguration cxfConfig = new ManualConnectionFactoryConfiguration(server); |
The connection factory also can recover from server failures. If a server in a cluster fails, then the connection factory will route subsequent connections to another server in the cluster. If that server later fails, then the connection factory will once again redirect subsequent requests to another server in the cluster including the original server if it is back up.
If a server fails, active connections to that server will not be rerouted to other servers in the failover cluster. Instead, requests over those connections will get IO exceptions or CORBA system exceptions. The failover feature applies only to requests for new connections.
Only one server in a failover cluster is used by the connection factory at a time. In other words, if the connection factory routes a connection to a server in a cluster, and that server never fails, no other servers in the cluster will be used by the factory. If you are interested in spreading connections across several servers, see the sections on load balancing and connection pooling.
Here is a code fragment demonstrating the use of failover clusters.
String classID = Server.CLSID_SAS; Server server0 = new BridgeServer(classID,"foo0.bar.abc.com",1234); Server server1 = new BridgeServer(classID,"foo1.bar.abc.com",1234); Server[] servers = {server0,server1}; Cluster cluster = new FailoverCluster(servers); ConnectionFactoryConfiguration cxfConfig = new ManualConnectionFactoryConfiguration(cluster); |
All servers in a cluster are expected to be configured in a similar
manner such that they can be used interchangeably by the factory. In
particular, all servers must have the same class ID and the same
authentication domain. If they do not, the Cluster
constructor will throw an IllegalArgumentException
.
The
connection factory uses clustered servers in the order that they appear
in the server array. In the above example, the connection factory will
use the IOM server on host foo0.bar.abc.com
until it fails,
and only then will it attempt a connection to the server on host
foo1.bar.abc.com
.
From the perspective of a connection factory user, a load balancing cluster is very much like a failover cluster; indeed, a load balancing cluster includes all the fault tolerance features of a failover cluster. However, load balancing clusters require additional configuration on the server side (not covered here).
Here is a code fragment demonstrating the use of load balancing clusters.
String classID = Server.CLSID_SAS; Server server0 = new BridgeServer(classID,"foo0.bar.abc.com",1234); Server server1 = new BridgeServer(classID,"foo1.bar.abc.com",1234); Server[] servers = {server0,server1}; Cluster cluster = new LoadBalancingCluster(servers); ConnectionFactoryConfiguration cxfConfig = new ManualConnectionFactoryConfiguration(cluster); |
Because the connection factory reuses connections, the
ConnectionInterface.close()
method has a different behavior
for pooling factories compared to non-pooling factories. Instead of
destroying the connection when the close()
method is
called, the factory may simply refresh it. The refresh
operation reinitializes the state of the connection without all the
overhead of disconnecting and reconnecting.
Having reusable connections implies that, sometimes, the connection
factory will make a connection to an IOM server before it knows what
user will use the connection. The connection factory employs a
two-tiered security model to ensure that a factory user is authorized to
use a connection. When configuring a factory for pooling, you not only
provide a Credential
object that the factory will use when
it connects to an IOM server, but you also provide the identities of
users that are allowed to use the connections. The two-tiered security
model allows the connection factory to make connections in advance of
connection requests, and it also reduces the number of user accounts
that must be maintained on the IOM server.
Note that, for the manual connection factory configuration, a user
identity is specified using a PasswordCredential
object that
encapsulates the user's user name and password. The user may not always
wish to expose his or her user name and password to the person who
configures the connection factory. Therefore, it is expected that the
manual connection factory configuration for pooling will only be used in
situations where this exposure is not a concern. Connection factory
configurations using LDAP, SAS Metadata Server, or SAS Foundation
Services (discussed later) do not have this exposure.
Connection pools are subdivided into puddles, and each pool has at least one puddle. A puddle is an association of one or more IOM servers with a login which will be used by the factory to make connection to the servers. You may want to subdivide a pool into more than one puddle for either of two reasons. First, if you want the factory to pool connections to servers that belong to different authentication domains, you will need one puddle for each domain because each puddle can have only one login. Second, if you want to provide different levels of permission to different users, you can set up several puddles, each with the same set of servers, and associate different logins with varying degrees of permission on the servers with each puddle. Then you can use the two-tiered security model to determine which users will be authorized to use which puddle.
Here is a code fragment demonstrating how to configure a factory for connection pooling. The pool will be subdivided into two puddles. One puddle will be allowed read/write access to some file on the server, and the other will have only read access.
String classID = Server.CLSID_SAS; Server server = new BridgeServer(classID,"foo.bar.abc.com",1234); Credential writerLogin = new PasswordCredential("writer","writerPW"); Credential writerUser = new PasswordCredential("writerUser","writerSecret"); Set authorizedWriters = new HashSet(1); authorizedWriters.add(writerUser); Puddle writerPuddle = new Puddle(server,writerLogin); writerPuddle.setUserCredentials(authorizedWriters); Credential readerLogin = new PasswordCredential("reader","readerPW"); Credential readerUser = new PasswordCredential("readerUser","readerSecret"); Set authorizedReaders = new HashSet(1); authorizedReaders.add(readerUser); Puddle readerPuddle = new Puddle(server,readerLogin); readerPuddle.setUserCredentials(authorizedReaders); Puddle[] puddles = {writerPuddle,readerPuddle}; ConnectionFactoryConfiguration cxfConfig = new ManualConnectionFactoryConfiguration(puddles); |
If a user presents the "writerUser" credentials to the factory created in the example above, he will get a connection from the "writerPuddle". Likewise, if a user presents the "readerUser" credentials to the factory created in the example above, he will get a connection from the "readerPuddle".
Connection factory managers facilitate reuse and sharing because,
whenever a user tries to create a factory with a configuration that
is equal to the configuration of an existing factory, the manager
returns the existing factory instead of creating a new one. Of course,
all factory users must have access to the same connection factory
manager instance. The connection service provides a default connection
manager that can be used for this purpose. The default manager is
very convenient because a reference to it is stored in the static
field ConnectionFactoryManager.defaultManager
. However,
it may facilitate broader sharing than you desire. You can always
create your own connection factory manager and make it available
only to certain factory users.
Despite the advantages of reusing and sharing a connection factory,
care must always be taken to destory the factory when it is no longer
needed. Otherwise, some potentially expensive resources may by tied up
longer than necessary. Typically, that requires a call to
shutdown()
or destroy()
(or both).
There are some exceptions. If a connection factory encounters a fatal
error, then the method executing at the time the fatal error is
discovered will throw a FatalConnectionFactoryException
,
and the factory will destroy itself. Also, a factory created using an
alternate configuration style may be able
to destroy itself.
A good example of a situation where factory sharing works well is in a web application server. If several web applications running in the server require connections to the same IOM servers, it is often advantageous for all the web applications to share a single connection pooling factory. In this case, the shared factory could be created when the web application server starts up, and it would not be destroyed until the web application server terminates.
Factory usage is not different for single servers, failover clusters, load balancing clusters, and connection pools. Furthermore, the factory will tell you what authentication domains are expected so you will not need to query the metadata server to find what authentication domains particular servers belong to.
|
Foundation |
|
| |||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |