CORBA Common Object Request Broker Architecture by sdfwerte

VIEWS: 58 PAGES: 49

									       CORBA
Common Object Request
  Broker Architecture
         Lecture 13
  Concurrent and Distributed
          Systems
                         CORBA
CORBA, the Common Object Request Broker Architecture
  specifies middleware which provides an interface to a software
  system. To clients of the system, using the interface, the system
  is presented as a collection of objects. External programs
  (clients) interact with the system by invoking methods on the
  objects.
Note that middleware is a general term for intermediate software
  that connects systems together.
The Object Management Architecture (OMA), a reference
  architecture, specifies that a client application connects to an
  object via an Object Request Broker (ORB) - a piece of
  middleware that also provides various services and facilities
  such as naming and printing.
  Main Components of CORBA
1. Interface definition language known as IDL

2. A reference architecture – the Object Management
   Architecture (OMA) which involves the use of an Object
   Request Broker or ORB.

3. A protocol which allows objects in different implementations
   to communicate – the General Inter-ORB Protocol. GIOP
   specifies message formats, and an external data representation.
   The Internet Inter-Orb Protocol is a version of GIOP that runs
   over TCP/IP.
      Using a CORBA System
1. The IDL specification lists CORBA object types and the
   operations for each object type.
2. A CORBA interface presents a view of a computer system.
   Client programs view the system as a collection of CORBA
   objects. The client program interacts with the computer
   system by invoking methods on the CORBA objects.
3. A CORBA method is invoked as a remote method invocation
   using a list of parameters. Each parameter is marked as an in
   parameter, an out parameter or an inout parameter. Parameters
   of type in or inout are sent to the remote object and parameters
   of type out and inout are received as responses. Parameters are
   either CORBA objects or data structures of arbitrary
   complexity.
                   Applications
1. Adding an object-oriented interface to legacy systems.
   Many existing legacy systems are written in languages that are
   no longer supported, and an added interface in Java or C++ is
   likely to be easier to support.
2. Integrating heterogeneous systems
   CORBA provides a uniform interaction model to allow such
   systems to be given a single integrated interface.
3. Creating a distributed system using an object-oriented
   approach.
   The remote objects of CORBA can be accessed from any
   client.
                 IDL Example
This example presents CORBA IDL. An object acts as a
  server of one-line jokes. The IDL specification,
  joking.idl, is used for the object and is shown below:

interface joke {
     string oneLiner(in short lineWanted);
     string nextLine();
     oneway void shutdown();
  };
      Accessing CORBA objects
If a client program has got the address of a CORBA Joke object
   then it can call the methods defined in the IDL file.
For example, in Java, the IDL code is compiled to a Java
   interface. If the client program contains the address of the Joke
   object in the Java variable, jokeListObj, the client can
   access the Joke object with code such as:

String joke1 = jokeListObj.next_line();
String joke2 = jokeListObj.one_liner((short) 4));
         OMA - Architecture
                                    Server
                                     Server code
Client
                                       Servant A
                Implementation
                Repository             e.g. Java methods
 Client code

                                       Skeleton
                       Interface
 Proxy for A
                       Repository
                                       Object Adaptor


               ORB core
                    ORB Core(1)
1. A message bus. Allows clients and servers to exchange
   messages.
2. Interface to ORB core allows:
   (a) Starting and stopping
   (b) Operations to convert between remote object references
   and strings.
   (c) Operations that allow clients to interrogate the ORB to get
   the methods associated with a CORBA object and the
   associated signatures.
                    ORB Core(2)
1. Activates and de-activates objects
2. Responsible for load-balancing.
3. Controls resources
4. Manages fault-tolerance
www.omg.org
“So, some ORBs run all of their functionality in a single process
   on the same machine as their clients and servers, as you
   probably imagined before we started this discussion. On the
   other hand, some ORBs spread their work over multiple
   processes on a single machine, and others spread their work
   over many machines using the network”
                        Servant

The actual code which implements a CORBA object is usually
  written in a standard programming language such as Java or
  C++. It is called the Servant code or the Implementation code.
                          Server
A server in CORBA terms is a software entity which is
  responsible for managing one or more CORBA objects.

The Server contains code which:
(1) Creates one or more Servant objects.
(2) Connects to the ORB core
(3) Gets each servant object a CORBA object reference
   associated with the ORB.
