VisiBroker for C++ Developer’s Guide : Using the VisiNaming Service

Using the VisiNaming Service
This section describes the usage of the VisiBroker VisiNaming Service which is a complete implementation of the CORBA Naming Service Specification Version 1.2 (formal/02-09-02).
Overview
The VisiNaming Service allows you to associate one or more logical names with an object reference and store those names in a namespace. With the VisiNaming Service, your client applications can obtain an object reference by using the logical name assigned to that object.
The figure below contains a simplified view of the VisiNaming Service that shows how
1
an object implementation can bind a name to one of its objects within a namespace.
2
client applications can then use the same namespace to resolve a name which returns an object reference to a naming context or an object.
Figure 25
There are some important differences to consider between locating an object implementation with the VisiNaming Service and doing so with the Smart Agent.
For more information about the Smart Agent (osagent), see “Using the Smart Agent”.
Understanding the namespace
The figure below shows how the VisiNaming Service might be used to name objects that make up an order entry system. This hypothetical order entry system organizes its namespace by geographic region, then by department, and so on. The VisiNaming Service allows you to organize the namespace in a hierarchical structure of NamingContext objects that can be traversed to locate a particular name. For example, the logical name NorthAmerica/ShippingDepartment/Orders could be used to locate an Order object.
Figure 26
Naming contexts
To implement the namespace shown above with the VisiNaming Service, each of the shadowed boxes in the diagram above, would be implemented by a NamingContext object. A NamingContext object contains a list of Name structures that have been bound to object implementations or to other NamingContext objects. Though a logical name may be bound to a NamingContext, it is important to realize that a NamingContext does not, by default, have a logical name associated with it nor is such a name required.
Object implementations use a NamingContext object to bind a name to an object that they offer. Client applications use a NamingContext to resolve a bound name to an object reference.
A NamingContextExt interface is also available which provides methods necessary for using stringified names.
Naming context factories
A naming context factory provides the interface for bootstrapping the VisiNaming Service. It has operations for shutting down the VisiNaming Service and creating new contexts when there are none. Factories also have an additional API that returns the root context. The root context provides a very critical role as a reference point. This is the common starting point to store all data that are supposed to be publicly available.
Two classes are provided with the VisiNaming Service that allow you to create a namespace; the default naming context factory and the extended naming context factory. The default naming context factory creates an empty namespace that has no root NamingContext. You may find it more convenient to use the extended naming context factory because it creates a namespace with a root NamingContext.
You must obtain at least one of these NamingContext objects before your object implementations can bind names to their objects and before client applications can resolve a name to an object reference.
Each of the NamingContext objects shown in the figure above could be implemented within a single name service process, or they could be implemented within as many as five distinct name server processes.
Names and NameComponent
A CosNaming::Name represents an identifier that can be bound to an object implementation or a CosNaming::NamingContext. A Name is not simply a string of alphanumeric characters; it is a sequence of one or more NameComponent structures.
Each NameComponent contains two attribute strings, id and kind. The Naming service does not interpret or manage these strings, except to ensure that each id and kind is unique within a given NamingContext.
The id and kind attributes are strings which uniquely identify the object to which the name is bound. The kind member adds a descriptive quality to the name. For example, the name "Inventory.RDBMS" has an id member of "Inventory" and a kind member of "RDBMS."
module CosNaming
typedef string Istring;
struct NameComponent {
Istring id;
Istring kind;
};
typedef sequence<NameComponent> Name;
};
The id and kind attributes of NameComponent in the code example above, must be a character from the ISO 8859-1 (Latin-1) character set, excluding the null character (0x00) and other non-printable characters. Neither of the strings in NameComponent can exceed 255 characters. Furthermore, the VisiNaming Service does not support NameComponent which uses wide strings.
Note
The id attribute of a Name cannot be an empty string, but the kind attribute can be an empty string.
Name resolution
Your client applications use the NamingContext method resolve to obtain an object reference, given a logical Name. Because a Name consists of one or more NameComponent objects, the resolution process requires that all of the NameComponent structures that make up the Name be traversed.
Stringified names
Because the representation of CosNaming::Name is not in a form that is readable or convenient for exchange, a stringified name has been defined to resolve this problem. A stringified name is a one-to-one mapping between a string and a CosNaming::Name. If two CosNaming::Name objects are equal, then their stringified representations are equal and vice versa. In a stringified name, a forward slash (/) serves as a name component separator; a period (.) serves as the id and kind attributes separator; and a backslash (\) serves as an escape character. By convention a NameComponent with an empty kind attribute does not use a period (for example, Order).
"MF.Company/Engineering.Department/Printer.Resource"
Note
In the following examples, NameComponent structures are given in their stringified representations.
Simple and complex names
A simple name, such as Billing, has only a single NameComponent and is always resolved relative to the target naming context. A simple name may be bound to an object implementation or to a NamingContext.
A complex name, such as NorthAmerica/ShippingDepartment/Inventory, consists of a sequence of three NameComponent structures. If a complex name consisting of n NameComponent objects has been bound to an object implementation, then the first (n-1) NameComponent objects in the sequence must each resolve to a NamingContext, and the last NameComponent object must resolve to an object implementation.
If a Name is bound to a NamingContext, each NameComponent structure in the sequence must refer to a NamingContext.
The code sample below shows a complex name, consisting of three components and bound to a CORBA object. This name corresponds to the stringified name, NorthAmerica/SalesDepartment/Order. When resolved within the topmost naming context, the first two components of this complex name resolve to NamingContext objects, while the last component resolves to an object implementation with the logical name "Order."
. . .
// Name stringifies to "NorthAmerica/SalesDepartment/Order"
CosNaming::Name_var continentName =
     rootNamingContext->to_name("NorthAmerica");
CosNaming::NamingContext_var continentContext =
rootNamingContext->bind_new_context(continentName);
CosNaming::Name_var departmentName =
      continentContext->to_name("SalesDepartment");
CosNaming::NamingContext_var departmentContext =
rootNamingContext->bind_new_context(departmentName);
CosNaming::Name_var objectName =
     departmentContext->to_name("Order");
      departmentContext->rebind(objectName,
            myPOA->servant_to_reference(managerServant));
