Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "William Grosso, (C) 1999, all rights reserved CORBA."— Presentation transcript:

1 William Grosso, grosso@pacbell.net (C) 1999, all rights reserved CORBA

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

3 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)

4 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

5 What is CORBA zSpecification for distributed object communications yDefined and maintained by the Object Management Group (www.omg.org) 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

6 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

7 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

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

9 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

10 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

11 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

12 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

13 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

14 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

15 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

16 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

17 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

18 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

19 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; }

20 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); };

21 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

22 Basic Types in IDL

23 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; };

24 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; };

25 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

26 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 ;

27 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;

28 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);

29 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

30 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

31 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); };

32 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

33 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(); };

34 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); };

35 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); };

36 Limos Revisited Remote RemoteObject UnicastRemoteObject DispatcherLimo DispatcherImpl LimoImpl DriverLocationPassenger Serializable RemoteServer

37 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); };

38 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); };

39 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

40 Break Time

41 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

42 The Mapping is more Complicated

43 Conceptual Mappings

44 Mapping Basic Types

45 Mapping Constructed Types

46 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

47 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

48 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(); }

49 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

50 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);

51 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

52 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

53 The FastLimo Hierarchy

54 Back to our Generated Files

55 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

56 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.

57 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)); }

58 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;

59 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...

60 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... }

61 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); }

62 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

63 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

64 Break Time

65 SimpleClient GUI is the Same

66 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

67 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; }

68 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

69 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

70 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; }

71 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; }

72 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; }

73 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); }

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

75 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

76 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(); }

77 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

78 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)

79 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

80 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

81 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

82 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)

83 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(); }

84 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; }

85 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); }

86 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 ?

87 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

88 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

89 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....

90 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

91 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

92 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");

93 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

94 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

95 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); };

96 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) }

97 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(); };

98 org.omg.COSNaming in UML

99 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

100 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

101


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

Similar presentations


Ads by Google