(4) (Optionally) registers each object with a Naming Service.
                 Object Adapter
Software which links language-specific software that links each
   object with the software in the ORB core. For example, an
   object might be implemented in Java or C++, so we would
   need object adaptors to allow interactions between the Java
   code and the ORB and C++ and the ORB.
The Portable Object Adapter standard allows CORBA
   applications to run on ORBs produced by different software
   developers.
An object adapter:
(a) Creates remote object references for CORBA objects
(b) Transmits RMI messages to servant skeleton.
(c) Activates and deactivates servants.
                 CORBA Client
A CORBA client program contains code to do the following:
(1) Connect to the ORB core
(2) (Optionally) Locate CORBA objects by performing a lookup
   operation on a Naming service.
(3) Use client stub code (aka proxy code) to make remote method
   invocations on CORBA objects.
     Implementation Repository
Some CORBA objects are designed to exist over long periods.
  For example, a database object may have a CORBA interface.
  The server which presents such a persistent object to the
  outside world may not always be running, and it may be
  necessary to activate the object by running the server.
The IMR stores a table in which each row contains a reference to
  a persistent object and a reference to the server which must be
  run to activate the object, plus a reference to the object adaptor
  which must be used.
Because different applications have differing needs the IMR is
  implemented in different ways in different CORBA systems.
            Interface Repository
The Interface Repository (IR) lists the interfaces which are
  currently registered with an ORB and the associated method
  signatures.
The IR is not needed for static invocations where clients are
  already provided with stubs to use, but is useful for dynamic
  invocations whereby clients may send the IR the identifier of a
  given interface and receive back specifications of the
  associated interfaces.
             CORBA IDL
     Interface Definition Language
The CORBA Interface Definition Language (IDL) allows system
  designers to specify more complex interfaces than the ones
  already shown. IDL is language-independent. It allows
  systems designers to specify the interfaces to objects in a
  standard format and then to compile the IDL specification to
  any language for which a CORBA mapping exists. IDL
  mappings exist for many languages, but most often C++ and
  Java are used because they are object-oriented languages.

The example below, is a file, Pieshop.idl. It defines three classes.
  The first class, Base is extended by two other classes, Order
  and PieShop.
module Pieshop {

interface Base {
    const float       PI = 3.14159;
    typedef float     Price;
    typedef string    Date;
    typedef string    Name;

      struct   Pie {
      string   piename;
      string   type;
      short    weight_in_grams;
      Price    cost_price;
      Price    sale_price;
      short    quantity;
      };

      typedef sequence <Pie> Pies;
} ;
interface Order : Base {

     readonly attribute Date    when;
     readonly attribute Pies    pies_ordered;
     readonly attribute Price   total_agreed_price;
     readonly attribute Name    customer_name;
     void cancel()
         raises (TooLate);
};

interface PieShop : Base {

     readonly  attribute string name;
     boolean   checkIfAvailable(in Pie which_pie);
     Pies      listAvailablePies(in name customer_name);
     boolean   orderPies(in Pies selected_pies,
                         in Price customer_offer_price,
                         in Date    when,
                         in string customer_name,
                         out Price pie_shop_sale_price)
          raises (NoPiesAvailable);
     };
};
   Five Main Components of IDL
1. Module
A module is a collection of interface definitions. (It can contain
  other modules, so the definition is recursive.)
Example: there is one module called Pieshop.
2. Interface
An interface defines (the external behaviour of) a class and the
  operations and attributes which are defined for that class. It can
  also define data types, constants and exceptions.
Example: there are three interfaces, one called Base, one called
  Order and one called Pieshop.
An attribute is a value, defined for each instance of a class, which
  can be read from or written to.
Examples: when, pies_ordered, total_agreed_price and
  customer_name are attributes of an order.
A method is an operation which can be performed, e.g.
boolean orderPies(in Pies           selected_pies,
                  in Price           customer_offer_price,
                  in Date            when,
                  in string          customer_name,
                  out Price          pie_shop_sale_price)
raises (NoPiesAvailable);
3. Data Type
A data type can be either a basic data type or a user-defined data type.
    – Basic data types include:
    – short - 16 bit integer - maps to Java short
    – long - 32-bit - maps to Java int
    – char - 8-bit character
    – wchar - wide char - implementation-dependent
    – string - string - maps to java.lang.String.
    – octet - Java byte
    – ... and more
