Object Implementation
An object implementation provides the state and processing activities for the ORB objects used by client applications. An ORB object is created when its implementation class is instantiated in C++ by an implementation process or server. An object implementation uses the Basic Object Adaptor ( BOA) to activate its ORB objects so that they can be used by client applications. ORB objects fall into two categories: transient and persistent.
Transient Objects
Objects that are only available during the lifetime of the process that created them are called transient objects. Transient objects are not registered with ISB for C++'s directory service. Only those entities that possess an explicit object reference to a transient object may invoke its methods. The following code example shows you how to modify a library application so that library_server
is created as a transient object. The scope must be set prior to instantiating the object.
NOTE:
Clients can only access objects of transient objects when passed as an
argument, as defined by the IDL; for instance, object_to_string
will fail.
Creating a transient object.
#include <lib_srv.h>
int main(int argc, char **argv)
{
// Initialize ORB and Basic Object Adaptor (BOA)
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
CORBA::BOA_var boa = orb->BOA_init(argc, argv);
// Set local registration scope
boa->scope(CORBA::BOA::SCOPE_LOCAL);
// Instantiate the Library class as a transient object
Library library_server();
// Since Library object is transient, it won't get
// registered with the directory service
boa->obj_is_ready(&library_server);
...
};
// MsgService.cpp
#include "HelloImpl.cpp"
#include <iostream.h>
#include <NameUtil.hpp>
int main(int argc, char* const* argv) {
try {
// Initialize the ORB and the BOA.
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
CORBA::BOA_var boa = orb->BOA_init(argc, argv);
HelloImpl* hi = new HelloImpl();
WAIReturnType_t rc;
char *objectName = "Howdy";
char *hostAndPort = "mikelee:80";
rc = registerObject(hostAndPort, objectName, hi);
boa->obj_is_ready(hi);
cerr << "Ready for client requests." << endl;
boa->impl_is_ready();
} catch (CORBA::SystemException& e) {
cerr << e << endl;
return(1);
}
return(0);
}
NOTE: You do not have to set the scope of a persistent object because the default scope is global, or persistent.
_is_persistent
method returns 1
if the object is persistent and 0 if the object is transient.
The method for checking for persistent object implementations.
class Object {
...
Boolean _is_persistent() const;
...
};
obj_is_ready
method notifies the BOA that a particular service object is ready to receive requests from client applications. If a server offers more than one service object, it must call obj_is_ready
for each object, passing the object reference as an argument.
If the object reference passed to obj_is_ready
represents a persistent object, the BOA will register the object with ISB for C++'s directory service. If the object is transient, no such registration will occur.
NOTE: If a client tries to bind to a service andWhen all of the objects have been instantiated and all the calls toobj_is_ready
has not been called, the exceptionNO_IMPLEMENT
is raised.
obj_is_ready
have been made, the server must call impl_is_ready
to enter an event loop and await client requests. The Handling Events chapter in this guide discusses event handling in detail.
The Basic Object Adaptor
ISB for C++'s BOA provides several important functions to client applications and the object implementations they use. An object may reside in the same process as its client application or it may reside in a separate process called a server. Servers may contain and offer a single object or multiple objects. Furthermore, servers may be activated by the BOA on demand or they may be started by some entity external to the BOA.
Object Server Activation Policies
The CORBA specification defines four activation policies that describe the way in which an object implementation is started and the manner in which it may be accessed by a client application. These activation policies only apply to persistent objects, not transient objects.
Shared Server Policy
When the shared server policy is specified, only one server is launched regardless of the number of clients; the clients share the server. Along with persistent servers, shared servers are the most common types of servers.
Persistent Server Policy
This policy describes servers that, like shared servers, implement multiple objects. Persistent servers are started by some entity outside of the Basic Object Adaptor, but they still register their objects and receive requests using the BOA.
Unshared Server Policy
Unshared servers are processes that implement a single object. A client application causes this type of server to be activated. Once that client exits, the unshared server will exit.
Server-Per-Method Policy
This activation policy requires a server process to be started for each method that is invoked. After the method has been completed, the server will exit. Subsequent method invocations on the same object will require a new server process to be started.
Object Activation Daemon
You can register an object implementation with ISB for C++'s Object Activation Daemon (OAD) to automatically activate the implementation when a client binds to the object. Object implementations can be registered using a command-line interface or programmatically with the BOA::create
method. There is also an ORB Interface to the OAD. In each case, the interface name, object name, the activation policy, and the executable program representing the implementation must be specified.
The Implementation Repository
All object implementations registered with the OAD are stored in an implementation repository maintained by the OAD. By default, the implementation repository data are stored in a file named impl_rep
. This file's path name depends on where ISB for C++ was installed on your system. The default value can be overridden using OAD environment variables, described in the Netscape Internet Service Broker for C++ Reference Guide.
OAD Registration with regobj
The regobj
command can be used to register an object implementation from the command line or from program code. The required parameters are the interface name, object name and path name. If the activation policy is not specified, the default policy of shared server will be used. For complete information on using this command, see the Netscape Internet Service Broker for C++ Reference Guide.
NOTE: The implementation of your object does not need to be modified in order for you to useregobj
. You can write an implementation and start it manually during the development and testing phases. When your implementation is ready to be deployed, useregobj
to register your implementation with the OAD.
NOTE: When registering an object implementation, use the same object name as is used when the implementation object is contructed.Figure 4.1 The
regobj
command
For information about the Windows implementation of regobj
, see the "Commands" chapter of the Netscape Internet Service Broker for C++ Reference Guide.
regobj
command manually or in code, ISB for C++ provides the BOA::create
method to register one or more objects with the OAD and the ISB for C++ directory service. The OAD will store the information in the implementation repository, allowing the object implementation to be located and activated when a client attempts to bind to the object.
The BOA::create
method and its parameters.
class CORBA {
...
typedef OctetSequence ReferenceData
;
...
class BOA {
virtual Object_ptr create(
const ReferenceData& ref_data,
InterfaceDef_ptr inf_ptr,
ImplementationDef_ptr impl_ptr) = 0;
...
};
...
};
ref_data
parameter to distinguish between multiple instances of the same object. The value of the reference data is chosen by the implementation at object creation time and remains constant during the lifetime of the object. The ReferenceData typedef
is portable across platforms and ORBs.
NOTE: ISB for C++ does not use theinf_ptr
, defined by the CORBA specification to identify the interface of the object being created. Applications created with ISB for C++ should always specify aNULL
value for this parameter.
impl_ptr
parameter supplies the information that the BOA needs to register an ORB object. The ImplementationDef
class defines the interface name, object name, and reference id properties used by the BOA. The following code listing shows the methods for querying and setting these properties.
The ImplementationDef
class.
class ImplementationDefThe
{
public:
static ImplementationDef_ptr_duplicate
(ImplementationDef_ptr obj);
static void_release
(ImplementationDef_ptr obj);
static ImplementationDef_ptr_nil
();
const char*interface_name
() const;
voidinterface_name
(const char *val);
const char*object_name
() const;
voidobject_name
(const char *val);
ReferenceData_ptrid
() const;
voidid
(const ReferenceData_ptr& data);
...
protected:
String_var _interface_name;
String_var _object_name;
ReferenceData _id;
...
};
_interface_name
property represents the name specified in the object's IDL specification. The _object_name
property is the name of this object, provided by the implementor or the person installing the object. The _id
property is chosen by the implementation and has no meaning to the BOA or the OAD. The implementor may use the _id
property as they chose.
ImplementationDef
class, as defined by the CORBA specification, does not supply all the information that the OAD needs to activate an object implementation when a client attempts to bind to the object. The CreationImplDef
class is derived from ImplementationDef
and adds the properties the OAD requires. The properties added are _path_name
, _policy
, _args
, and _env
. Methods for getting and setting their values are also provided. These additional properties are used by the OAD to activate an ORB object. The code listing below shows the CreationImplDef
class, its properties and methods.
The _path_name
property specifies the exact path name of the executable program that implements the object. The _policy
property represents the server's activation policy. The _args
and _env
properties represent optional arguments and environment settings to be passed to the server.
The CreationImplDef
class.
enum
Policy
{
SHARED_SERVER,
UNSHARED_SERVER,
SERVER_PER_METHOD
};
class CreationImplDef
: public ImplementationDef
{
public:
CreationImplDef
();
CreationImplDef
(const char *interface_name,
const char *object_name,
const RefereneData& id,
const char *path_name,
const StringSequence& args,
const StringSequence& env);
~CreationImplDef
() {};
static CreationImplDef_ptr _duplicate
(CreationImplDef_ptr obj);
static void _release
(CreationImplDef_ptr obj);
static CreationImplDef_ptr _nil
();
static CreationImplDef_ptr _narrow
(ImplementationDef_ptr ptr);
Policy activation_policy
() const;
void activation_policy
(Policy p);
const char *path_name
() const;
void path_name
(const char *val);
StringSequence *args
() const;
void *args
(const StringSequence& val);
StringSequence *env
() const;
void env
(const StringSequence& val);
...
pro
BOA::create Example
The following code example shows how to use the CreationImplDef
class and the BOA::create
method to create an ORB object and register it with the OAD.
Creating an ORB object and registering with the OAD.
#include "libsrv.h"
void main(int argc, char * const * argv)
{
CORBA::Object_ptr obj;
// Initialize the ORB and BOA
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
CORBA::BOA_var boa = orb->BOA_init(argc, argv);
// Optional reference data
ReferenceData id;
CORBA::CreationImplDef impl_def("library", "Harvard", id,
"/usr/home/dir/libsrv",
NULL /* no args */,
NULL /* no envs */);
obj = boa->create(id, NULL, &impl_def);
if (obj != NULL)
cout << "ORB object created successfully" << endl;
}NOTE:
If the
impl_def
parameter passed to BOA::create
cannot be narrowed to a
CreationImplDef
reference, create
will fail and a CORBA::BAD_PARAM
exception will be raised.
Changing an ORB Implementation
The following code listing shows the BOA::change_implementation
method which can be used to dynamically change an object's implementation. You can use this method to change the object's activation policy, path name, arguments and environment variables. If the impl
parameter cannot be narrowed to a CreationImplDef
, this method will fail and a CORBA::BAD_PARAM
exception will be raised.
The change_implementation
method.
class BOA {
...
virtual void change_implementation(const Object &obj,
...
const ImplementationDef& impl);
};
Caution Changing an object's implementation name and object name using this method will prevent client applications from locating the object with the old name.
BOA::change_implementation
method cannot change the object's implementation. As with the registration process, unregistering may be done with a command line or programmatically. There is also an ORB object interface to the OAD.
Unregistering with unregobj
The unregobj
command can be used to unregister an object implementation from the command line or from within code. If the interface name is specified by itself, all objects instances associated with that interface name will be unregistered. You can specify both the interface and object name if you only wish to unregister a specific object within an interface. For complete information on using this command, see the Netscape Internet Service Broker for C++ Reference Guide.
Figure 4.2 The unregobj command.
For information about the Windows implementation of unregobj
, see the "Commands" chapter of the Netscape Internet Service Broker for C++ Reference Guide.
Unregistering with the BOA::dispose Method
An object's implementation can use the BOA::dispose
method to unregister an ORB object. Any connections that exist between a client application and the object will be terminated as soon as the object is unregistered.
The BOA::dispose
method.
class CORBA {
class BOA {
...
virtual void dispose(Object_ptr);
...
};
}; The listimpl Command
You can use the listimpl
command to list the contents of a particular implementation repository. For each implementation in the repository, the listimpl
command lists all the object instance names, the path name of the executable program, the activation mode, and the reference data. Any arguments or environment variables that are to be passed to the executable program are also listed. For complete details on using this command see the Netscape Internet Service Broker for C++ Reference Guide.
Figure 4.3 The listimpl
command.
For information about the Windows implementation of listimpl
, see the "Commands" chapter of the Netscape Internet Service Broker for C++ Reference Guide.
ORB Interface to the OAD
The Object Activation Daemon is implemented as an ORB object. The code listing below shows the IDL interface specification for the OAD. You can create a client application that binds to the OAD and uses this interface to query the status of objects that have been registered.
The OAD interface specification.
// IDL
module Activation
{
enum State {
ACTIVE,
INACTIVE,
WAITING_FOR_ACTIVATION
};
struct ObjectStatus {
long process_id;
State activation_state;
Object objRef;
;
typedef sequence<ObjectStatus> ObjectStatusList;
struct ImplementationStatus {
CORBA::CreationImplDef impl;
ObjectStatusList status;
};
typedef sequence<ImplementationStatus> ImplStatusList;
exception NotRegistered {};
...
interface OAD {
// Internal methods are not shown here.
...
// Get status info for a given implementation
ImplementationStatus get_status(in string interface_name,
in string object_name)
raises (NotRegistered);
// Get status of all implementations for a given interface
ImplStatusList get_status_interface(in string interface_name)
raises (NotRegistered);
// Get list of all registered interfaces.
ImplStatusList get_status_all();
... Activating Objects Directly
Direct activation of an object involves instantiating all the C++ implementation classes, invoking the BOA::obj_is_ready
method for each object and then invoking BOA::impl_is_ready
to begin receiving requests. The following code example shows how this processing would occur for a server offering two Library
objects; one with the object name of "Stanford" and the other named "Harvard." Once the objects have been instantiated and activated, the server invokes BOA::impl_is_ready
to begin receiving client requests.
NOTE:
The BOA::obj_is_ready
must be called for each object offered by the
implementation.
Server activating two objects and the implementation
.#include <lib_server.hh>
int main(int argc, char * const * argv)
{
// Initialize ORB and Basic Object Adaptor (BOA)
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
CORBA::BOA_var boa = orb->BOA_init(argc, argv);
// Instantiate Harvard Library Class
Library harvard_lib("Harvard");
boa->obj_is_ready(&harvard_lib);
// Instantiate Stanford Library Class
Library stanford_lib("Stanford");
boa->obj_is_ready(&stanford_lib);
// Begin event loop of receiving messages
boa->impl_is_ready();
return(1);
}
BOA::obj_is_ready
and BOA::impl_is_ready
methods may be used with the ActivationImplDef
class to instantiate objects upon receipt of a client request.
The BOA::obj_is_ready
and BOA::impl_is_ready
methods.
class CORBA {In previous examples, the
class BOA {
...
virtual void obj_is_ready(Object_ptr,ImplementationDef_ptr impl=NULL
) = 0;
virtual void impl_is_ready(ImplementationDef_ptr impl=NULL
) = 0;
...
};
};
obj_is_ready
method was only passed an object reference. The impl_is_ready
was passed no parameters at all. It is possible to pass an ActivationImplDef
pointer to the obj_is_ready
method, which can be used to override the activation and deactivation methods used by the BOA. The following code listing shows the ActivationImplDef
class, which adds an Activator
pointer and provides methods for setting and retrieving that pointer. This class is derived from ImplementationDef
.
The ActivationImplDef
class.
classActivationImplDef
: publicImplementationDef
{
public:
ActivationImplDef();
ActivationImplDef(const char *interface_name,
const char *object_name,
const ReferenceData& id,
Activator_ptr act
);
~ActivationImplDef();
static ActivationImplDef_ptr _duplicate(ActivationImplDef_ptr obj);
static ActivationImplDef_ptr _nil();
static ActivationImplDef_ptr _narrow(ImplementationDef_ptr ptr);
Activator_ptr activator_obj();
void activator_obj(Activator_ptr val);
protected:
Activator_ptr _activator;
...
};
Activator
class, which provides the two methods used by the BOA to activate and deactivate an ORB object.
The Activator
class.
classDeriving your own class from theActivator
{
public:
Activator();
~Activator();
static Activator_ptr _duplicate(Activator_ptr obj);
static void _release(Activator_ptr);
static Activator_ptr _nil();
virtual Object_ptractivate
(ImplementationDef impl) = 0;
virtual voiddeactivate
(Object_ptr, ImplementationDef_ptr impl);
};
Activator
class lets you override the activate
and deactivate
methods that the ORB will use for the Library
object. This allows you to delay the instantiation of the Library
object until the BOA activates the ORB object. It also allows you to provide clean-up processing when the ORB deactivates the object. The following code listing shows how to create an Activator
for the Library
class.
Deriving the LibraryActivator
class, implementing the activate
and deactivate
methods.
classLibraryActivator
: CORBA::Activator
{
public:
virtual CORBA::Object_ptractivate
(CORBA::ImplementationDef_ptr impl);
virtual voiddeactivate
(CORBA::Object_ptr,
CORBA::ImplementationDef_ptr impl);
};
CORBA::Object_ptr LibraryActivator::activate
(CORBA::ImplementationDef_ptr impl)
{
// When the BOA activates us, instantiate the Library object.
return new Library(impl->object_name());
}
void LibraryActivator::deactivate
(CORBA::Object_ptr obj, CORBA::ImplementationDef_ptr impl)
{
// When the BOA deactivates us, release the Library object.
obj->release();
}
ActivationImplDef
class with the LibraryActivator
class to defer the activation of the Library
object until a client request is received. The instantiation of the Library
object no longer appears in the main
routine. Instead, the Library
object will be instantiated when the BOA receives a client request and invokes the activate
method.
In this example, the invocation of BOA::obj_is_ready
is passed a NULL
object reference and an ActivationImplDef
reference. The Library object named "Harvard" will not be created until the first client request for that object is received.
Using the ActivationImplDef
class with the BOA::obj_is_ready
method.
int main(int argc, char * const * argv)If an implementation has only one object,
{
// Initialize ORB and Basic Object Adaptor (BOA)
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
CORBA::BOA_var boa = orb->BOA_init(argc, argv);
CORBA::ReferenceData id;
CORBA::ActivationImplDef impl("library", "Harvard", id,
(CORBA::Activator_ptr) new LibraryActivator);
// obj_is_ready is passed an ActivationImplDef object to override
// the activation of the Library object.
boa->obj_is_ready(NULL, &impl);
// activate other objects
...
// Begin event loop of receiving requests
boa->impl_is_ready();
return(1);
};
impl_is_ready
can be called with the ActivationImplDef
reference to activate both the object and the implementation. Since impl_is_ready
can accept only one object's implementation, this approach cannot be used if multiple objects reside in the same implementation. The following code example shows one invocation of impl_is_ready
.
The use of a single impl_is_ready
method.
int main(int argc, char * const * argv)
{
// Initialize ORB and Basic Object Adaptor (BOA)
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
CORBA::BOA_var boa = orb->BOA_init(argc, argv);
CORBA::ReferenceData id;
CORBA::ActivationImplDef impl("library", "Harvard", id,
(CORBA::Activator_ptr) new LibraryActivator);
// impl_is_ready is passed an ActivationImplDef object to override
// the activation of the Library object.boa->impl_is_ready(&impl);
return(1);
};
Last Updated: 02/03/98 15:30:18
Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use