. . .
Running the VisiNaming Service
The VisiNaming Service can be started with the following commands. Once you have started the Naming service, you may browse its contents by using the VisiBroker Console.
Installing the VisiNaming Service
The VisiNaming Service is installed automatically when you install VisiBroker. It consists of a file nameserv, which for Windows is a binary executable and for UNIX is a script, and Java class files which are stored in the vbjorb.jar file.
Configuring the VisiNaming Service
In previous versions of VisiBroker, the VisiNaming Service maintained persistence by logging any modifying operations to a flat-file. From version 4.0 onward, the VisiNaming Service works in conjunction with backing store adapters. It is important to note that not all backing store adapters support persistence. The default InMemory adapter is non-persistent while all the other adapters are. For more details about adapters, see “Pluggable backing store”.
Note
A Naming Server is designed to register itself with the Smart Agent. In most cases you should to run the Smart Agent to bootstrap the VisiNaming Service. This allows clients to retrieve the initial root context by calling the resolve_initial_references method. The resolving function works through the Smart Agent for the retrieval of the required references. Similarly, Naming Servers that participate in a federation also uses the same mechanism for setting up a federation.
For more information about the Smart Agent, go to , “Using the Smart Agent.”
Starting the VisiNaming Service
You can start the VisiNaming Service by using the nameserv launcher program in the /bin directory. The nameserv launcher uses the com.inprise.vbroker.naming.ExtFactory factory class by default.
UNIX
nameserv [driver_options] [nameserv_options] <ns_name> &
Windows
start nameserv [driver_options] [nameserv_options] <ns_name>
See “Programmer tools for C++” for descriptions of the driver options available to all of the VisiBroker programmer tools.
-?, -h, -help, -usage
Use <properties_file> as the configuration file when starting up the VisiNaming Service.
In order to force the VisiNaming Service to start on a particular port, the VisiNaming Service must be started with the following command line option:
prompt> nameserv -J-Dvbroker.se.iiop_tp.scm.iiop_tp.listener.port=
        <port number>
The default name for VisiNaming is "NameService", if you want to specify a name other than this, you can start VisiNaming in the following way:
prompt> nameserv -J-Dvbroker.se.iiop_tp.scm.iiop_tp.listener.port=
         <port number> <ns_name>
Invoking the VisiNaming Service from the command line
The VisiNaming Service Utility (nsutil) provides the ability to store and retrieve bindings from the command line.
Configuring nsutil
To use nsutil, first configure the Naming service instance using the following commands:
prompt>nameserv <ns_name>
prompt>nsutil -VBJprop <option> <cmd> [args]
Note: Before using SVCnameroot, you must first run OSAgent.
File name or URL, prefixed by its type, which may be (corbaloc:, corbaname:, file:, ftp:, http:, or ior:). For example, to assign a file in a local directory, the ns_config string would be:-VBJprop ORBInitRef=NameService=<file:ns.ior>
Running nsutil
The VisiNaming Service Utility supports all the CosNaming operations as well as two additional commands. The CosNaming operations supported are:
The additional nsutil commands are:
Resolves the stringified name and contacts the object to see if it is still alive.
Shuts the VisiNaming Service down gracefully from the command line. The ns_name is the name specified when the VisiNaming Service was started.
Note: The initial context need not have been set for this command to be invoked.
To run an operation from the nsutil command, place the operation name and its parameters as the <cmd> parameter. For example:
prompt>nsutil -VBJprop ORBInitRef=NameService=file://ns.ior resolve myName
Shutting down the VisiNaming Service using nsutil
To shut down the VisiNaming Service using nsutil, use the shutdown command:
prompt>nsutil -VBJprop ORBInitRef=NameService=file://ns.ior shutdown
           <ns_name>
Bootstrapping the VisiNaming Service
There are three ways to start a client application to obtain an initial object reference to a specified VisiNaming Service. You can use the following command-line options when starting the VisiNaming Service:
The following example illustrates how to use these options.
Suppose there are three VisiNaming Services running on the host TestHost:
ns1, ns2, and ns3.
And there are three server applications:
sr1, sr2, sr3,
each running on a different port:
20001, 20002, and 20003
on the host TestHost.
Server sr1 binds itself in ns1,
Server sr2 binds itself in ns2,
and server sr3 in ns3.
Calling resolve_initial_references
The VisiNaming Service provides a simple mechanism by which the resolve_initial_references method can be configured to return a common naming context. You use the resolve_initial_references method which returns the root context of the Naming Server to which the client program connects.
. . .
CORBA::ORB_ptr orb = CORBA::ORB_init(argv, argc, NULL);
CORBA::Object_var rootObj =
          orb->resolve_initial_references("NameService");
. . .
Using -DSVCnameroot
You use the -DSVCnameroot option to specify into which VisiNaming Service instance (especially important if several unrelated Naming service instances are running) you want to bootstrap.
For instance, if you want to bootstrap into ns1, you would start your client program as:
<client_application> -DSVCnameroot=ns1
You can then obtain the root context of ns1 by calling the resolve_initial_references method on an ORB reference inside your client application as illustrated below. The Smart Agent must be running in order to use this option.
Keep in mind that the -DSVCnameroot bootstrapping mechanism is based on the proprietary functionality that VisiBroker Smart Agent provides and it is not interoperable with other CORBA implementations.
Using -ORBInitRef
You can use either the corbaloc or corbaname URL naming schemes to specify which VisiNaming Service you want to bootstrap. This method does not rely on the Smart Agent.
Using a corbaloc URL
If you want to bootstrap using VisiNaming Service ns2, then start your client application as follows:
<client_application> -ORBInitRef=NameService=corbaloc://TestHost:20002/
                    NameService
