New York University

Computer Science Department

Courant Institute of Mathematical Sciences

 

Interoperability and the CORBA Specification

 

Course Title: Application Servers                                           Course Number: g22.3033-011

Instructor: Jean-Claude Franchitti                                            Session: 4

 

 

1. Overview of Universal Networked Objects (UNO)

The Object Management Group (OMG) adopted a specification called Universal Networked Objects (UNO) that supports interoperation among ORBs, that is, the ability of a client in one ORB to invoke an operation on an object in another ORB. UNO defines the following:

 

·       An ORB Interoperability Architecture that provides a conceptual and architectural framework within which ORB components relevant to interoperability are positioned.

 

·       A General Inter-ORB Protocol (GIOP) that can be mapped onto multiple transport layers. The GIOP consists of:

 

·       A Common Data Representation (CDR) for all data types

·       An Interoperable Object Reference (IOR) format

·       Interoperable TypeCodes for all data types

·       Inter-ORB Protocol (IOP) message contents, formats, and semantics, independent of the method of message conveyance

 

The intention is for standard mappings to be developed from GIOP to alternative transport domains (OSI, SNA, IPX, etc.), enabling out-of-the-box interoperability among ORBs that share a common transport protocol.

 

·       The Internet Inter-ORB Protocol (IIOP), which is the first transport mapping for the GIOP. The Internet IOP maps the GIOP to TCP/IP. It is mandatory for CORBA 2.0 (and above) networked ORBs and guarantees out-of-the-box interoperability among them.

 

·       CORBA extensions that support the construction of inter-ORB bridges. These extensions are mandatory for all CORBA 2.0-compliant ORBs, since they are more generally useful than simply for building bridges. For example, they support the construction of distributed debugging tools. The primary new CORBA component specified by UNO is a Dynamic Skeleton Interface (DSI), which is the server-side analog of the client-side DII. The DSI provides a way to deliver requests from an ORB to a Dynamic Implementation Routine (DIR) in a server without compile-time knowledge of the type of object it implements. For example, the DSI can be used to deliver an inter-ORB request to a bridge for transmission to another ORB.

 

·       The DCE Common Inter-ORB Protocol (DCE-CIOP), the first Environment-Specific Inter-ORB Protocol (ESIOP). ESIOPs are IOPs that do not comply with the GIOP specification. Instead, they are specialized for particular operating environments and support out-of-the-box interoperation at sites where a particular networking or distributed computing infrastructure is already in general use.

 

UNO organizes the various components of the CORBA specification into the following categories for future compliance testing and branding purposes:

 

CORBA2/Core

