Implementing a CORBA Client and Server

Credit: Duncan Grisby

Problem

You need to implement a CORBA server and client to distribute a processing task, such as the all-important network-centralized, fortune-cookie distribution.

Solution

CORBA is a mature object-oriented RPC protocol, and several CORBA ORBs offer excellent Python support. This recipe requires multiple files. Here is the interface definition file, fortune.idl:

module Fortune {
  interface CookieServer {
    string get_cookie(  );
  };
};

The server script is a simple Python program:

import sys, os
import CORBA, Fortune, Fortune_ _POA

FORTUNE_PATH = "/usr/games/fortune"

class CookieServer_i(Fortune_ _POA.CookieServer):
    def get_cookie(self):
        pipe   = os.popen(FORTUNE_PATH)
        cookie = pipe.read(  )
        if pipe.close(  ):
            # An error occurred with the pipe
            cookie = "Oh dear, couldn't get a fortune\n"
        return cookie

orb = CORBA.ORB_init(sys.argv)
poa = orb.resolve_initial_references("RootPOA")

servant = CookieServer_i(  )
poa.activate_object(servant)

print orb.object_to_string(servant._this(  ))

poa._get_the_POAManager().activate(  )
orb.run(  )

And here’s a demonstration of the client code, using the Python interactive command line:

>>> import CORBA, Fortune
>>> orb = CORBA.ORB_init(  )
>>> o = orb.string_to_object(
...   "corbaloc::host.example.com/fortune")
>>> o = o._narrow(Fortune.CookieServer)
>>> print o.get_cookie(  )

Discussion

CORBA has a reputation for being hard to use, but it is really very easy, especially if you use Python. This example shows the complete CORBA implementation of a fortune-cookie server and its client. To run this example, you need a Python CORBA implementation (or two, as you can use two different CORBA implementations, one for the client and one for the server, and let them interoperate with the IIOP inter-ORB protocol). There are several free ones you can download.

With most ORBs, you must convert the IDL interface definition into Python declarations with an IDL compiler. For example, with omniORBpy:

$ omniidl -bpython fortune.idl

This creates Python modules named Fortune and Fortune_ _POA to be used by clients and servers, respectively.

In the server, we implement the CookieServer CORBA interface by importing Fortune_ _POA and subclassing the CookieServer class that the module exposes. Specifically, in our own subclass, we need to override the get_cookie method (i.e., implement the methods that the interface asserts we’re implementing). Then, we start CORBA to get an orb instance, ask the ORB for a POA, instantiate our own interface-implementing object, and pass it to the POA instance’s activate_object method. Finally, we call the activate method on the POA manager and the run method on the ORB to start our service.

When you run the server, it prints out a long hex string, such as:

IOR:010000001d00000049444c3a466f7274756e652f436f6f6b69655365727665723
a312e300000000001000000000000005c000000010102000d0000003135382e313234
2e36342e330000f90a07000000666f7274756e6500020000000000000008000000010
0000000545441010000001c0000000100000001000100010000000100010509010100
0100000009010100

Printing this is the purpose of the object_to_string call that our recipe’s server performs just before it activates and runs.

You have to give this value to the client’s orb.string_to_object call to contact your server. Of course, such long hex strings may not be very convenient to communicate to clients. To remedy this, it’s easy to make your server support a simple corbaloc URL string, like the one used in the client example, but this involves omniORB-specific code. (See the omniORBpy manual for details of corbaloc URL support.)

See Also

omniORBpy at http://www.omniorb.org/omniORBpy/.

Get Python Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.