VisiBroker for Java Developer’s Guide : Using POAs

Using POAs
What is a Portable Object Adapter?
Portable Object Adapters replace Basic Object Adapters; they provide portability on the server side.
A POA is the intermediary between the implementation of an object and the VisiBroker ORB. In its role as an intermediary, a POA routes requests to servants and, as a result may cause servants to run and create child POAs if necessary.
Servers can support multiple POAs. At least one POA must be present, which is called the rootPoa. The rootPoa is created automatically for you. The set of POAs is hierarchical; all POAs have the rootPoa as their ancestor.
Servant managers locate and assign servants to objects for the POA. When an abstract object is assigned to a servant, it is called an active object and the servant is said to incarnate the active object. Every POA has one Active Object Map which keeps track of the object IDs of active objects and their associated active servants.
Note
Users familiar with versions of VisiBroker prior to 6.0 should note the change in inheritance hierarchy to support CORBA Specification 3.0, which requires local interfaces. For example, a ServantLocator implementation would now extend from org.omg.PortableServer._ServantLocatorLocalBase instead of org.omg.PortableServer.ServantLocatorPOA.
Figure 5
POA terminology
Following are definitions of some terms with which you will become more familiar as you read through this section.
Steps for creating and using POAs
Although the exact process can vary, the basic steps that occur during the POA lifecycle are:
1
2
3
4
5
6
Depending on your needs, some of these steps may be optional. For example, you only have to activate the POA if you want it to process requests.
POA policies
Each POA has a set of policies that define its characteristics. When creating a new POA, you can use the default set of policies or use different values to suit your requirements. You can only set the policies when creating a POA; you can not change the policies of an existing POA. POAs do not inherit the policies from their parent POA.
The following lists the POA policies, their values, and the default value (used by the rootPoa).
Thread policy The thread policy specifies the threading model to be used by the POA.
The thread policy can have the following values:
ORB_CTRL_MODEL: (Default) The POA is responsible for assigning requests to threads. In a multi-threaded environment, concurrent requests may be delivered using multiple threads. Note that VisiBroker uses multi-threading model.
SINGLE_THREAD_MODEL: The POA processes requests sequentially. In a multi-threaded environment, all calls made by the POA to servants and servant managers are thread-safe.
MAIN_THREAD_MODEL: Calls are processed on a distinguished “main” thread. Requests for all main-thread POAs are processed sequentially. In a multi-threaded environment, all calls processed by all POAs with this policy are thread-safe. The application programmer designates the main thread by calling ORB::run() or ORB::perform_work(). For more information about these methods, see “Activating objects”.
Lifespan policy The lifespan policy specifies the lifespan of the objects implemented in the POA.
The lifespan policy can have the following values:
TRANSIENT: (Default) A transient object activated by a POA cannot outlive the POA that created it. Once the POA is deactivated, an OBJECT_NOT_EXIST exception occurs if an attempt is made to use any object references generated by the POA.
PERSISTENT: A persistent object activated by a POA can outlive the process in which it was first created. Requests invoked on a persistent object may result in the implicit activation of a process, a POA and the servant that implements the object.
Object ID Uniqueness policy The Object ID Uniqueness policy allows a single servant to be shared by many abstract objects.
The Object ID Uniqueness policy can have the following values:
UNIQUE_ID: (Default) Activated servants support only one Object ID.
MULTIPLE_ID: Activated servants can have one or more Object IDs. The Object ID must be determined within the method being invoked at run time.
ID Assignment policy The ID assignment policy specifies whether object IDs are generated by server applications or by the POA.
The ID Assignment policy can have the following values:
USER_ID: Objects are assigned object IDs by the application.
SYSTEM_ID: (Default) Objects are assigned object IDs by the POA. If the PERSISTENT policy is also set, object IDs must be unique across all instantiations of the same POA.
Typically, USER_ID is for persistent objects, and SYSTEM_ID is for transient objects. If you want to use SYSTEM_ID for persistent objects, you can extract them from the servant or object reference.
Servant Retention policy The Servant Retention policy specifies whether the POA retains active servants in the Active Object Map.
The Servant Retention policy can have the following values:
RETAIN: (Default) The POA tracks object activations in the Active Object Map. RETAIN is usually used with ServantActivators or explicit activation methods on POA.
NON_RETAIN: The POA does not retain active servants in the Active Object Map. NON_RETAIN must be used with ServantLocators.
ServantActivators and ServantLocators are types of servant managers. For more information on servant managers, see “Using servants and servant managers”.
Request Processing policy The Request Processing policy specifies how requests are processed by the POA.
USE_ACTIVE_OBJECT_MAP_ONLY: (Default) If the Object ID is not listed in the Active Object Map, an OBJECT_NOT _EXIST exception is returned. The POA must also use the RETAIN policy with this value.
USE_DEFAULT_SERVANT: If the Object ID is not listed in the Active Object Map or the NON_RETAIN policy is set, the request is dispatched to the default servant. If no default servant has been registered, an OBJ_ADAPTER exception is returned. The POA must also use the MULTIPLE_ID policy with this value.
USE_SERVANT_MANAGER: If the Object ID is not listed in the Active Object Map or the NON_RETAIN policy is set, the servant manager is used to obtain a servant.
Implicit Activation policy The Implicit Activation policy specifies whether the POA supports implicit activation of servants.
The Implicit Activation policy can have the following values:
IMPLICIT_ACTIVATION: The POA supports implicit activation of servants. There are two ways to activate the servants as follows:
Converting them to an object reference with org.omg.PortableServer.POA.servant_to_reference() .
Invoking _this() on the servant.
The POA must also use the SYSTEM_ID and RETAIN policies with this value.
NO_IMPLICIT_ACTIVATION: (Default) The POA does not support implicit activation of servants.
Bind Support policy The Bind Support policy (a VisiBroker-specific policy) controls the registration of POAs and active objects with the VisiBroker osagent. If you have several thousand objects, it is not feasible to register all of them with the osagent. Instead, you can register the POA with the osagent. When a client request is made, the POA name and the object ID is included in the bind request so that the osagent can correctly forward the request.
The BindSupport policy can have the following values:
BY_INSTANCE: All active objects are registered with the osagent. The POA must also use the PERSISTENT and RETAIN policy with this value.
BY_POA: (Default) Only POAs are registered with the osagent. The POA must also use the PERSISTENT policy with this value.
NONE: Neither POAs nor active objects are registered with the smart agent.
Note
The rootPoa is created with NONE activation policy.
Creating POAs
To implement objects using the POA, at least one POA object must exist on the server. To ensure that a POA exists, a rootPoa is provided during the VisiBroker ORB initialization. This POA uses the default POA policies described earlier in this section.
Once the rootPoa is obtained, you can create child POAs that implement a specific server-side policy set.
POA naming convention
Each POA keeps track of its name and its full POA name (the full hierarchical path name.) The hierarchy is indicated by a slash (/). For example, /A/B/C means that POA C is a child of POA B, which in turn is a child of POA A. The first slash (see the previous example) indicates the rootPoa. If the BindSupport:BY_POA policy is set on POA C, then /A/B/C is registered with the osagent and the client binds with /A/B/C.
If your POA name contains escape characters or other delimiters, VisiBroker precedes these characters with a double back slash (\\) when recording the names internally. For example, if you have coded two POAs in the following hierarchy,
org.omg.PortableServer.POA myPOA1 = rootPoa.create_POA
("A/B",
poaManager,
policies);
org.omg.PortableServer.POA myPOA2 = myPOA1.create_POA
("\t",
poaManager,
policies);
then the client would bind using:
org.omg.CORBA.Object manager = ((com.inprise.vbroker.orb.ORB) orb).
bind("/A\\/B/\t",
managerId,
null,
null);
Obtaining the rootPoa
The following code sample illustrates how a server application can obtain its rootPoa.
// Initialize the ORB.
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);
// get a reference to the rootPoa
org.omg.PortableServer.POA rootPoa =
POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
Note
The resolve_initial_references method returns a value of type org.omg.CORBA.Object . You are responsible for narrowing the returned object reference to the desired type, which is org.omg.PortableServer.POA in the previous example.
Setting the POA policies
Policies are not inherited from the parent POA. If you want a POA to have a specific characteristic, you must identify all the policies that are different from the default value. For more information about POA policies, see “POA policies”.
org.omg.CORBA.Policy[] policies = {
rootPoa.create_lifespan_policy(LifespanPolicyValue.PERSISTENT)
};
Creating and activating the POA
A POA is created using create_POA on its parent POA. You can name the POA anything you like; however, the name must be unique with respect to all other POAs with the same parent. If you attempt to give two POAs the same name, a CORBA exception (AdapterAlreadyExists) is raised.
To create a new POA, use create_POA as follows:
POA create_POA(POA_Name, POAManager, PolicyList);
The POA manager controls the state of the POA (for example, whether it is processing requests). If null is passed to create_POA as the POA manager name, a new POA manager object is created and associated with the POA. Typically, you will want to have the same POA manager for all POAs. For more information about the POA manager, see “Managing POAs with the POA manager”.
POA managers (and POAs) are not automatically activated once created. Use activate() to activate the POA manager associated with your POA. The following code sample is an example of creating a POA.
// Create policies for our persistent POA
org.omg.CORBA.Policy[] policies = {
rootPoa.create_lifespan_policy(LifespanPolicyValue.PERSISTENT)};
// Create myPOA with the right policies
org.omg.PortableServer.POA myPOA =
rootPoa.create_POA( "bank_agent_poa", rootPoa.the_POAManager(), policies );
Activating objects
When CORBA objects are associated with an active servant, if the POA's Servant Retention Policy is RETAIN, the associated object ID is recorded in the Active Object Map and the object is activated. Activation can occur in one of several ways:
Activating objects explicitly
By setting IdAssignmentPolicy::SYSTEM_ID on a POA, objects can be explicitly activated without having to specify an object ID. The server invokes activate_object on the POA which activates, assigns and returns an object ID for the object. This type of activation is most common for transient objects. No servant manager is required since neither the object nor the servant is needed for very long.
Objects can also be explicitly activated using object IDs. A common scenario is during server initialization where the user invokes activate_object_with_id to activate all the objects managed by the server. No servant manager is required since all the objects are already activated. If a request for a non-existent object is received, an OBJECT_NOT_EXIST exception is raised. This has obvious negative effects if your server manages large numbers of objects.
This code sample is an example of explicit activation using activate_object_with_id.
// Create the account manager servant.
Servant managerServant = new AccountManagerImpl(rootPoa);
// Activate the newly created servant.
testPoa.activate_object_with_id("BankManager".getBytes(), managerServant);
// Activate the POAs
testPoa.the_POAManager().activate();
Activating objects on demand
On-demand activation occurs when a client requests an object that does not have an associated servant. After receiving the request, the POA searches the Active Object Map for an active servant associated with the object ID. If none is found, the POA invokes incarnate on the servant manager which passes the object ID value to the servant manager. The servant manager can do one of three things:
Raise an OBJECT_NOT_EXIST exception that is returned to the client.
The POA policies determine any additional steps that may occur. For example, if RequestProcessingPolicy.USE_SERVANT_MANAGER and ServantRetentionPolicy.RETAIN are enabled, the Active Object Map is updated with the servant and object ID association.
An example of on-demand activation is shown below.
Activating objects implicitly
A servant can be implicitly activated by certain operations if the POA has been created with ImplicitActivationPolicy.IMPLICIT_ACTIVATION, IdAssignmentPolicy.SYSTEM_ID, and ServantRetentionPolicy.RETAIN. Implicit activation can occur with:
_this() servant method
If the POA has IdUniquenessPolicy.UNIQUE_ID set, implicit activation can occur when any of the above operations are performed on an inactive servant.
If the POA has IdUniquenessPolicy.MULTIPLE_ID set, servant_to_reference and servant_to_id operations always perform implicit activation, even if the servant is already active.
Activating with the default servant
Use the RequestProcessing.USE_DEFAULT_SERVANT policy to have the POA invoke the same servant no matter what the object ID is. This is useful when little data is associated with each object.
This is an example of activating all objects with the same servants
import org.omg.PortableServer.*;
public class Server {
public static void main(String[] args) {
try {
// Initialize the ORB.
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
// get a reference to the rootPoa
POA rootPoa =
POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
// Create policies for our persistent POA
org.omg.CORBA.Policy[] policies = {
rootPoa.create_lifespan_policy(LifespanPolicyValue.PERSISTENT),
rootPoa.create_request_processing_policy(
RequestProcessingPolicyValue.USE_DEFAULT_SERVANT
)
rootPoa.create_id_uniqueness_policy(IdUniquenessPolicyValue.MULTIPLE_ID)
};
// Create myPOA with the right policies
POA myPOA = rootPoa.create_POA( "bank_default_servant_poa",
rootPoa.the_POAManager(),
policies );
// Create the servant
AccountManagerImpl managerServant = new AccountManagerImpl();
// Set the default servant on our POA
myPOA.set_servant(managerServant);
org.omg.CORBA.Object ref;
// Activate the POA manager
rootPoa.the_POAManager().activate();
// Generate the reference and write it out. One for each Checking
//and Savings account types. Note that we are not creating any
// servants here and just manufacturing a reference which is not
// yet backed by a servant.
try {
ref =
myPOA.create_reference_with_id("CheckingAccountManager".getBytes(),
"IDL:Bank/AccountManager:1.0");
// Write out checking object ID
java.io.PrintWriter pw = new java.io.PrintWriter(
new java.io.FileWriter("cref.dat") );
pw.println(orb.object_to_string(ref));
pw.close();
ref =
myPOA.create_reference_with_id("SavingsAccountManager".getBytes(),
"IDL:Bank/AccountManager:1.0");
// Write out savings object ID
pw = new java.io.PrintWriter( new java.io.FileWriter("sref.dat") );
pw.println(orb.object_to_string(ref));
pw.close();
} catch ( java.io.IOException e ) {
System.out.println("Error writing the IOR to file ");
return;
}
System.out.println("Bank Manager is ready.");
// Wait for incoming requests
orb.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Deactivating objects
A POA can remove a servant from its Active Object Map. This may occur, for example, as a form of garbage-collection scheme. When the servant is removed from the map, it is deactivated. You can deactivate an object using deactivate_object(). When an object is deactivated, it doesn't mean this object is lost forever. It can always be reactivated at a later time.
This is an example of deactivating an object:
import org.omg.PortableServer.*;
public class AccountManagerActivator extends _ServantActivatorLocalBase {
public Servant incarnate (byte[] oid, POA adapter) throws ForwardRequest {
Servant servant;
String accountType = new String(oid);
System.out.println("\nAccountManagerActivator.incarnate called
with ID = "
+ accountType + "\n");
// Create Savings or Checking Servant based on AccountType
if ( accountType.equalsIgnoreCase("SavingsAccountManager"))
servant = (Servant )new SavingsAccountManagerImpl();
else
servant =(Servant)new CheckingAccountManagerImpl();
new DeactivateThread(oid, adapter).start();
return servant;
}
public void etherealize (byte[] oid,
POA adapter,
Servant serv,
boolean cleanup_in_progress,
boolean remaining_activations) {

System.out.println("\nAccountManagerActivator.etherealize called
with ID =" + new String(oid) + "\n");
}
}
class DeactivateThread extends Thread {
byte[] _oid;
POA _adapter;
public DeactivateThread(byte[] oid, POA adapter) {
_oid = oid;
_adapter = adapter;
}
public void run() {
try {
Thread.currentThread().sleep(15000);
System.out.println("\nDeactivating the object with ID = " +
new String(_oid) + "\n");
_adapter.deactivate_object(_oid);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Using servants and servant managers
Servant managers perform two types of operations: find and return a servant, and deactivate a servant. They allow the POA to activate objects when a request for an inactive object is received. Servant managers are optional. For example, servant managers are not needed when your server loads all objects at startup. Servant managers may also inform clients to forward requests to another object using the ForwardRequest exception.
A servant is an active instance of an implementation. The POA maintains a map of the active servants and the object IDs of the servants. When a client request is received, the POA first checks this map to see if the object ID (embedded in the client request) has been recorded. If it exists, then the POA forwards the request to the servant. If the object ID is not found in the map, the servant manager is asked to locate and activate the appropriate servant. This is only an example scenario; the exact scenario depends on what POA policies you have in place.
Figure 6
There are two types of servant managers: ServantActivator and ServantLocator. The type of policy already in place determines which type of servant manager is used. For more information on POA policy, see “POA policies”. Typically, a Servant Activator activates persistent objects and a Servant Locator activates transient objects.
To use servant managers, RequestProcessingPolicy.USE_SERVANT_MANAGER must be set as well as the policy which defines the type of servant manager (ServantRetentionPolicy.RETAIN for Servant Activator orServantRetentionPolicy.NON_RETAIN for Servant Locator.)
ServantActivators
ServantActivators are used when ServantRetentionPolicy.RETAIN and RequestProcessingPolicy.USE_SERVANT_MANAGER are set.
Servants activated by this type of servant manager are tracked in the Active Object Map.
The following events occur while processing requests using ServantActivators:
1
2
3
If the object ID is not found in the active object map, the POA invokes incarnate on a servant manager. incarnate passes the object ID and the POA in which the object is being activated.
4
5
Note
The etherealize and incarnate method implementations are user-supplied code.
 
At a later date, the servant can be deactivated. This may occur from several sources, including the deactivate_object operation, deactivation of the POA manager associated with that POA, and so forth. More information on deactivating objects is described in “Deactivating objects”.
This code sample is an example of servant activator-type servant manager:
import org.omg.PortableServer.*;
public class Server {
public static void main(String[] args) {
try {
// Initialize the ORB.
org.omg.CORBA.ORB orb = org.omg.CORBA.FORB.init(args,null);
// get a reference to the rootPoa
POA rootPoa =
POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
// Create policies for our POA. We need persistence life span and
// use servant manager request processing policies
org.omg.CORBA.Policy[] policies = {
rootPoa.create_lifespan_policy(LifespanPolicyValue.PERSISTENT),
rootPoa.create_request_processing_policy(RequestProcessingPolicyValue.
USE_SERVANT_MANAGER)
};
// Create myPOA with the right policies
POA myPOA = rootPoa.create_POA( "bank_servant_activator_poa",
rootPoa.the_POAManager(),
policies );
// Create the servant activator servant and get its reference
ServantActivator sa = new AccountManagerActivator();
// Set the servant activator on our POA
myPOA.set_servant_manager(sa);
org.omg.CORBA.Object ref;
// Activate the POA manager
rootPoa.the_POAManager().activate();
// Generate the reference and write it out. One for each Checking
and Savings
// account types. Note that we are not creating any
// servants here and just manufacturing a reference which is not
// yet backed by a servant.
try {
ref =
myPOA.create_reference_with_id("CheckingAccountManager".getBytes(),
"IDL:Bank/AccountManager:1.0");
// Write out checking object ID
java.io.PrintWriter pw =
new java.io.PrintWriter( new java.io.FileWriter
("cref.dat") );
pw.println(orb.object_to_string(ref));
pw.close();
ref =
myPOA.create_reference_with_id("SavingsAccountManager".getBytes(),
"IDL:Bank/AccountManager:1.0");
// Write out savings object ID
pw = new java.io.PrintWriter( new java.io.FileWriter
("sref.dat") );
pw.println(orb.object_to_string(ref));
pw.close();
} catch ( java.io.IOException e ) {
System.out.println("Error writing the IOR to file ");
return;
}
System.out.println("Bank Manager is ready.");
// Wait for incoming requests
orb.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The servant manager for the servant activator example follows:
import org.omg.PortableServer.*;
public class AccountManagerActivator extends _ ServantActivatorLocalBase {
public Servant incarnate (byte[] oid, POA adapter) throws ForwardRequest {
Servant servant;
String accountType = new String(oid);
System.out.println("\nAccountManagerActivator.incarnate called with ID =
" + accountType + "\n");
// Create Savings or Checking Servant based on AccountType
if ( accountType.equalsIgnoreCase("SavingsAccountManager"))
servant = (Servant )new SavingsAccountManagerImpl();
else
servant =(Servant)new CheckingAccountManagerImpl();
new DeactivateThread(oid, adapter).start();
return servant;
}

public void etherealize (byte[] oid,
POA adapter,
Servant serv,
boolean cleanup_in_progress,
boolean remaining_activations) {
System.out.println("\nAccountManagerActivator.etherealize called
with ID = " + new String(oid) + "\n");
}
}
class DeactivateThread extends Thread {
byte[] _oid;
POA _adapter;
public DeactivateThread(byte[] oid, POA adapter) {
_oid = oid;
_adapter = adapter;
}

public void run() {

try {
Thread.currentThread().sleep(15000);
System.out.println("\nDeactivating the object with ID =
" + new String(_oid) + "\n");
_adapter.deactivate_object(_oid);
} catch (Exception e) {
e.printStackTrace();
}
}
}
ServantLocators
In many situations, the POA's Active Object Map could become quite large and consume memory. To reduce memory consumption, a POA can be created with RequestProcessingPolicy.USE_SERVANT_MANAGER and ServantRetentionPolicy.NON_RETAIN, meaning that the servant-to-object association is not stored in the active object map. Since no association is stored, ServantLocator servant managers are invoked for each request.
The following events occur while processing requests using ServantLocators:
1
2
Since ServantRetentionPolicy.NON_RETAIN is used, the POA does not search the active object map for the object ID.
3
The POA invokes preinvoke on a servant manager. preinvoke passes the object ID, the POA in which the object is being activated, and a few other parameters.
4
5
6
The POA invokes postinvoke on the servant manager.
Note
The preinvoke and postinvoke methods are user-supplied code.
This example server code shows servant locator-type servant managers:
import org.omg.PortableServer.*;
public class Server {
public static void main(String[] args) {
try {
// Initialize the ORB.
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
// get a reference to the rootPoa
POA rootPoa =
POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
// Create policies for our POA. We need persistence life span,
// use servant manager request processing policies and non retain
// retention policy. This non retain policy will let us use the
// servant locator instead of servant activator
org.omg.CORBA.Policy[] policies = {
rootPoa.create_lifespan_policy(LifespanPolicyValue.PERSISTENT),
rootPoa.create_servant_retention_policy(ServantRetentionPolicyValue.
NON_RETAIN),
rootPoa.create_request_processing_policy(RequestProcessingPolicyValue.
USE_SERVANT_MANAGER)
};
// Create myPOA with the right policies
POA myPOA = rootPoa.create_POA( "bank_servant_locator_poa",
rootPoa.the_POAManager(),
policies );
// Create the servant locator servant and get its reference
ServantLocator sl = new AccountManagerLocator();
// Set the servant locator on our POA
myPOA.set_servant_manager(sl);
org.omg.CORBA.Object ref ;
// Activate the POA manager
rootPoa.the_POAManager().activate();
// Generate the reference and write it out. One for each Checking
and Savings
// account types .Note that we are not creating any
// servants here and just manufacturing a reference which is not
// yet backed by a servant.
try {
ref =
myPOA.create_reference_with_id("CheckingAccountManager".getBytes(),
"IDL:Bank/AccountManager:1.0");
// Write out checking object ID
java.io.PrintWriter pw =
new java.io.PrintWriter( new java.io.FileWriter("cref.dat") );
pw.println(orb.object_to_string(ref));
pw.close();
ref =
myPOA.create_reference_with_id("SavingsAccountManager".getBytes(),
"IDL:Bank/AccountManager:1.0");
// Write out savings object ID
pw = new java.io.PrintWriter( new java.io.FileWriter("sref.dat") );
pw.println(orb.object_to_string(ref));
pw.close();
} catch ( java.io.IOException e ) {
System.out.println("Error writing the IOR to file ");
return;
}
System.out.println("BankManager is ready.");
// Wait for incoming requests
orb.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The servant manager for this example follows:
import org.omg.PortableServer.*;
import org.omg.PortableServer.ServantLocatorPackage.CookieHolder;
public class AccountManagerLocator extends _ServantLocatorLocalBase {
public Servant preinvoke (byte[] oid,POA adapter,
java.lang.String operation,
CookieHolder the_cookie) throws ForwardRequest {
String accountType = new String(oid);
System.out.println("\nAccountManagerLocator.preinvoke called
with ID = " +
accountType + "\n");
if ( accountType.equalsIgnoreCase("SavingsAccountManager"))
return new SavingsAccountManagerImpl();
return new CheckingAccountManagerImpl();
}
public void postinvoke (byte[] oid,
POA adapter,
java.lang.String operation,
java.lang.Object the_cookie,
Servant the_servant) {
System.out.println("\nAccountManagerLocator.postinvoke called with ID = " +
new String(oid) + "\n");
}
}
Managing POAs with the POA manager
A POA manager controls the state of the POA (whether requests are queued or discarded), and can deactivate the POA. Each POA is associated with a POA manager object. A POA manager can control one or several POAs.
A POA manager is associated with a POA when the POA is created. You can specify the POA manager to use, or specify null to have a new POA Manager created.
The following is an example of naming the POA and its POA Manager:
POA myPOA = rootPoa.create_POA( "bank_agent_poa",
rootPoa.the_POAManager(),
policies );
POA myPOA = rootPoa.create_POA( "bank_agent_poa",
null,
policies );
A POA manager is “destroyed” when all its associated POAs are destroyed.
A POA manager can have the following four states:
These states in turn determine the state of the POA. They are each described in detail in the following sections.
Getting the current state
To get the current state of the POA manager, use
enum State{HOLDING, ACTIVE, DISCARDING, INACTIVE};
State get_state();
Holding state
By default, when a POA manager is created, it is in the holding state. When the POA manager is in the holding state, the POA queues all incoming requests.
Requests that require an adapter activator are also queued when the POA manager is in the holding state.
To change the state of a POA manager to holding, use
void hold_requests (in boolean wait_for_completion)
raises (AdapterInactive);
wait_for_completion is Boolean. If FALSE, this operation returns immediately after changing the state to holding. If TRUE, this operation returns only when all requests started prior to the state change have completed or when the POA manager is changed to a state other than holding. AdapterInactive is the exception raised if the POA manager was in the inactive state prior to calling this operation.
Note
POA managers in the inactive state cannot change to the holding state.
 
Any requests that have been queued but not yet started will continue to be queued during the holding state.
Active state
When the POA manager is in the active state, its associated POAs process requests.
To change the POA manager to the active state, use
void activate()
raises (AdapterInactive);
AdapterInactive is the exception raised if the POA manager was in the inactive state prior to calling this operation.
Note
POA managers currently in the inactive state can not change to the active state.
Discarding state
When the POA manager is in the discarding state, its associated POAs discard all requests that have not yet started. In addition, the adapter activators registered with the associated POAs are not called. This state is useful when the POA is receiving too many requests. You need to notify the client that their request has been discarded and to resend their request. There is no inherent behavior for determining if and when the POA is receiving too many requests. It is up to you to set up thread monitoring if so desired.
To change the POA manager to the discarding state, use
void discard_requests(in boolean wait_for_completion)
raises (AdapterInactive);
The wait_for_completion option is Boolean. If FALSE, this operation returns immediately after changing the state to holding. If TRUE, this operation returns only when all requests started prior to the state change have completed or when the POA manager is changed to a state other than discarding. AdapterInactive is the exception raised if the POA manager was in the inactive state prior to calling this operation.
Note
POA managers currently in the inactive state can not change to the discarding state.
Inactive state
When the POA manager is in the inactive state, its associated POAs reject incoming requests. This state is used when the associated POAs are to be shut down.
Note
POA managers in the inactive state cannot change to any other state.
 
To change the POA manager to the inactive state, use
void deactivate (in boolean etherealize_objects, in boolean wait_for_completion)
raises (AdapterInactive);
After the state changes, if etherealize_objects is TRUE, then all associated POAs that have Servant RetentionPolicy.RETAIN and RequestProcessingPolicy.USE_SERVANT_MANAGER set call etherealize on the servant manager for all active objects. If etherealize_objects is FALSE, then etherealize is not called. The wait_for_completion option is Boolean. If FALSE, this operation returns immediately after changing the state to inactive. If TRUE, this operation returns only when all requests started prior to the state change have completed or etherealize has been called on all associated POAs (that have ServantRetentionPolicy.RETAIN and RequestProcessingPolicy.USE_SERVANT_MANAGER). AdapterInactive is the exception raised if the POA manager was in the inactive state prior to calling this operation.
Listening and Dispatching: Server Engines, Server Connection Managers, and their properties
Note
Policies that cover listener and dispatcher features previously supported by the BOA are not supported by POAs. In order to provide these features, a VisiBroker-specific policy (ServerEnginePolicy) can be used.
VisiBroker provides a very flexible mechanism to define and tune endpoints for VisiBroker servers. An endpoint in this context is a destination for a communication channel for clients to communicate with servers. A Server Engine is a virtual abstraction for connection endpoint provided as a configurable set of properties.
A ServerEngine abstraction can provide control in terms of:
Server Engine and POAs
A POA on Visibroker can have many-to-many relationship with a ServerEngine. A POA can be associated with many ServerEngines and vice-versa. The manifestation of this fact is that a POA, and hence the CORBA objects on the POA, can support multiple communication channels.
Figure 7
The simplest case is where POAs have their own unique single server engine. Here, requests for different POAs arrive on different ports. A POA can also have multiple server engines. In this scenario, a single POA supports requests coming from multiple input ports.
Notice that POAs can share server engines. When server engines are shared, the POAs listen to the same port. Even though the requests for (multiple) POAs arrive at the same port, they are dispatched correctly because of the POA name embedded in the request. This scenario occurs, for example, when you use a default server engine and create multiple POAs (without specifying a new server engine during the POA creation).
A Server Engine is identified by a name and is defined the first time its name is introduced. By default Visibroker defines three Server Engine names. They are:
Two more Server Engines, boa_tp and boa_ts, are available for BOA backward compatibility.
Associating a POA with a Server Engine
The default Server Engine associated with POA can be changed by using the property vbroker.se.default. For example, setting
vbroker.se.default=MySE
defines a new server engine with the name MySE. Root POA and all child POAs created will be associated with this Server Engine by default.
A POA can also be associated with a particular ServerEngine explicitly by using the SERVER_ENGINE_POLICY_TYPE POA policy. For example:
// create ServerEngine policy value
org.omg.CORBA.Any seAny = orb.create_any();
org.omg.CORBA.StringSequenceHelper.insert(seAny, new String[]{"MySE"});
org.omg.CORBA.Policy sePolicy = orb.create_policy(com.inprise.vbroker.PortableServerExt.
SERVER_ENGINE_POLICY_TYPE.value,seAny);

// create POA policies
org.omg.CORBA.Policy[] policies = {
rootPoa.create_lifespan_policy(LifeSpanPolicyValue.PERSISTENT),
sePolicy
};

// create POA with policies
POA myPOA = rootPoa.create_POA("bank_se_policy_poa", rootPoa.the_POAManager(), policies);
The POA has an IOR template, profiles for which, are obtained from the Server Engines associated with it.
If you don't specify a server engine policy, the POA assumes a server engine name of iiop_tp and uses the following default values:
vbroker.se.iiop_tp.host=null
vbroker.se.iiop_tp.proxyHost=null
vbroker.se.iiop_tp.scms=iiop_tp
To change the default server engine policy, enter its name using the vbroker.se.default property and define the values for all the components of the new server engine. For example:
vbroker.se.default=abc,def
vbroker.se.abc.host=cob
vbroker.se.abc.proxyHost=null
vbroker.se.abc.scms=cobscm1,cobscm2
vbroker.se.def.host=gob
vbroker.se.def.proxyHost=null
vbroker.se.def.scms=gobscm1
Defining Hosts for Endpoints for the Server Engine
Since Server Engines help define a connection's endpoints, the following properties are provided to specify their hosts:
vbroker.se.<se-name>.host=<host-URL>: vbroker.se.mySE.host=host.microfocus.com, for example.
vbroker.se.<se-name>.proxyHost=<proxy-host-URL-or-IP-address>: vbroker.se.mySE.proxyHost=proxy.microfocus.com, for example.
The proxyHost property can also take an IP address as its value. Doing so replaces the default hostname in the IOR with this IP address.
The endpoint abstraction of ServerEngine is further fine-grained in terms of configurable set of entities referred to as Server Connection Managers (SCM). A ServerEngine can have multiple SCMs. SCMs are not shareable between ServerEngines. SCMs are also identified using a name and are defined for a ServerEngine using:
vbroker.se.<se-name>.scms=<SCM-name>[,<SCM-name>,...]
Note
The iiop_tp Server Engine has a SCM named iiop_tp created for it.
Server Connection Managers
The Server Connection Manager defines the configurable components of an endpoint. Its responsibilities are connection resource management, listening for requests, and dispatching requests to its associated POA. Three logical entities, defined through property groups, are provided by the SCM to fulfill these responsibilities:
Each SCM has one Manager, Listener, and Dispatcher. All three, when defined, form a single endpoint definition allowing clients to contact servers.
Manager
Manager is a set of properties defining the configurable portions of a connection resource. VisiBroker provides a manager of type Socket.
VisiBroker for Java only supports the Socket type, and a variation of the Socket type, Socket_nio, that uses the Java NIO package. See section “High scalability configuration for VisiBroker for Java (using Java NIO)” for further details.
You can specify the maximum number of concurrent connections acceptable to the server endpoint using the connectionMax property:
vbroker.se.<se-name>.scm.<scm-name>.manager.connectionMax=<integer>
Setting connectionMax to 0 (zero) indicates that there is no restriction on the number of connections, which is the default setting.
You specify the maximum number of idle seconds using the connectionMaxIdle property:
vbroker.se.<se-name>.scm.<scm-name>.manager.connectionMaxIdle=<seconds>
Setting connectionMaxIdle to 0 (zero) indicates that there is no timeout, which is the default setting.
Garbage collection time is specified through the following property:
vbroker.orb.gcTimeout=<seconds>
A value of 0 (zero) means that the connection will never be garbage collected.
Listener
The Listener is the SCM component that determines how and where the SCM listens for messages. Like the Manager, the Listener is also a set of properties. VisiBroker defines a IIOP listener for the TCP connections.
Since listeners are close to the actual underlying transport mechanism, their properties are not portable across listener types. Each listener type has its own set of properties, defined below.
IIOP listener properties
IIOP listners need to define a port and (if desired) a proxy port in conjunction with their hosts. These are set using the port and proxyPort properties, as follows:
vbroker.se.<se-name>.scm.<scm-name>.listener.port=<port>
vbroker.se.<se-name>.scm.<scm-name>.listener.proxyPort=<proxy-port>
Note
If you do not set the port property (or set it to 0 [zero]), a random port will be selected. A 0 value for the proxyPort property means that the IOR will contain the actual port (defined by the listener.port property or selected by the system randomly). If it is not required to advertise the actual port, set the proxy port to a non-zero (positive) value.
 
VisiBroker additionally supports a property allowing you to specify your GIOP version:
vbroker.se.<se-name>.scm.<scm-name>.listener.giopVersion=<version>
Dispatcher
The Dispatcher defines a set of properties that determine how the SCM dispatches requests to threads. Three types of dispatchers are provided: ThreadPool, ThreadSession, and MainThread. You set the dispatcher type with the type property:
vbroker.se.<se-name>.scm.<scm-name>.dispatcher.type=ThreadPool|ThreadSession|MainThread
Further control is provided through the SCM for the ThreadPool dispatcher type. The ThreadPool defines the minimum and maximum number of threads that can be created in the thread pool, as well as the maximum time in seconds after which an idled thread is destroyed. These values are controlled with the following properties:
vbroker.se.<se-name>.scm.<scm-name>.dispatcher.threadMin=<integer>
vbroker.se.<se-name>.scm.<scm-name>.dispatcher.threadMax=<integer>
vbroker.se.<se-name>.scm.<scm-name>.dispatcher.threadMaxIdle=<seconds>
The ThreadPool dispatcher allows a “cooling time” to be set. A thread is said to be “hot” when the GIOP connection being served is potentially readable, either upon creation of the connection or upon the arrival of a request. After the cooling time (in seconds), the thread can be returned to the thread pool.
VisiBroker for Java supports the cooling time property when configured to use the Java NIO package. See the section “High scalability configuration for VisiBroker for Java (using Java NIO)” for more information.
The following property is used to set the cooling time:
vbroker.se.<se-name>.scm.<scm-name>.dispatcher.coolingTime=<seconds>
When to use these properties
There are many times where you need to change some of the server engine properties. The method for changing these properties depends on what you need. For example, suppose you want to change the port number. You could accomplish this by:
Changing the default listener.port property
Changing the default listener.port property is the simplest method, but this affects all POAs that use the default server engine. This may or may not be what you want.
If you want to change the port number on a specific POA, then you'll have to create a new server engine, define the properties for this new server engine, and then reference the new server engine when creating the POA. The previous sections show how to update the server engine properties. The following code snippet shows how to define properties of a server engine and create a POA with a user-defined server engine policy:
// Server.java
import org.omg.PortableServer.*;
public class Server {
public static void main(String[] args) {
try {

// Initialize the ORB.
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
// Get property manager
com.inprise.vbroker.properties.PropertyManager pm =
((com.inprise.vbroker.orb.ORB)orb).getPropertyManager();
      pm.addProperty("vbroker.se.mySe.host", "");
pm.addProperty("vbroker.se.mySe.proxyHost", "");
pm.addProperty("vbroker.se.mySe.scms", "scmlist");
pm.addProperty("vbroker.se.mySe.scm.scmlist.manager.type", "Socket");
pm.addProperty("vbroker.se.mySe.scm.scmlist.manager.connectionMax",
            100);
      pm.addProperty("vbroker.se.mySe.scm.scmlist.manager.connectionMaxIdle"
       , 300);
pm.addProperty("vbroker.se.mySe.scm.scmlist.listener.type", "IIOP");
pm.addProperty("vbroker.se.mySe.scm.scmlist.listener.port", 55000);
pm.addProperty("vbroker.se.mySe.scm.scmlist.listener.proxyPort", 0);
pm.addProperty("vbroker.se.mySe.scm.scmlist.dispatcher.type",
"ThreadPool");
      pm.addProperty("vbroker.se.mySe.scm.scmlist.listener.giopVersion",
         "1.2");
pm.addProperty("vbroker.se.mySe.scm.scmlist.dispatcher.threadMax",
          100);
pm.addProperty("vbroker.se.mySe.scm.scmlist.dispatcher.threadMin", 5);
pm.addProperty("vbroker.se.mySe.scm.scmlist.dispatcher.threadMaxIdle",
300);
// get a reference to the root POA
POA rootPoa =
         POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
// Create our server engine policy
org.omg.CORBA.Any seAny = orb.create_any();
org.omg.CORBA.StringSequenceHelper.insert(seAny, new String[]          {"mySe"});
org.omg.CORBA.Policy sePolicy = orb.create_policy(
          com.inprise.vbroker.PortableServerExt.SERVER_ENGINE_POLICY_TYPE.
          value, seAny);
// Create policies for our persistent POA
org.omg.CORBA.Policy[] policies = {rootPoa.create_lifespan_policy
           (LifespanPolicyValue.PERSISTENT),sePolicy
};
// Create myPOA with the right policies
POA myPOA = rootPoa.create_POA("bank_se_policy_poa",
rootPoa.the_POAManager(),
policies );
// Create the servant
AccountManagerImpl managerServant = new AccountManagerImpl();
// Activate the servant
myPOA.activate_object_with_id("BankManager".getBytes(),
            managerServant);
// Obtaining the reference
org.omg.CORBA.Object ref = myPOA.servant_to_reference(managerServant);

// Now write out the IOR
try {
java.io.PrintWriter pw =
new java.io.PrintWriter( new java.io.FileWriter("ior.dat") );
pw.println(orb.object_to_string(ref));
pw.close();
} catch ( java.io.IOException e ) {
System.out.println(<Default Para Font>"Error writing the IOR to
            file ior.dat");
return;
}
// Activate the POA manager
rootPoa.the_POAManager().activate();
System.out.println(ref + " is ready.");
// Wait for incoming requests
orb.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Adapter activators
Adapter activators are associated with POAs and provide the ability to create child POAs on-demand. This can be done during the find_POA operation, or when a request is received that names a specific child POA.
An adapter activator supplies a POA with the ability to create child POAs on demand, as a side-effect of receiving a request that names the child POA (or one of its children), or when find_POA is called with an activate parameter value of TRUE. An application server that creates all its needed POAs at the beginning of execution does not need to use or provide an adapter activator; it is necessary only for the case in which POAs need to be created during request processing.
While a request from the POA to an adapter activator is in progress, all requests to objects managed by the new POA (or any descendant POAs) will be queued. This serialization allows the adapter activator to complete any initialization of the new POA before requests are delivered to that POA.
For an example on using adapter activators, see the POA adaptor_activator example included with the product.
Processing requests
Requests contain the Object ID of the target object and the POA that created the target object reference. When a client sends a request, the VisiBroker ORB first locates the appropriate server, or starts the server if needed. It then locates the appropriate POA within that server.
Once the VisiBroker ORB has located the appropriate POA, it delivers the request to that POA. How the request is processed at that point depends on the policies of the POA and the object's activation state. For information about object activation states, see “Activating objects”.
If the POA has ServantRetentionPolicy.RETAIN , the POA looks at the Active Object Map to locate a servant associated with the Object ID from the request. If a servant exists, the POA invokes the appropriate method on the servant.
If the POA has ServantRetentionPolicy.NON_RETAIN or has ServantRetentionPolicy.RETAIN but did not find the appropriate servant, the following may take place:
If the POA has RequestProcessingPolicy.USE_DEFAULT_SERVANT , the POA invokes the appropriate method on the default servant.
If the POA has RequestProcessingPolicy.USE_SERVANT_MANAGER , the POA invokes incarnate or preinvoke on the servant manager.
If the POA has RequestProcessingPolicy.USE_OBJECT_MAP_ONLY , an exception is raised.
If a servant manager has been invoked but cannot incarnate the object, the servant manager can raise a ForwardRequest exception.