The user can create new structures and define arrays.
struct
A struct is a fixed data structure that can be used throughout a
  module definition.
Example: The Pie struct below defines attributes of a pie.
struct Pie    {
    string    piename;
    string    type;
    short     weight_in_grams;
    Price     cost_price;
    Price     sale_price;
    short     quantity;
    };
Sequences
An IDL sequence is a one-dimensional array. (It is mapped to
  a Java array).
Example:
The example allows the user to define an array of pies.

typedef sequence <Pie> Pies;
4. Constants and Literals
These follow fairly standard rules.
Thus:
3.1459 is a literal for a floating point number,
'a' is a character literal,
1000 is an integer literal,
'\n' is a newline
"Antonin Dvorak" is a string literal.
5. Exceptions
Just as in Java, so too in CORBA can one define exceptions, that
    signal errors or other situations that need to be handled
    explicitly.
The syntax for an exception in IDL is:
exception identifier { data-member, data-member, ....}
Example:
exception BadIP {
       short ipvalue;
}
There are also standard system exceptions that can be raised. These
  all have the same structure:

exception <SystemExceptionName>
  unsigned long minor; // minor error code
                       // (more detail about error)
  CompletionStatus completed;   // yes, no, maybe
           Interface Inheritance
An IDL interface can inherit methods and attributes from another
  interface.
