William Grosso, (C) 1999, all rights reserved CORBA.

Slides:



Advertisements
Similar presentations
Slides for Chapter 20: CORBA Case Study From Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edition 4, © Addison-Wesley 2005.
Advertisements

Copyright © 2001 Qusay H. Mahmoud RMI – Remote Method Invocation Introduction What is RMI? RMI System Architecture How does RMI work? Distributed Garbage.
15-May-15 RMI Remote Method Invocation. 2 “The network is the computer” Consider the following program organization: If the network is the computer, we.
Common Object Request Broker Architecture (CORBA) By: Sunil Gopinath David Watkins.
CORBA Architecture Nitin Prabhu. Outline CORBA Object Model CORBA Architecture Static Invocation Dynamic Invocation CORBA Communication Model.
CORBA - Common Object Request Broker Architecture.
Seminarium on Component-based Software Engineering Jan Willem Klinkenberg CORBA.
Netprog CORBA Intro1 CORBA Common Object Request Broker Architecture Based partially on Notes by D. Hollinger and Java Network Programming and Distributed.
Event Service Outline Events Channels Event Services Examples
Remote Method Invocation Chin-Chih Chang. Java Remote Object Invocation In Java, the object is serialized before being passed as a parameter to an RMI.
DISTRIBUTED FILE SYSTEM USING RMI
CORBA Framework Eelements 1 CORBA Framework Elements  Object Request Broker (ORB)  This is the object manager in CORBA  Mechanisms for specifying interfaces.
OCT 1 Master of Information System Management Organizational Communications and Distributed Object Technologies Lecture 11: CORBA.
CORBA Case Study By Jeffrey Oliver March March 17, 2003CORBA Case Study by J. T. Oliver2 History The CORBA (Common Object Request Broker Architecture)
CS 501: Software Engineering Fall 2000 Lecture 16 System Architecture III Distributed Objects.
Introduction to Remote Method Invocation (RMI)
OCT 1 Master of Information System Management Organizational Communications and Distributed Object Technologies Lecture 13: CORBA.
II. Middleware for Distributed Systems
CORBA & JAVA A Good Partnership For Distributed Computing.
By Dr. Jiang B. Liu 11. Java IDL and CORBA  Generic ORB Core  idltojava development tool  CORBA Object Service (COS) name service - nameserv  Java.
CORBA Chapter 17 Coulouris text. Today’s Topics CORBA History and goals CORBA RMI CORBA services The Distributed Whiteboard Revisited.
CORBA Programming Using ACE/TAO
Common Object Request Broker Architecture (CORBA) CS-328.
Copyright © 2003 ProsoftTraining. All rights reserved. Distributed Object Computing Using Java and CORBA.
Understanding the CORBA Model. What is CORBA?  The Common Object Request Broker Architecture (CORBA) allows distributed applications to interoperate.
CORBA Celsina Bignoli Enterprise Computing Corporation have similar computing environments: –mixed set of HW platforms –a mixed set.
Cli/Serv.: rmiCORBA/131 Client/Server Distributed Systems v Objectives –introduce rmi and CORBA , Semester 1, RMI and CORBA.
Information Management NTU Interprocess Communication and Middleware.
Copyright (c) Qusay H. Mahmoud 1 The Naming Service (Client’s View) A tree-like directory for object references Much like a file system: provides directory.
1 Java RMI G53ACC Chris Greenhalgh. 2 Contents l Java RMI overview l A Java RMI example –Overview –Walk-through l Implementation notes –Argument passing.
Spring/2002 Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads 1 RMI.
Abhishek Bachchan Vishal Patangia
CORBA/IDL Common Object Resource Broker Architecture (CORBA) Interface Definition Language (IDL) Object Management Group (OMG) ( Specification.
CORBA – Command Line CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L.
RMI remote method invocation. Traditional network programming The client program sends data to the server in some intermediary format and the server has.
RMI Remote Method Invocation Distributed Object-based System and RPC Together 2-Jun-16.
CORBA Event Service Martin Senger
CORBA Details Three Tier Architecture CORBA API Holders and Helpers COS Naming and Naming Contexts Transient and Persistent Objects Properties Callbacks.
 Remote Method Invocation  A true distributed computing application interface for Java, written to provide easy access to objects existing on remote.
Slides for Chapter 17: CORBA Case Study From Coulouris, Dollimore and Kindberg Distributed Systems: Concepts and Design Edition 3, © Addison-Wesley 2001.
CORBA Common Object Request Broker Architecture. Basic Architecture A distributed objects architecture. Logically, an object client makes method calls.
Update on CORBA Support for Babel RMI Nanbor Wang and Roopa Pundaleeka Tech-X Corporation Boulder, CO Funded by DOE OASCR SBIR.
Java Programming: Advanced Topics 1 Networking Programming Chapter 11.
CORBA – Eclipse CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L.
CS 501: Software Engineering Fall 1999 Lecture 12 System Architecture III Distributed Objects.
CORBA_1/001 Department of Computer Science Southern Illinois University Edwardsville Spring, 2010 Dr. Hiroshi Fujinoki CORBA:
 Common Object Request Broker Architecture  An industry standard developed by OMG to help in distributed programming.
Li Tak Sing COMPS311F. RMI callbacks In previous example, only the client can initiate a communication with the server. The server can only response to.
Server-Side Java Mapping Copyright © ZeroC, Inc. Ice Programming with Java 6. Server-Side Java Mapping.
Java Basics Opening Discussion zWhat did we talk about last class? zWhat are the basic constructs in the programming languages you are familiar.
Remote Method Invocation with Java-RMI
CORBA (Common Object Request Broker Architechture) Aniket Prabhune Varun Saini Balaprasuna Chennupati Lally Singh.
1 Distributed Programming low level: sending data among distributed computations higher level: supporting invocations among distributed computations network.
(C) 2003 University of ManchesterCS31010 Lecture 14: CORBA.
IDL Models The Inheritance Model: Using the Inheritance Model, you implement the IDL interface using an implementation class that also extends the compiler-generated.
CEN6502, Spring Understanding the ORB: Client Side Structure of ORB (fig 4.1) Client requests may be passed to ORB via either SII or DII SII decide.
Topic 5: CORBA RMI Dr. Ayman Srour
Topic 4: Distributed Objects Dr. Ayman Srour Faculty of Applied Engineering and Urban Planning University of Palestine.
CORBA Barış COŞKUN Çağatay DİKİCİ. INTRODUCTION Computer networks are heterogenous In 1989 OMG(Object Management Group) was formed to address the problems.
Java Distributed Computing
Common Object Request Broker Architecture (CORBA)
CORBA Alegria Baquero.
CORBA Alegria Baquero.
Lecture 4: RPC Remote Procedure Call Coulouris et al: Chapter 5
Lecture 4: RPC Remote Procedure Call CDK: Chapter 5
Distribution Infrastructures
Exercises for Chapter 20: CORBA CASE STUDY
Java Remote Method Invocation
Java Chapter 5 (Estifanos Tilahun Mihret--Tech with Estif)
Presentation transcript:

William Grosso, (C) 1999, all rights reserved CORBA

This Lecture zCommon Object Request Broker Architecture (CORBA) zStart with Limo example to illustrate general principles (and IDL syntax) zNaming Service

Recall: Sockets zStreams-based communication between any two computers on a network zNo requirement that the both client and server use Java (language independence) zConnection, location, and lifecycle management written by application programmers zApplication programmers must convert data and method calls into and out of stream format (marshalling)

Recall: RMI zLayer on top of Sockets zHas solutions for all the Socket red stuff yConnection management and marshalling is in the stubs yLocation management via the registry yLifecycle management via activation zBoth client and server must be Java yDistributed garbage collection, yCan pass (serializable) objects by value

What is CORBA zSpecification for distributed object communications yDefined and maintained by the Object Management Group ( yLocation transparency and object activation are fundamental to the specification zLanguage independent and platform neutral zLarge number of extensions (Services and Facilities) designed by industry working groups

The Object Management Group zIndustry consortium zAt this point, about 800 members yVarious types of members; xSome vote xSome just serve on task forces OMG Board Architecture Board Task Forces

History of CORBA z1989: OMG founded by 8 members z1991: CORBA 1.1 yIncludes IDL and basic functionality definitions yNo real specifications for interoperability z1994: CORBA 2.0 yInteroperability (GIOP) and the BOA defined zCurrently: CORBA 2.4 yMinor modifications to 2.0, the definition of the POA, and objects-by-value

Reference Model Object Request Broker (ORB) Application Objects Services Facilities

Process-Level Schematic GIOP / IIOP (Wire protocol) Client Object Static Stubs Dynamic Invocation Orb Functionality Interface Repository Implementation Repository Server Object static Skeletons Dyunaic Skeleton Interface Orb Functionality and Object Adapters

The ORB zThe ORB, and the associated object adapters, define the infrastructure for client- server programming zMore conceptual than architectural yThere is no distinct process you can point to and say “that’s the orb” yIt’s a library you link into your code zA client uses an object reference and a method call (in the client language) yORB handles the rest of the networking details

IIOP  ORB Independence zThe ORB is a message bus that takes client language message calls and translates them into IIOP invocations zThe ORB is a message bus that takes IIOP invocations and translates them into server language method calls zWorks across vendors yCode can be ported to a different vendor yClient and server don’t need to be using same vendor’s orb

CORBAServices zIdea: standardize common servers and design decisions zThese are not things in the environment (like printers) so much as objects that most developers, across most domains, use zExamples: Naming, Trader, Events, Lifecycle, Transaction, Properties zYou can go out and buy an event service and plug it into your orb

CORBAFacilities zOriented towards the end-user, rather than the developer zPartially abstractions of standard environmental features yPrinting Facility ySystems Management Facility zAlso contains things like a document model (pretty much OpenDoc) and the Mobile Agent Facility

Interface Definition Language zRemember-- CORBA wants to be platform and language independent zWhat does this mean ? yYou can write a client in one language yYou can have an already existing server written in another language yCORBA will connect them zThe way CORBA achieves this is through IDL

Define Interfaces in IDL zRigorously defined language for specifying an API yMethod definitions, but no computational constructs zC++ like syntax (and preprocessor) zCORBA spec contains a complete definition of IDL and a set of mappings from IDL to target languages yOther groups have proposed additional mappings

Language Independence ? Server Interfaces Defined in IDL Skeleton Stub Skeleton Stub Skeleton Stub Skeleton IDL Compilers use mappings to generate stubs and skeletons in target languages

The CORBA Development Cycle zWrite IDL definitions zCompile IDL to java yJavasoft has idltojava, Visigenic has idl2java,... yThis will give you stubs and skeletons zWrite the server and client code in Java zUse javac to compile the programs zConfigure the deployment environment

Recall our Banking Program zWe had a set of bank account objects, which could be found by using the owner’s name. zEach object function as a small server zPersistence was handled by a background thread zDeactivation handled by use of Unreferenced and the activation framework

BankAccount public interface BankAccount extends Remote { public String getOwner() throws RemoteException; public float getBalance() throws RemoteException; public boolean withdrawCash(float amount) throws RemoteException; public boolean depositCash(float amount) throws RemoteException; }

IDL for a Similar Server module grosso { module simplebank { exception NegativeAmountException{}; exception OverdraftException { boolean succeeded; }; interface BankAccount{ attribute string owner; readonly attribute float balance; void withdrawCash(in float amount) raises (NegativeAmountException, OverdraftException); void depositCash(in float amount) raises(NegativeAmountException); };

The Structure of IDL zAbstract specification language zSyntax derived from C++ yC++ style comments yAll declarations end in semicolons yStandard preprocessor commands (#ifdef, #define, #include, #pragma) zCase sensitive but with an exclusionary rule yTwo constructs cannot upper-case to the same string zAll identifiers start with a letter

Basic Types in IDL

Structs zDeclared using the keyword struct zCan contain any other types (including structs and objects) struct BugDescription { species bug_species; string first_name; string last_name; unsigned short number_of_legs; unsigned short calories_when_used_as_salad_topping; }; struct Species{ kingdom kingdom; // an enumerated type defined earlier phylum phlya; // an enumerated type defined earlier string formal_name; };

Exceptions zAlmost exactly like structs zAlso define types zCan be passed as arguments or returned as values zCan also be raised by methods enum Rationale { bug_never_existed, bug_escaped, bob_ate_it}; exception BugNotFound{ bug_description the_bug; rationale why_missing; };

Template Types zSequences and arrays are the standard containers zUsually typedef’d as well (must be typedef’d to be used as argument or return types in a method call) sequence variable_name type[int][int] variable_name typedef sequence BookShelf; typedef Book[30] BookShelf; typedef sequence UnboundedBookShelf; typedef LastName string

Typedefs zTypes are frequently aliased and renamed in IDL. zThis is especially true for structs and template types typedef old_type_name new_type_name; typedef template_definition new_type_name ;

Attributes zAn attribute is simply shorthand for declaring an accessor/mutator pair zNice part of this: exact syntax of accessor/mutator is specified in the language mapping (according to the local idiom) zAttributes can be readonly attribute string food; attribute long height, width, depth; readonly attribute string food;

Method Calls zGeneral syntax is a little more complex than in Java delivery-style return-type method-name (comma delimited sequence of arguments) raises (comma delimited sequence of exceoptions);

Delivery Style zIf omitted, defaults to synchronous delivery yHas at-most-once semantics yCaller blocks until method returns or exception is thrown zCan be specified as oneway ybest-effort semantics yCannot have any return values or raise exceptions yMessage is sent and client immediately continues processing

Arguments zEvery argument must have a directional indicator yin: this argument is sent to the server, but need not be sent back yout: this argument is, in essence, a return value yinout: this argument is sent to the server. The server will also send back a value for this argument to assume

Interfaces zInterfaces define Servers. yThey define “object” in CORBA yInterfaces are like objects that extend Remote in RMI zSupport multiple inheritance interface BankAccount { attribute string owner; readonly attribute float balance; void withdrawCash(in float amount) raises (NegativeAmountException, OverdraftException); void depositCash(in float amount) raises(NegativeAmountException); };

Modules zA module is a grouping mechanism, much like a package in Java zModules can contain other modules zScoping of references is done with the :: operator ycontaining-module::inner-module::interface

Event Channel IDL // CosEventComm.idl #pragma prefix "omg.org" module CosEventComm { exception Disconnected {}; interface PushConsumer { void push(in any data) raises(Disconnected); void disconnect_push_consumer(); }; interface PushSupplier { void disconnect_push_supplier(); }; interface PullSupplier { any pull() raises(Disconnected); any try_pull(out boolean has_event) raises(Disconnected); void disconnect_pull_supplier(); }; interface PullConsumer { void disconnect_pull_consumer(); };

Event Channel IDL II // CosEventChannelAdmin.idl #include "CosEventComm.idl" #pragma prefix "omg.org" module CosEventChannelAdmin { exception AlreadyConnected {}; exception TypeError {}; interface ProxyPushConsumer : CosEventComm::PushConsumer { void connect_push_supplier(in CosEventComm::PushSupplier push_supplier) raises(AlreadyConnected); }; interface ProxyPullSupplier : CosEventComm::PullSupplier { void connect_pull_consumer(in CosEventComm::PullConsumer pull_consumer) raises(AlreadyConnected); }; interface ProxyPullConsumer : CosEventComm::PullConsumer { void connect_pull_supplier(in CosEventComm::PullSupplier pull_supplier) raises(AlreadyConnected); }; interface ProxyPushSupplier : CosEventComm::PushSupplier { void connect_push_consumer(in CosEventComm::PushConsumer push_consumer) raises(AlreadyConnected); };

Event Channel IDL III interface ConsumerAdmin { ProxyPushSupplier obtain_push_supplier(); ProxyPullSupplier obtain_pull_supplier(); }; interface SupplierAdmin { ProxyPushConsumer obtain_push_consumer(); ProxyPullConsumer obtain_pull_consumer(); }; interface EventChannel { ConsumerAdmin for_consumers(); SupplierAdmin for_suppliers(); void destroy(); }; interface EventChannelFactory { exception AlreadyExists {}; exception ChannelsExist {}; EventChannel create(); EventChannel create_by_name(in string name) raises(AlreadyExists); EventChannel lookup_by_name(in string name); void destroy() raises(ChannelsExist); };

Limos Revisited Remote RemoteObject UnicastRemoteObject DispatcherLimo DispatcherImpl LimoImpl DriverLocationPassenger Serializable RemoteServer

Limo in IDL module grosso{ module corbalimo{ struct Location { short x; short y; }; struct Passenger{ Location starting_location; Location destination; }; struct Driver{ string name; }; interface Limo; // Forward declaration to break compiler // circularity interface Dispatcher{ Limo hailLimo(in Passenger new_passenger); void limoAvailable(in Limo limo); void limoUnavailable(in Limo limo); };

Limo in IDL //.... interface Limo { attribute Dispatcher current_ispatcher; readonly attribute Location current_location; readonly attribute Driver current_driver; boolean getIsCarryingPassenger(out Passenger current_passenger); /* multiple return values */ boolean wantPassenger(in Passenger possible_passenger); boolean pickupPassenger(in Passenger new_passenger); };

The CORBA Development Cycle zWrite IDL definitions zCompile IDL to java yJavasoft has idltojava, Visigenic has idl2java,... yThis will give you stubs and skeletons zWrite the server and client code in Java zUse javac to compile the programs zConfigure the deployment environment

Break Time

Compiling is Simple zORB vendors are required to provide an IDL to Java compiler that implements the standard mapping yInput: IDL yOutput: Java source code zWarning: vendors frequently implement other mappings as well idl2java BankAccount.idl -strict -portable -VBJvmflag ”-Xbootclasspath:%CLASSPATH_WITHOUTINTERBASE%" idltojava -fno-cpp -ftie limo.idl

The Mapping is more Complicated

Conceptual Mappings

Mapping Basic Types

Mapping Constructed Types

Holders zProblem: out, and inout, arguments do not correspond to anything in the java language zSolution: Wrap the value in a holder class which can read and write the argument to a stream zMethod calls which have out, or inout, arguments take a holder class instead of the original type yAdditional complexity for client side developer

public interface Limo extends org.omg.CORBA.Object { public void current_ispatcher(grosso.corbalimo.Dispatcher current_ispatcher); public grosso.corbalimo.Dispatcher current_ispatcher(); public grosso.corbalimo.Location current_location(); public grosso.corbalimo.Driver current_driver(); public boolean getIsCarryingPassenger(grosso.corbalimo.PassengerHolder current_passenger ); public boolean wantPassenger(grosso.corbalimo.Passenger possible_passenger); public boolean pickupPassenger(grosso.corbalimo.Passenger new_passenger ); } Holders in Limo interface Limo { attribute Dispatcher current_ispatcher; readonly attribute Location current_location; readonly attribute Driver current_driver; boolean getIsCarryingPassenger(out Passenger current_passenger); /* multiple return values */ boolean wantPassenger(in Passenger possible_passenger); boolean pickupPassenger(in Passenger new_passenger); }; becomes

PassengerHolder package grosso.corbalimo; final public class PassengerHolder implements org.omg.CORBA.portable.Streamable { public grosso.corbalimo.Passenger value; public PassengerHolder() { } public PassengerHolder(grosso.corbalimo.Passenger value) { this.value = value; } public void _read(org.omg.CORBA.portable.InputStream input) { value = grosso.corbalimo.PassengerHelper.read(input); } public void _write(org.omg.CORBA.portable.OutputStream output) { grosso.corbalimo.PassengerHelper.write(output, value); } public org.omg.CORBA.TypeCode _type() { return grosso.corbalimo.PassengerHelper.type(); }

Any zGeneric type, similar to void * with reflection added. Can represent any IDL type (basic or constructed, object or non-object) zUsed in IDL as a type zCorresponds to org.omg.CORBA.Any

Any Methods boolean equal(Any a) ; Any extract_any() ; boolean extract_boolean(); char extract_char() ; char extract_wchar(); String extract_string(); String extract_wstring(); BigDecimal extract_fixed(); double extract_double(); float extract_float() ; short extract_short() ; short extract_ushort(); int extract_long(); int extract_ulong(); long extract_longlong(); long extract_ulonglong(); Object extract_Object(); byte extract_octet(); TypeCode extract_TypeCode(); TypeCode type() ; void type(TypeCode t); insert_any(Any a); insert_boolean(boolean b); insert_char(char c) ; insert_wchar(char c); insert_string(String s); insert_wstring(String s); insert_fixed(BigDecimal bD); insert_double(double d); insert_float(float f); insert_short(short s); insert_ushort(short s); insert_long(long l) ; insert_ulong(long l); long insert_longlong(long l); insert_ulonglong(long l) ; insert_Object(Object o); insert_Object(Object o, TypeCode t); insert_octet(byte b);

Helpers zEvery constructed type has an associated Helper class as well zHelpers extend the CORBA type system to deal with your object definitions zThey have static methods to yInsert and extract instances from an Any yGet typecodes yPerform narrowing (down-casting) operations

Helpers and Narrowing zInterfaces in IDL have an inheritance hierarchy zJava is a single (implementation) inheritance language zSuppose FastLimo was a sub-class of Limo in our IDL

The FastLimo Hierarchy

Back to our Generated Files

zInterfaces in IDL compile into 7 different objects zLimo compiles into x_LimoImplBase x_LimoOperations x_LimoTie x_LimoStub xLimo xLimoHelper xLimorHolder Servers _LimoImplBase org.omg.CORBA.DynamicImplementation _LimoStub Limo LimoHelper LimoHolder _LimoOperations_LimoTie org.omg.CORBA.Object

Ties versus Bases zServers can be built by inheriting from an abstract superclass which knows about IIOP and how to send messages / marshall data over the wire y_xxxImplBase has a set of template methods that you can implement in a subclass in order to build a server zYou can also build them by aggregating out the “real server functionality” to a servant class.

Base Approach public abstract class _LimoImplBase extends org.omg.CORBA.DynamicImplementation implements grosso.corbalimo.Limo { // Constructor public _LimoImplBase() { super(); } // Type strings for this class and its superclases private static final String _type_ids[] = { "IDL:grosso/corbalimo/Limo:1.0" }; public String[] _ids() { return (String[]) _type_ids.clone(); } private static java.util.Dictionary _methods = new java.util.Hashtable(); static { _methods.put("_get_current_dispatcher", new java.lang.Integer(0)); _methods.put("_set_current_dispatcher", new java.lang.Integer(1)); _methods.put("_get_current_location", new java.lang.Integer(2)); _methods.put("_get_current_driver", new java.lang.Integer(3)); _methods.put("getIsCarryingPassenger", new java.lang.Integer(4)); _methods.put("wantPassenger", new java.lang.Integer(5)); _methods.put("pickupPassenger", new java.lang.Integer(6)); }

Base Approach II public void invoke(org.omg.CORBA.ServerRequest r) { switch (((java.lang.Integer) _methods.get(r.op_name())).intValue()) { case 0: // grosso.corbalimo.Limo.current_dispatcher { org.omg.CORBA.NVList _list = _orb().create_list(0); r.params(_list); grosso.corbalimo.Dispatcher ___result = this.current_dispatcher(); org.omg.CORBA.Any __result = _orb().create_any(); grosso.corbalimo.DispatcherHelper.insert(__result, ___result); r.result(__result); } break; case 1: // grosso.corbalimo.Limo.current_dispatcher { org.omg.CORBA.NVList _list = _orb().create_list(0); org.omg.CORBA.Any _arg = _orb().create_any(); _arg.type(grosso.corbalimo.DispatcherHelper.type()); _list.add_value("arg", _arg, org.omg.CORBA.ARG_IN.value); r.params(_list); grosso.corbalimo.Dispatcher arg; arg = grosso.corbalimo.DispatcherHelper.extract(_arg); this.current_dispatcher(arg); org.omg.CORBA.Any a = _orb().create_any(); a.type(_orb().get_primitive_tc(org.omg.CORBA.TCKind.tk_void)); r.result(a); } break;

Base Approach III case 2: // grosso.corbalimo.Limo.current_location { org.omg.CORBA.NVList _list = _orb().create_list(0); r.params(_list); grosso.corbalimo.Location ___result = this.current_location(); org.omg.CORBA.Any __result = _orb().create_any(); grosso.corbalimo.LocationHelper.insert(__result, ___result); r.result(__result); } break; case 3: // grosso.corbalimo.Limo.current_driver { org.omg.CORBA.NVList _list = _orb().create_list(0); r.params(_list); grosso.corbalimo.Driver ___result = this.current_driver(); org.omg.CORBA.Any __result = _orb().create_any(); grosso.corbalimo.DriverHelper.insert(__result, ___result); r.result(__result); } break; // and so on...

Tie Approach package grosso.corbalimo; public class _LimoTie extends grosso.corbalimo._LimoImplBase { public grosso.corbalimo._LimoOperations servant; public _LimoTie(grosso.corbalimo._LimoOperations servant) { this.servant = servant; } public grosso.corbalimo.Dispatcher current_dispatcher() { return servant.current_dispatcher(); } public void current_dispatcher(grosso.corbalimo.Dispatcher arg) { servant.current_dispatcher(arg); } public grosso.corbalimo.Location current_location() { return servant.current_location(); } public grosso.corbalimo.Driver current_driver() { return servant.current_driver(); } // and so on... }

The Operations Class z_LimoOperations still unexplained zBasically, the Limo interface without any extra funcitonality yUnlike Limo, which inherits from org.omg.CORBA.Object package grosso.corbalimo; public interface _LimoOperations { grosso.corbalimo.Dispatcher current_dispatcher(); void current_dispatcher(grosso.corbalimo.Dispatcher arg); grosso.corbalimo.Location current_location(); grosso.corbalimo.Driver current_driver(); boolean getIsCarryingPassenger(grosso.corbalimo.PassengerHolder current_passenger); boolean wantPassenger(grosso.corbalimo.Passenger possible_passenger); boolean pickupPassenger(grosso.corbalimo.Passenger new_passenger); }

Fundamental Truth zThe code we just went through did three things: yThe client connected to the server yThe client sent a request yThe client got a response zAll methods for distributed programming, at their core, must handle these three things. zThe way to understand an architecture is to make the above sequence into questions

The CORBA Development Cycle zWrite IDL definitions zCompile IDL to java yJavasoft has idltojava, Visigenic has idl2java,... yThis will give you stubs and skeletons zWrite the server and client code in Java zUse javac to compile the programs zConfigure the deployment environment

Break Time

SimpleClient GUI is the Same

Most SimpleClient code is identical too private class ButtonAction implements ActionListener{ public void actionPerformed(ActionEvent e){ try{ Dispatcher dispatcher = CorbaLimoProperties.getDispatcher(); Limo limo = dispatcher.hailLimo(getPassenger()); if (null!=limo){ Driver driver = limo.current_driver(); _reportsBack.append("Limo is driven by " + driver.name +"\n"); } else{ _reportsBack.append("No limos available \n"); } catch (Exception ee){} } z90% of the code is identical to the RMI code zOnly difference is in the Button’s listener

CorbaLimoProperties public class CorbaLimoProperties { private static Properties _properties; public static Properties getProperties() { if (null==_properties) { _properties = new Properties(); _properties.put("org.omg.CORBA.ORBInitialPort", "3500"); _properties.put("org.omg.CORBA.ORBInitialHost", "localhost"); _properties.put("org.omg.CORBA.ORBClass", "com.sun.CORBA.iiop.ORB"); } return _properties; } public static Dispatcher getDispatcher(){ try{ Properties properties = CorbaLimoProperties.getProperties(); ORB orb = ORB.init((String[]) null, properties); org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext nameServer = NamingContextHelper.narrow(objRef); NameComponent ourComponent = new NameComponent("Dispatcher", ""); NameComponent path[] = {ourComponent}; org.omg.CORBA.Object dispatcherRef = nameServer.resolve(path); return DispatcherHelper.narrow(dispatcherRef); } catch (Exception e){ e.printStackTrace(); } return null; }

Properties used by JavaIDL zJavaIDL is the free CORBA implementation ySupplied by Javasoft yNot really intended for industrial-strength use (no real support for servers or object adapters) z4 properties can be set

Using Inheritance to build Servers zWe’re going to separate out the launchers from the servers again (just like in the RMI case) zWe’ll build Limo_Inheritance as a subclass of _LimoBaseImpl zWe’ll build Dispatcher_Inheritance as a subclass of _DispatcherBaseImpl

Limo_Inheritance public class Limo_Inheritance extends _LimoImplBase { private boolean _havePassenger; private Dispatcher _dispatcher; private Location _currentLocation; private Driver _driver; private Passenger _passenger; public Limo_Inheritance (Dispatcher dispatcher, Driver driver) { _havePassenger = false; _dispatcher = dispatcher; _driver = driver; dispatcher.limoAvailable(this); } public grosso.corbalimo.Dispatcher current_dispatcher() { return _dispatcher; }

Limo_Inheritance II public void current_dispatcher(grosso.corbalimo.Dispatcher arg) { if ((false==_havePassenger) &&(null!=_dispatcher)) { _dispatcher.limoUnavailable(this); if(null!=arg) { arg.limoAvailable(this); } _dispatcher = arg; } public grosso.corbalimo.Location current_location() { return _currentLocation; } public grosso.corbalimo.Driver current_driver(){ return _driver; }

Limo_Inheritance III public boolean getIsCarryingPassenger(grosso.corbalimo.PassengerHolder current_passenger){ if (null!=_passenger) { current_passenger.value = _passenger; // using a Holder class } return _havePassenger; } public boolean wantPassenger(grosso.corbalimo.Passenger possible_passenger) { return (false ==_havePassenger); // a very simple model of // cabbie decision making } public boolean pickupPassenger(grosso.corbalimo.Passenger new_passenger) { if (true==_havePassenger) { return false; } _dispatcher.limoUnavailable(this); _passenger = new_passenger; _currentLocation=new_passenger.destination; // in theory we'd drive around for a while now _passenger=null; _dispatcher.limoAvailable(this); return true; }

Dispatcher_Inheritance public class Dispatcher_Inheritance extends _DispatcherImplBase { private ArrayList _availableLimos; public Dispatcher_Inheritance () { _availableLimos= new ArrayList(); } public grosso.corbalimo.Limo hailLimo(grosso.corbalimo.Passenger new_passenger) { Collections.shuffle(_availableLimos); Iterator i = _availableLimos.iterator(); while(i.hasNext()) { Limo limo = (Limo) i.next(); if (limo.pickupPassenger(new_passenger)){ return limo; } return null; } public void limoAvailable(grosso.corbalimo.Limo limo) { if (false==_availableLimos.contains(limo)) { _availableLimos.add(limo); }

Dispatcher_Inheritance II public void limoUnavailable(grosso.corbalimo.Limo limo) { _availableLimos.remove(limo); }

public class Launcher_Dispatcher { public static void main(String[] args) { try { Properties properties = CorbaLimoProperties.getProperties(); ORB orb = ORB.init(args, properties); Dispatcher_Inheritance dispatcher = new Dispatcher_Inheritance(); orb.connect(dispatcher); // This is pretty much a JavaIDL hack // JavaIDL doesn't really support servers well org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext nameServer = NamingContextHelper.narrow(objRef); NameComponent ourComponent = new NameComponent("Dispatcher", ""); NameComponent path[] = {ourComponent}; nameServer.rebind(path, dispatcher); (new SelfCleaningFrame("Dispatcher Server")).show(); //hack to keep JVM alive //because JavaIDL uses Daemon threads } catch (Exception e){ e.printStackTrace(); } Launcher_Dispatcher

Launcher_Limos public class Launcher_Limos { public static void main(String[] args) { // In reality, we'd probably do something a little cleverer // here (use more command line args or use a factory server) try { // first we find the dispatcher Dispatcher dispatcher = CorbaLimoProperties.getDispatcher(); for (int currentTaxiDriver=0; currentTaxiDriver < args.length; currentTaxiDriver++) { Driver driver = new Driver(args[currentTaxiDriver]); Limo currentLimo = new Limo_Inheritance(dispatcher, driver); } (new SelfCleaningFrame("Limos Server")).show(); //hack to keep JVM alive //because JavaIDL uses daemon threads } catch (Exception e){ e.printStackTrace(); }

Running the Application zLaunch the nameserver zLaunch the dispatcher zLaunch the limos zRun the client start java grosso.corbalimo.Launcher_Dispatcher start tnameserv -ORBInitialPort 3500 start java grosso.corbalimo.Launcher_Limos Bob Fred Alice java grosso.corbalimo.SimpleClient.java

Infrastructure in CORBA zThe org.omg.CORBA.ORB class provides basic infrastructure for object management yCreation of CORBA types yStringifying and destringifying object references zAll xxxBaseImpl objects implement org.omg.CORBA.Object yExtra methods that can be called on the object reference (but which are handled locally) zDefined using pseudo-idl (the //PIDL comment)

org.omg.CORBA.ORB zAs usual, defined in IDL zLots of functionality (cf: Chapter 4 of the CORBA spec) interface ORB { string object_to_string(in Object obj); Objecxt string_to_object(in string str); //.... The ORB object is the interface to those functions which do not depend on which object adapter is used. These operations are the same for all ORBs and all object implementations and can be performed either by clients of the objects or by implementations

Stringifying References zThe ORB provides basic object management functionality zOne important piece of functionality is stringifying object references yAny CORBA object reference may be stringified yThe string can be converted back to an object reference yString format defined by OMG, encodes all the information needed to connect to server zEnables bootstrapping of systems

Useful ORB Functionality String[] list_initial_services() Object resolve_initial_references(String object_name) String object_to_string(Object obj) Object string_to_object(String str) shutdown(boolean wait_for_completion) Lists the CORBAServices that are available Takes a canonical name (returned from list_initial_services or known in advance) and returns an object reference Stringifies an object reference Destringifies an object reference Shuts the ORB down. Rarely called on the client side

org.omg.CORBA.Object Object _duplicate() boolean _non_existent() void _release() Request _create_request(Context ctx, String operation, NVList arg_list, NamedValue result) Request _create_request(Context ctx, String operation, NVList arg_list, NamedValue result, ExceptionList exclist, ContextList ctxlist) Request _request(String operation) DomainManager[] _get_domain_managers() Object _get_interface_def() boolean _is_a(String repositoryIdentifier) boolean _is_equivalent(Object other) int _hash(int maximum) Object _set_policy_override(Policy[] policies, SetOverrideType set_add) Policy _get_policy(int policy_type)

Example use of Requests public class _LimoStub extends org.omg.CORBA.portable.ObjectImpl implements grosso.corbalimo.Limo { //... //IDL operations //Implementation of attribute ::current_dispatcher public grosso.corbalimo.Dispatcher current_dispatcher() { org.omg.CORBA.Request r = _request("_get_current_dispatcher"); r.set_return_type(grosso.corbalimo.DispatcherHelper.type()); r.invoke(); grosso.corbalimo.Dispatcher __result; __result = grosso.corbalimo.DispatcherHelper.extract(r.return_value()); return __result; } public void current_dispatcher(grosso.corbalimo.Dispatcher arg) { org.omg.CORBA.Request r = _request("_set_current_dispatcher"); org.omg.CORBA.Any _current_dispatcher = r.add_in_arg(); grosso.corbalimo.DispatcherHelper.insert(_current_dispatcher, arg); r.invoke(); }

More _LimoStub // Implementation of ::grosso::corbalimo::Limo::wantPassenger public boolean wantPassenger(grosso.corbalimo.Passenger possible_passenger) { org.omg.CORBA.Request r = _request("wantPassenger"); r.set_return_type(org.omg.CORBA.ORB.init().get_primitive_tc(org.omg.CORBA.TCKind.tk_boolean)); org.omg.CORBA.Any _possible_passenger = r.add_in_arg(); grosso.corbalimo.PassengerHelper.insert(_possible_passenger, possible_passenger); r.invoke(); boolean __result; __result = r.return_value().extract_boolean(); return __result; } // Implementation of ::grosso::corbalimo::Limo::pickupPassenger public boolean pickupPassenger(grosso.corbalimo.Passenger new_passenger) { org.omg.CORBA.Request r = _request("pickupPassenger"); r.set_return_type(org.omg.CORBA.ORB.init().get_primitive_tc(org.omg.CORBA.TCKind.tk_boolean)); org.omg.CORBA.Any _new_passenger = r.add_in_arg(); grosso.corbalimo.PassengerHelper.insert(_new_passenger, new_passenger); r.invoke(); boolean __result; __result = r.return_value().extract_boolean(); return __result; }

Servers in JavaIDL zAll the above code is generic (either works or can easily be modifed to work with any CORBA 2.x ORB) zBut there’s a remarkably large and unspecified piece in the middle of it yWhat is the following code really doing ? Dispatcher dispatcher = CorbaLimoProperties.getDispatcher(); for (int currentTaxiDriver=0; currentTaxiDriver < args.length; currentTaxiDriver++) { Driver driver = new Driver(args[currentTaxiDriver]); Limo currentLimo = new Limo_Inheritance(dispatcher, driver); }

Real Questions ? zIt’s clearly creating a bunch of server objects zThey’re probably in a single JVM yProbably in the same JVM as the code that creates them zHow many sockets have been allocated ? zHow many threads are listening at the sockets ? zWhat’s the request handling policy ?

Object Adapters zRecall our previous (from slide 10) picture: zThe Object Adapter is a server-side layer, living between the skeletons and the ORB, that helps to answer these questions. GIOP / IIOP (Wire protocol) Server Object static Skeletons Dyunaic Skeleton Interface Orb Functionality and Object Adapters

Common Threading Policies zThread-per-request zThread-per-client zGeneral thread pool Spawns a new thread for each incoming request A different thread is used for each client connection. Has a single thread pool for all the client requests that come in

This decision is made in the Object Adapter zThe Object Adapter is a layer between the ORB and the skeletons. yORB does “generic CORBA stuff” like unmarshalling parameters and passes the method call along to the Object Adapter yObject Adapter does “server-side specific” stuff and then passes the request along to the skeletons xSo it has a chance to check security, or spawn a thread or....

The State of Object Adapters zJavaIDL doesn’t provide an implementation zThe OMG has specified two different Object Adapters yBOA: Basic Object Adapter. xEvery commercial vendor has this right now yPOA: Portable Object Adapter. xBasically, the next generation of BOA Fixes some loopholes in the spec Includes support for common server-side idioms and activation

The Naming Service zDefined as “white pages” for object systems yIf you know the name, you can contact the server ySupports notion of tree-like directory structures zRuns as a server, with an IDL specification yIf you have the object reference, you can talk to any vendor’s Naming Service zFinding a naming service can be vendor specific

Finding the Naming Service zOne way to find the Naming Service is to have a pointer to it already yStringified IIOR can be very useful for this zGetting an original reference to a naming service is more problematic yYou use the reserved name and hope that the ORB can find it org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");

How ORB finds Naming Service is vendor specific zRecall CorbaLimoProperties if (null==_properties) { _properties = new Properties(); _properties.put("org.omg.CORBA.ORBInitialPort", "3500"); _properties.put("org.omg.CORBA.ORBInitialHost", "localhost"); _properties.put("org.omg.CORBA.ORBClass", "com.sun.CORBA.iiop.ORB"); } return _properties; } public static Dispatcher getDispatcher() { try { Properties properties = CorbaLimoProperties.getProperties(); ORB orb = ORB.init((String[]) null, properties); org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); Sun specific OMG defined

IDL for the Naming Service # pragma prefix "omg.org" module CosNaming { typedef string Istring; struct NameComponent { Istring id; Istring kind; }; typedef sequence Name; enum BindingType { nobject, ncontext }; struct Binding { Name binding_name; BindingType binding_type; }; typedef sequence BindingList; interface BindingIterator; // forward declaration

Naming Service IDL (NamingContext Interface) interface NamingContext { enum NotFoundReason { missing_node, not_context, not_object }; exception NotFound { NotFoundReason why; Name rest_of_name; }; exception CannotProceed { NamingContext cxt; Name rest_of_name; }; exception InvalidName {}; exception AlreadyBound {}; exception NotEmpty {}; void bind(in Name n, in Object obj) raises(NotFound, CannotProceed, InvalidName, AlreadyBound); void rebind(in Name n, in Object obj) raises(NotFound, CannotProceed, InvalidName); void bind_context(in Name n, in NamingContext nc) raises(NotFound, CannotProceed, InvalidName, AlreadyBound); void rebind_context(in Name n, in NamingContext nc) raises(NotFound, CannotProceed, InvalidName); Object resolve(in Name n) raises(NotFound, CannotProceed, InvalidName); void unbind(in Name n) raises(NotFound, CannotProceed, InvalidName); NamingContext new_context(); NamingContext bind_new_context(in Name n) raises(NotFound, CannotProceed, InvalidName, AlreadyBound); void destroy() raises(NotEmpty); void list(in unsigned long how_many, out BindingList bl, out BindingIterator bi); };

org.omg.COSNaming public interface NamingContext { public void bind_context(NameComponent[] n, NamingContext nc) ; public NamingContext bind_new_context(NameComponent[] n) ; public void bind(NameComponent[] n, Object obj); public void destroy() ; public void list(int how_many, BindingListHolder bl, BindingIteratorHolder bi); public NamingContext new_context() ; public void rebind_context(NameComponent[] n, NamingContext nc); public void rebind(NameComponent[] n, Object obj) ; public Object resolve(NameComponent[] n) ; public void unbind(NameComponent[] n); } public class NameComponent { public String id public String kind public NameComponent() public NameComponent(String __id, String __kind) }

Naming Service IDL III interface BindingIterator { boolean next_one(out Binding b); boolean next_n(in unsigned long how_many, out BindingList b); void destroy(); }; interface NamingContextFactory { NamingContext create_context(); oneway void shutdown(); }; // The Extended factory contains a root context which allows // clients to bootstrap to a particular factory through // resolve_initial_references() interface ExtendedNamingContextFactory : NamingContextFactory { NamingContext root_context(); };

org.omg.COSNaming in UML

References zHenning and Vinoski, Advanced CORBA Programming with C++ (Addison Wesley) yA Great Book. Period. yOf the 1,000 pages, 400 are C++ specific. The rest constitute the best possible 600 page overview of the CORBA standard zVogel and Duddy, Java Programming with CORBA (Wiley) yA good book; we’ve covered most of it though. yJava specific

Homework zChange the limo example so that the limos launch first and insert themselves into the naming service (under the NamingContext “Limos”) zWhen the dispatcher is launched, it finds all the limos and calls current_dispatcher on them (with itself as argument) zFrom then on, the application is identical