Basically, the CORBA 1.2 specification, minus the IDL C language mapping, plus extensions and modifications resulting from the CORBA 2.0 RFPs (including UNO's bridging support) and requirements of COSS 2 Object Services.

CORBA2/C

CORBA2/C++

CORBA2/Smalltalk

IDL language mappings that can be supported selectively by vendors on top of the basic CORBA2/Core capability.

CORBA2/Java

CORBA2/Internet IOP

CORBA2/DCE IOP

UNO's IIOP and DCE-CIOP

 

UNO also defines a CORBA2 networked ORB as an ORB that supports the CORBA2/Core and some set of CORBA2 language mappings; provides multinode operation using either the IIOP, an ESIOP, or a proprietary protocol; and interoperates with other networked ORBs via IIOP, supported either natively or via a half-bridge.

 

To show how the mechanisms defined by UNO support interoperation among ORBs, Section 2 considers one possible implementation of an IIOP half-bridge. Section 3 contains concluding remarks and our expectations of how OMG's adoption of the UNO specification affects ORB vendors and users.

 

2. Example Implementation of an IIOP Bridge

2.1 Introduction

Suppose we have two ORBs -- ORB A and ORB B (Figure 1). Suppose further that a client in ORB A wishes to invoke an operation on an object -- John -- in ORB B. Before describing how this can be accomplished, let us consider how the client might come to possess a reference to an object in another ORB. In the discussion that follows, we refer to any ORB other than the client's as a foreign ORB and any object in a foreign ORB as a foreign object.


 

 


Figure 1. A client in ORB A wishes to invoke an operation on an object in ORB B.

Object references are ORB-specific. UNO defines an IOR format (described below) that contains sufficient information for any ORB to determine how to direct requests to the ORB with the object in question. UNO specifies how an IOR can be CDR-encoded and converted to string format. The resulting string can be made available to ORBs in a variety of ways. An agent (a bridge, for example) in any ORB can unstring the IOR, create a proxy for it (as discussed below), and distribute references to the proxy among clients in the same ORB. Clients can use a reference to the proxy to invoke operations on the foreign object. Requests to the proxy are delivered to the bridge, and the bridge forwards them to the foreign ORB. The proxy server may deliver requests to the bridge or the bridge may be the proxy server itself. The scenario that follows assumes the bridge is the proxy server.

 

Once a client possesses a reference to a foreign object, operations on that object may return references to additional foreign objects as result values or output parameters. Thus, for example, distributing a stringified IOR for a Naming Service makes the transitive closure of all the objects defined in the Naming Service available to other ORBs.

 

Figure 2 shows the proxy for John -- Gian -- in ORB A. The proxy is shown in bridge A because bridge A is the proxy's server. The bridges are labeled half-bridges because a full bridge spans two ORBs and can receive requests from clients in one and invoke them on objects in the other. A half-bridge receives requests from clients in one ORB and transmits them in an agreed-upon format using an agreed-upon protocol to the half-bridge in another ORB. One way we expect vendors to comply with the UNO specification is by delivering a half-bridge to IIOP with their ORBs. Figure 2 also shows the Proxy Table in each bridge. The Proxy Table is used to store the association between a proxy and the IOR of the foreign object it represents.


 

 


Figure 2. The client in ORB A has a proxy for the object in ORB B.

2.2 Dynamic Skeleton Interface (DSI)

Now suppose the client invokes an operation on John through its reference to the proxy Gian, passing a reference to an object Maria in ORB A as an in parameter (Figure 3). ORB A delivers the request, through the DSI, to a DIR in bridge A, which is Gian's server.


 

 


Figure 3. The client in ORB A invokes a request through the proxy.

The DSI defines a new interface between the ORB and an object's methods. In the original common ORB architecture, the ORB delivers a request to a server through an IDL-generated skeleton. Precisely what constitutes a skeleton is ORB-dependent. For example, in one ORB, it might be a function that the ORB invokes when it delivers a request for the corresponding operation. By fleshing out such a skeleton with actual method code and linking it with whatever other code and libraries a particular ORB requires, the object developer generates a server in which the ORB can invoke methods properly.

 

The DSI defines a new way for an ORB to deliver requests to a server through a so-called dynamic skeleton. The ORB delivers a request packaged as a ServerRequest pseudo-object to a DIR, which is a single function that takes an arbitrary object reference and a ServerRequest as arguments. The bridge developer can follow a particular ORB's rules for writing a DIR and then link the DIR with whatever other code and libraries the ORB requires to create a server (the bridge) in which the ORB delivers requests to the DIR using the DSI.

 

The DIR in bridge A is invoked with a ServerRequest pseudo-object that contains the name of the requested operation, its OperationDef, a Context pseudo-object (if required by the requested operation's IDL definition), an NVList with parameters (including the reference to Maria), and a NamedValue to return the result (Figure 4).

 

Figure 4. ServerRequest pseudo-object definition.

 

module CORBA

{

   pseudo interface ServerRequest

   {

      Identifier    op_name ();

      OperationDef  op_def ();

      Context       ctx ();

      void          params (inout NVList parms);

      NamedValue    result ();

   };

};

 

 

2.3 IIOP Request Message

Bridge A uses the identity of the object on which the request was invoked -- Gian -- to retrieve John's IOR from its Proxy Table (Figure 5). The type_id field in the IOR identifies John's type, and the profiles field contains a sequence of one TaggedProfile. The tag field in this TaggedProfile has the value TAG_INTERNET_IOP, and the profile_data field contains an instance of IIOP::ProfileBody (Figure 6) that has been CDR-encoded into what UNO calls an encapsulation octet stream.

 

Figure 5. IOR definition.

 

module IOR

{

   typedef unsigned long         ProfileId;

   const ProfileId               TAG_INTERNET_IOP = 0;

 

   struct TaggedProfile

   {

      ProfileId                  tag;

      sequence <octet>           profile_data;

   };

 

   struct IOR

   {

      string                     type_id;

      sequence <TaggedProfile>   profiles;

   };

};

 

 

Figure 6. IIOP::ProfileBody definition.

 

module IIOP

{

   struct Version

   {

      char               major;

      char               minor;

   };

 

   struct ProfileBody

   {

      Version            iiop_version;

      string             host;

      unsigned short     port;

      sequence <octet>   object_key;

   };

};

 

 

The host and port fields in the IIOP::ProfileBody identify the host and port on which bridge B is listening for inter-ORB requests. The object_key field contains a value that identifies John to bridge B (it may be an object reference for John in ORB B or some value that bridge B associates with a reference to John). Bridge A has everything it needs to construct and send an IIOP Request message. This consists of an IIOP MessageHeader (Figure 7), an IIOP RequestHeader (Figure 8), and an IIOP Request body. The Request body includes all in and inout parameters (including an IOR for Maria) and a Context pseudo-object (if required).

 

Figure 7. IIOP::MessageHeader definition.

 

module IIOP

{

   enum MsgType

   {

      Request, Reply, CancelRequest, LocateRequest,

      LocateReply, CloseConnection, MessageError

   };

 

   struct MessageHeader

   {

      char            magic [4];

      Version         iiop_version;

      boolean         byte_order;

      octet           message_type;

      unsigned long   message_size;

   };

};

 

 

Figure 8. IIOP::RequestHeader definition.

 

module IIOP

{

   typedef unsigned long               ServiceID;

 

   struct ServiceContext

   {

      ServiceID                        context_id;

      sequence <octet>                 context_data;

   };

 

   typedef sequence <ServiceContext>   ServiceContextList;

 

   const ServiceID                     TransactionService = 0;

 

   struct RequestHeader

   {

      ServiceContextList               service_context;

      unsigned long                    request_id;

      boolean                          response_expected;

      sequence <octet>                 object_key;

      string                           operation;

      Principal                        requesting_principal;

   };

};

 

 

The IIOP MessageHeader contents are as follows:

 

·       magic contains the four characters "IIOP."

·       iiop_version identifies the major and minor IIOP version (the version defined by UNO is major version 1, minor version 0).

·       byte_order identifies the byte ordering (big-endian or little-endian) in which the message is encoded.

·       message_type contains the CDR-encoded value IIOP::Request.

·       message_size contains the number of bytes following the message header.

 

The IIOP RequestHeader contents are as follows:

 

·       service_context contains service context information that may need to accompany the request. The Transaction Service defines a TSInteroperation::PropagationContext for this purpose and is the first Object Service to do so. Thus, the only ServiceID currently defined is IIOP:TransactionService.

·       request_id contains a unique request ID that bridge A generates to allow it to identify the corresponding reply.

·       response_expected identifies whether the client (and, therefore, bridge A) expects to receive a response. No response is expected if the operation's IDL definition includes the oneway keyword or if the client invokes the operation using the DII and specifies the INV_NO_RESPONSE flag.

·       object_key contains a CDR-encoded version of a value that identifies John to bridge B (as discussed above). This is obtained from the IOR in bridge A's Proxy Table as described previously.

·       operation contains the name of the requested operation.

·       requesting_principal identifies the user requesting the operation and is completely ORB-dependent at this time (pending OMG specification of a Security Service).

 

Bridge A must place a reference to Maria in the Request body of the message, since it is an in parameter of the request. Rather than pass a real reference to Maria, which would most likely be useless to ORB B, bridge A constructs an IOR for Maria and places the IOR in the Request body. When bridge A has finished constructing the Request message, it opens a TCP/IP connection to bridge B using the host and port information in the IOR for John  (Figure 9).

 

 


 


Figure 9. Bridge A transmits the request to bridge B.

When bridge B receives the message from bridge A, the IIOP MessageHeader identifies it as an IIOP Request message and enables bridge B to unpack the RequestHeader and Request body. The RequestHeader yields a reference to John as the target of the request; it also yields the name of the operation to be invoked on John. While unpacking parameters in the Request body, bridge B encounters the IOR for Maria. Bridge B creates a proxy for Maria (Mary), places an entry in its Proxy Table that associates the new proxy with the IOR for Maria, and uses a reference to the new proxy as the in parameter when it invokes the request on John (Figure 10).


 


Figure 10. Bridge B invokes the request on the target object.

2.4 IIOP Reply Message

If the client (and, therefore, bridge A) expects a response, bridge B constructs an IIOP Reply message when the invocation is completed and transmits the reply to bridge A. The IIOP Reply message consists of an IIOP MessageHeader (Figure 10), an IIOP ReplyHeader (Figure 11), and an IIOP Reply body.

 

Figure 11. IIOP::ReplyHeader definition.

 

module IIOP

{

   enum ReplyStatusType { NO_EXCEPTION,

                          USER_EXCEPTION,

                          SYSTEM_EXCEPTION,

                          LOCATION_FORWARD };

 

   struct ReplyHeader

   {

      ServiceContextList  service_context;

      unsigned long       request_id;

      ReplyStatusType     reply_status;

   };

};

 

 

The IIOP MessageHeader contents are described above. In this case, however, message_type contains the CDR-encoded value IIOP::Reply. The IIOP ReplyHeader contents are as follows:

 

·       service_context contains service context information that may need to be returned to the client (see above).

·       request_id contains the same unique ID as in the request received by bridge B.

·       reply_status indicates the completion status of the request and determines the contents of the Reply body. Two possible values are:

·       NO_EXCEPTION, in which case the Reply body contains the operation's return value followed by all inout and out parameters.

·       USER_EXCEPTION or SYSTEM_EXCEPTION, in which case the Reply body contains the exception that was raised by the operation.

 

There is a third possible value for reply_status -- LOCATION_FORWARD -- in which case the Reply body contains an IOR. The client's bridge is expected to reinvoke the request using the new IOR, and this redirection is expected to be transparent to the client. This supports object migration. For example, if John moves to a location that requires the use of a different IOR between the time Gian is created and the time the client invokes an operation through Gian, the LOCATION_FORWARD reply gives bridge A a new IOR it can use to send the request to a bridge appropriate for John's new location. This mechanism also supports ORB-wide location services; for example, an ORB may provide a location server for all of the object references it exports to the external world and then simply publish the address of that server in all of the IORs it exports.

 

2.5 IIOP LocateRequest and LocateReply Messages

If a bridge does not want to receive a LOCATION_FORWARD response and have to retransmit a request, it may use an IIOP LocateRequest message to determine whether the reference it has for the target of the request is valid, whether the receiver is prepared to accept requests to that reference, and if not, to what address it should send requests to the target object. The IIOP LocateRequest message consists of an IIOP MessageHeader (Figure 7) and an IIOP LocateRequestHeader (Figure 12).

 

Figure 12. IIOP::LocateRequestHeader definition.

 

module IIOP

{

   struct LocateRequestHeader

   {

      unsigned long     request_id;

      sequence <octet>  object_key;

   };

};

 

 

The IIOP MessageHeader contents are described above. In this case, however, message_type contains the CDR-encoded value IIOP::LocateRequest. The IIOP LocateRequestHeader contents are as follows:

 

·       request_id contains a unique request ID the sending bridge generates to allow it to identify the corresponding reply.

·       object_key contains a CDR-encoded version of the key value extracted from the IOR associated with the proxy on which the client invoked the request.

 

When a bridge receives an IIOP LocateRequest message, it responds with an IIOP LocateReply message. An IIOP LocateReply message consists of an IIOP MessageHeader (Figure 7), an IIOP LocateReplyHeader (Figure 13), and an IIOP LocateReply body.

 

Figure 13. IIOP::LocateReplyHeader definition.

 

module IIOP

{

   enum LocateStatusType { UNKNOWN_OBJECT,

                           OBJECT_HERE,

                           OBJECT_FORWARD };

 

   struct LocateReplyHeader

   {

      unsigned long     request_id;

      LocateStatusType  locate_status;

   };

};

 

 

The IIOP MessageHeader contents are described above. In this case, however, message_type contains the CDR-encoded value IIOP::LocateReply. The IIOP LocateReplyHeader contents are as follows:

 

·       request_id contains the same unique ID as in the corresponding LocateRequest message.

·       locate_status determines whether the message includes a LocateReply body. The possible values for locate_status are as follows:

·       UNKNOWN_OBJECT, which means the object specified in the LocateRequest message is unknown to the bridge, and no LocateReply body exists.

·       OBJECT_HERE, which means the bridge sending the LocateReply message is prepared to accept requests to the specified object, and no LocateReply body exists.

·       OBJECT_FORWARD, which means a LocateReply body exists and contains an IOR that may be used as the target for requests to the object specified in the LocateRequest message.

 

2.6 Observations

The scenario in Section 2 shows how the bridging support specified in UNO can be used to implement a half-bridge to IIOP. The bridge can be implemented at the application level by end-user developers and requires no proprietary information about the ORB or modifications to the ORB. In fact, if and when all of the server-side ambiguities in the CORBA specification are removed, the technique described here can be used to build a portable half-bridge to IIOP that can run on any ORB (that is, whose source code can be compiled and linked to run on any ORB).

While some vendors will satisfy the IIOP requirement for a CORBA networked ORB by providing a half-bridge similar to that described here, other vendors will support IIOP directly in their ORBs. When a client invokes a request on a foreign object, an IIOP-aware ORB could marshal the request directly into an IIOP Request message, open a TCP/IP connection to the server indicated in the IOR, if necessary, and transmit the Request message to the foreign server. This is more efficient than using a bridge, but requires modifications to the ORB itself and would increase the size of clients and servers somewhat.

 

3. Concluding Remarks

 

The UNO specification defines three significant components:

 

·       The Internet Inter-ORB Protocol (IIOP), which supports out-of-the-box interoperability in the ubiquitous transport domain of TCP/IP.

·       The DCE-CIOP, which supports out-of-the-box interoperability among DCE-based ORBs.

·       The General Inter-ORB Protocol (GIOP) and CORBA extensions that support the construction of bridges to non-compliant ORBs and ORBs in different transport domains.

 

CORBA compliance for networked ORBs requires IIOP, which may be supported via half-bridges. We noted previously (in Section 2.6) that half-bridges can be developed by end- users or third parties without proprietary information about an ORB or modifications to the ORB. Mappings have been developed from GIOP to additional transport domains. ICL has developed an OSI mapping, and Novell has developed a mapping to IPX.

 

Glossary

CDR - Common Data Representation
CIOP - Common Inter-ORB Protocol
COM - DEC's and Microsoft's Common Object Model
CORBA - Common Object Request Broker Architecture
COSS - Common Object Services Specification
DCE - OSF's Distributed Computing Environment
DII - Dynamic Invocation Interface
DIR - Dynamic Implementation Routine
DSI - Dynamic Skeleton Interface
ESIOP - Environment-Specific Inter-ORB Protocol
GIOP - General Inter-ORB Protocol
IDL - Interface Definition Language
IIOP - Internet Inter-ORB Protocol
IOP - Inter-ORB Protocol
IOR - Interoperable Object Reference
IPX - Novell's Internet Packet Exchange
ISO - International Standards Organization
OLE - Microsoft's Object Linking and Embedding
OMG - Object Management Group
ORB - Object Request Broker
OSF - Open Software Foundation
OSI - ISO's Open Systems Interconnection
RFP - Request For Proposals
SNA - IBM's System Network Architecture
TCP/IP - Transmission Control Protocol/Internet Protocol
UNO - Universal Networked Objects