VisiBroker for Java Developer’s Guide : Using the VisiBroker Server Manager

Using the VisiBroker Server Manager
The VisiBroker Server Manager allows client applications to monitor and manage object servers, view and set properties at runtime for those servers, and view and invoke methods on Server Manager objects. The Server Manager uses elements known as containers which represent each major ORB component. A container can contain properties, operations, and even other containers.
Note
Do not confuse the Server Manager container with J2EE containers. The Server Manager container is simply a logical grouping of ORB components and selected runtime properties.
Getting Started with the Server Manager
This section covers enabling the Server Manager on a server, obtaining a Server Manager reference, working with containers, the Storage interface and the Server Manager IDL.
Enabling the Server Manager on a server
A VisiBroker server is not enabled to be managed by default. The command which starts the server must set the following property to manage the server:
vbroker.orb.enableServerManager=true
The property can be specified either through the command-line or through the server's properties file.
Obtaining a Server Manager reference
The first step in interacting with a Server Manager is to obtain a reference to a server's Server Manager. This reference points to the top level container. A client can obtain the reference in two ways:
1
prompt> vbj -Dvbroker.serverManager.name=BigBadBoss Server
registers the Server Manager name “BigBadBoss” to the Smart Agent namespace. From this point onward, the client can bind to that name and start invoking operations on the reference. This property can be set in the properties file as well. This method of locating a Server Manager can be used when the client does not have object references to any other objects implemented by the server, for example:
import com.inprise.vbroker.ServerManager.*;

// returns reference to Server Manager "BigBadBoss" top container.
Container topContainer = ContainerHelper.bind(orb,"BigBadBoss");
2
If the client has an object reference to some other object implemented by the server, then the client can perform _resolve_reference("ServerManager") on that object to obtain the ServerManager for the ORB corresponding to the object. Te following code fragment obtains the Server Manager's top-level container from the Bank::AccountManager object.
import com.inprise.vbroker.ServerManager.*;

