Object Implementation
Activating Objects with the BOA
Object and Implementation Deactivation
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, or 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 VisiBroker's directory service. Only those entities that possess an explicit object reference to a transient object may invoke its methods. Figure 4-1 shows you how to modify the library application so that library_server
is created as a transient object. The scope must be set prior to instantiating the 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);
...
};
object_to_string
will fail.
Note: Registration is handled by the
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);
// Instantiate the Library class
Library library_server();
// Or
// Library * library_server = new Library;
boa->obj_is_ready(&library_server);
boa->impl_is_ready();
boa::obj_is_ready
method.
#include <lib_srv.h>
Note: You do not have to set the scope of a persistent object because the default scope is global, or persistent.
// Register the Library object with directory service
// Server is ready to receive requests Checking for Persistent Objects
Figure 4-3 shows a method your client application can use to determine whether a persistent or transient object implementation is associated with a given object reference. It is important to know whether or not an object is persistent because some methods for
manipulating object references will fail if the object is transient. The _is_persistent
method returns 1
if the object is persistent and 0 if the object is transient.
The following example shows the method for checking for persistent object implementations.
class Object {...
Boolean _is_persistent() const;
...
};
The
obj_is_ready
method notifies the BOA that a particular ORB object is ready to receive requests from client applications. If your server offers more than one ORB object, it must make a call to 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 VisiBroker's directory service. If the object is transient, no such registration will occur.Note: When
obj_is_ready
is not called and a client attempts to call _bind
, the exception NO_IMPLEMENT
is raised.Once all of the objects have been instantiated and all the calls to
obj_is_ready
have been made, the server must call impl_is_ready
to enter an event loop and await client requests. Chapter 7 in this guide discusses event handling in detail.
The Basic Object Adaptor
VisiBroker's BOA provides several important functions to client applications and the object implementations they use. It is important to realize that an object may reside in the same process as its client application or it may reside in a separate processes called servers. 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 VisiBroker's Object Activation Daemon to automatically activate the implementation when a client requests a bind 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, described in "ORB Interface to the OAD" on page 4-14. 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 is dependent on where VisiBroker was installed on your system. If VisiBroker was installed in /usr/local/visibroker/
, then the path to this file would be
/usr/local/visibroker/adm/impl_dir/impl_rep
. These defaults can be overridden using OAD environment variables, described in the VisiBroker 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 within a script. 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 VisiBroker for C++ Reference Guide.
regobj -o library,Harvard -p shared -f /home/user/dir/libsrv -a arg1 -e env1 - r refdata
For information about the Windows implementation of
regobj
, see the "Commands" chapter of the VisiBroker for C++ Reference Guide.
regobj
command manually or in a script, VisiBroker allows applications written in C++ to use the BOA::create
method to register one or more objects with the activation daemon. Using this method results in an object implementation being registered with the OAD and the VisiBroker 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 following example shows 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: VisiBroker does not use the
inf_ptr
, defined by the CORBA specification to identify the interface of the object being created. Applications created with VisiBroker should always specify a NULL
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. Figure 4-6 shows the methods for querying and setting these properties.
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;
void interface_name(const char *val);
const char *object_name() const;
void object_name(const char *val);
ReferenceData_ptr id() const;
void id(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 setting and querying their values are also provided. These additional properties are used by the OAD to activate an ORB object. Figure 4-7 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, discussed in "Object Server Activation Policies" on page 4-5. The _args
and _env
properties represent optional arguments and environment settings to be passed to the server.
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& i d,
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);
...
protected:
String_val _path_name;
Policy _policy;
StringSequence _args;
StringSequence _env;
};
CreationImplDef
class and the BOA::create
method to create an ORB object and register it with the OAD.
#include "libsrv.h"Note: If thevoid 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"
exit (1);
}
impl_def
parameter passed to BOA::create
cannot be narrowed to a CreationImplDef
reference, the create will fail and a CORBA::BAD_PARAM
exception will be raised.
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
...
virtual void change_implementation(
const Object &obj,
const ImplementationDef& impl);
};
impl
parameter cannot be narrowed to a CreationImplDef
, this method will fail and a CORBA::BAD_PARAM
exception will be raised.change_implementation
method.
class BOA {
Caution: Though you can change an object's implementation name and object name with the
this
method, you should exercise caution. Doing so will prevent client applications from locating
the object with the old name.
Unregistering Implementations
When the services offered by an object are no longer available or temporarily suspended, the object should be unregistered with the OAD. When an ORB object is unregistered, it is removed from the OAD's list of objects. The object is also removed from the directory service and from the implementation repository. Once an object is unregistered, client applications will no longer be able to locate or use it. In addition, the BOA::change_implementation method will no longer be able to be used to 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, described in "ORB Interface to the OAD" on page 4-14.
Unregistering with unregobj
Figure 4-10 shows the unregobj command, which can be used to unregister an object implementation from the command line or from within a script. 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 VisiBroker for C++ Reference Guide.
unregobj -i library,HarvardFor information about the Windows implementation of unregobj, see the "Commands" chapter of the VisiBroker for C++ Reference Guide.
BOA::dispose
method to unregister an ORB object. Any connections that might exist between a client application and the object will be terminated as soon as the object is unregistered.The following example shows the use of the
BOA::dispose
method.
class CORBA {class BOA {
...
virtual void dispose(Object_ptr);
...
};
};
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 VisiBroker for C++ Reference Guide. The following example shows the use of
listimpl
for UNIX users. For more information, see the VisiBroker for C++ Reference Guide.
listimpl -i interfaceFor information about the Windows implementation of listimpl, see the "Commands" chapter of the VisiBroker for C++ Reference Guide.
The following example shows the OAD interface specification.
// IDLmodule 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();
...
Library
object was activated directly by the server. 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. Figure 4-14 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.
#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.
class CORBA {In previous examples, theclass 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. Figure 4-16 shows the ActivationImplDef
class, which adds an Activator
pointer and provides methods for setting and retrieving that pointer. Note that this class is derived from ImplementationDef
.
class ActivationImplDef: public ImplementationDef{
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.
class Activator {Deriving your own class from thepublic:
Activator();
~Activator();
static Activator_ptr _duplicate(Activator_ptr obj);
static void _release(Activator_ptr);
static Activator_ptr _nil();
virtual Object_ptr activate(ImplementationDef impl) = 0;
virtual void deactivate(Object_ptr,
ImplementationDef_ptr impl);
};
Activator
class lets you to 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. Figure 4-18 shows how to create an Activator
for the Library
class.class LibraryActivator : CORBA::Activator {public:
virtual CORBA::Object_ptr activate(
CORBA::ImplementationDef_ptr impl);
virtual void deactivate(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 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 as well as an ActivationImplDef
reference. The creation of the Library object named "Harvard" will now be deferred until the first client request for that object is received.
void main(int argc, char * const * argv)If an implementation has only one object, then the{
// 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
method 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. Figure 4-20 shows the use of a one invocation of the impl_is_ready
method.
The following example shows the use of a single
impl_is_ready
method.
void 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);
};
CORBA::release(Object_ptr)
on
the object to unregister the object from the list of objects maintained by the directory service. This also calls the destructor if no other references to the object exist. Calling delete on the object is not recommended since the object could be deleted prematurely.
BOA::deactivate_impl
method. Once this method is called, the implementation will not be available to service client requests. The implementation can only be re-activated if it is restarted or if it again calls the impl_is_ready
method.
BOA::deactivate_obj
method is provided to deactivate objects activated by the BOA. After this method is called, the object will be removed from the directory service list of objects offered by that implementation. Figure 4-21shows the definition of the deactivate_obj
method.
class CORBA {class BOA {
...
virtual void deactivate_obj(Object_ptr);
...
};
};