You can then obtain the root context of ns2 by calling the resolve_initial_references method on the VisiBroker ORB reference inside your client application as illustrated in the example above.
Note
This example will work only if there is a server running at port 20002 that is bound to the VisiNaming Service you want to access.
Note
The deprecated iioploc and iiopname URL schemes are implemented by corbaloc and corbaname, respectively. For backwards compatibility, the old schemes are still supported.
Using a corbaname URL
If you want to bootstrap into ns3 by using corbaname, then you should start your client program as:
<client_application> -ORBInitRef NameService=corbaname://TestHost:20003/
You can then obtain the root context of ns3 by calling the resolve_initial_references method on the VisiBroker ORB reference inside your client application as illustrated above.
-ORBDefaultInitRef
You can use either a corbaloc or corbaname URL to specify which VisiNaming Service you want to bootstrap. This method does not rely on the Smart Agent.
Using -ORBDefaultInitRef with a corbaloc URL
If you want to bootstrap into ns2, then you should start your client program as:
<client_application> -ORBDefaultInitRef corbaloc://TestHost:20002
You can then obtain the root context of ns2 by calling the resolve_initial_references method on the VisiBroker ORB reference inside your client application as illustrated in the sample above.
Using -ORBDefaultInitRef with corbaname
The combination of -ORBDefaultInitRef or -DORBDefaultInitRef and corbaname works differently from what is expected. If -ORBDefaultInitRef or -DORBDefaultInitRef is specified, a slash and the stringified object key is always appended to the corbaname.
For example, if the URL is corbaname::TestHost:20002, then by specifying -ORBDefaultInitRef, resolve_initial_references in C++ will result in a new URL: corbaname::TestHost:20003/NameService.
NamingContext
This object is used to contain and manipulate a list of names that are bound to VisiBroker ORB objects or to other NamingContext objects. Client applications use this interface to resolve or list all of the names within that context. Object implementations use this object to bind names to object implementations or to bind a name to a NamingContext object. The sample below shows the IDL specification for the NamingContext.
Module CosNaming {
interface NamingContext {
void bind(in Name n, in Object obj)
raises(NotFound, CannotProceed, InvalidName, AlreadyBound);
void rebind(in Name n, in Object obj)
raises(NotFound, CannotProceed, InvalidName);
void bind_context(in Name n, in NamingContext nc)
raises(NotFound, CannotProceed, InvalidName, AlreadyBound);
void rebind_context(in Name n, in NamingContext NC)
raises(NotFound, CannotProceed, InvalidName);
Object resolve(in Name n)
raises(NotFound, CannotProceed, InvalidName);
void unbind(in Name n)
raises(NotFound, CannotProceed, InvalidName);
NamingContext new_context();
NamingContext bind_new_context(in Name n)
raises(NotFound, CannotProceed, InvalidName, AlreadyBound);
void destroy()
raises(NotEmpty);
void list(in unsigned long how_many,
out BindingList bl,
out BindingIterator bi);
};
};
NamingContextExt
The NamingContextExt interface, which extends NamingContext, provides the operations required to use stringified names and URLs.
Module CosNaming {
interface NamingContextExt : NamingContext {
typedef string StringName;
typedef string Address;
typedef string URLString;
StringName to_string(in Name n)
raises(InvalidName);
Name to_name(in StringName sn)
raises(InvalidName);
exception InvalidAddress {};
URLString to_url(in Address addr, in StringName sn)
raises(InvalidAddress, InvalidName);
Object resolve_str(in StringName n)
raises(NotFound, CannotProceed, InvalidName);
};
};
Default naming contexts
A client application can specify a default naming context, which is the naming context that the application will consider to be its root context. Note that the default naming context is the root only in relation to this client application and, in fact, it can be contained by another context.
Obtaining the default context
The VisiBroker ORB method resolve_initial_references can be used by a client application to obtain the default naming context. The default naming context must have been specified by passing the SVCnameroot or ORBInitRef command-line argument when the client application was started. The sample below shows how a C++ client application could invoke this method.
#include "CosNaming_c.hh"
. . .
int main(int argc, char* const* argv) {
try {
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
. . .
CORBA::Object_var ref = orb->resolve_initial_references("NameService");
CosNaming::NamingContext_var rootContext =
CosNaming::NamingContext::_narrow(ref);
. . .
} catch(const CORBA::Exception& e) {
cout << "Failure: " << e << endl;
exit(1);
}
exit(0);
}
VisiNaming Service properties
The following tables list the VisiNaming Service properties:
vbroker.naming.
enableSlave
If 1, enables master/slave naming services configuration. See “VisiNaming Service Clusters for Failover and Load Balancing” for information about configuring master/slave naming services.
This property specifies the full path name for storing the Naming Service IOR. If you do not set this property, the Naming Service will try to output its IOR into a file named ns.ior in the current directory. The Naming Service silently ignores file access permission exceptions when it tries to output its IOR.
This property allows special logging for all of the update operations on the CosNaming::NamingContext, CosNamingExt::Cluster, and CosNamingExt::ClusterManager interfaces.
The CosNaming::NamingContext interface operations for which this property is effective are:
bind, bind_context, bind_new_context, destroy, rebind, rebind_context, unbind.
The CosNamingExt::Cluster interface operations for which this property is effective are:
bind, rebind, unbind, destroy.
The CosNamingExt::ClusterManager interface operation for which this property is effective is:
create_cluster
When this property value is set to true and any of the above methods is invoked, the following log message is printed (the output shows a bind operation being executed):
For more information see “Object Clusters”.
vbroker.naming.
enableClusterFailover
When set to true, it specifies that an interceptor be installed to handle fail-over for objects that were retrieved from the VisiNaming Service. In case of an object failure, an attempt is made to transparently reconnect to another object from the same cluster as the original.
If 1, the implicit clustering feature is turned on.
This property is relevant when the name service cluster uses the Smart Round Robin criterion. When this property is set to 1, a stale object reference that was previously bound to a cluster with the Smart Round Robin criterion will be removed from the bindings when the name service discovers it. If this property is set to 0, stale object reference bindings under the cluster are not eliminated. However, a cluster with Smart Round Robin criterion will always return an active object reference upon a resolve() or select() call if such an object binding exists, regardless of the value of the vbroker.naming.smrr.pruneStaleRef property. By default, the implicit clustering in the name service uses the Smart Round Robin criterion with the property set to 1.
For more information see “VisiNaming Service Clusters for Failover and Load Balancing”.
This property is used to configure VisiNaming Service instances in the cluster mode or in the master/slave mode. The vbroker.naming.enableSlave property must be set to 1 for this property to take effect.
Set this property to cluster to configure VisiNaming Service instances in the cluster mode. VisiNaming Service clients will then be load balanced among the VisiNaming Service instances that comprise the cluster. Client failover across these instances are enabled.
Set this property to slave to configure VisiNaming Service instances in the master/slave mode. VisiNaming Service clients will always be bound to the master server if the master is running but failover to the slave server when the master server is down.
vbroker.naming.
serverClusterName
See the related property vbroker.naming.serverAddresses.
vbroker.naming.
serverAddresses
This property specifies the host and listening port for the VisiNaming Service instances that comprise a VisiNaming Service cluster. The order of VisiNaming Service instances in this list must be identical to that of the related property vbroker.naming.serverNames, which specifies the names of the VisiNaming Service instances that comprise a VisiNaming Service Cluster. This property supports the format:
vbroker.naming.
anyServiceOrder
This property must be set to true on the VisiNaming Service client to utilize the load balancing and failover features available when VisiNaming Service instances are configured in the VisiNaming Service cluster mode. The following is an example of how to use this property:
Pluggable backing store
The VisiNaming Service maintains its namespace by using a pluggable backing store. Whether or not the namespace is persistent depends on how you configure the backing store: to use JDBC adapter, the Java Naming and Directory Interface (JNDI, which is certified for LDAP), or the default, in-memory adapter.
Types of backing stores
The types of backing store adapters supported are:
Note
For an example using pluggable adapters, see the code located in the directory:
<install dir>/vbe/examples/ins/pluggable_adaptors
In-memory adapter
The in-memory adapter keeps the namespace information in memory and is not persistent. This is the adapter used by the VisiNaming Service by default.
JDBC adapter
Relational databases are supported via JDBC. The following databases have been certified to work with the VisiNaming Service JDBC adapter:
Multiple VisiNaming Service instances can use the same back-end relational database if one of these is true:
DataExpress adapter
In addition to the JDBC adapter, there is also a DataExpress adapter which allows you to access JDataStore databases natively. It is much faster than accessing JDataStore through JDBC, but the DataExpress adapter has some limitations. It only supports a local database running on the same machine as the Naming Server. To access a remote JDataStore database, you must use the JDBC adapter.
JNDI adapter
A JNDI adapter is also supported. Sun's JNDI (Java Naming and Directory Interface) provides a standard interface to multiple naming and directory services throughout the enterprise. JNDI has a Service Provider Interface (SPI) with which different naming and service vendors must conform. There are different SPI modules available for Netscape LDAP server, Novell NDS, WebLogic Tengah, etc. By supporting JNDI, the VisiNaming Service allows you to have portable access to these naming and directory services and other future SPI providers.
The VisiNaming JNDI adapter is certified with the following LDAP implementations:
You must use Sun and Netscape JNDI Driver version 1.2 to leverage LDAP.
Configuration and use
Backing store adapters are pluggable, which means that the type of adapter used can be specified by user-defined information stored in a configuration (properties) file used when starting up the VisiNaming Service. All adapters, except the in-memory one, provide persistence. The in-memory adapter should be used when you want to use a lightweight VisiNaming Service which keeps its namespace entirely in memory.
Note
For the current version of the VisiNaming Service, you cannot change settings while the VisiNaming Service is running. To change a setting, you must bring down the service, make the change to the configuration file, and then restart the VisiNaming Service.
Properties file
As with the VisiNaming Service in general, which adapter is to be used and any specific configuration of it is handled in VisiNaming Service properties file. The default properties common to all adapters are:
vbroker.naming.
backingStoreType
This property is required when the Naming Service cache is enabled (vbroker.naming.cacheOn=1) and the Naming Service instances are configured in Cluster or Master/Slave mode. It helps locate an Event Service/VisiNotify instance in the format <hostname>:<port>. For example:
See “Caching facility” for details about enabling the caching facility and setting the appropriate properties.
0 (no limit)
JDBC Adapter properties
The following sections describe the JDBC Adapter properties.
vbroker.naming.backingStoreType
This property should be set to JDBC. The poolSize , jdbcDriver, url, loginName, and loginPwd properties must also be set for the JDBC adapter.
vbroker.naming.jdbcDriver
This property specifies the JDBC driver that is needed to access the database used as your backing store. The VisiNaming Service loads the appropriate JDBC driver specified. The default is the Java DataStore JDBC driver.
vbroker.naming.minReconInterval
This property sets the database reconnection retry time by the Naming Service in seconds. The default value is 30. The Naming Service will ignore the request and throw a CannotProceed exception if the time interval between this request and the last reconnection time is less than the value set by this property. The valid value for this property is 0 (zero) or a greater integer. If the property value is 0 (zero), the VisiNaming Service will try to reconnect to the database for every request, once disconnected.
vbroker.naming.loginName
This property is the login name associated with the database. The default is VisiNaming.
vbroker.naming.loginPwd
This property is the login password associated with the database. The default value is VisiNaming.
vbroker.naming.poolSize
This property specifies the number of database connections in your connection pool when using the JDBC Adapter as our backing store. The default value is 5, but it can be increased to whatever value the database can handle. If you expect many requests will be made to the VisiNaming Service, you should make this value larger.
vbroker.naming.url
This property specifies the location of the database which you want to access. The setting is dependent on the database in use. The default is JDataStore and the database location is the current directory and is called rootDB.jds. You can use any name you like not necessarily rootDB.jds. The configuration file needs to be updated accordingly.
1You should start InterServer before accessing InterBase via JDBC. If the InterBase server resides on the local host, specify <server> as localhost; otherwise specify it as the host name. If the InterBase database resides on Windows, specify the <full_db_path> as driver:\\dir1\dir2\\db.gdb (the first backslash [\] is to escape the second backslash [\]). If the InterBase database resides on UNIX, specify the <full_db_path> as \dir1\dir2\db.gdb.
2Before you access DB2 via JDBC, you must register the database by its alias <db_name> using the Client Configuration Assistant. After the database has been registered, you do not have to specify <host> and <port> for the vbroker.naming.url property.
3 If the JDataStore database resides on Windows, the <full path of the JDataStore database> should be Driver:\\dir1\\dir2\\db.jds (the first backslash [\] is to escape the second backslash [\]). If the JDataStore database resides on UNIX, the <full path of the JDataStore database> should be /dir1/dir2/db.jds.
DataExpress Adapter properties
The following table describes the DataExpress Adapter properties:
JNDI adapter properties
The following is an example of settings that can appear in the configuration file for a JNDI adapter:
vbroker.naming.jndiInitialFactory=
com.sun.jndi.ldap.LdapCtxFactory
vbroker.naming.jndiProviderURL=
ldap://<hostname>:389/<initial root
context>
Configuration for OpenLDAP
OpenLDAP is one of the supported VisiNaming back-end stores. When using OpenLDAP, additional configuration is required on the OpenLDAP server. You must perform the following actions:
1
Add corba.schema in the OpenLDAP server's config file (the default is slapd.conf). The corba.schema is included with your OpenLDAP server installation.
2
Add openldap_ns.schema in the OpenLDAP config file. openldap_ns.schema is provided with VisiBroker and is located in
<install-dir>/etc/ns_schema/
Note
The user must have the necessary privilege to add schemas/attributes to the Directory Server.
Caching facility
By enabling the caching facility you can improve the performance of the Naming Service when it uses a backing store. For example, in the case of the JDBC adapter, directly accessing the database every time there is a resolve or bind operation is relatively slow. If you cache the results, you can reduce the number of times you access the database. You will only see improvement in the performance of the backing store if the same piece of data is accessed multiple times.
Note
Multiple Naming Service instances can access the same backing store if they are configured in the Naming Service Cluster mode or in the Master/Slave mode. In order to use the caching facility in these two modes, each Naming Service instance must be specially configured using the vbroker.naming.cache.connectString property. The VisiBroker Event Service or VisiNotify is used to coordinate the caching facility amongst the various Naming Service instances.
To enable the caching facility set the following property in your configuration file:
vbroker.naming.cacheOn=1
If multiple Naming Service instances in Cluster or Master/Slave mode will access the cache, set the vbroker.naming.cache.connectString property so that the Naming Services can locate the Event Service (or VisiNotify).
The format for vbroker.naming.cache.connectString is:
vbroker.naming.cache.connectString=<host>:<port>
Where <host> is the hostname or IP address of the machine where VisiBroker Event Service is running and <port> is the port used by VisiBroker Event Service/VisiNotify (default is 14500 for Event Service and 14100 for VisiNotify).
For example:
vbroker.naming.cache.connectString=127.0.0.1:14500
or
vbroker.naming.cache.connectString=myhost:14100
If the host address is an IPv6 style address then enclose it in square brackets.
Note
The VisiBroker Event Service (version 6.5 or later) should be started before starting the Naming Service instances. If VisiNotify is used instead, VisiNotify should be started. Start the Event Service/VisiNotify without any channel name (so the default name is used) before Naming Service instances are started.
If the cache needs tuning, set the following properties:
vbroker.naming.cache.size
vbroker.naming.cache.timeout
See “Properties file” for more information about the caching facility properties.
Important Notes for users of Caching Facility
Consistent configuration is very important. It is extremely important to configure all Naming Service instances in a Cluster to use the Caching Facility in a consistent manner. Naming Service instances that constitute a Cluster must either all use the caching facility or none use it. If certain Naming Service instances use the caching facility while others do not, the behaviour of the Cluster will be inconsistent. This is also true for Naming Services configured in the Master-Slave mode. If the Master is configured to use the caching facility, it is required that the Slave also be configured to use it, and vice versa.
The distributed cache depends on the Event Service/VisiNotify. If the Caching Facility is used in Naming Service Cluster mode (or the Master-Slave mode), the distributed cache needs synchronization across the multiple Naming Services instances. This is achieved using the Event Service (or VisiNotify). Please note that in such a configuration, the cached data might be stale. The quality of data would depend on the health of the Event Service/VisiNotify. Applications that do not find this acceptable are advised to avoid using the Caching Facility. It is advisable to perform tests to gauge the suitability of the distributed Caching Facility for a particular application.
Object Clusters
VisiBroker supports a clustering feature which allows a number of object bindings to be associated with a single name. The VisiNaming Service can then perform load balancing among the different bindings in a cluster. You can decide on a load balancing criterion at the time a cluster is created. Clients, which subsequently resolve name-object bindings against a cluster, are load balanced amongst different cluster server members. These clusters of object bindings should not be confused with “VisiNaming Service Clusters for Failover and Load Balancing”.
A cluster is a multi-bind mechanism that associates a Name with a group of object references. The creation of a cluster is done through a ClusterManager reference. At creation time, the create_cluster method for the ClusterManager takes in a string parameter which specifies the criterion to be used. This method returns a reference to a cluster, which you can add, remove, and iterate through its members. After deciding on the composition of a cluster, you can bind its reference with a particular name to any context in a VisiNaming Service. By doing so, subsequent resolve operations against the Name will return a particular object reference in this cluster.
Object Clustering criteria
The VisiNaming Service uses a SmartRoundRobin criterion with clusters by default. After a cluster has been created, its criterion cannot be changed. User-defined criteria are not supported, but the list of supported criteria will grow as time goes on. SmartRoundRobin performs some verifications to ensure that the CORBA object reference is an active one; that the object reference is referring to a CORBA server which is in a ready state.
Cluster and ClusterManager interfaces
Although a cluster is very similar to a naming context, there are certain methods found in a context that are not relevant to a cluster. For example, it would not make sense to bind a naming context to a cluster, because a cluster should contain a set of object references, not naming contexts. However, a cluster interface shares many of the same methods with the NamingContext interface, such as bind, rebind, resolve, unbind and list. This common set of operations mainly pertains to operations on a group. The only cluster-specific operation is pick. Another crucial difference between the two is that a cluster does not support compound names. It can only use a single component name, because clusters do not have a hierarchical directory structure, rather it stores its object references in a flat structure.
IDL Specification for the Cluster interface
CosNamingExt module {
typedef sequence<Cluster> ClusterList;
enum ClusterNotFoundReason {
missing_node,
not_context,
not_cluster_context
};
exception ClusterNotFound {
ClusterNotFoundReason why;
CosNaming::Name rest_of_name;
};
exception Empty {};

interface Cluster {
Object select() raises(Empty);
void bind(in CosNaming::NameComponent n, in Object obj)
raises(CosNaming::NamingContext::CannotProceed,
CosNaming::NamingContext::InvalidName,
CosNaming::NamingContext::AlreadyBound);
void rebind(in CosNaming::NameComponent n, in Object obj)
raises(CosNaming::NamingContext::CannotProceed,
CosNaming::NamingContext::InvalidName);
Object resolve(in CosNaming::NameComponent n)
raises(CosNaming::NamingContext::NotFound,
CosNaming::NamingContext::CannotProceed,
CosNaming::NamingContext::InvalidName);
void unbind(in CosNaming::NameComponent n)
raises(CosNaming::NamingContext::NotFound,
CosNaming::NamingContext::CannotProceed,
CosNaming::NamingContext::InvalidName);
void destroy()
raises(CosNaming::NamingContext::NotEmpty);
void list(in unsigned long how_many,
out CosNaming::BindingList bl,
out CosNaming::BindingIterator BI);
};
IDL Specification for the ClusterManager interface
CosNamingExt module {
interface ClusterManager
Cluster create_cluster(in string algo);
Cluster find_cluster(in CosNaming::NamingContext ctx,
         in CosNaming::Name n)
raises(ClusterNotFound, CosNaming::NamingContext::CannotProceed,
CosNaming::NamingContext::InvalidName);
Cluster find_cluster_str(in CosNaming::NamingContext ctx, in string n)
raises(ClusterNotFound, CosNaming::NamingContext::CannotProceed,
CosNaming::NamingContext::InvalidName);
ClusterList clusters();
};
};
Creating an object cluster
To create a cluster, use the Cluster Manager interface. A single ClusterManager object is automatically created when a Naming Server starts up. There is only one ClusterManager per Naming Server. The role of a ClusterManager is to create, retrieve, and keep track of the clusters that are in the Naming Server. Here are the general steps in creating an object cluster:
1
2
Get a reference to the Cluster Manager by calling get_cluster_manager method on the factory reference.
3
4
5
Bind the Cluster object itself to a Name.
6
. . .
ExtendedNamingContextFactory_var myFactory =
ExtendedNamingContextFactory::_bind(orb, "NamingService");
ClusterManager_var clusterMgr = myFactory->get_cluster_manager();
Cluster_var clusterObj = clusterMgr->create_cluster("RoundRobin");
clusterObj->bind(new NameComponent("member1", "aCluster"), obj1);
clusterObj->bind(new NameComponent("member2", "aCluster"), obj2);
clusterObj->bind(new NameComponent("member3", "aCluster"), obj3);
NameComponent_var myClusterName = new NameComponent("ClusterName", "");
root->bind(myClusterName, clusterObj);
root->resolve(myClusterName); // a member of the Cluster is returned
root->resolve(myClusterName); // the next member of the Cluster is returned
root->resolve(myClusterName); // the last member of the Cluster is returned
. . .
Explicit and implicit object clusters
The clustering feature can be turned on automatically for a VisiNaming Service. The caveat is that once this facility is on, a cluster is created transparently to bind the object. The round robin criterion is used. The implication is that it is possible to bind several objects to the same name in the Naming Server. Conversely, resolving that name will return one of those objects, and an unbind operation would destroy the cluster associated with that name. This means that the VisiNaming Service is no longer compliant to the CORBA specification. The Interoperable Naming Specification explicitly forbids the ability to bind several objects to the same name. For a compliant VisiNaming Service, an AlreadyBound exception is thrown if a client tries to use the same name to bind to a different object. You must decide whether to use this feature for a dedicated server only.
Note
Do not switch from an implicit cluster mode to an explicit cluster mode as this can corrupt the backing store.
Once a Naming Server is used with the implicit clustering feature, it must be activated with that feature turned "on". To turn on the clustering feature, define the following property value in the configuration file:
vbroker.naming.propBindOn=1
Note
For an example of both explicit and implicit clustering, see the code located in the following directories:
<install_dir>/examples/vbe/ins/implicit_clustering
<install_dir>/examples/vbe/ins/explicit_clustering
Load balancing
Both the ClusterManager and the Smart Agent provide RoundRobin criterion load balancing facilities, however, they are of very different nature. You get load balancing from the Smart Agent transparently. When a server starts, it registers itself automatically with the Smart Agent, and this in turn allows VisiBroker ORB to provide an easy and proprietary way for the client to get a reference to the server. However, you have no choice in determining what constitutes a group and the members of a group. The Smart Agent makes all the decisions for you. This is where a Cluster provides an alternative. It enables a programmatic way to define and create the properties of a Cluster. You can define the criterion for a Cluster, including choosing the members of a Cluster. Though the criterion is fixed at creation time, the client can add or remove members from the Cluster throughout its existence.
VisiNaming Service Clusters for Failover and Load Balancing
Multiple instances of the VisiNaming Service can be clustered to provide for load balancing and failover. These clusters of VisiNaming Service instances should not be confused with the clustering of object bindings described in “Object Clusters”. Clients can bind to any one of the VisiNaming Service instances that comprise the cluster, which allows for load sharing across multiple VisiNaming Service instances. If a particular VisiNaming Service instance becomes inactive or terminates, the client will automatically fail over to another VisiNaming Service instance within the same cluster.
All instances of the VisiNaming Service within a cluster must use the common underlying data in a persistent backing store. The caching facility is available to Naming Service instances provided that a VisiBroker Event Service (or VisiNotify) instance is made available to the Naming Service instances via the vbroker.naming.cache.connectString property. There are certain restrictions regarding the choice of backing store. See the following Note that discusses these restrictions.
When failover occurs, it is transparent to the client, but there can be a slight delay because server objects might have to be activated on demand by the requests that are coming in. Also, object reference transients like iterator references are no longer valid. This is normal because clients using transient iterator references must be prepared for those references becoming invalid. In general, a VisiNaming Service instance never keeps too many resource-intensive iterator objects, and it may invalidate a client's iterator reference at any time. Other than these transient references, any other client request using persistent references will be rerouted to another VisiNaming Service instance.
In addition to the VisiNaming Service cluster, a Master/Slave model is also supported. This is a special cluster with the configuration of two VisiNaming Service instances. It is useful only when failover is required. The two VisiNaming Services instances must be running at the same time; the master in active mode and the slave in standby mode. If both VisiNaming Services are active, the master is always preferred by clients that are using VisiNaming Service. In the event that the master terminates unexpectedly, the slave VisiNaming Service takes over. This changeover from master to slave is seamless and transparent to clients. However, the slave VisiNaming Service does not become the master server. Instead, it provides temporary backup when the master server is unavailable. You must take whatever remedial actions necessary to revive the master server. After the master comes back up again, only requests from the new clients are sent to the master server. Clients that are already bound to a slave naming server will not automatically switch back to the master.
Note
Clients that are bound to a slave naming server provide only one level of failover support. They will not switch back to the master, therefore, if the slave naming server terminates, the VisiNaming Service also becomes unavailable.
Note
VisiNaming Service Clusters configured in the Master/Slave mode may use either the JNDI adapter or the JDBC adapter. Clusters not configured in the Master/Slave mode must use the JDBC adapter for RDBMS. Each clustered service must obviously point to the same backing store. See “Pluggable backing store” for information on configuring the backing store for the cluster.
Configuring the VisiNaming Service Cluster
The VisiNaming Service instances that comprise the cluster must be started with the relevant properties set as illustrated in the code sample below. The configuration is set to cluster mode using the enableSlave and the slaveMode properties. The instances of the VisiNaming Service that comprise the cluster have to be started on the hosts and ports specified using the serverAddresses property. The snippet shows the host and port entries for the three VisiNaming Service instances in the sample cluster. The serverNames property lists the factory names of the VisiNaming Service instances. These names are unique and the ordering identical to the serverAddresses property. Finally, the serverClusterName property names the cluster.
Note
Starting from VisiBroker 6.0, VisiNaming Service contains several properties for proxy support:
vbroker.naming.proxyEnable allows the VisiNaming Service to use a proxy. Turn off this property (default is turned off), and the VisiNaming Service will ignore other Naming service properties for the proxy.
vbroker.naming.proxyAddresses gives each Naming service in the cluster a proxy host and a proxy port. The ordering of the proxyAddresses is identical to the serverAddresses.
C++ clients need to set the boolean property vbroker.naming.anyServiceOrder in order to benefit from the load-balancing and failover capabilities provided by VisiNaming Service clusters. Clients must use the corbaloc mechanism to resolve to a VisiNaming Service instance within the cluster, provided osagent is being used.
The Naming Service instances comprising a Cluster can benefit from the Naming Service Caching Facility. Use the vbroker.naming.cacheOn and vbroker.naming.cache.connectString properties to configure caching for a Naming Service cluster. See “Caching facility” for details.
The following code sample shows the configuration of the VisiNaming Service cluster:
vbroker.naming.enableSlave=1
vbroker.naming.slaveMode=cluster
vbroker.naming.serverAddresses=host1:port1;host2:port2;host3:port3
vbroker.naming.serverNames=Server1:Server2:Server3
vbroker.naming.serverClusterName=ClusterX
vbroker.naming.proxyEnable=1
//Any value other than 1 means proxy is not enabled.
vbroker.naming.proxyAddresses=proxyHost1:proxyPort1;proxyHost2:proxyPort2;proxyHost3:proxyPort3
Note
When using the vbroker.naming.proxyAddresses property, place a semicolon (;) separator between each host and port pair.
Configuring the VisiNaming Service in Master/Slave mode
The two VisiNaming Services must be running. You must designate one as the master and the other as the slave. The same property file can be used for both the servers. The relevant property values in the property file are shown in the following code sample to configure for the Master/Slave mode.
vbroker.naming.enableSlave=1
vbroker.naming.slaveMode=slave
vbroker.naming.masterServer=<Master Naming Server Name>
vbroker.naming.masterHost=<host ip address for Master>
vbroker.naming.masterPort=<port number that Master is listening on>
vbroker.naming.slaveServer=<Slave Naming Server Name>
vbroker.naming.slaveHost=<host ip address for Slave>
vbroker.naming.slavePort=<Slave Naming Server port address>
vbroker.naming.proxyEnable=1
vbroker.naming.masterProxyHost=<proxy host ip address for Master>
vbroker.naming.masterProxyPort=<proxy port number for Master>
vbroker.naming.slaveProxyHost=<proxy host ip address for Slave>
vbroker.naming.slaveProxyPort=<proxy port number for slave>
Note
There is no restriction in the start sequence of the master and the slave servers.
Starting up with a large number of connecting clients
In a production environment with a large number of clients it may be impossible to avoid clients trying to connect to a Naming Service which is still in the startup phase (still initializing and not yet ready to service requests). When a Naming Service is not yet completely started up it may receive incoming requests and discard them. Depending on the number of requests, which must be received then discarded, this activity can use too many CPU resources which can disturb the startup process itself, resulting in a long startup time for the Naming Service.
To solve this particular problem, and let the Naming Service start quickly, the following configuration settings can be used:
1
vbroker.se.iiop_tp.scm.iiop_tp.listener.deferAccept=true
2
vbroker.se.iiop_tp.scm.iiop_tp.listener.port=<port_number>
vbroker.se.iiop_tp.scm.iiop_tp.listener.portRange=0
For this to succeed, make sure that the <port_number> is available on the host on which the Naming Service is running. Make sure that the portRange property is set to 0 (zero). You can leave it at its default setting or explicitly set the property. Note that both the port and portRange settings described above should be applied.
Clients that try to connect to a Naming Service configured in this manner while it is starting up will be denied any connection. If they are accessing a Naming Service Cluster, then they would fail over to another Naming Service that has finished its initialization. If no Naming Services are up and running, the client application would get an OBJECT_NOT_EXIST exception.
These settings are per SCM (Server Connection Manager). If needed, all SCMs can be set to take advantage of this feature.
If SSL is involved in the Naming Service, in addition to the settings described above, the following settings might also be needed:
vbroker.se.iiop_tp.scm.ssl.listener.deferAccept=true
vbroker.se.iiop_tp.scm.ssl.listener.port=<port_number_for_ssl>
vbroker.se.iiop_tp.scm.ssl.listener.portRange=0
Note
The deferAccept property should only be used for Naming Services. Using for other services or user written servers can result in undefined behavior.
VisiNaming Service Security
The VisiNaming Service in the VisiBroker integrates with the Security Service, providing two levels of security: Client authentication and Method level authorization. This allows fine grained control over which clients can use the VisiNaming Service and what methods they can call. The following properties are used to enable or disable security and to configure the Security Service.
ServerQoPPolicy.SECURE_ONLY=1
ServerQoPPolicy.CLEAR_ONLY=0
ServerQoPPolicy.ALL=3
vbroker.naming.security.
requireAuthentication
Indicates whether naming client authentication is required. When vbroker.naming.security.disable is true, no client authentication will be performed regardless what value this property takes.
vbroker.naming.security.
enableAuthorization
vbroker.naming.security.
requiredRolesFile
Naming client authentication
Note
For detailed information on authentication and authorization, see “Using the VisiNaming Service” and “Using the VisiNaming Service”.
Configuring VisiNaming to use SSL
Depending on the security requirements, different properties can be set to configure the VisiNaming service. For the full list of security properties and their descriptions, go to the VisiBroker Security Guide, “Security Properties for Java” or “Security Properties for C++.”
Important
In order to enable security in the VisiNaming Service, you must have a valid VisiSecure license.
The following is a sample of the properties that can be used to configure the VisiNaming Service to use SSL:
# Enable Security in Naming Service
vbroker.naming.security.disable=false

