CORBA and Omegahat

The CORBA package in the Omega distribution is somewhat more complete and is known to work with the Orbacus implementation. It provides both the Dynamic Server Interface (DSI) and the Dynamic Invocation Interface (DII) I have spoken about. These allow applications to call methods in remote servers and to provide servers from arbitrary local Omegahat and Java objects without requiring the compilation of CORBA stubs or skeletons. This allows newly discovered CORBA objects to be used directly, with no additional compilation, etc. Mechanisms are now in place in the Omegahat language and associated CORBA packages to allow the user consider CORBA objects and CORBA method invocations as if they were local (except for the speed). This allows users to employ existing services developed in other languages and availabe from other machines.

S and R

The same interactive features for invoking CORBA methods and providing CORBA servers as in Omegahat are now available in both S and R. No stubs or skeletons need to be compiled. Servers can be implemented entirely using Conversion is done automatically, but can be specialized by registering server methods and even C code that creates native CORBA servers for efficiency reasons. Facilities for interrogating the naming service and interface repository allow one to discover other servers and methods available in the CORBA environment.

In S, facilities for attaching naming contexts from the naming service as regular S databases allow CORBA objects to be used as local variables. Also, methods can be invoked on these objects using a notation similar in spirit to C++/Java

    server$method(...)
See Getting Started and other documents for a description of installing and using the S and R CORBA interfaces.

Distributed Task Management

We have provided some Java classes that manage a collection of CORBA tasks by distributing them to appropriate CORBA servers as they become available. Saikat DebRoy, Jose Pinheiro and some of the omega group have used this to run a distributed bootstrap for LME parameter estimates.

Conversion from Java to IDL

A second level of automation is provided in the form of a tool that converts Java classes to IDL. This is intended to allow existing Java classes to be instantiated and offered as CORBA servers without having to write IDL or implement the IDL skeleton directly. The instantiation can come from processing a CORBA request in another server. The generated IDL can be written to a file or directly to an Interface Repository.

The DII provides three different classes for invoking requests. These are one-way, blocking and deferred. These are explained in the CORBA documentation and are somewhat suggestive of their behavior.

Interactive Version

The dynamic invocation is done programmatically something like the following (using the interactive Omegahat language)
 call = new CorbaCall(server, "methodName", new Object[]{arg, arg, arg});
 call.result();
We provide syntactic sugar for the interactive user to allow the same call to be specified interactively as
 Server.methodName(arg,arg,arg);
where Server is accessed directly from the CORBA Naming Service. This utilizes the extensibility of the parser, evaluator and expression classes and the facility to attach general objects as databases in the search path.

Calls involving primitive-type arguments (e.g String, int, double,... and their corresponding class-based versions Integer, Double) are handled automatically by the default CorbaConverter. Non-primitive objects can be either compiled from the CORBA stubs and skeletons or more easily by arranging for

  1. the object to have the appropriately named methods and using the DynamicJavaObject class as a proxy, or
  2. for functions to exist in the Omegahat Evaluator corresponding to the CORBA methods, each taking the local server object as the argument.
  3. an Omegahat-object, which is an interpreted "object" (similar to a multi-function closure) that provides these named functions local to itself.
In these last two cases, the BasicDynamicOmegaObject class is used as the dynamic proxy.

The local non-primitive arguments in a CORBA call are automatically converted to dynamic CORBA objects using one of these dynamic proxy classes. This is controlled by the CorbaConverter which can be extended programmatically or customized using properties mapping local classes to CORBA classes.

This is explained in more detail in other documents. The basic points are:

  1. we can implement CORBA servers using Omegahat functions and expressions at the interpreted level without any compilation. These functions can be updated while the server is still active.
  2. servers can be located and their methods invoked dynamically, without prior knowledge of their IDL description and any compilation and linking of new classes.

Omega Database Access

The Omega NamingService class provides a simplified interface to the CORBA NamingContext class. There are methods accept Strings and String[] rather than NameComponents. Similalry, many of the exceptions are handled locally and re-assignments performed without the need to remove the original object.

Perhaps more important to the user is that NamingServiceDatabase objects (which extend NamingService) can be attached to the Evaluator's SearchPath. In this way, objects in that naming context can be referenced directly as local Omega variables.

When the top-level name server is attached, objects within it can be used simply by referring to their name. The usual search rules of the Evaluator apply. (See the NameServerViewer Tool for more information about examining the contents of the Naming Service.)

[1] orb = ORB.init(commandLine(), System.getProperties());
com.ooc.CORBA.ORB@80cdd48
[2]  attach(new NamingServiceDatabase(orb),0)
org.omegahat.Environment.Databases.AttachedDatabase@80ce90d
[3] objects()
A
z
Trace
delta
GlobalServer
 ... 
Call Center
Server
Wafers
[4] 
[5] Server
com.ooc.CORBA.StubForObject@80ce2df
[6] A
org.omegahat.Interfaces.CORBA.NamingService@80ce028
The object A illustrates that Naming Contexts can be nested in the CORBA naming service. Accordingly, referring to CORBA objects in the naming service may involve specifying nested qualifiers. The NamingService supports the DynamicFieldAccessInt interface which allows nested qualifiers to evaluate to the appropriate object. For example, to obtain the object c in the naming context B which is itself contained in the naming context A, the Omegahat language supports
A.B.c
Note also that when a NamingContext is returned, it is converted to a NamingService object. This can be converted to a NamingServiceDatabase by passing it to that class' constructor.

