TAO's Naming Service

So far we have used string_to_object() and object_to_string() to bootstrap the client, if the system is going to be used in a truly distributed environment we cannot count on having a shared file system or on the user to type the IOR to initialize the client. CORBA has several location services that can be used for that purpose, the simplest of them is the CORBA Naming Service. There are many good tutorials on how to use the Naming Service, and Henning and Vinoski discuss the issue at detail in their book.

In this section we will cover very simple uses of the Naming Service, but we will concentrate on how to configure and bootstrap the Naming Service itself! Including TAO's support for the Interoperable Naming Service.

Registering an Object in the Naming Service

First we modify the server to register the stock factory with the naming service. We need to include the right header:

#include "orbsvcs/CosNamingC.h"

We recall that we activate the stock factory using:

    // Activate it to obtain the object reference
    Quoter::Stock_Factory_var stock_factory =
      stock_factory_i._this ();

We need to obtain a reference to the Naming Service, this is done using the resolve_initial_references() call:

    CORBA::Object_var naming_context_object =
      orb->resolve_initial_references ("NameService");
    CosNaming::NamingContext_var naming_context =
      CosNaming::NamingContext::_narrow (naming_context_object.in ());

Next we initialize the name that we will assign to the objects, the naming service uses a sequence of structures for the name, think about it as a pathname decomposed in its directories, in this case we will use a simple name, on production environments some better organized hierarchy may be imposed. First create and initialize the sequence:

    CosNaming::Name name (1);
    name.length (1);

Now we initialize the name:

    name[0].id = CORBA::string_dup ("Stock_Factory");

Now we are ready to register the object reference on the naming service:

    naming_context->bind (name, stock_factory.in ());

Notice that bind() fails if the name is already in the naming service, you may want to use rebind() to override any values already there.

Looking up the Object

Now the client can use the Naming Service to locate the object, instead of relying on the command line, we have to perform the same calls to locate the naming service and initialize the name of the object we want to lookup:

    CORBA::Object_var naming_context_object =
      orb->resolve_initial_references ("NameService");
    CosNaming::NamingContext_var naming_context =
      CosNaming::NamingContext::_narrow (naming_context_object.in ());

    CosNaming::Name name (1);
    name.length (1);
    name[0].id = CORBA::string_dup ("Stock_Factory");

Now we can resolve the name:

    CORBA::Object_var factory_object =
      naming_context->resolve (name);
    Quoter::Stock_Factory_var factory =
      Quoter::Stock_Factory::_narrow (factory_object.in ());

And then we can use the object as before.

Exercise 1

Complete the changes to the server.cpp file.

You can use the following files to complete and test your implementation: Quoter.idl, Makefile, Stock_i.h, Stock_i.cpp, Stock_Factory_i.h Stock_Factory_i.cpp. For more fun you can modify the original client.cpp file too. What about the first argument? Do we need the IOR now?

Solution

Compare your solution with client.cpp and server.cpp they should be very similar.

Testing

To test your changes you need to run three programs, first configure TAO's naming service lookup protocol to use a hopefully unique port, something base in your user id is a good idea, for example:

$ setenv NameServicePort `expr 10000 + $uid`

Now we can startup the Naming Service provided with TAO:

$ $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service

and your server:

$ server

and finally the client:

$ client MSFT RHAT RHAT MSFT

Finding the Naming Service

So how does TAO find the naming service? Until recently there was not standard way to configure how the Naming Service was bootstrapped. In TAO we decided to use IP multicast to locate the server. The multicast protocol is very simple minded, but works well in small LANs where there are not many naming services running.

A more interesting approach is to use the Interoperable Naming Service features in TAO to control the resolve_initial_references() call. For example, you can ask the Naming Service to dump its IOR to a file, as in:

$ $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service -o ns.ior

And then use the -ORBInitRef to that IOR instead of the multicast protocol:

$ server -ORBInitRef NameService=`cat ns.ior`

Or even better use the file: scheme to read the file directly:

$ server -ORBInitRef NameService=file://ns.ior

But this still assumes that there is a shared filesystem between the hosts, or that the user will copy the file across the network. If we know what host and port the Naming Service is using to accept IIOP requests then we can use the iioploc: scheme:

$ server -ORBInitRef NameService=iioploc://ace.cs.wustl.edu:12345/NameService

In fact, controlling the host and port of any TAO program, including the Naming Service is easy, just use the -ORBEndPoint option:

$ $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service -ORBEndPoint iiop://ace.cs.wustl.edu:12345

Of course, this only works if you are running the program in ace.cs.wustl.edu and the 12345 port is free. You can use the magic port number 0 to let the ORB find a free port, in fact that is exactly what TAO does by default. Finally you can use multiple -ORBEndPoint options to listen on multiple endpoints, this is very useful for multi-hosted machines.

Exercise 2

Try using different approaches to find the Naming Service. Also try to run the server with an invalid IOR for the naming service. What happens if the server and client pick different naming services through their multicast protocol? What happens if they are not configured consistently with respect to their Naming Service?

Persistence

What happens if the naming service is killed between the object registration and the lookup? By default TAO's Naming Service is not persistent, but it is a matter of using a flag to save its state on a file:

$ $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service -f name_service.dat

Notice that this is little use unless your services are persistent too, or can be automatically restarted, that is the role of the Implementation Repository.


Carlos O'Ryan
Last modified: Sun Nov 28 23:31:04 CST 1999