// assume "manager" contains the reference to AccountManager
// object. No need to narrow since AccountManager is a
// com.inprise.vbroker.CORBA.Object, however a narrow is still
// required to convert returned Server Manager reference to
// Container.
Container topContainer = ContainerHelper.narrow(
manager._resolve_reference("ServerManager"));
The client code needs to include the servermgr_c.hh to use the Server Manager interfaces.
Working with Containers
Once a client application has obtained the reference to the top level container, it can:
The top-level container does not support any properties or operations but just contains the ORB container. The ORB container in turn contains few ORB properties, a shutdown method, and other containers like RootPOA, Agent, OAD, and so forth.
See “The Container Interface” for information on how to interact with containers. “Server Manager examples” shows a Java example.
The Storage Interface
Server Manager provides an abstract notion of storage that can be implemented in any fashion. Individual containers may choose to store their properties in the different ways. Some containers may choose to store their properties in a database, while others may choose to store them in files or in some other method. The Storage interface is defined in Server Manager IDL.
Every container uses the same methods to get and set storage, along with the ability to optionally set storage on all child containers of the parent. Similarly, each container uses the same methods to read and write its properties from the storage.
For information on the Storage Interface and its methods, see “The Storage Interface”.
The Container Interface
The container interface defines an interface and associated methods for logically grouping sets of objects, properties, operations, and so forth.
Container class
public interface Container extends
com.inprise.vbroker.CORBA.Object
com.inprise.vbroker.ServerManager.ContainerOperations
org.omg.CORBA.portable.IDLEntity
When using this class in your code, you must include the following include statements:
import com.borland.vbroker.ServerManager.*;
import com.borland.vbroker.ServerManager.ContainerPackage.*;
Container Methods for Java
A container can hold properties, operations, and other containers. Each major ORB component is represented as a container.
This section explains the Java methods that can be executed on the container interface. There are four categories:
Methods related to property manipulation and queries
public String[] list_all_properties();
Returns the names of all the properties in the contianer as a StringSequence.
public com.inprise.vbroker.ServerManager.ContainerPackage.
Property[]
get_all_properties();
Returns the PropertySequence containing the names, values, and read-write status of all the properties in the container.
public com.inprise.vbroker.ServerManager.ContainerPackage.
Property
get_property(String name) throws com.inprise.vbroker.ServerManager.ContainerPackage.
NameInvalid
Returns the value of the property name passed as an input parameter.
public void set_property(String name, org.omg.CORBA.Any
value) throws com.inprise.vbroker.ServerManager. ContainerPackage.NameInvalid,
com.inprise.vbroker.ServerManager. ContainerPackage.ValueInvalid,
com.inprise.vbroker.ServerManager. ContainerPackage.ValueNotSettable
Sets the value of the property name to the requested value.
public void persist_properties(boolean recurse) throws
com.inprise.vbroker.ServerManager.StorageException;
Causes the container to actually store its properties to the associated storage. If no storage is associated with the container, a StorageException will be raised. When it is invoked with the parameter recurse=true, the properties of the children containers are also stored into the storage. It is up to the container to decide if it has to store all the properties or only the changed properties.
public void restore_properties(boolean recurse) throws
com.inprise.vbroker.ServerManager.StorageException;
Instructs the container to obtain its properties from the storage. A container knows exactly what properties is manages and it attempts to read those properties from the storage. The containers shipped with the ORB do not support restoring from the storage. You must create containers that support this feature yourself.
Methods related to operations
public String[] list_all_operations();
Returns the names of all the operations suppored in the container.
public com.inprise.vbroker.ServerManager.ContainerPackage.
Operation[]
get_all_operations();
Returns all the operations along with the parameters and the type code of the parameters so that the operation can be invoked with the appropriate parameters.
public com.inprise.vbroker.ServerManager.ContainerPackage.
Operation
get_operation(String name) throws com.inprise.vbroker.ServerManager.ContainerPackage.
NameInvalid;
Returns the parameter information of the operation specified by name which can be used to invoke the operation.
public org.omg.CORBA.Any do_operation(
com.inprise.vbroker.ServerManager.ContainerPackage.
Operation op) throws
com.inprise.vbroker.ServerManager.ContainerPackage.
NameInvalid,
com.inprise.vbroker.ServerManager.ContainerPackage.
ValueInvalid,
com.inprise.vbroker.ServerManager.ContainerPackage.
OperationFailed;
Invokes the method in the operation and returns the result.
Methods related to children containers
public String[] list_all_containers();
Returns the names of all the children containers of the current container.
public com.inprise.vbroker.ServerManager.ContainerPackage.
NamedContainer[]
get_all_containers();
Returns all the children containers.
public com.inprise.vbroker.ServerManager.ContainerPackage.
NamedContainer
get_container(String
name) throws
com.inprise.vbroker.ServerManager.ContainerPackage.
NameInvalid;
Returns the child container identified by the name parameter. If there is not any child container with this name, a NameInvalid exception is raised.
public void add_container(
com.inprise.vbroker.ServerManager.ContainerPackage.
NamedContainer
container) throws com.inprise.vbroker.ServerManager.ContainerPackage.
NameAlreadyPresent,
com.inprise.vbroker.ServerManager.ContainerPackage.
ValueInvalid;
Adds the container as a child container of this container.
public void set_container(String name, com.inprise.vbroker.ServerManager.Container value) throws
com.inprise.vbroker.ServerManager.ContainerPackage.
NameInvalid,
com.inprise.vbroker.ServerManager.ContainerPackage.
ValueInvalid,
com.inprise.vbroker.ServerManager.ContainerPackage.
ValueNotSettable;
Modifies the child container identified by the name parameter to one in the value parameter.
Methods related to storage
void set_storage(in com.inprise.vbroker.ServerManager.Storage s, in boolean recurse);
Sets the storage of this container. If recurse=true, it also sets the storage for all its children as well.
com.inprise.vbroker.ServerManager.Storage get_storage();
Returns the current storage of the container.
The Storage Interface
The Server Manager provides an abstract notion of storage that can be implemented in any fashion. Individual containers may choose to store their properties in databases, flat files, or some other means. The storage implementation included with the VisiBroker ORB uses a flat-file-based approach.
Storage Interface Class and Methods
Storage Class
public interface Storage extends
com.inprise.vbroker.CORBA.Object
com.inprise.vbroker.ServerManager.StorageOperations,
org.omg.CORBA.portable.IDLEntity
The following include statements must appear in your code when using the Storage interface:
import com.inprise.vbroker.ServerManager.*;
import com.inprise.vbroker.ServerManager.ContainerPackage.*;
Storage Interface Methods
public void open() throws
com.inprise.vbroker.ServerManager.StorageException;
Opens the storage and makes it ready for reading and writing the properties. For the database-based implementation, logging into the database is performed in this method.
public void close() throws
com.inprise.vbroker.ServerManager.StorageException;
Closes the storage. This method also updates the storage with any properties that have been changed since the last Container::persist_properties call. In database implementations, this method closes the database connection.
public com.inprise.vbroker.ServerManager.ContainerPackage.
Property[]
read_properties() throws
com.inprise.vbroker.ServerManager.StorageException;
Reads all the properties from the storage.
public com.inprise.vbroker.ServerManager.ContainerPackage.
Property
read_property(String
propertyName) throws com.inprise.vbroker.ServerManager.ContainerPackage.
NameInvalid,
com.inprise.vbroker.ServerManager.StorageException;
Returns the property value for propertyName read from the storage.
public void write_properties(com.inprise.vbroker.ServerManager.
ContainerPackage.
Property[] props) throws com.inprise.vbroker.ServerManager.StorageException;
Saves the property sequence into the storage.
public void write_property
(com.inprise.vbroker.ServerManager.ContainerPackage.
Property
prop) throws com.inprise.vbroker.ServerManager.StorageException;
Saves the single property into the storage.
Limiting access to the Server Manager
A client that obtains the Server Manager can control the entire ORB and hence security is paramount. The following properties can limit a user's access to the Server Manager functionality:
Setting this property to True enables the Server Manager.
Controls the permission to invoke operations in the containers. If set to false, the client will not be able to invoke do_operation on any container. This helps protect Server Manager from unintentional changes including shutting down the server by mistake.
Controls the setting of properties from the client. If set to the false, clients cannot modify any of the container properties.
Server Manager IDL
Server Manager IDL is as shown below:
module ServerManager {
interface Storage;

exception StorageException {
string reason;
};

interface Container
{
enum RWStatus {
READWRITE_ALL,
READONLY_IN_SESSION,
READONLY_ALL
};

struct Property {
string name;
any value;
RWStatus rw_status;
};
typedef sequence<Property> PropertySequence;

struct NamedContainer {
string name;
Container value;
boolean is_replaceable;
};
typedef sequence<NamedContainer> NamedContainerSequence;

struct Parameter {
string name;
any value;
};
typedef sequence<Parameter> ParameterSequence;

struct Operation {
string name;
ParameterSequence params;
::CORBA::TypeCode result;
};
typedef sequence<Operation> OperationSequence;

struct VersionInfo {
unsigned long major;
unsigned long minor;
};

exception NameInvalid{};
exception NameAlreadyPresent{};
exception ValueInvalid{};
exception ValueNotSettable{};
exception OperationFailed{
string real_exception_reason;
};

::CORBA::StringSequence list_all_properties();
PropertySequence get_all_properties();
Property get_property(in string name) raises (NameInvalid);
void add_property(in Property prop)
raises(NameAlreadyPresent, NameInvalid, ValueInvalid);
void set_property(in string name, in any value)
raises(NameInvalid, ValueInvalid, ValueNotSettable);

::CORBA::StringSequence get_value_chain(in string propertyName) raises (NameInvalid);
void persist_properties(in boolean recurse) raises (StorageException);
void restore_properties(in boolean recurse) raises (StorageException);

::CORBA::StringSequence list_all_operations();
OperationSequence get_all_operations();
Operation get_operation(in string name)
raises (NameInvalid);
any do_operation(in Operation op)
raises(NameInvalid, ValueInvalid, OperationFailed);

::CORBA::StringSequence list_all_containers();
NamedContainerSequence get_all_containers();
NamedContainer get_container(in string name)
raises (NameInvalid);
void add_container(in NamedContainer container)
raises(NameAlreadyPresent, ValueInvalid);
void set_container(in string name, in Container value)
raises(NameInvalid, ValueInvalid, ValueNotSettable);


void set_storage(in Storage s, in boolean recurse);
Storage get_storage();

readonly attribute VersionInfo version;
};

interface Storage
{
void open() raises (StorageException);
void close() raises (StorageException);
Container::PropertySequence read_properties() raises
(StorageException);
Container::Property read_property(in string propertyName)
raises (StorageException, Container::NameInvalid);
void write_properties(in Container::PropertySequence p) raises
(StorageException);
void write_property(in Container::Property p) raises (StorageException);
};

};
Server Manager examples
The following examples demonstrate how to:
1
2
3
4
Invoke the shutdown() method on the ORB container.
These example files can be found in:
<install_dir>/examples/vbroker/ServerManager/basic
The following example uses the bank_agent server. This server should be started by passing the property storage file. Initially the property file contains the properties to enable the Server Manager and set its name. The file is used by the Server Manager to update the properties if the user changes them. The properties to enable the Server Manager and set its name can be passed as command-line options, but the property file is required if any of the properties are to be modified and saved during the session.
Initially, the property file contains the following:
# server properties
vbroker.orb.enableServerManager=true
vbroker.serverManager.name=BigBadBoss
The server is started from the command-line:
prompt> vbj -DORBpropStorage=server.properties Server
Obtaining the reference to the top-level container
This example uses the second, or bind method since the Server Manager has been started with a name (see “Obtaining a Server Manager reference”).
Container topContainer = ContainerHelper.bind(orb,"BigBadBoss");
Getting all the containers and their properties
The following example shows how get_all_properties, get_all_operations, and get_all_containers can be used to query all the properties and operations of all the containers below the current container recursively.
public void displayContainer(NamedContainer cont, boolean top) {

// Get All Containers
NamedContainer[] nc = cont.value.get_all_containers();

// Get All Properties for the current container
Property[] props=cont.value.get_all_properties();

// Get All Operations for the current container
Operation[] ops=cont.value.get_all_operations();

....
// Now print all properties and operations and recurse
// through all containers

}
Getting and setting properties and saving them into the file
The following code fragment shows how to query a property of a container. If the container is not the top-level container, it needs to be reached first by traversing through all its parents from the top container. The get and set methods can be called only on the container which owns the property.
Note
Properties with RW_STATUS values of READONLY_ALL are not settable.
public void getSetProperties(NamedContainer topCont) throws Exception {

// Obtain the ORB container from top level container.
Container orbCont=topCont.value.get_container("ORB").value;

// Obtain the "iiop_tp" SCM container. This container is
// contained as follows:
// topCont->ORB->ServerEngines->iiop_tp->iiop_tp (the first
// iiop_tp is the ServerEngine name)'

Container iiopCont=orbCont.get_container(
"ServerEngines").value.get_container(
"iiop_tp").value.get_container(
"iiop_tp").value;

// Obtain the "bank_agent_poa" container. This container is
// contained as follows:
// topCont->ORB->RootPOA->Children->bank_agent_poa
Container poaCont=orbCont.get_container(
"RootPOA").value.get_container(
"Children").value.get_container(
"bank_agent_poa").value;

// get the process Id property from ORB container
Property procIdProp=orbCont.get_property("vbroker.orb.procId");

// get the listener port property from iiop_tp container
Property portProp=iiopCont.get_property(
"vbroker.se.iiop_tp.scm.iiop_tp.listener.port");

// get the upTime property from bank_agent_poa container
Property upTimeProp=poaCont.get_property("upTime");
...
// let the user modify listener port value
org.omg.CORBA.Any portAny=orb.create_any();
portAny.insert_long(newPort);
iiopCont.set_property(
"vbroker.se.iiop_tp.scm.iiop_tp.listener.port",portAny);
...
// save the updated property to file

iiopCont.persist_properties(true);
}
Invoking an operation in a Container
The ORB container supports the operation shutdown. The operation can be obtained by calling get_operation on the container.
public void invokeShutdown(NamedContainer topCont) throws Exception {

Container orbCont=topCont.value.get_container("ORB").value;

System.out.println("Executing ShutDown ...");

// Prepare parameter (boolean wait_for_completion)
org.omg.CORBA.Any any=orb.create_any();
any.insert_boolean(false);
Parameter[] params=new Parameter[1];

// Prepare result (void)
params[0]=new Parameter("waitForCompletion",any);
org.omg.CORBA.TypeCode result=orb.get_primitive_tc(
org.omg.CORBA.TCKind.tk_void);

// Prepare operation
Operation op=new Operation("shutdown",params, result);

// Invoke operation
orbCont.do_operation(op);
}
The operation returned by the get_operation call has the default parameters. If the default values of the parameters are not the intended ones, these values should be modified before calling the do_operation method.
Custom Containers
It is possible for a user application to define containers and add them to the Server Manager. The container manages two properties and defines one operation. It also uses its own storage for storing the properties. The two properties are:
This property has a read-write status of READWRITE_ALL, so it can be modified and takes effect while the server is running. The purpose of this property is to make AccountManager unavailable for client applications. The initial value of this property is read by the server on startup and saved to the same file when server shuts down/restarts.
This property has a read-write status of READONLY_ALL, so it can only be read. The purpose of this property is to provide the number of Accounts in the AccountManager. The value of this property is not written to the storage.
The operation is:
Shuts down the server without starting it again. Before shutdown, the manager.lockAllAccounts property is written (persisted) to the property file.
For a complete example, go to:
<install_dir>/examples/vbroker/ServerManager/custom_container/
The main steps in writing custom containers is follows:
1
2
3
The server then can be started with the Server Manager enabled and a client can interact with the custom container.
If you want your application to implement its own storage, it has to implement the Storage interface defined in Server Manager IDL. The basic steps are same as implementing custom containers.