As objects can be retrieved from NamingServiceDatabase objects, they can also be assigned in the same. For example, the commands

 A.foo = Server
 bar = new TraceServer()
binds the name foo in the NamingContext named A with the CORBA object Server retrieved from the top-level NamingServiceDatabase attached in the SearchPath and the second binds a newly created CORBA Object to the name bar. If the default database is a NamingServiceDatabase object, other applications can see this object.

When the attaching of NamingServiceDatabase is used in conjunction with the CORBA-extended grammar mentioned above, CORBA invocations appear identical to local method invocations and their complexity is hidden (except when errors occur!).

Errors can manifest themselves as Exceptions when non-existent objects are retrieved from a NamingContext or when new objects are assigned to a NamingContext before a BOA has been initialized.

Interface Repository Browser

The contents of the Interface Repository can also be referenced in the same way as the NamingService. Likewise, there is a class that can be attached as an element of the Evaluator's search path.

CORBA-aware Evaluators

Many of the services mentioned above are made transparent when using the appropriate parser, evaluator, etc. To this end, there are two derived Evaluator classes that provide this syntactic sugar to make the CORBA access appear as local calls, etc. These are CorbaAugmentedEvaluator and OrbacusEvaluator. The former provides the connection to the ORB and the facilities for obtaining the toplevel NamingServiceDatabase and AttachableInterfaceRepository and attaching the former simply. For experimenting with CORBA, I suggest that you change the configuration OmegaOptions file to use one of these.

Tools

Configuring and discovering the CORBA bus with objects and interfaces can be complicated. Two tools are currently provided to examing and "edit" the Interface Repository (IR) and Name Service (NS). Both can be used as stand-alone applications (via the main method in the class) or as a regular Swing component in a GUI. In the former case, the component is embedded in a scroll window within a JFrame. A menu controlling the window is also provided.

Both components connect to the appropriate default top-level server. However, they can also be instantiated with sub-servers (e.g. sub-NamingContexts or IR Container objects) so that small segments of the overall contents can be viewer.

Interface Repository Viewer

Name Server Viewer

org.omegahat.Interfaces.CORBA.Tools.InterfaceRepository.IRViewer org.omegahat.Interfaces.CORBA.Tools.NameServer.NameServerViewer Note the entry delta is being edited. The enter key in this textfield commits the renaming change in the CORBA name server.
omega -CORBA -ix InterfaceRepository.IRViewer omega -CORBA -ix NameServer.NameServerViewer
These tools need some additional work in terms of customizability and illustrating their state.

Other Languages/Environments

The approach used in this package will work for other interpreted languages such as S, R, Xlisp. The level of automation will vary for these languages as they provide more or less structure. The only major difference between the implementation in these languages and Omegahat is due to the interface between the native internal objects and user-level variables. For these systems, they will have to maintain references to the C/C++-level CORBA objects. This can be done easily and robustly using each object's IOR obtained from the object_to_string() method it supports. The slight expense of converting between this and the native reference should not be overwhelming.

R & S Implementation

The code for the R & S implementations is date back to last year. They can be completed by porting the design and implementation in Java to the C/C++ version. Much of the tedious and CORBA-specific work has already been done. Others are encouraged to take it and complete it as I am unlikely to get to it soon.

Locating Objects

A simple way to access objects spread across different machines is to use the CORBA naming service. In many CORBA implementations, there is a mechanism for specifying the default naming service object. The interface repository is a problem however in the Orbacus implementation. (It appears to ignore the specification of the iiop specification in its configuration file.) We can put the IR ior in the naming service and this would allow us to bootstrap ourselves from any machine. However, another mechanism is readily available from within Omega. The following commands show how to read an IOR from a file located on an HTTP server.
u = new URL("http://piglet/IR.ref");
s = u.openConnection().getContent();
r = new BufferedReader(new InputStreamReader(s));
r.readLine();

Distributed Task Management

The package TaskManagement provides the basic tools which support scriptable distributed task management. A collection of tasks is easily constructed as a TaskQueue and a collection of CORBA servers created as a ServerPool. The tasks can reject certain servers either as being of the incorrect type or for other reasons (such as speed, etc.) The TaskManager can also be easily extended to support different scheduling algorithms - e.g. task priorities, machine knowledge, etc.

The benefits of this approach include

Saikat DebRoy, Jose Pinheiro, Greg Warnes, John Chambers and I have used this to implement a distributed bootstrap for LME setup. While the server code (LME material) was written in Java, the distributed task management can be used to control arbitrary (and non-homogeneous) CORBA servers and tasks. Thus, it can be used to distribute R/S computations across a cluster. The primitives exist for implementing the task management in those languages. See getRequestValue, .Corba, etc.


Duncan Temple Lang <duncan@research.bell-labs.com>
Last modified: Thu Sep 16 07:18:11 EDT 1999