# Enabling Security Service
vbroker.security.disable=false

# Setting SSL Layer Attributes
vbroker.security.peerAuthenticationMode=REQUIRE_AND_TRUST
vbroker.se.iiop_tp.scm.ssl.listener.trustInClient=true
vbroker.security.trustpointsRepository=Directory:./trustpoints

# Set the certificate identity for the VisiNaming Service using wallet properties
vbroker.security.wallet.type=Directory:./identities
vbroker.security.wallet.identity=delta
vbroker.security.wallet.password=Delt@$$$
For information about how to configure the client to use SSL, go to “Using the VisiNaming Service” or “Using the VisiNaming Service”.
Note
Currently, there is no way to specify security and secure transport components in an IOR using corbaloc. So, when using SSL, bootstrapping a VisiNaming Service using the corbaloc method at the Naming client side is not possible. However, the SVCnameroot and stringified IOR methods can still be used.
Method Level Authorization
Method level authorization is supported for the following object types:
When security is enabled for the Naming service and enableAuthorization is set to true, only authorized users of each method of these object types can invoke the corresponding method.
The Naming service predefines two roles to support the method level authorization:
Other roles can be defined if required. Users need to configure the roles map for these two roles, assigning roles to clients. The following is an example role map definition:
Administrator {
*CN=admin
*group=admin
uid=*, group=admin
}