The syntax is:
interface identifier : parent interface, parent interface , {...


Note the colon - it's the symbol that indicates inheritance.
Example
The interface, Base, is used to define various constants and data
  structures that are inherited by both Order and Pieshop.
         Advantages of CORBA
CORBA is suitable for software, which must run on a network of
  machines.
CORBA facilitates interoperability between heterogeneous
  systems. Systems may have been developed at different times
  using different programming languages and operating systems.
  Systems may also be autonomous - capable of acting
  independently. It is desirable to have systems interoperate in a
  tidy fashion. CORBA is the Araldite of middleware. It is
  capable of allowing different types of system to operate
  together.
A standard - so it's portable. The programmer can use the same
  interfacing language, IDL, for many different situations.
      Disadvantages of CORBA
1. It adds extra layers of software to an application, which both
   slow down processing and add to the complexity of
   development.
2. Not all applications are suited to object-oriented interfaces (see
   comments on SQL).
3. Full CORBA systems may be expensive.
 CORBA Compared to Java rmi
1. Many different languages can be used to implement the
   components of the same CORBA system. For example, a
   server and its servants can be written in Java, but the client can
   be written in Visual Basic or C++.
   Java rmi must be written in Java and all the code is compiled
   into the Java run-time language.
2. In Java rmi it is possible to transmit the code associated with
   an object as well as the object itself. In CORBA, only either
   data structures or the addresses of objects may be transmitted.
3. Because CORBA must accommodate many languages it tends
   to be slower than Java rmi.
             CORBA and JDBC
JDBC allows any SQL operation on the associated database
   (subject to security restrictions). CORBA allows only the
   operations specified in the IDL.
1. CORBA may be less flexible than a JDBC interface because
   the end user cannot vary the range of operations allowed.
2. CORBA may be more secure than JDBC because of the
   restriction on the allowed operations.
3. A CORBA remote method invocation returns exactly the data
   specified in one operations. An SQL query usually returns a
   recordset and the client must arrange to move through the
   recordset in order to scan the full results of the query.
               Java and CORBA
1.   Create IDL
2.   Compile IDL file and create various Java classes.
3.   Create Java file to implement Servant for each interface.
4.   Create Java file for Server which interfaces to ORB, creates
     Servant objects and possibly registers Servants with the
     CORBA Name Service.
5.   Create Java Client file which interfaces to ORB, possibly
     looks up CORBA objects with Name Service and invokes
     remote methods on CORBA objects.
6.   (Possibly) Run Name Service, run Server, run Clinet
                   IDL Compiler
1. An IDL compiler generates the actual data structures to be
   used in an actual language such as Java.

2. The IDL compiler also creates stub code - this code is used by
   the client and translates the parameters in the method into data
   in a message.

3. The skeleton code created by the IDL compiler is attached to
   the object on the server machine. The skeleton code unpacks
   the message into data for the object to process.
• E:\joke-example>compile-idl       Run the java IDL
• E:\joke-example>idlj -fall joking.idlcompiler on
• E:\joke-example>dir                   joking.idl
• Directory of E:\joke-example
     The Joke interface for
•   01/11/2003 08:30           <DIR>         .
              client
•   01/11/2003 08:30           <DIR>         ..
      Helper file to convert
•   01/11/2003 08:29                      23 compile-
    CORBA methods to java
    idl.bat
•           methods
    01/11/2003 08:30                     299 Joke.java
•     Holder file 08:30
    01/11/2003 to create               1,763
    JokeHelper.java
    CORBA input and output
•      from java 08:30
    01/11/2003 methods                   707
    JokeHolder.java
•   01/11/2003 08:30
     Java interface to                   333
    JokeOperations.java
    actual operations                           Stub class for
•   01/11/2003 08:30       Portable     2,403
    JokePOA.java                                    client
                           Object Adapter
•   01/11/2003 08:28                     133 joking.idl
•   01/11/2003 08:30                   3,456
  Implementation - JokeServant
class JokeServant extends JokePOA {
   private ORB orb;
   private BufferedReader qfs = null;
   private int nextLineInFile = 1;

public void setORB(ORB orb_val) {
   orb = orb_val;
}
// implement shutdown() method
public void shutdown() {
   orb.shutdown(false);
}
/** Construct a CORBA object. */
public JokeServant() {
   this.openInputFile();
}
/** JokeServant Read the next line in file of jokes   */

public synchronized java.lang.String nextLine() {
   if (qfs == null) return
           "JokeServant: I haven't opened the file!";
   String returnValue = null;
   try {
      if ((returnValue = qfs.readLine()) == null) {
         qfs.close();
         this.openInputFile();
         returnValue = qfs.readLine();
         nextLineInFile = 2;
      // we know the file has at least one input line!
      }
      else
         nextLineInFile++;
   } catch (IOException e) {
         returnValue = "IOException occurred in Server.";
   }
   return returnValue;
}
/** JokeServant Get a specific line from the file    */

public synchronized java.lang.String oneLiner(short lineWanted)
   {
   ...
   if (lineWanted > nextLineInFile) { // skip lines
       int lines = 0;
       for (lines = nextLineInFile; lines <= lineWanted; lines++)
   {……
            returnValue = qfs.readLine()) == null) {
            nextLineInFile++;
       }
       return returnValue;
   }
   else { // close file, re-open, then read till line is found
       qfs.close();
       this.openInputFile();
       for (lines = 1; lines <= lineWanted; lines++) {……
          returnValue = qfs.readLine()) == null )
          nextLineInFile++;
       }
       return returnValue;
   }
/** JokeServant - Open the input file (private) */

private void openInputFile() {
   try {
      qfs = new BufferedReader(
            new FileReader("one-liners.txt"));
   } catch (java.io.FileNotFoundException e) {
      System.err.println("Could not open quote file");
   }
}
}
                       Servers
As we have already remarked the processes providing access to
  the implementation of CORBA objects are called servers.
  There are many options as to how these processes are
  implemented.
A server may contain the code for just one object or it may
  contain the code for many objects.
When an invocation for an object is made there are many
  different options for handling the invocation.
/* The JokeServer */

public class JokeServer {

