Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java / JavaSE / J2SE4

CORBA - Manipulating Naming Service

5.00/5 (1 vote)
19 May 2012CPOL5 min read 27.2K  
This is a short post describing how to implement a simple tool to manage CORBA Naming Service.

Corba

The aim of this section is not to describe CORBA, but just to explain a little bit about how it works, so later I can explain what is and how the Naming Service works - which is part of the CORBA architecture.

So CORBA stands for Common Object Request Broker Architecture. It is a standard which enables programmers to write distributed applications, we can simplify it a lot and say it enables us to write apps working over the network.

CORBA is just an implementation of a standard Server - Client architecture. In CORBA's world, we create objects on the server side - and these objects can be used by clients which are running on other computers on the network.

The client has to know the structure of the object (the methods and the attributes). The objects which are created on server side and used by the clients are before described by the IDL - interface definition language. The very big advantage of Corba is that if we describe the object by IDL, we can later generate Java code as well as C++ code.

When the server creates the object, it will put its reference to ORB - Object Request Broker. This is the container that takes care of serialization of object over the network. This is the abstraction layer which permits us to run distributed apps. When the Server submits the object to ORB, it will obtain IOR - string identification of the object reference in ORB.

When the client wants to access the object, it will need the IOR. If the server and client meet before, they can somehow exchange this info - if not we need to transfer the IOR a different way. Here we will use Naming Service.

Naming Service

Naming Service is a tree structure which allows to store object references of objects which are being managed by the Object Request Broker. Basically that means that the client can now access the object not only by its IOR - but also by a string like name of the object.

Naming Service is a tree structure. There are generally 2 types of nodes - contexts and object references. When a node is a context, it can contain several children - this can be again of type context or object. When the client wants an object reference, he needs to now the exact place of the object reference in the tree structure and its name.

There is some valuable information about CORBA Naming Service on this site.

NSAdmin

The tool which I called NSAdmin allows creating or deleting references to objects as well as creating and destroying contexts. The tool can visualize the tree structure using the Java JTree component. Here is how it looks like:

How It Works

I wrote NSAdmin in Java and I have used SWING to create the GUI. The program is composed of two classes NSAdminFrame (the GUI) and NSAdmin - a static class which actually contains the implementations of the methods. To test the tool, you can use the Java implementation of ORB which is a generic part of JDK. To start ORB, run:

orbd.exe -ORBInitialPort 1234

The Initialisation

In order to work with the Naming Service, we have to initialize the Object Request Broker. From the ORB, we can obtain the reference to root naming context. This context is always called "NameService". The method for initialization looks like this, if you have started the ORB on your local machine, then the parameters that you will submit to this method will be: 1234,localhost. Note that the variable rootContext and orb are defined on top of the static class.

Java
public static void init(String port, String initialHost) 
throws Exception{ String[] args = new String[4]; args[0] = "-ORBInitialPort"; 
args[1] = port; args[2] = "-ORBInitialHost"; args[3] = initialHost; 
orb = ORB.init(args,null); rootContext = NamingContextExtHelper.narrow
    (orb.resolve_initial_references("NameService")); } 

Exploring the Naming Service Tree

To list the content of the naming context, we have a method which recursively calls itself. This method will create a tree structure of classes which I called Entry.

Entry is a simple class which has a name and can have multiple children in its ArrayList entries.

Java
public class Entry {
 public ArrayList<entry> entries;
 
 public String name;
 
 public Entry(String n){
  name = n;
  entries = new ArrayList<entry>();
 }
}

The structure of Entry classes will be later used to visualize the content in JTree. OK now the method explore which recursively traverses the naming context.