User {
*CN=admin
*group=user
uid=*, group=user
}
You need to specify the roles before invoking each method of the objects listed above. This is done using the required_roles property for each method. Below is the list of these properties and the corresponding default values. These default values are used only when you do not define any required_roles specified using the property vbroker.naming.security.requiredRolesFile. The values of these properties are space or comma separated:
#
# naming_required_roles.properties
#

# all roles
required_roles.all=Administrator User

required_roles.Context.bind=Administrator
required_roles.Context.rebind=Administrator
required_roles.Context.bind_context=Administrator
required_roles.Context.rebind_context=Administrator
required_roles.Context.resolve=Administrator User
required_roles.Context.unbind=Administrator
required_roles.Context.new_context=Administrator User
required_roles.Context.bind_new_context=Administrator User
required_roles.Context.list=Administrator User
required_roles.Context.destroy=Administrator

required_roles.ContextFactory.root_context=Administrator User
required_roles.ContextFactory.create_context=Administrator
required_roles.ContextFactory.get_cluster_manager=Administrator User
required_roles.ContextFactory.remove_stale_contexts=Administrator
required_roles.ContextFactory.list_all_roots=Administrator
required_roles.ContextFactory.shutdown=Administrator

required_roles.Cluster.select=Administrator User
required_roles.Cluster.bind=Administrator
required_roles.Cluster.rebind=Administrator
required_roles.Cluster.resolve=Administrator User
required_roles.Cluster.unbind=Administrator
required_roles.Cluster.destroy=Administrator
required_roles.Cluster.list=Administrator User