  public static void main(String args[]) {
    try{
      // create and initialize the ORB
      ORB orb = ORB.init(args, null);

      // get reference to rootpoa & activate the POAManager
      POA rootpoa =

  POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
     rootpoa.the_POAManager().activate();

      // create servant and register it with the ORB
      JokeServant jokeImpl = new JokeServant();
      jokeImpl.setORB(orb);

                                      only one object here but
                                        could define several
// Get object reference from the servant object
      org.omg.CORBA.Object ref =
              rootpoa.servant_to_reference(jokeImpl);
      Joke jref = JokeHelper.narrow(ref);

      // get the root naming context
      // NameService invokes the name serviceNeeded so we can
      org.omg.CORBA.Object objRef =            use the Name
          orb.resolve_initial_references("NameService");
                                                  Service
      // Use NamingContextExt which is part of the Interoperable
      // Naming Service (INS) specification.
      NamingContextExt ncRef =
                 NamingContextExtHelper.narrow(objRef);

      // bind the Object Reference in Naming
      String name = "myjoke";
      NameComponent path[] = ncRef.to_name( name );
      ncRef.rebind(path, jref);

      System.out.println("JokeServer ready and waiting ...");
      // wait for invocations from clients
      orb.run();
          Creating and Running Server
1. Compile idl file
2. Implement the Java class, JokeServant (inside JokeServer.java in
   example)
3. Implement the code for the server, JokeServer
4. Run the Name Server e.g. runnameserver.bat:
     start tnameserv -ORBInitialPort 1050
     Note that the ORB is accessed at port 1050 and a new window is created
Initial Naming Context:
                                                                Port number
IOR:000000000000002b49444c3a6f6d672e6f72672f436f734e616d696e672f4e616d696e67436f
6e746578744578743a312e30000000000001000000000000007c000102000000000a3132372e302e
                                                                1050 in use.
302e3100041a00000035afabcb0000000020968de8160000000100000000000000010000000d544e
                                                                start used in
616d65536572766963650000000000000004000000000a0000000000000100000001000000200000
000000010001000000020501000100010020000101090000000100010100
TransientNameServer: setting port for initial
                                                                  MS-Dos.
                                                           object references
    to: 1050                                                     Unix might
Ready.                                                             run in
Run the server e.g. runserver.bat:                              background
     java JokeServer -ORBInitialPort 1050
              The CORBA Client
The CORBA client uses the Joke interface to access the remote
  objects. The Joke.class file must be in the client's class path.
The CORBA client must be able to connect to the Java ORB, to
  locate the remote CORBA object, and then to invoke the
  methods on the object.
We have created two CORBA clients. The first one,
  JokeClient.java requests jokes and the second shuts down
  the object.
The next slide shows the files in the client directory.
  Files in CORBA client directory
                            Class files created in
Directory of … client-dir     Server directory

01/11/2003   09:02             179 Joke.class
01/11/2003   09:39           1,394 JokeClient.class
01/11/2003   09:39           1,001 JokeClient.java
01/11/2003   09:02           2,565 JokeHelper.class
01/11/2003   09:02             219 JokeOperations.class
01/11/2003   09:42           1,396 RemoteShutDown.class
01/11/2003   09:42             985 RemoteShutDown.java
01/11/2003   09:20              38 runclient.bat
01/11/2003   09:45              42 runshutdown.bat
01/11/2003   09:02           2,691 _JokeStub.class
               10 File(s)    10,510 bytes
public class JokeClient {

public static void main(String args[]) {
  try{// create and initialize the ORB
    ORB orb = ORB.init(args, null);
    org.omg.CORBA.Object objRef = // access Naming Service
    orb.resolve_initial_references("NameService");
    NamingContextExt ncRef =
             NamingContextExtHelper.narrow(objRef);
    String name = "myjoke";
    Joke jokeImpl =
             JokeHelper.narrow(ncRef.resolve_str(name));
     System.out.println(
       "Obtained a handle on server object: " +
                           jokeImpl);

       System.out.println( jokeImpl.nextLine() );
   }
     Creating and Running Client
1.   Create code for client. (E.g. JokeClient.java)
2.   Compile client.
3.      javac JokeClient.java
4.     Check that stubs, Narrowing files, etc. are in class path
3.   Check that Name Server and Server are running
4. Run client, e.g. runclient.bat
     java JokeClient -ORBInitialPort 1050
    Client which shuts down object
public class RemoteShutDown {

public static void main(String args[]) {
   try{
      ORB orb = ORB.init(args, null);
      org.omg.CORBA.Object objRef =
          orb.resolve_initial_references("NameService");

     NamingContextExt ncRef =
  NamingContextExtHelper.narrow(objRef);

      String name = "myjoke";
      Joke jokeImpl = JokeHelper.narrow(ncRef.resolve_str(name));

      System.out.println("Obtained a handle on server object: " +
                           jokeImpl);
      jokeImpl.shutdown();
   }
   catch……
                    Conclusion
CORBA can be used where interoperability is needed.
Recent versions of Java implement CORBA quite easily
There are some extra penalties for using CORBA but many cases
  where it is the only possibility.

								
To top