• Introduction. This section describes:
• For either an Oracle Tuxedo CORBA client or joint client/server (that is, a client that can receive and process object invocations), the programmer writes the client main(). The main() uses Oracle Tuxedo CORBA environmental objects to establish connections, set up security, and start transactions.In an Oracle Tuxedo server, you use the buildobjserver command to create the main program for the C++ server. (Java servers are not supported in release 8.0 and later of Oracle Tuxedo.) Server main program takes care of all Oracle Tuxedo- and CORBA-related initialization of the server functions. However, since you implement the Server object, you have an opportunity to customize the way in which the server application is initialized and shut down. The server main program automatically invokes methods on the Server object at the appropriate times.The specific initialization needed for a joint client/server is discussed in the section “Servants” on page 11‑3.The Server interface is used in Oracle Tuxedo CORBA servers to allow the TP Framework to ask the user to create a servant for an object when the ORB receives a request for that object. However, in joint client/servers, the user program is responsible for creating a servant before any requests arrive; thus, the Server interface is not needed. Typically, the program creates a servant and then activates the object (using the servant and an ObjectId; the ObjectId is possibly system generated) before handing a reference to the object. Such an object might be used to handle callbacks. Thus, the servant already exists and the object is activated before a request for the object arrives.For C++ joint client/servers, instead of invoking the TP interface to perform certain operations, client servants directly invoke the ORB and POA (which is what the TP interface does internally). Alternately, since much of the interaction with the ORB and POA is the same for all applications, for ease of use, the client library provides a convenience wrapper object that does the same things, using a single operation. For a discussion of how to use the convenience wrapper object, see Callback Object Models Supported and Preparing Callback Objects Using OracleWrapper Callbacks.The skeleton generated by the idl command contains a “skeleton” class, POA_Hospital, that the user-written class inherits from, as in:In a server, the skeleton class inherits from the TP Framework class Tobj_ServantBase, which in turn inherits from the predefined PortableServer::ServantBase.The inheritance tree for a callback object implementation in a joint client/server is different than that in a server. The skeleton class does not inherit from the TP Framework class Tobj_ServantBase, but instead inherits directly from PortableServer::ServantBase. This behavior is achieved by specifying the -P option in the idl command.Not having the Tobj_ServantBase class in the inheritance tree for a servant means that the servant does not have activate_object and deactivate_object methods. In a server, these methods are called by the TP Framework to dynamically initialize and save a servant’s state before invoking a method on the servant. For a client that supports callbacks, you must write code that explicitly creates a servant and initializes a servant’s state.
• The IdAssignmentPolicy, which controls who assigns the ObjectId—the user or the system.
• Transient/SystemId—object references are valid only for the life of the client process. The ObjectId is not assigned by the client application, but is a unique value assigned by the system. This type of object is useful for invocations that a client wants to receive only until the client terminates. (The corresponding POA LifeSpanPolicy value is TRANSIENT and the IdAssignmentPolicy is SYSTEM_ID.)
• Persistent/SystemId—object references are valid across multiple activations. The ObjectId is not assigned by the client application, but is a unique value assigned by the system. This type of object and object reference is useful when the client goes up and down over a period of time. When the client is up, it can receive callback objects on that particular object reference.
Typically, the client will create the object reference once, save it in its own permanent storage area, and reactivate the servant for that object every time it comes up. If used with an Oracle Tuxedo CORBA Notification Service application, for example, these are callbacks that correspond to the concept of a persistent subscription; that is, the Notification Service remembers the callback reference and delivers events any time the client is up and declares that it is again ready to receive events. This allows notification service subscriptions to survive client failures or offline-time. (The corresponding POA policy values are PERSISTENT and SYSTEM_ID.)
• Persistent/UserId—this is the same as Persistent/SystemId with the exception that the ObjectId has to be assigned by the client application. Such an ObjectId might be, for example, a database key meaningful only to the client. (The corresponding POA policy values are PERSISTENT and USER_ID.)
Notes: The Transient/UserId policy combination is not considered particularly important. It is possible for users to provide for themselves by using the POA in a manner analogous to either of the persistent cases, but the Oracle Tuxedo wrappers do not provide special help to do so.In order for an Oracle Tuxedo server to call remote joint client/server objects, that is, joint client/server objects located outside the Oracle Tuxedo domain, the server must be configured to enable outbound IIOP. This capability is enabled by specifying the -O (uppercase letter O) option in the IIOP Server Listener (ISL) server command. Setting the -O option enables outbound invokes (outbound IIOP) on joint client/server objects that are not connected to an IIOP Listener Handler (ISH).You set ISL command options in the SERVERS section of the server’s UBBCONFIG file. Because support for outbound IIOP requires a small amount of extra resources, the default is outbound IIOP disabled. For more information, see “Using the ISL Command to Configure Outbound IIOP” in Setting Up an Oracle Tuxedo Application and “ISL(1)” in the BEA Tuxedo Command Reference.
3. Inform the POA that the servant is ready to accept requests on the callback object. Technically, this means the client activates the object in the POA (that is, puts the servant and the ObjectId into the POA’s Active Object Map).Assuming that the client already has obtained a reference to the ORB, performing this task takes four interactions with the ORB and the POA. It might look like the model show in Listing 11‑1. In this model, only the Root POA is needed.Listing 11‑1 Transient/SystemId ModelTo use the Persistent/UserId model, there are some additional steps required when creating a POA. Further, the ObjectId is specified by the client, and this requires more steps. It might look like the model shown in Listing 11‑2.Listing 11‑2 Persistent/UserId ModelListing 11‑3 OracleWrapper IDLmodule BEAWrapper {
interface Callbacks
{
exception ServantAlreadyActive{ };
exception ObjectAlreadyActive { };
exception NotInRequest{ };
// set up transient callback Object
// -- prepare POA, activate object, return objref
Object start_transient(
in PortableServer::Servant Servant,
in CORBA::RepositoryId rep_id)
raises (ServantAlreadyActive);// set up persistent/systemid callback Object
Object start_persistent_systemid(
in PortableServer::Servant servant,
in CORBA::Repository rep_id,
out string stroid)
raises (ServantAlreadyActive);// set up persistent/userid callback Object
Object start_persistent_userid(
in PortableServer::Servant servant,
in CORBA::RepositoryId rep_id,
in string stroid)
raises (ServantAlreadyActive, ObjectAlreadyActive);// get oid string for the current request
string get_string_oid() raises (NotInRequest);
};
}
#endif /* _BEA_WRAPPER _IDL_ */Listing 11‑4 C++ Declarations (in beawrapper.h)The BEAWrapper::Callbacks class has already be instantiated with an ORB pointer. Only one instance of this class can be used in a process. Users who need additional flexibility should use the POA directly.The repository id of the interface.The servant is already being used for a callback. A servant can be used only for a callback with a single ObjectId. To receive callbacks on objects containing different ObjectIds, you must create different servants and activate them separately. The same servant can be reused only if a stop_object operation tells the system to stop using the servant for its original ObjectId.
• Activates an object using the Servant supplied to service objects of the type rep_id, using an ObjectId generated by the system.
• Returns an object reference to the activated object. The returned object reference will be valid only until the termination of the client or until the callback servant is halted by the user via the stop_object operation; after that, invocations on that object reference are no longer valid and can never be made valid.A reference to the object that was created with the ObjectId generated by the system and the rep_id provided by the user. The object reference will need to be converted to a specific object type by invoking the _narrow() operation defined for the specific object. The caller is responsible for releasing the object when the conversion is done.Activates an object, sets the ORB and the POA to the proper state, sets the output parameter stroid, and returns an object reference to the activated object.Object start_persistent_systemid(
in PortableServer::Servant servant,
in CORBA::RepositoryId rep_id,
out string stroid)
raises ( ServantAlreadyActive );CORBA::Object_ptr start_persistent_systemid(
PortableServer::Servant servant,
const char* rep_id,
char*& stroid);
This argument is set by the system and is opaque to the user. The client will use it when it reactivates the object at a later time (using restart_persistent_systemid), most likely after the client process has terminated and restarted.The servant is already being used for a callback. A servant can be used only for a callback with a single ObjectId. To receive callbacks on objects containing different ObjectIds, you must create different servants and activate them separately. The same servant can be reused only if a stop operation tells the system to stop using the servant for its original ObjectId.
• Activates an object using the Servant supplied to service objects of the type rep_id, using an ObjectId generated by the system.
•
• Returns an object reference to the activated object. The returned object reference will be valid even after termination of the client. That is, if the client terminates, restarts again, and then activates a servant with the same rep_id and for the same ObjectId, the servant will accept requests made on that same object reference. Since the ObjectId was generated by the system, the application has to save that ObjectId.An object reference created with the ObjectId generated by the system and the rep_id provided by the user. The object reference will need to be converted to a specific object type by invoking the _narrow() operation defined for the specific object. The caller is responsible for releasing the object when the conversion is done.Object restart_persistent_systemid(
in PortableServer::Servant servant,
in CORBA::RepositoryId rep_id,
in string stroid)
raises (ServantAlreadyActive, ObjectAlreadyActive);CORBA::Object_ptr restart_persistent_systemid(
PortableServer::Servant servant,
const char* rep_id
const char* stroid);
The stringified version of the ObjectId provided by the user to be set in the object reference being created. It must have been returned from a previous call on start_persistent_systemid.The servant is already being used for a callback. A servant can be used only for a callback with a single ObjectId. To receive callbacks on objects containing different ObjectIds, you must create different servants and activate them separately. The same servant can be reused only if a stop_object operation tells the system to stop using the servant for its original ObjectId.The stringified ObjectId is already being used for a callback. A given ObjectId can have only one servant associated with it. If you wish to change to a different servant, you must first invoke stop_object with the servant currently in use.The repository ID was a NULL string or the servant was a NULL pointer or the ObjectId supplied was not previously assigned by the system.
• Activates an object using the Servant supplied to service objects of the type rep_id, using the supplied stroid (a stringified ObjectId), which must have been obtained by a previous call on start_persistent_systemid.
• The reactivation would be done using the restart_persistent_systemid method.An object reference created with the stringified ObjectId stroid and the rep_id provided by the user. The object reference will need to be converted to a specific object type by invoking the _narrow() operation defined for the specific object. The caller is responsible for releasing the object when done.Object start_persistent_userid(
portableServer::Servant a_servant,
in CORBA::RepositoryId rep_id,
in string stroid)
raises ( ServantAlreadyActive, ObjectAlreadyActive );The stringified version of an ObjectId provided by the user to be set in the object reference being created. The stroid holds application-specific data and is opaque to the ORB.The servant is already being used for a callback. A servant can be used only for a callback with a single ObjectId. To receive callbacks on objects containing different ObjectIds, you must create different servants and activate them separately. The same servant can be reused only if a stop_object operation tells the system to stop using the servant for its original ObjectId.The stringified ObjectId is already being used for a callback. A given ObjectId can have only one servant associated with it. If you wish to change to a different servant, you must first invoke stop_object with the servant currently in use.
• Activates an object using the Servant supplied to service objects of the type rep_id, using the object Id stroid.
• Returns an object reference to the activated object. The returned object reference will be valid even after termination of the client. That is, if the client terminates, and restarts again, and then activates a servant with the same rep_id and for the same ObjectId, the servant will accept requests made on that same object reference.An object reference created with the stringified ObjectId stroid and the rep_id provided by the user. The object reference will need to be converted to a specific object type by invoking the _narrow() operation defined for the specific object. The caller is responsible for releasing the object when the conversion is done.void stop_object(PortableServer::Servant servant);An instance of the C++ implementation class for the interface. The association between this servant and its ObjectId will be removed from the Active Object Map.
Note: If you do an invocation on a callback object after you call the stop_object operation, the OBJECT_NOT_EXIST exception is returned to the caller. This is because the stop_object operation, in effect, deletes the object.Requests the string version of the ObjectId of the current request.This operation returns the string version of the ObjectId of the current request.The string version of the ObjectId of the current request. This is the string that was supplied when the object reference was created. The string is meaningful to users only in the case when the object reference was created by the start_persistent_userid function. (That is, the ObjectId created by start_transient and start_persistent_systemid were created by the ORB and has no relationship to the user application.)