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 in 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 of it as a pathname decomposed into its directories. In this case we will use a simple name. In 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 in 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 look up:

    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 four programs. First configure TAO's naming service lookup protocol to use a unique port in your LAN. Something based on your user id is a good idea, for example:

$ setenv NameServicePort `expr 10000 + $uid`

Now we can start the Naming Service provided with TAO:

$ $TAO_ROOT/orbsvcs/Naming_Service/tao_cosnaming

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 no 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. To avoid problems when multiple naming services run in the same LAN, you must assign a different multicast port to each one, as shown above.

Unfortunately the protocol shown above does not work across multiple LANs, and it is hard to ensure that there are no conflicts in the assignment of multicast ports. TAO supports the Interoperable Naming Service specification that provides several mechanisms to control the behavior of 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/tao_cosnaming -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 corbaloc: scheme:

$ server -ORBInitRef NameService=corbaloc:iiop: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/tao_cosnaming -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/tao_cosnaming -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