8 Verteilte Plattformen Verteilte Plattform - auch Verteilungsplattform, Middleware - bietet Umgebung für verteilt ausgeführte Anwendungsprogramme, unabhängig von unterliegenden Betriebssystemen und Hardware, meist unabhängig von den verwendeten Programmiersprachen, aber orientiert an einem bestimmten Modell für Interaktion und Architektur (früher auch network operating system – vs. distributed operating system) Leistungen einer Plattform: Realisierung von Interaktionen durch Nachrichtenaustausch zwischen Prozessen, evtl. stationsübergreifend, gemäß unterliegender Infrastruktur (z.B. Internet Transport) Bereitstellung einer Schnittstellenbeschreibungssprache - interface description language, IDL – für die programmiersprachenunabhängige Beschreibung von Schnittstellen Generatoren zur automatischen Erzeugung programmiersprachenspezifischen Vertretercodes (stub generator, IDL compiler) Namensdienst für verteiltes Binden . . . diverse andere Standarddienste Prominente Beispiele: PVM, MPI (2.5) Architektur: Keine IDL: Dienste: Anwendungen: kommunizierende (schwergewichtige) Prozesse (weil „Schnittstelle“ sehr einfach) Prozeßfernerzeugung Parallelrechnen DCE – Distributed Computing Environment der OSF (jetzt Open Group): Architektur: IDL: Dienste: Client/Server C-ähnlich Directory Service, Security Service, . . . Distributed File Service ( = AFS, 7.5.4) Anwendungen: Dienste ONC - Open Network Computing = Sun RPC: (Begriff wird nicht mehr verwendet) ähnlich DCE COMANDOS - EU-Projekt 1986-92: Architektur: IDL: Dienste: Anwendungen: objektorientiert C++ -ähnlich minimal universell (verteiltes Rechnen und Dienste) Verdienst: hochgradige Verteilungsabstraktion trotz Programmiersprachen-Heterogenität (s.u. 8.2) (COM/OLE ) DCOM ActiveX .NET (Microsoft) COM: Binärcode-“Standard“ für Objektschnittstelle („vtable“) Interoperabilität zwischen Programiersprachen OLE: für heterogene Verbunddokumente (z.B. Excel Chart in Word Document) („lokale Fernaufrufe“) DCOM: fernaufrufbare „Objekte“; Schnittstellenbeschreibungssprache heißt MIDL und entstammt der DCE IDL .NET: s.u. 8.3 8.1 CORBA = Common Object Request Broker Architecture http://www.corba.org Standard (nicht Produkt!) der OMG – Object Management Group http://www.omg.org Architektur: objektorientiert IDL: C++ -ähnlich Dienste: sehr reichhaltig Anwendungen: Dienste, insbesondere Einbinden von Altsoftware CORBA-Objekt: irgendwie erzeugtes Exemplar irgendeiner Implementierung in irgendeiner Programmiersprache, mit einer bestimmten Schnittstelle, beschrieben in IDL identifizierbar über CORBA-Objektverweis oder (über Namensdienst) mit mnemonischem Namen fernaufrufbar über Stubs, die von programmiersprachenspezifischen „IDL-Übersetzern“ erzeugt werden Terminologie: ORB = eigentliche „Middleware“: verteilte Laufzeitunterstützung zwischen Betriebssystem einerseits und Anwendungscode und Vertretercode andererseits, zuständig für Fernaufrufe und lokale Basisdienste Stub = lokaler Vertreter (Proxy) eines fernaufrufbaren Objekts Skeleton = lokaler Vertreter eines entfernten Klienten Adapter = Verwalter lokal vorhandener, fernaufrufbarer Objekte IDL Compiler = Vertreter-Erzeuger (Stub Generator) . . . weitere Terminologie: Interface Repository: verwaltet IDL-Schnittstellenbeschreibungen Implementation Repository: verwaltet zugehörige Implementierungen CORBA Services: breite Palette von Standarddiensten wir z.B. Naming Service, Notification Service, Transaction Service, ... CORBA Facilities: branchenspezifische Dienste, z.B. für Banken, Medizin, . . . 8.1.1 Objektmodell und IDL CORBA-Objekt ist prinzipiell unabhängig von „Objekten“ der Programmiersprache (sofern diese überhaupt objektbasiert ist), wird über einen Fernverweis (remote reference, CORBA reference) identifiziert, wird über Operationen (operations) angesprochen, deren Signaturen in einer Schnittstelle zusammengefaßt sind, die programmiersprachenunabhängig mit IDL beschrieben ist. Objekterzeugung ist nicht Gegenstand des Objektmodells! IDL ist an C++ angelehnt und gruppiert Schnittstellen in Module Modul-Schachtelung erlaubt hierarchische Namensräume // IDL example: no nesting, one module module example { typedef string Name; exception NameClash {Name clashing;}; exception Overflow {unsigned long capacity;}; interface Phones { // private phone book long lookup(in string s); void enter (in string s, in long n) raises(NameClash, Overflow); void delete(in string s); attribute long capacity; }; }; Qualifizierte Namen: example::MyObjectDir Vordefiniert ist module CORBA { interface ORB { ..... }; interface Object { ..... }; ....... }; Der Typ jedes CORBA-Objekts ist verträglich mit CORBA::Object Typsystem: Typ Basistyp (basic type) einfach zusammengesetzt long char string ... struct{fields} [size] sequence<type> ... Verweistyp (reference type) Objekttyp Object Werttyp valuetype mit Vererbung (auch Mehrfachvererbung) Aufrufsemantik gemäß Signatur: Wertübergabe (in), Ergebnisübergabe (out und result) und Wert/Ergebnisübergabe (inout). Bei Verweistypen wird Verweis übergeben. Bei Werttypen wird Wert des Objekts übergeben (d.h. Kopie). Schlüsselwort oneway bewirkt asynchrone Ausführung (Voraussetzung: kein Ergebnis, keine Ausnahmen) Über Dynamic Invocation Interface (DII) auch asynchron mit Synchronisationsmöglichkeit. Ausnahmen gemäß raises und aus Modul CORBA Fehlersemantik ist at-most-once. 8.1.2 Umgang mit Verweisen interface Object { Object duplicate(); // copies reference boolean is_equivalent(in Object other); // compares references boolean is_nil(); // compares reference with nil reference ... }; interface ORB { string object_to_string(in Object o); Object string_to_object(in string s); ... }; Alle diese Operationen werden lokal ausgeführt. 8.1.3 Erzeugung von Vertreter- und Hilfscode am Beispiel Java, auf der Basis des Java Language Mapping der IDL idl2java example.idl erzeugt für jedes Modul ein Java Package, hier also ein einziges Package example. Das Package enthält die folgenden Dateien: PhonesOperations.java Schnittstelle entsprechend Phones Phones.java Schnittstelle, die PhonesOperations und org.omg.CORBA.Object zusammenfaßt PhonesStub.java Proxy-Klasse PhonesStub PhonesHelper.java Hilfsklasse PhonesHelper (s.u.) PhonesPOA.java Skeleton-Klasse PhonesPOA PhonesPOATie.java (s.u.) 8.1.4 Programmierbeispiel in Java Klient: import org.omg.CORBA.*; // equivalents from CORBA module ..... ..... ORB orb = ... // initialize ORB org.omg.CORBA.Object obj = ... // get stub Phones ph = PhonesHelper.narrow(obj); // adjust type if(ph == null) ... // type error int number = ph.lookup("Robert"); ..... // remote invocation zuzüglich Ausnahmebehandlung Anbieter besteht aus eigentlichem Objekt – genannt Servant – und dem Server-Prozeß, der als Träger des Objekts fungiert: // servant class import org.omg.CORBA.*; public class PhonesImpl extends PhonesPOA { // skeleton as superclass ... public int lookup(String n) {...} ... } // server class import org.omg.CORBA.*; import org.omg.PortableServer.*; public class Server { public static void main(String[] arg) { PhonesImpl ph = new PhonesImpl(); ..... ORB orb = ... // initialize ORB POA poa = ... // and POA ..... org.omg.CORBA.Object obj = poa.servant_to_reference(ph); ..... / e.g., publish obj via Naming Service orb.run(); // wait for invocations } } zuzüglich Ausnahmebehandlung 8.1.5 Portable Object Adapter (POA) erlaubt Vielzahl unterschiedlicher Strategien zur Gestaltung der Beziehungen zwischen Objekt, Servant und Server Lebensdauer eines CORBA-Objekts und des implementierenden Servants sind unabhängig. Objekt wird aktiviert (incarnated) durch Verbindung mit einem Servant, und wird deaktiviert (etherealized) durch Lösen dieser Verbindung. POA verwaltet seine Objekte in Objekttabelle (active object map), in der die jeweils zugehörigen Servants verzeichnet sind; für deaktivierte Objekte übernimmt ein Default Servant die Aufrufbehandlung. POA unterstützt persistente Objekte, deren Lebensdauer die des POA (d.h. des Server-Prozesss) übertrifft. Ferner: - Strategien sind programmgesteuert wählbar - Standard-Strategie: transiente Objekte - Persistenz wird unterstützt durch Implementation Repository und ORB Daemon, der bei Bedarf Server-Prozeß startet - Weitere POA-Exemplare – z.B. mit unterschiedlichen Strategien – können programmgesteuert erzeugt werden - usw. usf. 8.1.6 Naming Service = Namensdienst mit hierarchisch strukturiertem Namensraum Context enthält - reguläre Einträge, - subcontexts module CosNaming { ... typedef Sequence<NameComponent> Name; interface NamingContext { void bind(in Name n, in Object o); void bind_context(in Name n, in NamingContext c); Object resolve(in Name n); ... }; }; zuzüglich Ausnahmen Benutzung in Java: import org.omg.CosNaming.* import org.omg.CosNaming.NamingContextPackage.*; ..... org.omg.CORBA.Object obj = orb.resolve_initial_references("NameService"); NamingContext root = NamingContextHelper.narrow(obj); org.omg.CORBA.Object x = root.resolve(name); ..... 8.1.7 Interoperabilität zwischen verschiedenen CORBA-Implementierungen General Inter-ORB Protocol (GIOP) (Transfersyntax + Nachrichtenformate) Internet Inter-ORB Protocol (IIOP) (+ Realisierung über TCP/IP) andere Objektbezugnahme über Interoperable Object Reference (IOR) Ferner: Environment-Specific Inter-ORB Protocols (ESIOPs) statt GIOP/IIOP, falls auf bereits vorhandener Middleware aufgesetzt werden soll. Beispiel: DCE Common Inter-ORB Protocol (DCE-CIOP) ist ein ESIOP auf Basis des DCE RPC. 8.1.8 Java mit RMI oder CORBA oder ...? RMI CORBA Pangaea* Verteilungsabstraktion | - + Leichtgewichtig + - + Professionelle Infrastruktur - + Einbinden von Altsoftware | + Interoperabilität (s.u.) | + * André Spiegel, FU 1998-2002 Interoperabilität RMI – CORBA durch „RMI over IIOP“ (statt über JRMP – Java Remote Method Protocol) Klient bzw. Anbieter programmiert in Java RMI, Vertreter-Erzeugung mit rmic –iiop Client Server CORBA RMI RMI CORBA (Java IDL !) Einige Programmierunterschiede zu Java RMI: - Java Naming and Directory Interface (JNDI) statt Registry - keine verteilte Speicherbereinigung - ... 8.1.9 JacORB ! Gerald Brose u.a., FU Berlin 1996-2002 http://jacorb.inf.fu-berlin.de 8.2 COMANDOS Construction and Management of Distributed Open Systems Forschungsprojekt der EU (1986-92) Ziele: Verteilungsabstraktion und Persistenz Vorteile gegenüber CORBA: - hochgradige Verteilungsabstraktion - IDL ( CORBA IDL) nur bei Sprachheterogenität erforderlich Nachteile gegenüber CORBA: - Modifikation der Laufzeitsysteme (und evtl. der Sprache) 8.2.1 Sprachen in COMANDOS C** = C++ mit zusätzlichen Schlüsselwörtern für Persistenz und Verteilung Eiffel** = Eiffel-2, lediglich mit modifiziertem Laufzeitsystem Guide = nichtsequentielle objektorientierte Sprache Beispiel Eiffel**: Alle Eiffel-Objekte sind potentiell persistent: sie überdauern ihren Erzeuger-Prozeß, sofern sie über den COMANDOS Name Service (direkt oder indirekt) erreichbar sind. 8.2.2 Verbergen der IDL Ziel – in COMANDOS nur partiell erreicht: Automatische Generierung von IDL-Text aus Schnittstelle einer Klasse (Eiffel, C++, ...) interne, nicht lesbare „IDL“ genügt für Stub-Erzeugung! Ziel erreicht in Projekt HERON (FU Berlin, 1996) für Eiffel und Turbo-Pascal (OO) ( CORBA IDL aus Java-Text generieren mittels java2idl (VisiBroker u.a.) rmic –idl (Sun) )