Java
public static Entry explore(String contextName,NamingContext context,int treeDepth) 
    throws InvalidName, NotFound, CannotProceed, 
    org.omg.CosNaming.NamingContextPackage.InvalidName{
  
  BindingListHolder blh = new BindingListHolder();
  BindingIteratorHolder bih = new BindingIteratorHolder();
  
  context.list(0,blh, bih);
  
  Entry entry = new Entry(contextName);
  
     System.out.println(contextName); 
  //binding iterator
  BindingIterator bit = bih.value;
  
  boolean remains = true;
  while(remains){
   BindingHolder biholder = new BindingHolder();
   remains = bit.next_one(biholder);
   Binding binding = biholder.value;
   
   NameComponent[] name = binding.binding_name;
   
   
   if(binding.binding_type == BindingType.nobject){
    if(name.length == 1){
     System.out.println("ID: " + name[0].id + " KIND: " + 
        name[0].kind + " Depth: " + treeDepth);
     entry.entries.add(new Entry(name[0].id));
    }
   }else if(binding.binding_type == BindingType.ncontext){
    NamingContext tmpContext =  NamingContextHelper.narrow
        (context.resolve(binding.binding_name));
    NameComponent component = name[0];
    entry.entries.add(explore(component.id,tmpContext,treeDepth+1));
   }
  }
  return entry;
 } 

The method takes NamingContext as parameter and will return a structure of Entry classes which will correspond to the naming service tree. There are couple things to notice:
The method list(int,BindingListHolder, BindingIteratorHolder) has two ways of usage. The first possibility is to specify how many binding we want to load. If we specify the value, than the bindings will be loaded into the array Binding[] which will be returned in the BindingListHolder class.

The second possibility is to call list(0,blh,bih). This way, the BindingListHolder will contain no results and we will obtain an iterator which we can use to iterate through the array. That is the possibility which I chose.

You can see that I iterate through all the bindings, and for each binding I determine the type. If it is a context - than I will recursively explore the context, if the type is object (reference is binded), then I will just add a new Entry which will represent this reference.

Destroying and Creating a subcontext

Creating the context is quite straight forward.

Java
public static void createContext(String name) 
    throws org.omg.CosNaming.NamingContextPackage.InvalidName, 
    NotFound, CannotProceed, AlreadyBound{
  
  NameComponent[] contextName = rootContext.to_name(name);
  NamingContext newContext = rootContext.new_context();
  rootContext.bind_context(contextName,newContext);
 } 

Destroying context can be a bit tricker because in order to destroy a context, the context has to be empty. So I implemented a recursive method, which will destroy all the children of context and then the context can be destroyed.

Java
public static void deleteContext(String name) 
    throws org.omg.CosNaming.NamingContextPackage.InvalidName, 
    NotFound, CannotProceed, NotEmpty{
  NameComponent[] contextName = rootContext.to_name(name);
  NamingContext context = NamingContextHelper.narrow(rootContext.resolve(contextName));
  
  BindingListHolder blh = new BindingListHolder();
  BindingIteratorHolder bih = new BindingIteratorHolder();
  context.list(Integer.MAX_VALUE, blh, bih);
  
  for(Binding binding:blh.value){
   NameComponent[] componentName = binding.binding_name;
   if(binding.binding_type == BindingType.ncontext){
    NSAdmin.deleteContext(name + "/" + componentName[0].id);
   }
   else{
    NSAdmin.deleteObjectReference(name + "/" + componentName[0].id);
   }
  }
  
  context.destroy();
  rootContext.unbind(contextName);
 }

Creating Object Reference

This last method is a method to manually add object reference to a context. Let's say that an object was created on the server and we have the IOR - the Interoperable Object Reference - which is a identificator of the object. Well, then we can bind the reference of the object to the tree and a client application can use just the name to obtain the reference.

Java
public static void createObjectReference(String ior,String context,String objectName) 
 throws org.omg.CosNaming.NamingContextPackage.InvalidName, 
    NotFound, CannotProceed, AlreadyBound{
  org.omg.CORBA.Object reference=orb.string_to_object(ior);
  NameComponent[] componentName = rootContext.to_name(context + objectName);
  rootContext.bind(componentName,reference);
 } 

To obtain the reference of the object, we just call the method string_to_object of Object Request Broker. The actual binding is then performed as for any other object we want to bind in the tree.

Summary

This is just a light overview of the functions which are the core of the program. Of course, there is a bit of glue code to put it together and let it work with the GUI. I think you can easily understand the rest from the code itself.

You can download the source code here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)