required_roles.ClusterManager.create_cluster=Administrator
required_roles.ClusterManager.find_cluster=Administrator User
required_roles.ClusterManager.find_cluster_str=Administrator User
required_roles.ClusterManager.clusters=Administrator User
Compiling and linking programs
C++ applications that use the Naming service need to include the following generated files:
#include "CosNaming_c.hh"
#include "CosNamingExt_c.hh"
UNIX
The UNIX applications need to be linked with the cosnm_r.so (multi-threaded) library.
Windows
The Windows applications need to be linked with the cosnm_r.lib (cosnm_r_6.dll) (multi-threaded) library.
Sample programs
Several example programs that illustrate the use of the VisiNaming Service are provided with VisiBroker Edition. They show all of the new features available with the VisiNaming Service and are found in the <install_dir>/examples/vbe/ins directory. In addition, a Bank Naming example illustrates basic usage of the VisiNaming Service is found in the <install_dir>/examples/vbe/basic/bank_naming directory.
Before running the example programs, you must first start the VisiNaming Service, as described in Running the VisiNaming Service. Furthermore, you must ensure that at least one naming context has been created by doing one of the following:
Have your client bind to the NamingContextFactory and use the create_context method.
Have your client use the ExtendedNamingContextFactory.
Important
If no naming context has been created, a CORBA::NO_IMPLEMENT exception is raised when the client attempts to issue a CosNaming::NamingContext::bind.
Configuring VisiNaming with JdataStore HA
This section helps you configure JDataStore High Available (HA) to work with VisiNaming.
The Explicit Clustering example used throughout this section illustrates the usage of JDataStore HA with VisiNaming. In this example, JDataStore will be configured to have the following mirror types:
JDataStore HA supports automatic failover in the following circumstances:
VisiNaming works with JDataStore HA when a connection is made to the Directory mirror. When the Primary mirror is inaccessible, it will failover to one of the Read-only mirrors. VisiNaming must work with one Primary, and at least two Read-only mirrors at all times.
Notes
Create a DB for the Primary mirror
To make use of the JDataStore Explorer (JdsExplorer) to create a new DB, select New from the File menu.
Invoke JdsServer for each listening connection
In this example, the following connections are used:
Note
Always start JdsServer from the location where the AutoFailover_* jds files are located. Never start JdsServer from <JdataStore Install Directory>/bin unless vbroker.naming.url is set accordingly. The required jar files are:
Configure JDataStore HA
To configure JDataStore HA, complete the following steps:
1
2
Create a new project named NS_AutoFailover in the JDataStore Server Console.
Note
When creating a new DataSource, it is best to set its Protocol to Remote and include the machine IP in the ServerName
3
Click DataSource1 (in the Structure pane) to open it for editing.
4
Right-click DataSource1 and select Connect from the context menu.
5
Right-click Mirror (in the Structure pane) and select Add mirror from the context menu.
6
Each of the mirrors should also ensure that the host uses the IP of the machine where they are located instead the default value of localhost. You can use a different IP address for each of the mirrors, as long as the JdsServer is started for that mirror at the IP. The Directory mirror must have access to each of the mirrors.
7
8
Note that you do not need to create AutoFailover_Mirror2 beforehand. It is created automatically by JDataStore HA.
9
Set the Auto Failover and Instant Synchronization properties to true for all Read-only mirrors.
10
11
12
Set the Auto Failover and Instant Synchronization properties to false for this Directory mirror.
13
Choose Save Project "NS_AutoFailover.datasources" from the File menu to save the project.
14
Right-click Mirrors (in the Structure pane) and choose Synchronize all mirrors.
15
Click Mirror Status (in the Structure pane) and verify that Validate Primary is checked for Mirror1 only.
Run the VisiNaming Explicit Clustering example
To run the VisiNaming Explicit Clustering example, complete the following steps:
1
osagent
2
vbroker.naming.backingStoreType=JDBC
vbroker.naming.poolSize=5
vbroker.naming.jdbcDriver=com.borland.datastore.jdbc.
      DataStoreDriver
vbroker.naming.url=jdbc:borland:dsremote://143.186.141.14/AutoFailover_Mirror5.jds
vbroker.naming.loginName=SYSDBA
vbroker.naming.loginPwd=masterkey
vbroker.naming.traceOn=0
vbroker.naming.jdsSvrPort=2515
vbroker.naming.logLevel=debug
3
nameserv –VBJclasspath <JDS_Install>\lib\
jdsserver.jar –config autofailover.properties
4
Server ServerA -ORBpropStorage ns_client.properties &
5
Server ServerB -ORBpropStorage ns_client.properties &