124
Kommunikation über Middleware am Beispiel RPC Bachelor-Arbeit von Marco Freudenberger im Studiengang Informatik vorgelegt am 19.April 2002 Referent: Prof. Dr. Günter Turetschek Partnerunternehmen: Korreferent: Prof. Dr. Klaus W. Wente Software AG Fachhochschule Darmstadt Darmstadt-Eberstadt Fachbereich Informatik Sommersemester 2002

Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

  • Upload
    volien

  • View
    217

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

Kommunikationüber Middlewaream Beispiel RPC

Bachelor-Arbeit von Marco Freudenbergerim Studiengang Informatikvorgelegt am 19.April 2002

Referent: Prof. Dr. Günter Turetschek Partnerunternehmen:Korreferent: Prof. Dr. Klaus W. Wente Software AG Fachhochschule Darmstadt Darmstadt-Eberstadt Fachbereich Informatik

Sommersemester 2002

Page 2: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

1

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

VorwortDie vorliegende Bachelor-Arbeit entstand im Februar bis April 2002 als tiefergehende Diskussion aufbauend auf einem Teil meiner Mitarbeit am Projekt „Entire System Managment GUI Client Framework für Windows“, kurz: „ESM GUI Framework“, die ich während der Bachelor-Praxisphase im Wintersemester 2001/2002 bei der Software AG Darmstadt-Eberstadt im Team Natural Entire System Managment (kurz: Natural ESM) durchführte.Der im Anhang auf CD abgelieferte Quellcode ist vertraulich zu handhaben und darf nur vom Referenten und Korreferenten eingesehen werden, da es sich hierbei um in Produkten der Software AG verwendete Codings unter deren Urheberrecht handelt.

Mein besonderer Dank gilt folgenden Personen, die direkt oder indirekt ihren Anteil an der Entstehung dieser Bachelorarbeit hatten:

Josef Wohl (Software AG, Teamleiter Natural ESM) und Frank Hildebrandt (Projektleiter NOM) für die Betreuung während meiner Praxisphase.

Prof. Dr Udo Bleimann und Prof. Dr. Klaus W. Wente für Begleitung durch Projektseminar 1 und besonders Prof. Dr. Günter Turetschek für ebendiese und die Unterstützung beim Verfassen dieser Bachelorarbeit in Projektseminar 2.

Angelika Siffring (Software AG, Product Marketing Manager für EntireX) für den gewährten Überblick über Entire-X und die Hilfe bei der Beschaffung von Datenblättern und Spezifikationen sowie die Beantwortung einiger Fragen.

Den Mitarbeitern der Software AG Headquarters in Eberstadt, die mich mit Rat und Tat und Geduld während meiner Praxisphase unterstützt haben, insbesondere Birgit Rose, Patrick Goll und Kemp Schlesinger, die mich in Raum 135 aufgenommen und auf meine – zumindest anfänglich – reichlichen blöden* Fragen immer mit Geduld eingegangen sind.

Antje Pinseler, die sich als Korrekturleserin in Bezug auf Rechtschreibfehler und Ausdruck zur Verfügung gestellt und mir geholfen hat manches sprachliche Ungetüm in Form von 10 Zeilen langen Schachtelsätzen sinnerhaltend zu erschlagen. Auch wenn - oder gerade weil - wir oft längere Diskussionen darüber führten, „ob man einen Satz so schreiben kann oder nicht“...

*) ich weiß... es gibt keine Blöden Fragen, nur blöde Antworten

Page 3: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

2

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

per aspera ad astra(Lucius Annaeus Seneca der Jüngere, 4 v.Chr. - 65 n.Chr.)

Page 4: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

3

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Inhalt

Vorwort ······································································································ 1

1. Einleitung································································································· 5

2. Verteilte Systeme ···················································································· 82.1 Modelle······································································································ 82.2 Spezielle Anforderungen an die Kommunikation in Verteilten Systemen 12

3. Middleware····························································································· 143.1 Definitionen ····························································································· 143.2 Kategorien······························································································· 153.2.1 Datenbank-Middleware (DBCP: Database Connectivity Products)········· 163.2.2 MOM (Message Oriented Middleware) ··················································· 173.2.3 RPC (Remote Procedure Call)································································ 193.2.4 DTPM (Distributet Transaction Processing Middleware)························· 213.2.5 Komponenten-orientierte Middleware ····················································· 24

4. DCOM ····································································································· 264.1 Entwicklung von DCOM ·········································································· 264.2 Architektur, Konzepte und Begriffe·························································· 294.2.1 ActiveX-Komponenten ············································································ 294.2.2 COM-Konzepte ······················································································· 314.2.3 Komponenten, Klassen und Objekte······················································· 314.2.4 GUID, CLSID, IID ···················································································· 314.2.5 Schnittstellen (Interfaces) und MIDL······················································· 324.2.6 Wiederverwendung von Code································································· 354.2.6 Registry-Dienste und SCM······································································ 374.3 DCOM Services ······················································································ 384.3.1 MS RPC ·································································································· 394.3.2 COMTI····································································································· 404.3.3 MSMQ····································································································· 414.3.4 MTS········································································································· 424.3.5 OLEMessaging························································································ 424.3.6 OLE DB··································································································· 434.3.7 Security in DCOM ··················································································· 444.4 DCOM auf anderen Plattformen······························································ 47

5. CORBA··································································································· 495.2 Die Architektur························································································· 495.2.1 Stub und Skeleton··················································································· 505.2.2 IDL··········································································································· 505.2.3 DII und DSI······························································································ 515.2.4 POA (Portable Object Adapter) ······························································· 515.2.5 ORB ········································································································ 515.2.6 GIOP, IIOP ······························································································ 52

Page 5: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

4

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

5.2.7 CORBAservices ······················································································ 525.2.8 CORBAfacilities······················································································· 53

6. EntireX···································································································· 556.1 Architektur der EntireX-Familie ······························································· 556.2 EntireX Communicator ············································································ 586.2.1 EntireX Broker························································································· 586.2.2 SDKs und Wrapper ················································································· 636.2.3 RPC, Workbench und IDL-Compiler ······················································· 636.2.4 Besondere Services ················································································ 646.2.5 EntireX Security ······················································································ 666.2.6 EntireX DCOM ························································································ 676.3 EntireX DCOM für Linux ········································································· 68

7. Programmierung: RPC mit EntireX und COM-Interfaces mit ATL ···· 747.1 Motivation aus meiner Praxisphase ························································ 747.1.1 Das Umfeld: Natural················································································ 747.1.2 Praxis-Projekt: ESM GUI Framework······················································ 787.2 EntireX RPC-SDK für C ·········································································· 857.2.1 API-Funktionen ······················································································· 867.2.2 SDK-Datenstrukturen ·············································································· 867.3 BOM (Broker Object Model)···································································· 877.4 ActiveX Control ESMBrowse··································································· 877.4.1 Schnittstelle des ESM-GUI-Framework ·················································· 887.4.2 Funktion und Nutzung des Controls························································ 907.4.3 Die Implementierung ··············································································· 937.4.4 Codeauszüge························································································ 101

8. Zusammenfassung und Ausblick·······················································112

Literatur-Verzeichnis ··············································································119 Glossar·································································································· 121 Anhang·································································································· 122 Ehrenwörtliche Versicherung ································································ 123

Page 6: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

5

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

1. Einleitung

Aufgabenstellung der Praxisphase und Inhalt dieser ArbeitIm Rahmen der Praxisphase im 5. Semester des Studiums zum „Bachelor der Informatik / Bachelor of Science in Computer Science“ an der Fachhochschule Darmstadt arbeitete ich bei der Software AG Darmstadt-Eberstadt an dem Projekt „ESM GUI Framework“ mit. Projektziel ist, ein Framework für die Windows-Frontend-Programmierung mehrerer Applikationen des Natural ESM Teams zu erstellen. Maßgabe ist ein API unter der Programmiersprache Natural (derzeit Version 5.1.1 für Windows) bereitzustellen, das gemeinsam nutzbare Funktionen bündelt. Dadurch soll es den Applikations-Programmierern ermöglicht werden, schnell und größtenteils nur durch Programmierung von Definitionstabellen und Applikations-Dialogen anwenderfreundliche Win32 GUIs für bestehenden (und evtl. neue) Anwendungen zu schaffen. Die Zielanwendungen laufen derzeit mit einer charakter-basierten Oberfläche auf Mainframe-Systemen unter Natural und sind von PC bzw. Windows „nur“ über Terminal-Emulation zugänglich.Die neuen Anwendungen sollen so weit wie möglich auf bestehende Applikationslogik auf dem Mainframe zurückgreifen. Damit wird zum einen Entwicklungszeit gespart, zum anderen sind die bestehenden Module bereits gut getestet und bewährt. Schließlich kann man so auch zukünftig Wartungen der Software an wenigen zentralen Punkten ausführen.Das GUI soll die den Anwendern bekannte Struktur und Funktionalität der Mainframe-Oberfläche mit ergonomischer und benutzerfreundlicher Bedienung von Windows-Frontends vereinen.Das Framework stellt mehrere Standard-Fenster (MDI Rahmenfenster mit Menus, Toolbars und Statuszeile), einen in einer DialogBar enthaltenen Treeview, ein ListView-Child-Fenster, ein Browse-Child-Fenster (ListView mit eigener Logik zum assynchronen Laden und Cachen großer Dateninhalte über RPC), eine EditorView, mehrere Standard-Dialoge wie „Suchen“, „Gehe-zu“, „Bestätigen“, „Login“ sowie zugehörige Kontext-Menüs zur Verfügung. Außerdem bietet es Funktionalität zu kontext-sensitiver Hilfe zu Applikations-Elementen und kapselt Benutzerrechte und -authentifizierung.Dies alles wurde unter Natural für Windows implementiert, lediglich das Browse-Control wurde in C++ unter Nutzung von ATL, STL und EntireX Broker SDK als ActiveX Control erstellt, dazu aber mehr in Kapitel 7. Parallel zum Framework entstand die erste Applikation „NOM GUI Client“ (NOM = Natural Output Managment, ein System zur Verwaltung, Steuerung, Verteilung und Archivierung von Reports, das insbesondere in großen Unternehmen genutzt wird) und etwa zur Halbzeit meiner Praxisphase kam noch eine zweite Applikation ins Spiel, die auf dem Framework basiert: ein Prototyp unter dem internen Projektnamen „Andorra“, quasi eine Art Windows-Explorer für den Remotezugriff auf die „Dateisysteme“, sprich File-Datenbanken, verschiedener Mainframe-Betriebsyssteme wie OS/390, VSE und BS2000. Für die nähere

Page 7: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

6

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Zukunft ist auch noch an die Implementierung einer GUI für „Entire Operations“ (NOP) gedacht, ein Kontroll- und Scheduling-Tool für automatische Vorberitung, Durchführung, Überwachung und Logging von Batch-Prozessen auf verschiedene Betriebssystemen.

In dieser Bachelorarbeit widme ich mich vor allem einem sehr interessantem Teilbereich aus meiner Praxisphase, nämlich der RPC-Programmierung über Middleware, hier über den EntireX Broker (wird neuerdings unter dem Namen „EntireX Communicator“ verkauft). Die RPC-Programmierung wird in Natural vom Runtime System unter Maßgabe der Konfigurations-Profile komplett automatisiert und der Aufruf eines lokalen Unterprogrammes, das in der gleichen Library liegt, eines Unterprogrammes in einer anderen lokalen Library (nach dem „Step-Lib“-Konzept) und eines Unterprogrammes auf einem entfernten Server unterscheidet sich syntaktisch überhaupt nicht.Im Rahmen der Programmierung des ActiveX-Controls mit Browser-Funktionalität unter C++ bekam ich aber einen tieferen Einblick in das, was Natural vor dem Programmierer verbirgt und automatisch übernimmt: Intialisierung der EntireX Runtime, Anmeldung an einen Broker, Suche eines Servers, der den angeforderten Service (Unterprogramm) bereitstellt, Marshalling und Konvertierung der RPC-Parameter zwischen verschiedenen Zeichensätzen und die unterschiedliche Behandlung verschiedener Datentypen.

Um aber dorthin zu kommen, möchte ich zunächst den Begriff „Verteilte Systeme“ erläutern, erklären was eine „Middleware“ ist und welche Typen von Middleware es allgemein gibt. Danach werde ich zwei weit verbreitete Middlewares (genauer gesagt zwei Middleware-Konzeptionen) vorstellen, nämlich in Kapitel 4 Microsoft‘s DCOM (Distributet Component Object Model), und in Kapitel 5 CORBA (Common Object Request Broker Architecture) von OMG.In Kapitel 6 dieser Arbeit stelle ich dann Funktionalität und Konzeption von EntireX, dem Middlewarepaket der Software AG vor. Schwerpunkt liegt auf dem EntireX Broker (Communicator), der für die RPC‘s zuständig ist, allerdings auch mit Überblick über den neueren EntireX Integration Broker (Orchestrator) und den noch fast brandneuen (Release: November 2001) EntireX XML Mediator.Der Kreis wird sich in Kapitel 7 wieder schließen, in dem ich konkret auf meine Projektarbeit in der Praxisphase zurück komme und insbesondere die EntireX RPC-Programmierung in Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle.

Damit werde ich versuchen neben der Darlegung meiner Tätigkeit im Bachelor-Projekt drei Middleware-Konzepte vorzustellen. Jedoch möchte ich in dieser Arbeit auch einige oft nur als Schlagwörter bekannte Begriffe gerade aus den Bereichen von Microsoft‘s COM und DCOM-Konzepten verständlich machen, gegeneinander abgrenzen und in einen Zusammenhang mit den Begriffen aus anderen Konzepten zu stellen. Außerdem möchte ich das, den meisten bestenfalls vom Namen her bekannte, Sotware AG-Middleware-Produkt EntireX darstellen.

Page 8: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

7

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Verteilte Systeme

Page 9: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

8

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

2. Verteilte SystemeVon „verteilten Systemen“ spricht man, wenn mehrere Rechnersysteme, die in irgend einer Form miteinander kommunizieren, gemeinsam eine Aufgabe erledigen. In der Regel sind diese Computer – zumindest temporär – über ein Netzwerk miteinander verbunden.Wie bei der Arbeitsteilung zwischen Menschen in einem sozialen System, so kann auch die Arbeitsteilung zwischen den einzelnen Rechnern verschieden abgestuft sein. Man kann diese Abstufungen in folgende Modelle einteilen:

2.1 ModelleZur Verdeutlichung aller folgendenen Modelle wird als Beispiel eine typische Business-Applikation zu Grunde gelegt, die aus Datenbank (DB), Geschäftslogik (Business Logic, BL) und Benutzerschnittstelle (User Interface, UI) besteht.

a) Monolithische SystemeMonolithische Systeme sind keine wirklichen „verteilten Systeme“ und hier als historischer erster Schritt gezeigt. Die komplette Applikation läuft auf einem System, typischerweise einem Großrechner, ab, an das Terminals angebunden sind. DB, BL und UI liegen zentral auf diesen Systemen, das die komplette Verarbeitung übernimmt. An die Terminals werden nur (in der Regel textbasiert) Daten übermittelt und Benutzereingaben an das System zurückübertragen. Auf dem Zentralrechner läuft eine Applikation in der Regel als eine einzige, große Anwendung ab.

Dies ermöglicht die zentrale Verwaltung von Benutzerrechten und zentrale Wartung an der Applikation sowie kaum Abstimmungsaufwand, außerdem ist die Netzlast vergleichsweise gering. Auf der anderen Seite ist aber eine hohe Rechenleistung beim Server erforderlich, ein Terminal kann in der Regel nur mit einem Server verbunden sein und die Fähigkeiten des User-Interfaces sind gering.

Mainframe (Großrechner)

Anwendung Daten-bankBusiness-

Logic

User-Interface(Charakterbasiert)

Terminal TerminalTerminal

Page 10: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

9

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

b) 2-tier (Client-Server-Architektur)Mit dem Durchbruch der PCs kam auch das Client-Server Computing. Client-Server-Applikationen sind so aufgebaut, dass die DB auf dem Server liegt, das UI auf dem Client und die BL entweder auf dem Server oder dem Client oder zwischen beiden aufgeteilt ist. Typischerweise liegt der größte Teil der BL aber bei den Client-Applikationen und der Server hat fast nur die Aufgabe der Datenbereitstellung.

Die Server brauchen weniger Rechenleistung, da ein Großteil der Verarbeitungslast nun vom Client ausgeführt wird, was kleinere und skalierbarere Server erlaubt (PCs oder Midrange-Plattformen wie z.B. RS/400). Außerdem kann ein Client über das Netzwerk mit mehreren verschiedenen Servern kommunizieren.Änderungen an der DB führen allerdings dazu, dass alle Benutzer eine neue Client-Software benötigen. Außerdem sind die Applikationen schlecht mit der Anzahl der Clients skalierbar und der Netzverkehr wächst an, insbesondere wenn viele BL-Anteile auf den Clients liegen.

c) 3-tier Modell (3-stufige Client-Server-Architektur)Bei 3-tier Applikationen wird eine klare Abgrenzung zwischen UI und BL geschaffen, indem die Business-Logic eindeutig auf dem Server liegt und der Client nur noch das User-Interface beherbergt. Die BL kann dabei zwar auf einem weiteren Server liegen, ist aber aus Performance-Gründen in der Regel auf einer von der Datenbank getrennten Applikation auf dem Server, der auch die Datenbank beherbergt. Eine Datenbankzugriffschicht sorgt für die Anbindung an die Datenbank.Bei guter Planung dieses Modells ist es möglich, Änderungen an der BL durchzuführen oder neue Datenbanksysteme zu verwenden, ohne dass es damit nötig wird, alle Clients mit neuen Applikationen für das UI zu versorgen. Die Netzlast am Frontend zwischen BL und UI

Server (PC od. Midrange)

Server-Anwend. (Tier 1) Daten-bankBusiness-

Logic

Client

Client-Anwendung (Tier 2)

User-InterfaceBusiness-Logic

Server (PC od. Midrange)

Server-AnwendungDaten-bank

Business-Logic(Tier 2)

Client

User-Interface(Tier 3)

Datenzugriffs-Schicht (Tier 1)

Page 11: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

10

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

nimmt ab, weil die Clients nur noch mit den wirklich zur Benutzer-Interaktion nötigen Daten versorgt werden.Damit wird die Anwendung und das Firmennetz deutlich skalierbarer für eine wachsene Anzahl von Clients. Der Grundaufwand für die Entwicklung und Implementierung einer Applikation wächst aber.

d) n-tier Modell (verteilte Applikationen, Dienste)Dieses Modell ist die konsequente Weiterentwicklung des 3-tier Modells. Es wird nicht mehr fest nach BL und Datenbankzugriffs-Schicht unterschieden, sondern die gesamte Funktionalität wird in Objekte bzw. Komponenten oder Dienste aufgeteilt. Die Applikation ergibt sich erst durch das Zusammenspiel vieler solcher Komponenten. Diese kommunizieren über definierte Schnittstellen und bieten nach außen bestimmte Dienste an und nehmen Dienste von anderen Komponenten in Anspruch. Da eigentliche C l ien t -Komponenten auch Objekte enthalten können, die sich wie Server verhalten, verwischen die Grenzen zwischen Client und Server zusehends. Solche Komponenten, die sowohl Client als auch Server sind, bezeichnet man auch als Agenten.

Wichtiges Argument für solche Modelle ist zum einen die Wartbarkeit dieser Systeme: eine einzelne Komponente kann geändert, ausgetauscht oder auch in verschiedenen Ausbaustufen oder Versionen gleichzeitig laufen, solange sie sich anderen Komponenten gegenüber transparent verhält und ihre Schnittstelle unverändert bleibt. Beispiel: Eine Komponente die Kundendaten zur Verfügung stellt, kann ihre Daten bisher in einer relationalen Datenbank gespeichert haben. Diese Daten sollen zukünftig in einer objektorientierten Datenbank oder einer XML-Datenbank abgelegt werden. Selbst eine solch grundlegende Änderung an der Implementierung der Komponente kann nach außen und für die Gesamtanwendung(en) transparent bleiben.Zum anderen ist auch die Wiederverwendbarkeit ein wichtiges Argument für dieses Modell. So kann die gleiche Komponente in verschiedenen Anwendungen zum Tragen kommen, ohne das auch nur irgend ein geändertes Coding oder Anpassung notwendig wäre. Der Dienst der eben genannten Komponente, die Kundendaten liefert und speichert, kann für eine Applikation im Rechnungswesen ebenso in Anspruch genommen werden wie für die Marketing-Abteilung oder den Onlineshop im Webportal oder für die TBI-Anbindung

Client

User-Interfaceo. Web-Browser

Dienst A

Dienst E

Dienst D

Dienst C

Dienst BDienst F

DB 1

DB 2

Page 12: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

11

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

������

����������� ������������

������

�����������

�������

����������� ��� �������������������������� ��������

an die zur Qualitätssicherung bei einer Zuliefer-Firma eingesetzt werden. Bei früheren Modellen wurde diese Aufgabe unter Umständen mehrfach in verschiedenen Anwendungen implementiert, wenn ihre Daten nicht sogar in mehreren Datenbanken synchronisiert werden mussten.

Welches Modell für welche Applikation ?Bei der Auswahl des Modells für die Implementierung einer Applikation spielt natürlich deren Komplexität und erwartete Pflege und Erweiterung die entscheidende Rolle. Bei der Entwicklung einer einfachen Applikation, die nur wenig verschiedene Daten austauscht und auf die nur wenige Benutzer zugreifen, wird man sicherlich auf ein anderes Modell zurückgreifen als bei einer Enterprise- oder TBI-Anwendung, die eine Vielzahl großer und komplexer Daten zwischen vielen Systemen verschickt und auf die eine riesige Anzahl von Benutzern zugreifen. Natürlich gibt es bei der Entwicklung einer Anwendung nach dem n-tier Modell einen Overhead, sowohl in der Planung und Abstimmung von Komponenten als auch im Preis für benötigte Tools und Middleware, der nicht rechtfertigt, diesen Ansatz für eine Einzellösung in einem kleineren Unternehmen zu verfolgen:

Page 13: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

12

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

2.2 Spezielle Anforderungen an die Kommunikation in Verteilten SystemenBei monolitischen Systemen findet die Datenkommunikation innerhalb des gleichen Rechners, meistens sogar innerhalb des selben Prozesses statt. Je verteilter ein System ist, desto größer wird aber die Rolle der Datenkommunikation mit anderen Prozessen und anderen Rechnern. Schließlich – insbesondere beim n-tier Modell – ist in besonderem Maße zu beachten, dass die Übertragung von Daten auch zwischen verschiedenen Plattformen und Programmiersprachen stattfindet. Dadurch müssen nun auch Datenwerte konvertiert werden (Stichworte: Big Endian / Little Endian Integers, Zeichendarstellung). Außerdem sollen Komponenten austauschbar sein, z.B. ein Wechsel auf ein anderes Datenbanksystem oder Austausch einzelner Komponenten (auch eine Migration von Komponenten auf neue Rechner-Plattformen oder in andere Programmiersprachen) soll möglich sein, ohne dass andere Teile des Systems neu implementiert werden müssen.Die Netzlast soll möglichst gering, ein hoher Datendurchsatz gewährleistet sein. Außerdem hat die Verfügbarkeit eines Systems hohe Priorität; bei hoher Nutzlast soll ein System noch ebenso verfügbar sein wie bei Ausfällen einzelner Komponenten. Dieses kann nur durch das Vorsehen von redundanden Systemen gewährleistet werden, so dass automatisch bei Ausfall einer Instanz die Aufgaben auf eine oder mehrere Backup-Instanzen verteilt werden.Dienste, die austauschbar sein oder auf verschiedenen Rechnern laufen sollen, müssen adressierbar sein; ein Dienst soll unabhängig davon, auf welchem Rechner er läuft, aufgerufen werden können, ohne dass dazu die Software geändert werden muss.Ein weiterer Aspekt ist die Sicherheit. Die Komponenten in einem n-tier System tauschen eine Vielzahl an Daten aus, darunter auch solche, die nur einem bestimmten Personenkreis zugänglich sein soll. Die Komponenten müssen sich also gegeneinander autorisieren können. Da potentiell eine große Zahl einzelner Komponenten vorliegt, soll eine zentrale Verwaltung von Berechtigungen möglich sein. Außerdem stellt auch das Abhören des Netzverkehrs mit Paket-Sniffern oder ähnlichen Einrichtungen sowie die Veränderung von Daten auf der Route zwischen Sender und Empfänger eine Gefahr dar.Die Systeme sollen in Planung, Implementierung und Wartung überschaubar und planbar bleiben; der Implementierungsaufwand muss möglichst gering sein: ein Coding einer Komponente für die Bereitstellung von Kundendaten kann nicht n Code-Varianten für n mögliche Datenbanksysteme enthalten.Um dies alles gewährleisten zu können bedarf es Zugriffsschichten zwischen den einzelnen Komponenten, die dem Anwendungs-Programmierer Konvertiertungs-, Transport-, Routing- und Security-Aufgaben abnehmen und durch einheitliche Schnittstellen eine homogene Kommunikation nach außen ermöglichen. Dazu müssen sie auf verschiedenen Maschinentypen verfügbar sein und deren Heterogenität kapseln. Sie sollen eine zuverlässige, last-unabhängige Kommunikation nach verschiedenen Kommunikationsmustern unterstützen.Solche Zugriffs-Software bezeichnet man als Middleware.

Page 14: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

13

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Middleware

Page 15: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

14

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

3. MiddlewareWie im vorigen Kapitel beschrieben, wird Middleware zwischen den einzelnen Schichten von Aplikationen eingesetzt. Was aber genau ist, was kennzeichnet Middlware?

3.1 Definitionen„Software, die zwischen einem Anwendungsprogramm und einem Netz vermittelt. Sie handhabt die Interaktion zwischen verschiedenartigen Anwendungen über heterogene Rechner-Plattformen. […]“ [foldoc: „middleware“ – übersetzt aus dem Englischen]

„Software, die zwei ansonsten getrennte Applikationen verbindet. Es gibt zum Beispiel eine Reihe von Middleware-Produkten, die eine Datenbank an einen Web-Server anbinden. Das erlaubt Benutzern, über Formulare, die auf einem Web-Browser angezeigt werden, Daten aus einer Datenbank abzurufen und erlaubt es dem Web-Server dynamische Web-Seiten basierend auf den Benutzer-Abfragen und Profilen zurückzugeben.Der Begriff Middleware wird benutzt, um unterschiedliche Produkte zu beschreiben, die als Klebefläche zwischen zwei Anwendungen dienen. Middleware ist deshalb etwas anderes als Import- und Export-Merkmale, die in eine der Anwendungen eingebaut werden können. Middleware wird manchmal als ‚Klempnerarbeit‘ bezeichnet, weil sie zwei Seiten einer Anwendung aneinander anschließt und Daten zwischen ihnen übermittelt. Geläufige Middleware-Kategorien beinhalten: • TP-Monitore • DCE-Umgebungen • RPC-Systeme • Object Request Broker (ORBs) • Datenbank Zugriffs-Systeme • Nachrichten-Übermittlung“ [webop: „middleware“ – übersetzt aus dem Englischen]

Diese Definitionen sagen eigentlich das wichtigste über Middleware aus. Man kann noch folgende Definition hinzufügen: Während Netzwerk-Software die Kommunikation zwischen zwei Maschinen handhabt, gibt Middleware einem Software-Entwickler Dienste an die Hand, die Prozess-zu-Prozess-Kommunikation über ein Netzwerk erlauben. Diese Prozesse können auf verschiedenen Maschinen laufen. Einige fortschrittlichere Middlewares erlauben es auch, dass die Prozesse auf Maschinen mit unterschiedlichen Betriebssystemen laufen können. Middleware sorgt dafür, dass die involvierten Rechner wie eine einzige „Virtuelle Maschine“ erscheinen. [rock-evans]

1

Maschine 2

Middleware Prozess B

Maschine 1

Prozess A Middleware

ApplikationODBC-Manager

ODBC-Treiber 1

ODBC-Treiber 2

Datei-System

ApplikationODBC-Manager

ODBC-Treiber 1

ODBC-Treiber 2

DBMS

Netzwerk

ApplikationODBC-Manager

ODBC 3-Tier-Treiber

ServerODBC-Manager

ODBC-Treiber 1 ODBC-Treiber 2

DBMS

Netzwerk

Netzwerk

1-tie

r O

DB

C

2-tie

r O

DB

C

3-tie

r O

DB

CSQ

L

SQL

SQL

SQL

SQL

SQL

SQL

SQL

SQL

SQL

SQL

SQL

Page 16: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

15

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Middleware setzt dabei in der Regel auf bestehende Transportsysteme auf und ist unabhängig von den darunter liegenden Kommunikationsprotokollen:

Abbildung entnommen aus [geihs]Nur selten, und dann nur aus historischen Gründen, setzt Middleware auf einem eigenen, proprietären Transportprotokoll auf. Ein Beispiel hierfür sind alte EntireX-Versionen , die Entire Net-Work, ein eigenes Netzwerkprotokoll der Software AG, nutzen, weil damals das TCP-IP Protokoll noch nicht auf allen Plattformen verfügbar war.

3.2 KategorienDie Definitionen im vorigen Abschnitt sind recht allgemein gehalten. Das hat auch gute Gründe: Zum einen gibt es viele verschiedene Arten von Middleware für verschiedene Einsatzzwecke, ebenso gibt es Middleware-Konzepte, die versuchen, möglichst alle oder zumindest viele Einsatzzwecke abzudecken. Zum anderen gibt es verschiedene historische Entwicklungsschritte von einfachem Nachrichten-Austausch bis hin zu komplexen Middleware-Konzeptionen. Schließlich gibt es innerhalb komplexerer Middleware verschiedene Abstraktionsebenen, die aufeinander aufbauen können aber jede für sich als „Middleware“ bezeichnet werden kann. Um den Kategorieren vorzugreifen: oft baut eine RPC- oder Komponenten-Middleware auf einem MOM-Konzept auf, eine Datenbank-Middleware auf einem RPC- oder Komponenten-Konzept.Es ist schwierig eine genaue oder umfassende Einteilung in Kategorien vorzunehmen, in der Literatur findet man – je nach dem genauen Aspekt, aus der man das Thema betrachtet – viele verschiedene Abgrenzungen. Ich habe mich, ohne Anspruch auf Vollständigkeit, für eine Unterteilung in folgende Kategorien entschieden:• Datenbank-Middleware (Database Connectivity Products)• Nachrichten-orientierte Middleware (MOM)• Funktions-orientierte Middleware (RPC-Systeme)• Transaktions-orientierte Middleware (Distributed Transaction Processing Middleware)• Komponenten-orientierte Middleware (DCOM, CORBA, JEB)

Page 17: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

16

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

3.2.1 Datenbank-Middleware (DBCP: Database Connectivity Products)Sie ist weder die einfachste, noch die historisch erste Variante von Middleware, soll aber hier an erster Stelle genannt sein, einfach deshalb, weil der Verwendungszweck intuitiv verständlich und ihre Abgrenzung relativ einfach ist. Datenbank-Middleware dient dazu, aus einer Applikation auf eine Datenbank zugreifen zu können.Historisch betrachtet brachten DBMS früher meist ihre eigene Programmier- oder Scriptsprache mit (4GLs – fourth generation languages), mit der Daten aufbereitet und ausgegeben werden konnten.Beispiel hierfür ist Asthon-Tate‘s dBase (für dessen Scriptsprache ab Mitte der 80er Jahre der auf MS-DOS-Systemen sehr populäre Nantucket Clipper Compiler entwickelte wurde) oder auch Software AG‘s Adabas, für welche Natural, ein Cobol-Dialekt, als Scriptsprache entwickelt wurde, das (in weiterentwickelter Version) in meiner Bachelor-Praxisphase eine große Rolle spielte. Ein Zugriff auf diese Datenbanken von anderen Programmiersprachen oder Rechnern aus war oft nur durch einen Low-Level-Zugriff auf Dateisystem-Files der Datenbank oder – wenn überhaupt – über proprietäre API-Bibliotheken möglich. Mit der Folge von notwendig werdenden Code-Änderungen, wenn ein anderes DBMS (oder eine neuere Version des DBMS) eingesetzt wurde. Zwar gab es mit SQL, das erstmals 1979 von Oracle in einem kommerziellen Datenbank-System eingesetzt wurde, Versuche, Datenbank-Zugriffe auf verschiedene DBMS wenigstens mit einer einheitlichen Syntax zu gewährleisten. Wenige Datenbanken unterstützten aber SQL, und wenn (das ist bis heute so) in unzähligen abweichenden SQL-Dialekten.DBCPs entstanden in Form von Zugriffs-Schichten, mit denen man mehr oder weniger transparent von Applikationen auf Datenbanken zugreifen kann. ODBC ist eine der am weitesten verbreiteten Varianten. ODBC – entwickelt von Microsoft – setzt eine Mittel-Schicht zwischen Applikation und DBMS, den ODBC-Treiber. Dieser übersetzt die Anfragen der Applikation, die in Form einer SQL-Abfrage an den ODBC-Treiber gerichtet werden, in Kommandos oder SQL-Dialekte, die das DBMS versteht oder greifen direkt auf die Datenbank zu. ODBC ist in diesem Sinne nur eine einheitliche Schnittstelle, die auch noch keinen Zugriff auf Datenbanken auf entfernten Rechnern leistet, es sei denn der jeweilige ODBC-Treiber bewerkstelligt dies. Neben anderen Datenbank-Middlewares (JDBC, RDA oder ADO), die eine echte Middleware im Sinne auch von Verteilten Systemen sind, gibt es heute 2- und 3-tier ODBC; deren Remote-Funktionalität wird über die Treiber bereitgestellt.

1

Maschine 2

Middleware Prozess B

Maschine 1

Prozess A Middleware

ApplikationODBC-Manager

ODBC-Treiber 1

ODBC-Treiber 2

Datei-System

ApplikationODBC-Manager

ODBC-Treiber 1

ODBC-Treiber 2

DBMS

Netzwerk

ApplikationODBC-Manager

ODBC 3-Tier-Treiber

ServerODBC-Manager

ODBC-Treiber 1 ODBC-Treiber 2

DBMS

Netzwerk

Netzwerk

1-tie

r O

DB

C

2-tie

r O

DB

C

3-tie

r O

DB

CSQ

L

SQL

SQL

SQL

SQL

SQL

SQL

SQL

SQL

SQL

SQL

SQL

Page 18: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

17

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

3.2.2 MOM (Message Oriented Middleware)Bei der „Nachrichten-orientierten Middleware“ werden Datagramme als Nachrichten von einem Sender an einen oder mehrere Empfänger geschickt. Historisch gesehen ist MOM einer der ersten Middleware-Typen. Es gibt sie in mehreren Varianten. Dabei wird meist ein Plattform-unabhängiger Mechanismus zur Verfügung gestellt, um Nachrichten an andere Teilnehmer zu verschicken. Die Formulierung der Nachrichten bzw. deren Aufbereitung beim Empfang bleibt jedoch dem Anwendungsentwickler überlassen. Die meisten MOM-Systeme sind im übrigen untereinander nicht kompatibel. [muelle].Typisch ist das Message-Queueing bei oder vor potentiellen Empfängern, das gewährleistet, dass keine Nachrichten verloren gehen, weil der Empfänger vielleicht gerade „nicht auf Empfang“ ist. Solche Middleware wird auch als Message Queuing Middleware bezeichnet.Es gibt aber auch Szenarien, z.B. bei der Übertragung von Diagnose-Daten, in denen es für den Empfänger wichtiger ist, die aktuellsten Daten zu haben, als lückenlos alle Daten zu empfangen; dann wird auf Message Queuing verzichtet.MOM funktioniert asynchron, das heißt der Sender verschickt sein Datenpaket und kann direkt weiter arbeiten. Es gibt aber auch MOM-Systeme, die – obwohl im Prinzip noch asynchron – bei einer Punkt-zu-Punkt-Kommunikation zwischen genau zwei Prozessen nach einem Send-Acknowledge-Verfahren arbeiten. Der Empfänger quittiert den Emfpang der Nachricht, bis dahin ist der Sende-Prozess blockiert [mwbook].Es gibt im Allgemeinen drei Ausprägungen von Interaktionsmustern, nach denen unterschieden wird [geihs]:1. Request-Reply: 1:1-Kommunikation. Der Client sendet seine Anforderung (Request) an einen Server und erhält nach dessen Abarbeitung eine Antwort (Reply) mit den entsprechenden Daten. Es gibt hier noch einmal die Varianten eines synchronen R-R‘s, bei dem der Client während der Abarbeitungszeit des Servers blockiert oder eines asynchronen R-R‘s, bei dem er zunächst weiterarbeiten kann und später entweder per definierter Callback-Routine (oder Event) von der Antwort benachrichtigt wird oder die Antwort aus seiner Message Queue auslesen kann (get/pull); ein solches „get“ kann natürlich auch wieder blockierend wirken, falls das Reply noch nicht eingegangen ist.2. Broadcast-Request-Reply: 1:n-Kommunikation. Der Client sendet seinen Request an einen „Nachrichten-Bus“, die angeschlossenen Server, die den Request verarbeiten können, senden einen Reply.

Sender EmpfängerQueueput get

Sender EmpfängerQueueput get

Sender Empfängerblockiert

snd

acc verarbeitetDaten

Client Serverrequest

reply

Client

request

ServerCreply (C)

ServerB

ServerA

reply (A)

Publisher

message

SubscriberC

SubscriberB

SubscriberA

Client Serverrequest

reply

Client

request

ServerCreply (C)

ServerB

ServerA

reply (A)

Publisher

message

SubscriberC

SubscriberB

SubscriberA

Page 19: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

18

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

3. Publish-Subscribe: 1:n-Kommunikation, bei der der Sender (Publisher) die Empfänger (Subscriber) nicht kennt. Der Publisher sendet eine Nachricht, versehen mit einem bestimmten Nachrichten-Tag („Thema“) auf einen Bus, alle Subscriber, die dieses Thema „abonniert“ haben erhalten die Nachricht (typischerweise, in dem Sie eine Callback-Funktion zu dem Thema bei der Middleware registriert haben).

Message BrokerWie schon eingangs dieses Kaiptels erwähnt, bauen viele Middleware-Konzepte in ihrem Kern auf einem MOM-Konzept auf, nicht zuletzt, weil dieses den meisten unterhalb der Middleware liegenden Abstraktionsebenen (Transportschichten) gut entspricht. Diese Kernrolle ist auch der Grund für die relativ ausführliche Behandlung der MOM in diesem Kapitel.Viele – insbesondere modernere – Middleware-Systeme und MOM‘s arbeiten mit einem Message Broker, der die Verteilung und Steuerung der Daten übernimmt, und die Funktion des oben angesprochenen Bus-Modell‘s implementiert.Besser als mit einem Bus kann man den Broker allerdings mit einem Router vergleichen:Er adressiert die Nachrichten an alle Empfänger, die entweder explizit vom Sender genannt wurden oder er löst beim Broadcasting oder Publishing die impliziten Adressaten der Nachricht auf und kennt die Routen (Netzwerkadressen) zu ihnen. Außerdem dient er als gemeinsame Schnittstelle für alle Teilnehmer an der Kommunikation, so dass eine Anwendung zum Verschicken einer Nachricht (bzw. für deren Erhalt) nur mit dem Broker direkt kommunizieren muss. Ohne Broker haben n Teilnehmer an einer vollständigen Kommunikation n*(n-1) Schnittstellen (bzw. halb so viele Verbindungen), mit Broker gibt es je Anwendung nur eine Schnittstelle zum Broker [gossmer]. Eine Anwendung – gleich ob Client oder Server, ob Publisher oder Subscriber – meldet sich zu Beginn bei diesem Broker an und teilt ihm ihre Rolle mit und zum Beispiel auch, für welche Themen sie sich als Subscriber interessiert.Der Broker kann nun außerdem die Rolle einer Authorisierungs-Instanz übernehmen, indem sich die Anwendung oder deren Benutzer ihm gegenüber identifizieren muss, bevor sie an der Kommunikation teilnimmt.Außerdem kann ein Broker Load-Balancing zwischen mehreren gleichen Servern vornehmen.Der Message Broker interpretiert Nachrichten nicht inhaltlich.

Client Serverrequest

reply

Client

request

ServerCreply (C)

ServerB

ServerA

reply (A)

Publisher

message

SubscriberC

SubscriberB

SubscriberA

Anw.Broker

Anw.

Anw.Anw.

Anw.

Anw.

Page 20: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

19

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Interface (IDL)Function Add:

Parameter Summand1 [in]Parameter Summand2 [in]Parameter Summe [out]

Client Applikation

ClientCode Proxy

IDL Compiler

Add(1, 2, &s)

Server Applikation

ServerCodeStub

Add(1, 2, &s)Transport

000100111100101

3.2.3 RPC (Remote Procedure Call)Eine Middleware, die RPC-Dienste zur Verfügung stellt, bezeichnet man auch als Funktions-orientierte Middleware. Ihre Aufgabe ist es, transparente Funktionsaufrufe bereitzustellen, das heißt, dass es für die Applikation keinen Unterschied macht, ob eine Funktion, die sie aufruft, lokal vom gleichen Prozess, von einem anderen Prozess auf dem gleichen Rechner oder von einem Prozess auf einem entfernten Rechner ausgeführt wird. RPC‘s sind synchron, das heißt, der aufrufende Prozess (oder Thread) bleibt so lange blockiert, bis der ausführende Prozess ein Ergebnis geliefert hat, so wie dies bei einem lokalen Funktionsaufruf auch der Fall wäre.Aus Sicht des Anwendungs-Programmierers funktioniert ein RPC-Aufruf genau wie ein lokaler Funktionsaufruf. Zu bedenken ist, dass bei einem Funktionsaufruf auf einen entfernten Server keine Pointer übergeben werden können, da diese ja Speicheradressen des lokalen Adressraums sind. Ist bei einem Aufruf einer Funktion in einem anderen Prozess auf dem gleichen Rechner noch denkbar, dass diese auf einen gemeinsamen Adressraum (Shared Memory) zeigen, so ist bei einem Remote-Aufruf dafür zu sorgen, dass statt der Adressen die Dateninhalte, auf die sie zeigen, übertragen werden. Ebeso müssen die Inhalte, falls sie von der Remote-Funktion verändert werden, auch wieder zurückgeschrieben werden.

Stubs und ProxiesDafür werden in der Anwendung „Stubs“ eingebunden. Diese Stubs sind quasi die Stellvertreter für die entfernte Funktion bzw. für den entfernten Aufrufer der Funktion. Bei einem Client-Stub (dem Stellvertreter der aufzurufenden Funktion im Aufrufer-Prozess) spricht man oft auch von „Proxy“. Die Proxies übernehmen das Marshalling (das „Verpacken“ der übergebenen Parameter in eine flache, sequentielle Datenstruktur) auf der Seite des Aufrufers, und schicken diese Daten an die Middleware, die den (Server-)Stub der Gegenseite aufruft. Dieser entpackt die Daten wieder in Parameter in nativen Datentypen der aufzurufenden Ziel-Funktion (Unmarshalling) und ruft diese auf. Die Ergebniswerte der Funktion werden auf die gleiche Art wieder zurück übertragen.Da die Funktionen auf verschiedenen Plattformen oder Programmiersprachen mit unterschiedlichen internen Darstellungen implemtiert sein können, erledigen die Stubs bei einer plattform-unabhängigen RPC-Middleware beim Marshalling auch noch die Konvertierung in bzw. aus einem internen Übertragungsformat der Middleware.

Interfaces und IDLUm dies gewährleisten zu können nutzen die meisten RPC-Systeme folgende Technik: Die Schnittstelle des RPC-Aufrufs (also die Parameterliste und der Datentyp der Funktion) werden in einer „IDL“ (Interface Definition Language)

Page 21: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

20

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

beschrieben. Ein IDL-Compiler erstellt aus dieser Schnittstellen-Beschreibung Sourcecode für Proxy und Stub in der gewählten Ziel-Sprache, diese werden dann mit der Applikation compiliert. Eine weitere, bei RPC aber eher untypische Variante ist, dass Proxy und Stub als LIB oder DLL erstellt werden, die nur noch in die Applikation eingelinkt werden.RPC ist eines der Basiskonzepte von Verteilten Systemen. Bei entsprechender Middleware kann der ausführende Prozess auf einem anderen Maschinentyp, einem anderen Betriebsystem laufen oder in einer anderen Programmiersprache programmiert sein. Um dies alles zu gewährleisten, muss eine gute RPC-Middleware bei der oben angesprochenen Kovertierung in den Stubs folgende Aufgaben erfüllen: Konvertierung von Zeichen in Stringketten (ASCII ó EBCDIC, Codepage-Umsetzungen), Konvertierung verschiedener Fließkomma-Darstellungen (z.B. IEEE-Float ó IBM-Float) und Integer-Konvertierungen (Big-Endian ó Little-Endian). Außerdem ist es hilfreich, wenn sie in der Lage ist, komplexere Datentypen (Währungsdarstellungen, Datums- und Zeitdarstellungen) in verscheidene Darstellungen zu konvertieren. Dazu bieten einige Middlewares „virtuelle“ Datentypen in ihren IDL an.

ConversationsEine weitere Technik, die viele RPC-Systeme unterstützen, sind Conversations bzw. Sessions. Werden in Folge mehrere RPCs an den selben Server (oder gar mehrfach hintereinander der selbe RPC) ausgeführt, muss die Middleware für jeden Call eine Verbindung aufbauen (und eventuell erst den Server identifizieren und adressieren, Authorisierungen testen ...) und danach wieder abbauen. Dieser Overhead wird bei Nutzung von Conversations nur einmal ausgeführt, nicht für jeden Call.Außerdem bieten sie noch eine zweite Möglichkeit. Ein Server, der die aufgerufene Funktion bereitstellt, ist normalerweise zustandslos. Ein benötigter Zustand wird bei jedem Call erzeugt. Wenn man nun zum Beispiel einen RPC nimmt, der sequentiell eine Zeile aus einer Datei liest (die Zeilennummer wird als Parameter übergeben) und der Client will 100 Zeilen nacheinander lesen (mit 100 Calls), dann muss der Server bei jedem Call die Datei öffnen und den Datei-Zeiger auf die angeforderte Zeile positionieren. Dazu muss er die komplette Datei lesen, bis er n-1 Zeilenende-Zeichen gefunden hat. Bei einer Conversation kann man den Server in einen Zustand versetzen, den er über die Dauer der Conversation hält. In unserem Beispiel könnte er also die Datei geöffnet und den Datei-Zeiger positioniert halten.Natürlich haben Conversations auch ihre Tücken. Ein(e) Server(-Instanz) ist für die Dauer einer Conversation blockiert, d.h. kein anderer Client kann Anfragen an ihn richten. Ein Client sollte innerhalb einer Conversation also zum Beispiel

Client Server Client ServerBeginConversation

EndConversation

RPC()

RPC()

RPC()

RPC()

RPC()

RPC()

RPC()

ConversationalNon-Conversational

Client Server Client ServerBeginConversation

EndConversation

RPC()

RPC()

RPC()

RPC()

RPC()

RPC()

RPC()

ConversationalNon-Conversational

Page 22: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

21

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

niemals Benutzer-Eingaben anfordern. Als Programmierer weiß man nie, wann der User einen Kaffe holen geht und damit vielleicht den Rest der Abteilung blockiert, die sehnsüchtig darauf warten, Daten vom Server zu bekommen... Aber auch längere Verarbeitungszeiten auf dem Client oder Aktionen, bei denen Fehler auftreten können, die eventuell einen Benutzereingriff nötig machen, sollten innerhalb einer Conversation vermieden werden.Für den nächsten Abschnitt (DTPM) sollten Sie sich das Bild von Conversations vor Augen halten, denn die Idee von Transaktionen kann mit dem Grundansatz der Conversations verglichen werden. Transaktionen sind erweiterte Conversations. Wie schon beschrieben, setzen einige RPC-Systeme auf Message-Systemen auf, meist auf solchen mit einem Message Broker. Zum Beispiel EntireX, bei dem der RPC-Call über den Entire Broker, einem im Kern reinen Message-Broker, läuft.Ein Problem von RPC, einer Technologie, die bis in die 70er Jahre zurückreicht, ist, dass es viele RPC-Systeme gibt, von denen die wenigsten RPC interoparabel sind. Eine Abhilfe versuchte The Open Group (früher OSF) zu schaffen. Sie entwarfen ab Anfang der 90er Jahre DCE, ein „Distributed Computing Environment“, eigentlich ein ganzes Middleware-Konzept mit Directory-, Security-, Timing und weiteren Services. DCE ist keine konkrete Implementierung, lediglich ein Standard. Der RPC-Teil von DCE ist heute auf vielen Plattformen verfügbar. Auch Microsofts DCOM baut auf einem DCE-kompatiblen RPC auf, dazu aber mehr in Kapitel 4.

3.2.4 DTPM (Distributet Transaction Processing Middleware)Um erklären zu können, was eine DTPM leistet, muss zuerst verstanden sein, was eine Transaktion ist. Transaktionen spielen im Datenbank-Bereich (und bei DB-Middleware) eine große Rolle, aber auch in anderen Bereichen, wo Daten verändert werden.Daten in Applikationen sind selten alleinstehend, sondern meistens mit anderen Daten verknüpft. Eine Rechnung bezieht sich auf einen Kunden, auf eine Ware oder Leistung, die geliefert oder erbracht wurde. Beim Versand einer Rechnung entsteht eine Forderung dem Kunden gegenüber in der Buchhaltung, usw.Eine Änderung an Daten hat also oft Auswirkungen auf andere Daten, dort müssen ebenfalls Änderungen vorgenommen werden. Geschieht dies nicht, entstehen Inkonsitenzen im Datenbestand. Man stelle sich vor, eine Rechnung konnte nicht in der Datenbank angelegt werden, weil bei diesem Vorgang ein Fehler auftritt, der Rechnungsbetrag wurde aber als Kunden-Verbindlichkeit an die Buchhaltung gemeldet – oder umgekehrt! Selbst wenn kein Fehler auftritt, die Änderungen werden nie echt gleichzeitig gemacht werden, sondern mit einem zeitlichen Abstand. Auch während diesem – bei Verteilten Systemen potentiell langem – zeitlichen Abstand entstehen Inkonsistenzen. Und es gibt noch komplexere Änderungsvorgänge, bei denen weitreichende Änderungen an vielen Datenbeständen durchgeführt werden.Solche mehrschichtigen Änderungsvorgänge, die Inkonsistenzen auslösen können, werden

Page 23: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

22

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

in Transaktionen zusammengefasst. Vorhin habe ich geschrieben, das man sich das Bild von der Conversation einprägen soll; eine Transaktion sieht tatsächlich ähnlich aus: nach ihrem Beginn werden einige einzelne Operationen durchgeführt, wenn die Operationen beendet sind, wird die Transaktion beendet. Es gibt aber zwei Möglichkeiten eine Transaktion zu beenden – mit einem „Commit“ und einem „Rollback“.Die Operationen in Transaktionen werden erst dann wirklich persistent gemacht – das heißt, auch für andere Benutzer und Komponenten sichtbar auf das Speichermedium geschrieben (= „Commit“) – wenn alle Teilvorgänge erfolgreich abgeschlossen sind. Trat aber ein Fehler auf, werden alle bisherigen Teilvorgänge der Transaktion rückgängig gemacht („Rollback“). Dies führt also zu einem „alles oder nichts Ansatz“ [rock-evans]. Eine Transaktion erfüllt die sogenannten ACID-Eigenschaften (siehe unten). Die meisten Datenbanksysteme unterstützen Transaktionen.

ACID-EigenschaftenAtomicity: Eine Transaktion muss als Ganzes – atomar – ausgeführt werden. Wenn sie im Fehlerfall abbricht, müssen alle Teile rückgängig gemacht werden. Keiner der Teilvorgänge darf wirklich durchgeführt werden, bevor die ganze Transaktion „committed“ wird. Diese Eigenschaft wird von der Middleware zugesichert.Consistency: Eine Transaktion muss konsistent sein. Nach der Transaktion dürfen sich die Daten nicht in einem inkonsistenten Zustand befinden. Anders ausgedrückt: alle Änderungsschritte, die zur Erreichung eines konsistenten Zustands notwendig sind, müssen innerhalb einer Transaktion liegen. Dies muss vom Programmierer bewerkstelligt werden, indem er seine Transaktion ebenso aufbaut.Isolation: Jede Transaktion soll unabhängig von anderen Transaktionen funktionieren, die zur selben Zeit ablaufen. Anders ausgedrückt: mehrere Transaktionen, die gleichzeitig (überlappend) ausgeführt werden, sollen zu dem selben Ergebnis führen, als würden sie nacheinander ausgeführt. Durability: Eine abgeschlossene (commited) Transaktion soll permanent sein, selbst bei einem auftretenden Systemabsturz. Diese Eigenschaft wird von der Middleware zugesichert.[rock-evans], [webopedia: „acid“]

Verteilte Transaktionen (Distributed Transactions)Was eine Transaktion ist, ist nun klar. Eine verteilte Transaktion wiederum ist eine Transaktion, bei der die einzelnen Operationen, aus denen sie aufgebaut ist (potentiell...) nicht mehr auf einer Maschine stattfindet, sondern auf mehrere Server verteilt sein kann [rock-evans]. Um zum einführenden Beispiel zurück zu kommen, vielleicht liegen die Kundendaten in einer Datenbank auf einem anderen Rechner als die Rechnungsdaten, das Buchhaltungssystem läuft wiederum auf einem anderen Server. Unter Umständen sind auch die Kunden in einem anderen DBMS gespeichert als die Rechnungsdaten. Die Buchhaltung arbeitet mit einem eigenen System, auf dessen Datenbank wir nicht direkt zugreifen können, sondern wir nur mit der Applikation kommunizieren können.DTPMs nutzen Resource Manager zur Steuerung von verteilten Transaktionen.

Page 24: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

23

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Ressource ManagerRessource Manager sind Software-Produkte, die Ressourcen managen (aha!). Ressourcen sind alle externen Quellen und Ziele auf die eine Applikation zugreifen kann. Ressource Manager können demnach DBMSs (managen Datenbanken = Ressource), File Manager (managen Files = Ressource), Prozess Manager (steuern den Aufruf von Prozessen = Ressource), Druckerschlangen-Manager (Druckerschlange = Ressource) und andere sein.DTPM können mehrere Ressource Manager verschiedener Art innerhalb einer Transaktion steuern. Wenn einer der Ressource Manager einen Fehler meldet, führen DTPM die notwendigen Aktionen aus, um die bisherigen Operationen in der Transaktion rückgängig zu machen und die Ressourcen in ihren bisherigen (konsistenten) Zustand zurück zu versetzen. [rock-evans]Bei verteilten Transaktionen ist dazu das sogenannte „2-Phase-Commit“ nötig, ein Commit-Verfahren, das – wie der Name schon sagt – in zwei Phasen ausgeführt wird.

2-Phase CommitDie erste Phase besteht daraus, dass die DTPM alle involvierten Ressource Manager befragt, ob sie ein Commit auf ihre (lokale Teil-)Transaktionen durchführen könnten, also ob alle Operationen erfolgreich waren. Meldet auch nur ein Ressource Manager ein „Nein“ zurück, so wird an alle ein „Rollback“-Kommando geschickt. Melden alle RMs, dass der Commit durchgeführt werden kann, so startet die zweite Phase des 2-Phase-Commits. Alle RMs werden dazu aufgefordert, nun den (lokalen) Commit auszuführen, also die anstehenden Änderungen persistent zu machen. [rock-evans]

Bei der verteilten Transaktion können die Aufträge, also die Einzeltransaktionen, von der DTPM asynchron an die RMs geschickt werden, sie wird nicht warten, bis ein RM die komplette Transaktion durchgeführt hat und dann erst die nächste Transaktion beim nächsten RM in Auftrag geben. Statt dessen werden alle Aufträge an alle verschickt, dann die erste Phase des 2-Phase-Commit eingeleitet (man erinnere sich an das I aus ACID).Aufgrund dieser Asynchronität setzten DTPMs Messages ein. DTPMs sind typischerweise als TP-Monitore implementiert.

TP Monitor (Transaction Processing Monitor)TP-Monitore arbeiten Nachrichten-orientiert: Client-Anwendungen kommunizieren mit dem TP-Monitor über Nachrichten. Eingehende Nachrichten werden mit einer Transaktions-ID versehen und in einer Message Queue gepuffert. Diese muss persitent sein, also auch einen

Client

BusinessApplikation

mit TransaktionDTPM

Server 1

DTPM DBMS1

Server 2

DTPM DBMS2

Server 3

DTPM

Server 4

DTPM File-Manager

Prozess(Appl. Modul)

?

Page 25: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

24

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Systemabsturz überleben können. Ein Scheduler verteilt die eingehenden Bearbeitungs-Nachrichten an einzelne Server-Prozesse* (Ressource Manger), stellt damit also ein Load Balancing zur Verfügung. Einige TP-Monitore können bei Notwendigkeit weitere RM-Instanzen (Prozesse*) starten. Ein TP-Monitor verfügt über einen Lock-Manager, der Datenbereiche sperren kann, die gerade in Bearbeitung sind, und über einen Log-Manger, der Änderungen gegen die Ressourcen protokolliert und – sofern dies nicht vom Ressource Manager selbst gewährleistet wird – mit Hilfe eines Recovery Managers diese im Fehlerfall wieder rückgängig machen kann. In einem Repository verwaltet der TP-Monitor Benutzerdaten und -rechte. [spruth]*) In der Literatur (außer [rock-evans]) ist bei Ressource-Managern immer von Multitasking, also

mehreren Server-Prozessen die Rede. Der Korrektheit halber sei aber erwähnt, dass z.B. der MTS

von DCOM mit Multithreading – also mehreren Threads innerhalb eines Prozesses – arbeitet!

3.2.5 Komponenten-orientierte MiddlewareKomponenten-(bzw. Objekt-)orientierte Middleware wurde für den Einsatz in n-tier Systemen mit hoher Komplexität entworfen. Sie ist zunächst am besten mit RPC-Middleware vergleichbar: es werden entfernte Funktionen aufrufen und Herzstücke sind Interfaces, die mit Hilfe von IDLs beschrieben werden; ebenso werden Stubs, Proxies (bzw. „Skeletons“) und Marshalling eingesetzt.Komponenten-orientierte Middleware ist sich dabei allerdings „bewusst“, dass die RPCs sich nicht auf alleinstehende Funktionen, sondern auf Methoden von Objekten beziehen und kann Objekte (Komponenten) als Ganzes erzeugen und verabeiten. Sie arbeitet mit mehr oder weniger zentralen Registern, um Objekte identifizieren und verwalten zu können; sie kennt, berücksichtigt und unterstützt objektorientierte Konzepte wie Vererbung.Außerdem stellt Komponenten-orientierte Middleware außer der RPC-ähnlichen Kommunikation in der Regel noch eine ganze Reihe von anderen Transfermöglichkeiten (Nachrichten, Transaktionen, ...) zur Verfügung, über die Objekte untereinader kommunizieren können. Sie bietet Sicherheits- und eine Anzahl weiterer Dienste.Bei Komponenten-orientierter Middleware handelt es sich daher eigentlich um hybride Middleware-Architekturen, die viele der bisher vorgestellten Middlewares in sich vereinen. Beispiele für solche Middleware-Architekturen sind DCOM (Distributed Component Objekt Model), CORBA (Common Object Request Broker Architecture) und RMI (Java Remote Method Invokation). Da die Konzepte sehr unterschiedlich sind, lassen sie sich nicht allgemein und detailiert beschreiben; die ersten beiden Beispiele werden aber in den beiden folgenden Kapiteln genauer vorgestellt.

Client 1

Client 2

Client n

TP Monitor

Server-Prozess 1

Server-Prozess 2

Server-Prozess m

Client 1

Client 2

Client n

Server-Prozess 1

Server-Prozess 2

Server-Prozess m

Client 1

Client 2

Client n

TP Monitor

Server-Prozess 1

Server-Prozess 2

Server-Prozess m

Client 1

Client 2

Client n

Server-Prozess 1

Server-Prozess 2

Server-Prozess m

ohne TP Monitor: n = m

mit TP Monitor: n ≥ m TP Monitor nimmt Anwendung Skalierung und Autorisation ab.

Page 26: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

25

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

DCOM

IUnknown

Page 27: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

26

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

4. DCOMDCOM ist Microsoft‘s Middleware-Konzept für die komponenenten-basierte Kommunikation in Verteilten Systemen. Als Implementierung wurde DCOM ab Windows NT in die MS-Betriebssysteme integriert, aber auch für Windows 95/98 sind mit dem Internet-Explorer 4.0 DCOM-Komponenten verfügbar.DCOM ist keine einzelne Middleware, sondern eine ganze Sammlung von Middleware-Diensten die dem Programmierer zur Verfügung stehen.Außerdem ist es neben seiner konkreten Implementierung in Windows-Betriebssystemen auch ein Konzept, das auf anderen Plattformen umgesetzt werden kann und Aspekte von heterogenen Systemen prinzipiell berücksichtigt. Dies ermöglicht anderen Herstellern, DCOM-Implementierungen auf anderen Plattformen bereitzustellen (dies sind vor allem Software AG, Digital, HP).Eines der Hauptprobleme für das Verständnis von DCOM ist die Abgrenzung einiger Begriffe. Microsoft tendiert dazu, einige Begriffe schwammig zu definieren bzw. Begriffe in verschiedenen Veröffentlichungen und Verlautbarungen unterschiedlich zu gebrauchen.Weiterhin ist an manchen Stellen schwer abzugrenzen, was DCOM-Dienste und was Windows-Dienste sind, also den eigentlichen Funktionsumfang von DCOM klar zu umreißen, zumal dieser sich im Laufe der Zeit dynamisch wandelt.Im ersten Abschnitt dieses Kapitels werde ich daher einen Abriss über die geschichtliche Entwicklung geben und später einige Begriffe definieren, so wie ich sie verwenden werde, ohne Anspruch, damit auf aktueller Höhe der Microsoft-Semantik zu liegen.

4.1 Entwicklung von DCOM

ZwischenablageAm Anfang war die Zwischenablage. Eine typische Funktionalität schon von klassischen Textverabeitungssystemen und Editoren ist es, einen Textblock zu markieren und an eine andere Stelle zu verschieben oder zu kopieren. Dies ist eine klassische Aufgabe, die von der Andwendung selbst bereitgestellt wurde. Etwa ab 1987 bot Microsoft in seinen ersten Windows-Versionen eine revolutionäre Technik an: mit Hilfe der Zwischenablage konnten Daten nun in einer Anwendung ausgeschnitten oder kopiert werden und in eine andere Anwendung eingefügt werden, ohne den Umweg über eine Datei nehmen zu müssen und zu hoffen, dass beide Anwendungen ein gemeinsames Dateiformat unterstützen. Man konnte auf diese Art „Verbunddokumente“ (Compound Documents, strukturierte komplexere Daten, nicht nur flache Zeichenfolgen) über das DDE-Protokoll (Dynamic Data Exchange) austauschen, zum Beispiel Daten aus einem Spreadsheet in einen Text einfügen.Dies hatte aber noch den Nachteil, dass die Anwendung, in die eingefügt wurde, die Datenstrukturen erkennen und interpretieren musste. Außerdem war es nur möglich, statische Kopien (Snapshots) der Daten zu kopieren. Bei einer Änderung am Quelldokument musste der Vorgang wiederholt werden.

Page 28: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

27

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

OLE / COMAb etwa 1990 entwickelte Microsoft OLE (Objekt Linking and Embedding), das 1992 in Windows integriert wurde. Damit ist es möglich, Dokumente oder Ausschnitte aus Dokumenten („Objekte“) mit anderen zu verknüpfen, was auch eine automatische Aktualisierung ermöglichte.Mit OLE2 (1993) entstand der Komponenten-Begriff (zum Komponenten-Begriff später mehr). Die verlinkten Dokumente konnten mit Komponenten der Ursprungs-Anwendung (OLE-Server) innerhalb eines anderen Programmes (OLE-Client) bearbeitet werden (eine verlinkte Excel-Tabelle innerhalb eines Word-Dokumentes konnte mit Excel-Programmfunktionalität verändert werden, Graphen konnten von Excel aktualisiert werden usw.). Anders ausgedrückt: eine Anwendung kann das Erscheinungsbild einer anderen annehmen und deren Funktionalität bieten, um deren Objekte zu bearbeiten. OLE2 bot dazu einheitliche Schnittstellen an, über die die Komponenten eine Interprozess-Kommunikation führen können. Das Protokoll ist sprachunabhängig und binär definiert. 1995 wurde OLE2 in COM (Component Objekt Modell) umbenannt. Erstaunlicherweise sind es genau noch diese Schnittstellen, über sie später auch DCOM kommunzierte.

DCEEtwa zeitgleich (Ende der 80er bis Mitte der 90er Jahre) arbeitete die OSF (Open Software Foundation, heute The Open Group) an Standards für eine verteilte Datenverarbeitung auf heterogenen Plattformen. Mit DCE (Distrubeted Computing Environment) wurde 1992 ein Konzept (mit konkreter Implementierung) vorgestellt, solches zu gewährleisten. Ein Teil dieses Konzepts war der standardisierte DCE-RPC.

VBX / OCX / ActiveXEbenfalls etwa 1990 stellte Microsoft das VBX-Konzept (Visual Basic Custom Control) vor. VBX‘se sind wiederverwertbare Software-Komponenten, die in jeder Applikation eingesetzt werden können. Wie der Name schon vermuten lässt, wurde diese Konzept ursprünglich für die Nutzung in Visual Basic entwickelt. Durch die Verbindung von VBX mit OLE-Schnittstellen entstand etwa 1995 OCX (OLE Custom Controls). Eine Erweiterung des OCX-Standards führte 1996 zu ActiveX, einer Schnittstellendefinition für Komponenten. ActiveX-Komponenten sollen plattformunabhängig funktionieren und direkt aus dem Internet heraus geladen und in einem Web-Browser gestertet werden können. Auf ActiveX komme ich aber später noch einmal zurück.

DCOMDCOM (Distributed Component Objekt Modell) ist eine Weiterentwicklung von COM. Mit COM war es möglich, mit anderen Komponenten einer Interprozess-Kommunikation auf dem gleichen Rechner zu führen. DCOM bringt nun die Erweiterung, dass diese Prozesse auch auf anderen, entfernten Rechnern laufen können. Primär stellt DCOM dazu eine eigene Implementierung des DCE-RPC zur Verfügung, über die die Daten weitergeleitet werden.

Page 29: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

28

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Die Schnittstellen, die DCOM dazu verwendet, sind die gleichen, die schon von OLE2 bzw. COM angeboten wurden. Andwendungsprogrammierer mussten nicht mehr umlernen und COM-Komponenten können einfach zu DCOM-Komponenten umgebaut werden; die RPC-Funktionalität bleibt dabei vor dem Anwendungsprogrammierer weitestgehend verborgen.DCOM bietet aber auch noch weitere Dienste an, die es verteilten Komponenten ermöglichen, zu kommunizieren, so etwa Messaging- und Transaktionsdienste. DCOM entstand 1996.

COM+1998 veröffentlichte Microsoft COM+ als eine Erweiterung von DCOM. COM+ bietet weitere Dienst-Implementierungen wie Load-Balancing, einem Garbage-Collector und interne Schnittstellen-Erweiterungen, die für die Anbindung an eine JVM (Java Virtual Machine) nötig sind. Außerdem erleichtert es das Memory-Managment und stellt ein Objekt-Pooling zur Verfügung. In COM+ ist außerdem eine neue Version des MTS (Microsoft Transaction Servers) enthalten.Konzeptionell bringt COM+ gegenüber DCOM aber nichts neues, es erleichtert lediglich über die Automatisierung einiger Aufgaben, die bei klassischen DCOM-Anwendungen noch dem Programmierer überlassen blieben, die Erstellungen von verteilten COM-Komponenten und verbessert – z.B. durch o.g. Objekt-Pooling – die Ressourcen-Verwaltung innerhalb der DCOM Runtime. Die Grenzen zwischen COM+ und DCOM sind – insbesondere auch im Microsoft-Referenz-Material – sehr fließend und, wie schon gesagt, bringt es keine konzeptionellen Neuheiten mit sich. Ein Entwickler, der mit COM+-Erleichterungen arbeiten möchte, muss ohnehin das dahinter stehende DCOM-Konzept verstanden haben, auch wenn einige Aufgaben implizit übernommen werden. Man könnte es auch so ausdrücken: COM+ ist die komplette Microsoft-Implementierung der DCOM-Architektur.

.NET

.NET ist Microsofts neueste Offensive in der verteilten Kommunikation; es zielt vor allem auf Entwicklung von internetfähigen Komponenten ab. Zu .NET später noch einmal mehr.

OLE2

.NET

OLE

Zwischenablage

COM+

DCOM

DCE-RPCCOM

Schnittstellen KommunikationKomponenten

ActiveX

OCX

VBX

Page 30: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

29

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

4.2 Architektur, Konzepte und BegriffeWie schon beschrieben wurde DCOM als Plattform-unabhängiges Konzept für die verteilte Kommunikation mit wiederverwendbaren Komponenten erstellt. Der folgende Abschnitt bezieht sich auf den Aufbau von DCOM auf Windows-Plattformen. Einschränkungen und Abweichungen bei der Bereitstellung von DCOM auf anderen Betriebssystemen werden in einem gesonderten Abschnitt beleuchtet. Da ein Bild oft mehr als tausend Worte sagt im folgenden eine Grafik, die die Architektur von DCOM nach [rock-evans] darstellt:

Und nun zur Erläuterung der einzelnen Teile:

4.2.1 ActiveX-KomponentenIn der obigen Grafik als „ActiveX Komponenten“ angeführten Teile sind nichts anderes als Komponenten von Anwendungen, die auf DCOM basieren. Zum Komponentenbegriff weiter unten mehr. Diese ActiveX‘s greifen über COM-Schnittstelle, die im folgenden genauer erläutert wird, auf DCOM Dienste zu. ActiveX-Komponenten können (auf Windows-Systemen) in Form von EXE oder DLL-Programmen existieren.

Da ich dies für wichtig halte aber noch einige Sätze zum Begriff „ActiveX“:ActiveX wurde von Microsoft ursprünglich eingeführt als Begriff für besondere Komponenten, die ausschließlich auf dem (D)COM-Modell basieren und – in einer beliebigen Programmiersprache geschrieben – ohne Änderung auf jeder Plattform lauffähig sind, auf der es einen Compiler für diese Programmiersprache und eine DCOM-Implementierung gibt. Es gibt dabei aber vier Hindernisse [rock-evans]:

DCOM

COM-Schnittstelle

Administrations-D

ienste

Managment-Dienst-SchichtSecurity-Dienste MSMQ MTS

Translation-DiensteOLE DB LDAP/ADSI OLEMSGing

ActiveX-Kompon.

ActiveX-Kompon.

ActiveX-Kompon.

ActiveX-Kompon.

ActiveX-Kompon.

Kommunikations-Dienst-SchichtMS-RPC /DCE-RPC

COM TI(CISC, IMS)

Registry

/Active

Directory

Page 31: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

30

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

1) Auf der Zielplattform muss ein passender Compiler verfügbar sein, der mit dem Dialekt der gewählten Programmiersprache klar kommt (Visual Basic für Mainframes ???). Der Programmierer muss die ActiveX Komponenten mit einem solchen Compiler für jede Zielplattform compilieren.

2) ActiveX Komponenten können nach MS-Definition auch Windows GUI-Komponenten enthalten, die über Win32-API angesprochen werden. Auf den Zielplattformen müsste also für ActiveX-Komponenten mit GUI (im Allgemeinen als „ActiveX Controls“ bezeichnet) eine Übersetzungssoftware existieren, die Win32-Calls z.B. in Motif-Calls auf Unix Systemen umwandelt, oder eine Windows-GUI-Emulationen. Betriebssysteme die nur zeichenbasierte Oberflächen verfügen (Mainframes!) bleiben demnach ganz außen vor.

3) Die Speicherverwaltung ist Betriebssystem-abhängig. Eine Portierung von DCOM auf andere Betriebssysteme, die Active-X Komponenten unterstützen soll, muss also auch die Speicherverwaltung von Windows NT emulieren, zumindest die gleichen Schnittstellen bereitstellen.

4) Die Thread-Verwaltung, wie sie Windows NT bietet, müsste auf den Zielplattformen verfügbar sein, da DCOM ein Multithreading einem Multitasking vorzieht. Einige Betriebssysteme kennen das Thread-Konzept gar nicht, sondern nur Prozesse, andere nur eingeschränkt.

Dass es trotzdem möglich ist, ActiveX Komponenten, die konsequent unter Nutzung der COM-Funktionen und ATL (ActiveX Template Library) erstellt wurden, auch auf anderen Betriebssystemen laufen zu lassen, zeigt aber zum Beispiel Software AG‘s EntireX DCOM für Linux, ein einfaches Beispiel dafür gebe ich in Kapitel 6.4. Auch wenn hier die Einschränkung gilt, dass keine Win32-GUI-Calls möglich sind.

Problematisch an dem Begriff „ActiveX“ ist, dass er von Microsoft als Marketingbegriff genutzt und mit Komponenten in Verbindung gebracht wurde, die sicherlich so nicht portierbar sind. Ein Control, das sich zum Beispiel direkt Windows-SDK-Funktionen oder völlig anderen Third-Party-APIs bedient, die nicht per se auf allen Plattformen verfügbar sind, kann man immer noch als ActiveX bezeichnen. Nicht zuletzt gibt es in der MFC (Microsoft Foundation Classes für C++) ausdrücklich eine direkte Unterstützung zur Erstellung von ActiveX Komponeten. Um diese auf einer anderen Plattform zum Laufen zu bringen, müssten dort also auch die MFC verfügbar sein, was wohl niemand ernsthaft annimt. Als „ActiveX“ werden im praktischen Sprachgebrauch heute alle Controls oder Komponenten betitelt, die über COM-Schnittstellen ansprechbar sind und in andere Programme integriert, im Internet-Explorer laufen und in anderen Programmiersprachen genutzt werden können. Ein Beispiel dafür ist mein eigenes, in Kapitel 7 beschriebenes „ActiveX Control“.

„ActiveX“ bedeutet demnach aber quasi nur so viel wie „hat Funktionalität, die über eine COM-Schnittstelle ansprechbar ist“, genauer gesagt: „implementiert (mindestens) ein IUnknown- oder ein IDispatch- und ein IClassFactory-Interface“. Was wiederum diese Interfaces sind, ist auf den nächsten Seiten zu erfahren.

Page 32: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

31

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

4.2.2 COM-KonzepteCOM ist mehr als nur eine Schnittstellenbeschreibung. COM beinhaltet außerdem API-Funktionen zur Erstellung von COM-Komponenten (insbesondere Funktionen zur Objekterstellung und Automation = Offenlegung von Schnittstellen) sowie Bibliotheken zur Interprozess-Kommunikation und -Steuerung. Dieses COM-Konzept wird in den nun folgenden Unterkapiteln beschrieben.

4.2.3 Komponenten, Klassen und ObjekteKomponenten und Klassen sind als „Dinge“ anzusehen, die Eigenschaften besitzen und Methoden, mit denen auf diese Eigenschaften zugegriffen wird. Ein solches „Ding“ namens „Kunde“ hat zum Beispiel Eigenschaften wie Namen und Adresse, Methoden wie „Ändern des Kunden-Namens“, „Abfragen der Adresse“ oder „Berechnen des Jahresumsatzes“.Eine solches „Ding“ ist eine Komponente. Eine Klasse ist im Sinne von (D)COM ein Block von Maschinencode, der dieses „Ding“ und seine Methoden darstellt.Der Unterschied zwischen einer Komponente und einer Klasse ist eigentlich nur, dass Komponente dieses Ding während seiner ganzen Lebensphase beschreibt: während der Konzeption, im Source-Code und im Maschinen-Code, Klasse nur letzteres [rock-evans].Außerdem beschreibt Microsoft eine Klasse als eine einzelne Implementierung einer (oder mehrerer) Schnittstelle(n). MS meint mit Implementierung aber den entstandenen Maschinen-Code. Im Gegensatz dazu stehen Klassen im Quellcode bzw. in der OO-Analyse. Eine COM-Klasse kann durchaus aus mehreren C++-Klassen compiliert worden sein. Objekte wiederum sind „Ausprägungen“ dieses Maschinencodes; eine Instanz dieser Klasse die gerade auf irgend einer Maschine abläuft. Es können so also mehrere Instanzen, Objekte, der selben Klasse existieren.Manchmal sind aber auch binäre Interface-Darstellungen als Objekte bezeichnet. Das Problem dabei ist, dass Microsoft selbst sich in Veröffentlichungen nicht immer an diese Definitionen hält und Objekt, Klasse und Komponente schon einmal durcheinanderwürfelt.

4.2.4 GUID, CLSID, IIDGUIDs sind „Globally Unique Identifiers“, also „weltweit einmalige Identifikationsnummern“. GUIDs sind 128 bit groß und entsprechen den im DCE-Standard beschriebenden UUIDs (Unified Unique IDs). Sie können als Identfikationsnummern für alles mögliche dienen; innerhalb von COM dienen sie zur Identifikation von Klassen (dann heißen Sie CLSID -> CLaSs ID) und Schnittstellen (IID -> Interface ID).Das wichtige daran ist ihre Eindeutigkeit. Namen könnten mehrdeutig sein (es gibt bestimmt weltweit mehrere „Kunden“-Klassen oder -Interfaces). Die GUIDs sind aber eindeutig. Sie bestehen üblicherweise aus der IEEE-Maschinen-ID des Rechners, auf dem sie erzeugt werden (die MAC-Adresse der primären Netzwerkkarte, falls eine existiert), einem Zeitstempel (mit einer Auflösung im Nanosekunden-Bereich) und – falls nötig – einer fortlaufenden Nummer. Der Zeitstempel umfasst übrigens einen Zeitraum von 3240 Jahren, es ist in der

Page 33: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

32

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

nächsten Zeit also hier nicht mit Problemen zu rechnen...Das Darstellungsformat einer GUID ist; „xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx“, wobei jedes x für eine Hexadezimal-Ziffer steht.COM und DCOM sprechen intern alle Objekte nur über Ihre GUID an, während ein Programmierer den Namen des Objekts oder eine Syntax wie _uuidof(‚Objektname‘) benutzt.

4.2.5 Schnittstellen (Interfaces) und MIDLSchnittstellen (Interfaces) beschreiben die Zugriffsmöglichkeiten auf Funktionaltität von Komponenten. Jedes Interface definiert einen verbindlichen „Vertrag“ zwischen Client und Server; der Client kann von der Implementierung im Server abstrahieren und muss sich darauf Verlassen können, dass die Server-Komponente genau die im Interface zugesicherte Funktionalität bietet [mwbook]. Der Zugriff auf eine Server-Komponente ist ausschließlich über ihre in der Schnittstelle definierten Memberfunktionen möglich.Jedes Interface hat einen Namen (diese beginnen nach COM-Konvention mit „I“ für Interface) und eine IID. Eine Klasse implementiert eines oder mehrere Interfaces. Jedes Interface basiert auf einem Basis-Interface „IUnknown“. Dadurch wird gewährleistet, dass jede Klasse ein solches IUnknown-Interface besitzt, das Informationen über die Klasse selbst liefern kann (dazu später mehr !).Die COM-Spezifikation schreibt primär keine Syntax vor, in der Schnittstellen zu beschreiben sind, sondern nur die Darstellung der Schnittstellen auf binärer Ebene. Dies erlaubt die Implementierung von Servern und Clients in beliebigen Programmiersprachen. Nichtsdestotrotz gibt es von Microsoft eine eigene Vorgabe für eine Interface Definition Laguage (IDL), die MIDL. Der MIDL-Compiler kann aus einer MIDL-Schnitstellen-Beschreibung den sprachabhängigen Quellcode für Schnittstellen für verschiedene Programmiersprachen erstellen. Dieser Quellcode besteht aus einem Stub und einem Proxy, die in der Server- und Client-Klasse mitcompiliert werden. Dies entspricht 1:1 dem RPC-Konzept (Kapitel 2.2.3).Der MIDL-Compiler generiert aber auch Informationen für die Type Library, die eine Art Datenbank für Informationen über die Schnittstellen ist. Diese ist für den Zugriff von interpretierten Sprachen wie Visual Basic oder Java nötig, kann aber auch (recht kompliziert) von Compiler-Sprachen genutzt werden, um Informationen über unbekannte Objekte zu erhalten (siehe Automation). Zur Laufzeit können dymamisch Informationen über die Schnittstelle abgefragt werden, die in Compiler-Sprachen in Stub und Proxy-Code enthalten sind. So kann zur Laufzeit eine Typen-Prüfung für einen Zugriff auf das Interface durchgeführt und ein Methoden-Name in einen „Zeiger“ auf die Implementierungen der Methode geholt werden. Diese Methoden-Pointer werden sonst über VTables (siehe unten ...) abgefragt. Der Zugriff über die Type-Library ist aber langsamer als über VTables.

Interface

Client-Applikation COM-

Objekt(Server)

Interface A

Interface B

Interface C

IUnknown

BinärerObjektcode

pVtbl

VTablePointer Methode 1Pointer Methode 2Pointer Methode 3

. . .

Interface-Pointer

Methode 1

Methode 2

Methode 3

Page 34: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

33

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Ein Interface, das einmal festgelegt wurde, kann nicht mehr verändert werden. Das sorgt dafür, dass ein Client, der ein bestimmtes Interface benutzt, sich zu jeder Zeit – auch bei Versionsänderungen der Komponente – auf die Funktionalität voll verlassen kann. Soll eine Funktionalität erweitert werden, so muss eine neue Schnittstelle definiert werden, über die neue Clients diese Funktionalität ansprechen können.Das (D)COM-Konzept sieht keine Implementierungs-Vererbung vor, aber Interface-Vererbung. Das heißt eine neue Schnittstelle kann eine bestehende Schnittstelle „importieren“. Auch darauf gehe ich im weiteren Verlauf noch einmal ein.

IUnknownWie zuvor beschrieben, hat jede COM-Klasse ein IUnknown-Interface. Neben einem Referenzzähler-Mechanismus mit den zwei Methoden AddRef() und Release() stellt dieses Interface eine QueryInterface()-Methode zur Verfügung. Als Input-Parameter hat diese die IID eines Interfaces und prüft, ob das befragte Objekt das angegebene Interface unterstützt. Wenn ja, gibt es einen Pointer auf dieses Interface zurück, wenn nicht, NULL.

VTable (Virtual Function Table)Jedes Interface enthält einen Pointer auf eine „VTable“, die wiederum für jede Methode, die im Interface beschrieben ist, einen Pointer enthält.Liegt das Ziel im gleichen Prozessraum, so zeigt der Methoden-Pointer direkt auf den Code der Funktion und diese kann direkt aufgerufen werden. Ansonsten zeigt der Methoden-Pointer auf den Proxy, der über (D)COM Dienste den Aufruf auf den anderen Prozess, eventuell auf einem anderen Rechner, durchführt [rock-evans].DCOM ist über diesen Mechanismus in der Lage, vom eigentlichen Zugriff zu abstrahieren, daher kann ein Server-Objekt später lokal (im gleichen oder einem anderen Prozess) oder auch remote auf einem entfernten Rechner laufen, der Client greift nur auf das Interface zu.

Da jedes COM-Interface von IUnknown abgeleitet ist, sind die ersten drei Einträge in jeder VTable Pointer auf die Implementierungen von QueryInterface(), AddRef() und Release(). [msdnlib]

Interface

Client-Applikation COM-

Objekt(Server)

Interface A

Interface B

Interface C

IUnknown

BinärerObjektcode

pVtbl

VTablePointer Methode 1Pointer Methode 2Pointer Methode 3

. . .

Interface-Pointer

Methode 1

Methode 2

Methode 3

lokale MaschineClient-Prozess

Client-Applikation

Interface A

Interface C Proxy

Proxy

Server-ProzessServer-Objekt

Interface B

Interface C Stub

remote MaschineServer-ProzessServer-Objekt

Interface B Stub

In-ProcessServer-Objekt

Page 35: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

34

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Automation, IDispatchWie vorhin schon angedeutet gibt es außer den VTables noch einen zweiten Weg, wie man auf die Methoden einer Klasse zugreifen kann, der in interpretierten, Script- und Makrosprachen genutzt werden kann: Automation (früher: OLE-Automation). Dieser Weg bietet einen dynamischen Zugriff auf Methoden, das heißt, der Aufruf erfolgt durch Übergabe des Methodennamens, der zur Laufzeit in einen Pointer aufgelöst wird.Um Automation anbieten zu können, muss die Klasse ein „Dispatch Interface“ (IDispatch) implementieren, das natürlich auch auf IUnknown basiert. Eine Komponente, die ein solches Interface benutzt, nent man „Automation Server“, ein Client, der über IDispatch Methoden anfordert einen „Automation Controller“.Im Automation Server muss jede Methode, die über das IDispatch-Interface aufgerufen werden kann, mit einer ID verknüpft werden (die keine GUID und nur für diese Implementierung gültig ist!).Das IDispatch-Interface (das wie jedes anderen natürlich von IUnknown abgeleitet ist) verfügt über eine GetIDsofNames()-Methode, die vom Client mit dem Namen der angeforderten Methoden aufgerufen wird und deren ID zurückliefert.Außerdem gibt es im IDispatch die Methode Invoke(), die vom Client diese ID übergeben bekommt und einen Pointer auf die Methode ermittelt und diese dann aufruft. Dazu bekommt die Invoke()-Methode noch übergeben: Die Parameter für die tatsächlich aufzurufende Funktion, einen Speicher-Bereich für die Rückgabewerte, den Typ der Methode (normale, GetProperty, PutProperty oder PutPropertyByRef-Methode*) sowie weitere Parameter zur Fehlerbehandlung und Internationalisierung. Eine Liste der Funktionsparameter und ihrer Bedeutung kann aus der Type Library geladen werden [rock-evans, msdnlib]. Es gibt außerdem die Möglichkeit, ein sogenanntes „Dual Interface“ zu implementieren, das heißt, dem Client die Möglichekit zu geben, sowohl direkt über ein Interface und die VTable als auch über das IDispatch-Interface zuzugreifen.Die hellroten Bereiche in nebenstehender Veranschaulichung sind nur bei Dual-Interface-Implementierungen in der VTable von IDispatch vorhanden.*) COM-Interfaces kennen neben echten Methoden auch „Properties“, also Eigenschaftswerte. Auf

diese kann aber nur über Get-/Put-Methoden zugegriffen werden, die halbautomatisch erzeugt

werden und aufgerufen werden können. In 4GLs wie Visual Basic oder auch Natural wird dieser

Get/Put-Mechanismus allerdings vor dem Programmierer verborgen und er kann direkt mit

Zuweisungen oder Abfragen auf diese Properties zugreifen. Dahinter steht aber immer ein Aufruf

an die Get/Put-Methoden. PutByRef ermöglicht eine Übergabe per Refrenz (Pointer).

Interface(IDispatch-Abl.)

pVtbl

VTable&QueryInterface()

&AddRef()&Release()

&GetIDsofNames()

Interface-Pointer

&Invoke()&Methode1()&Methode2()&Methode3()

Name ID�Methode1��Methode2��Methode3�

123

PointerID&Methode1()&Methode2()&Methode3()

123

Methode 1

Methode 2

Methode 3

Page 36: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

35

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

DatentypenDCOM definiert einige eigene Datentypen, die dazu dienen, Datentypen, die nicht in jeder Programmiersprache verfügbar sind oder in jeder Sprache anders dargestellt werden, dennoch austauschen zu können. Die wichtigsten sind DATE (Datum und/oder Zeitangabe zwischen 1.1.100 und 31.12.9999 mit einer Auflösung von 1 Sekunde), CURRENCY (Geldbetrag oder andere Festkommazahl, Bereich ±922*1015 in einer Auflösung von 1/10000) und VARIANT (Variabler Datentype, kann DATE, CURRENCY und die üblichen einfachen Datentypen wie 1,2,4-Byte Integer mit oder ohne Vorzeichen, 4- und 8-Byte Fließkomma-Werte Bool‘sche Werte, Zeichen und Strings sowie Pointer auf alle diese enthalten).

Wiederverwendung von InterfacesWie schon beschrieben, erlaubt (D)COM keine Implementierungs-Vererbung. Ein Interface darf von einem anderen abgeleitet sein, eine COM-Klasse nicht.Um Wiederverwendung von Programmcode, der natürlich in einem Komponenten-Modell von elementarer Bedeutung ist, doch zu gewährleisten, steht dem Programmierer das Konzept der Interface-Vererbung zusammen mit den Modellen der Delegation bzw. der Aggregation zur Verfügung. Für das Interface bedeutet dies nichts anderes, als dass ein Interface ein anderes Interface (evtl. die alte Version) einschließen kann. Dazu steht in der MIDL das Schlüsselwort „IMPORT“ zur Verfügung, das wie die #inlucde-Direktive für den C-Präprozessor funktioniert.

4.2.6 Wiederverwendung von CodeUm neben der Nutzung der alten Interface-Definitionen bei der Erweiterung oder Erneuerung von Klassen auch Code wiederverwenden zu können, muss ein (inneres) Objekt der alten Klasse von dem (äußeren) Objekt der neuen Klasse instanziert werden („Containment“). Es gibt allerdings zwei Konzepte wie über das Interface des äußeren Objekts auf die Methoden des inneren Objekts zugegriffen werden kann: Delegation und Aggregation.

Containment by DelegationBei der Delegation erhält die äußere Klasse einfach noch einmal das Interface, das auch die innere Klasse hat (im Bild Interface A) und implementiert alle Methoden dieses Interfaces. Die Implementierung besteht allerdings nur aus einem Aufruf der ursprünglichen Methode über das Interface der inneren Klasse.Diese Variante ist relativ einfach, aber auch langsamer, weil die Interface-Pointer erneut aufgelöst werden müssen. Das innere Objekt verhält sich also so, als sei es ein Server für das äußere Objekt und ist mit dem Divide-and-Conquer-Ansatz zu vergleichen.

Äußeres Objekt

Interface A(alt)

Interface B(neu)

IUnknown

InneresObjekt

Int.A

IUnknown

Äußeres Objekt

Interface B(neu)

IUnknown

InneresObjekt

IUnknown

Interface A(alt)

Page 37: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

36

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Containment by AggregationBei der Aggregation wird das Interface der inneren Klasse „nach außen“ geleitet, das heißt ein Client greift direkt auf das Interface der inneren Klasse zu, es erscheint für ihn allerdings wie ein Interface der äußeren Klasse.Das klingt zwar einfach und funktioniert auch schneller, hat aber in der Praxis einen entscheidenen Haken, der in der Definition der QueryInterface()-Methode von IUnknown begründet liegt. Die QueryInterface()-Methode muss sich statisch, reflexiv, symmetrisch und transitiv verhalten.Das Problem liegt hier im Begriff symmetrisch: „Wenn ein Client einen Pointer auf ein Interface besitzt und [über dessen QueryInterface()] erfolgreich einen Pointer auf ein zweites Interface anfragt, muss eine Anfrage auf den zweiten Pointer nach dem ersten Interface erfolgreich sein.“ [msdnlib – Plattform SDK:COM – IUnknown::QueryInterface()].Das bedeutet für unser Beispiel: Ein Client, der einen Interface-Pointer für Interface B der äußeren Klasse hat, wird auf eine Anfrage nach Interface A (das ja ebenfalls zur äußeren Klasse gehört) erfolgreich einen Pointer pInterfaceA auf das Interface A erhalten (der auf die Implementierung in der inneren Klasse zeigt).Nach der Symmetrie-Forderung muss der Client aber nun, mit: pInterfaceA->QueryInterface( __uuidof(<Name Interface B>) ), also einer Anfrage auf Interface A nach Interface B auch einen Pointer auf Interface B erhalten können. Diese Anfrage wird aber nun von der QueryInterface()-Implementierung des inneren Objekts bearbeitet. Das innere Objekt kennt zunächst einmal weder das äußere Objekt noch die Interfaces von dessen Klasse! Die innere Klasse muss dazu mit einer zweiten Implementierung des IUknown, einem sogenannten „delegating IUnknown“ versehen werden, das im Gegensatz zum normalen „nondelegating IUnknown“ mit einen Pointer auf einen Container (auf das äußere Objekt) versorgt werden kann und bei Interface-Anfragen an dessen QueryInterface()-Implementierung weiterverzweigt.Dieses Verfahren ist umständlich und die innere Klasse muss außerdem als „aggregatable“ gekennzeichnet sein, was schon zu deren Implementierungszeit berücksichtigt werden muss.

Class FactoryDafür, dass zur Laufzeit tatsächlich ein Objekt von ihr erzeugt werden kann, muss jede Klasse eine sogenannte „Class Factory“ implementieren. Diese wird über ein IClassFactory-Interface angesprochen und sorgt dafür, dass ein Client ein Objekt dieser Klasse zur Laufzeit erhält, wenn er es anfordert. Dafür enthält die IClassFactory eine Methode namens „CreateInstance()“,

Äußeres Objekt

Interface A(alt)

Interface B(neu)

IUnknown

InneresObjekt

Int.A

IUnknown

Äußeres Objekt

Interface B(neu)

IUnknown

InneresObjekt

IUnknown

Interface A(alt)

Page 38: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

37

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

die dies bewerkstelligt und einen Pointer auf das IUnknown des erzeugten Objektes (oder gleich einen Pointer auf ein spezielles, angefordertes Interface) zurückliefert. CreateInstance() kann, wenn die Klasse aggregatfähig ist, außerdem den pIUnknown des äußeren Objektes mit übergeben bekommen, dies geschieht bei der Instanzierung einer äußeren Klasse.Das IClassFactory enthält außerdem eine zweite Methode LockServer(). Ein Client kann mit dieser dafür sorgen, dass die ClassFactory im Speicher bleibt, um mit ihr schneller mehrere Objekte der Klasse erzeugen zu können. LockServer() hat einen Bool‘schen Parameter, bei „TRUE“ wird der Lock-Zähler der Class Factory inkrementiert, bei „FALSE“ dekrementiert (was einem Unlock entspricht). Steht der Zähler auf null (kein Client benötigt diese Class Factory) so kann sie entladen werden.

4.2.6 Registry-Dienste und SCMWie ermittelt COM (und DCOM) zur Laufzeit, wo der Code liegt, wenn ein Client ein Objekt von einer bestimmten Klassen anfordert? Schließlich übergibt der Client keinen Pfad zu einer Datei, die den Code enthält, sondern nur eine CLSID, wenn er ein Objekt einer Klasse instanzieren bzw. ein Interface von ihr anfordern will!Nun, diesen Dienst übernimmt der SCM, der Service Control Manager. Wenn ein Client eine Instanz einer Klasse erzeugen will, tut er das entweder über CoCreateInstance() oder über die ClassFactory. Er übergibt dabei die CLSID der Klasse, von der er ein Objekt anfordert (eventuell über ihren Namen).Der SCM schlägt dann in der Registrierdatenbank, der Registry nach. Dort findet er so unter dem Schlüssel „HKEY_CLASSES_ROOT“ Informationen über die Komponente. Unter anderem auch den Pfad zu ihrer Maschinencode-Datei, die entweder eine DLL (In-Prozess-Server) oder eine EXE (Server in eigenem Prozess) ist.Der SCM prüft nun, ob der angegebene Server bereits läuft, wenn nicht, startet er ihn.Dann befragt der SCM den Server nach einem Interface-Pointer, den er an den Client zurück gibt. Danach kann der Client über das Interface, direkt mit dem Server kommunizieren. Dessen VTable wurde bei der Übergabe durch den SCM gefüllt (entweder mit Pointern auf Methoden des Servers bei In-Prozess- oder mit Pointern auf den Proxy bei externen Servern).Im Falle, dass es sich um einen Remote-Server handelt, ist in der Registry nicht der Name einer EXE- oder DLL-Datei, sondern der Hostname eines Rechners gespeichert, auf dem der Server läuft oder bereitsteht. In diesem Fall nimmt der SCM über DCOM Kontakt mit dem SCM der entfernten Maschine auf und dieser sucht dann anhand seiner lokalen Registry den Server (wie beim lokalen Fall) und gibt einen Interface-Pointer zurück (das Verfahren ist tatsächlich noch ein wenig komplizierter, intern überträgt DCOM noch ein OID- und ein OXID-Objekt als gegenseitige Stellvertreter der entfernten Komponenten, aber dieser Vorgang ist absolut transparent)Wie aber kommen die Daten in die Registry? Ein Server muss dort registriert sein. Dies geschieht im Falle einer EXE-Datei entweder mit Code zur Selbst-Registrierung (die EXE-Datei muss dann, quasi zur „Installation“, mit einem bestimmten Parameter gestartet

Page 39: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

38

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

werden) oder mit einem Registrierungstool (regsvr32.exe). Letzteres ist bei DLL-Dateien die einzige Möglichkeit. Es liest aus der Datei die dort vorhandene CLSID und trägt sie mit dem aktuellen Pfad der Datei in die Registry ein. Alternativ kann auch ein Installationsprogramm die Eintragungen vornehmen, das die CLSIDs seiner zu installierenden Komponenten ebenso kennt wie die Pfade, unter denen es die Dateien im Dateisystem ablegt.Problematischer ist der Punkt bei entfernten Komponenten. Der Administrator (oder eine Installationsroutine) muss den Hostnamen des Rechner, auf dem die entfernte Komponenten verfügbar ist, in die Registry eintragen, und zwar auf jedem Rechner, der die Komponente nutzen soll. Etwas einfacher wird dieser Vorgang erst mit COM+ bzw. Windows 2000, denn dieses bietet neben der Registry das „Active Directory“ an, das eine hierarchische Liste aller im Netzwerk verfügbaren Komponenten darstellen kann.

4.3 DCOM ServicesAlle vorab in den Kapitel 3.2.1 bis 3.2.6 gezeigten Architekturmuster (außer den Bemerkungen zum Remote-Server-Zugriff in „VTables“ auf Seite 33 und „Registry-Dienste“ auf der vorigen Seite) haben noch nichts mit DCOM zu tun, sondern sind reine COM-Architektur. Diese wird jedoch, wie schon in 3.2 erkennbar, von DCOM genutzt. Auf das wesentliche reduziert ist DCOM nur die Verlängerung von COM auf entfernte COM-Objekte. Dies wird über die DCOM-Services erreicht, von denen einige allerdings eine erweiterte Funktionalität bieten. Den Kern bildet jedoch der MS-RPC, der für den Anwendungsentwickler transparent die Kommunikation mit entfernten COM-Objekten durchführt, aber – wie alle DCOM-Services-auch direkt genutzt werden kann.

Die DCOM Services lassen sich in drei Kategorien einteilen:Translation Services übersetzen Anfragen, die über die COM-Schnittstelle an

sie gerichtet werden in Anfragen an andere Objekte (z.B. Datenbankzugriff über COM-Schnittstelle durch OLE DB).

Managment Services ermöglichen die Handhabung und Steuerung von Remote-Zugriffen (z.B. die Security- und Transaktions-Dienste).

Communication Services führen die tatsächliche Kommunikation mit entfernten Objekten aus (MS RPC und COM TI).

Zu den Translation Services sei noch erwähnt, dass nicht eindeutig ist, ob sie eher COM oder DCOM zuzuordnen sind, da sie Aufgaben erfüllen, die meist nur lokal ausgeführt werden und dabei dann nicht auf DCOM-Kommunikation zurückgreifen. Außerdem sind sie nicht in DCOM-Implementierung für anderen Plattformen enthalten. Die Literatur (z.B. [rock-evans]) neigt aber dazu, sie den DCOM-Services zuzurechnen, nicht zuletzt wohl deshalb, weil sie zeitgleich mit DCOM in Windows integriert wurden und prinzipiell Remote-Zugriffe unterstützen. Man kann aber diese Zuordnungsfrage auch lösen, indem man DCOM als Nachfolger und damit als Obermenge von COM ansieht.Auf den nächsten Seiten stelle ich die wichtigsten Services von DCOM so kompakt wie möglich vor, möchte aber hiermit auch noch einmal auf die Grafik auf Seite 29 verweisen.

Page 40: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

39

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

4.3.1 MS RPCWie schon mehrfach beschrieben ist der MS-RPC das Herzstück von DCOM. Über ihn werden alle Verbindungen zwischen zwei DCOM-Hosts durchgeführt. Die Aufrufe aller verteilten Dienste von DCOM werden in einen RPC-Call übersetzt. „It [MS-RPC] is what puts the D in DCOM; without it there would be no support for distribution“ [rock-evans].Der MS-RPC könnte mit Fug und und Recht als eigenständige Middleware bezeichnet werden, denn auch ohne andere DCOM-Dienste oder -Schnittstellen zu nutzen ist es mit ihm schon möglich, verteilte Applikationen zu schreiben. Ein Beispiel für eine direkte, plattformübergreifende RPC-Verbindung findet sich in Kapitel 6.3.Der MS-RPC basiert auf den DCE-RPC-Standards der Open Group um nach außen interoperabel zu sein. Microsoft schrieb zwar seinen eigenen Code und nutzte nicht etwa vorhandene DCE-Implementierungen, richtete sich aber nach den API-Vorgaben von DCE un dessen Protokoll. Damit ist es möglich RPC-Calls gegen andere Plattformen zu betreiben, auf denen der DCE-Standard implementiert ist. Tatsächlich nutzt der MS-RPC für die Kommunikation zwischen Windows-Plattformen eine etwas abgewandelte Form.Der Grund, warum MS seine eigene DCE-Implementierung codierte ist übrigens, dass man sich die Lizenzgebühren sparen wollte, um den Preis von DCOM niedrig zu halten.Es gibt nicht viel über die interne Funktionsweise des MS-RPC, das ich sagen könnte, ohne die Darstellungen in Kapitel 3.2.3 zu wiederholen. Der MS-RPC funktioniert wie jeder andere RPC auch. Interessant sind lediglich die folgenden Punkte:Sessions: Der MS-RPC nutzt intern Sessions (Conversations) um den Overhead von Verbindungsauf- und abbau zu reduzieren, und zwar nicht auf Applikationsebene, sondern auf Host-Ebene. Das heißt, wenn mehrere Threads oder Prozesse von einer Maschine innerhalb eines kurzen Zeitraums mit verschiedenen Threads oder Prozessen auf einer anderen Maschine kommunizieren, dann kann der MS-RPC diese (automatisch) in eine Conversation bündeln.Box-Carriing: Es liegt in der Natur Komponenten-orientierter Ansätze, dass bei der Kommunikation nicht nur einfache Datentypen, sondern komplexe Strukturen übertragen werden. Diese werden dann auf der Senderseite in mehrere RPC-Calls aufgesplittet und beim Empfänger wieder zusammen gesetzt. Dieser Vorgang ist transparent, so dass nach außen der Eindruck eines einzelnen RPC-Calls entsteht.Fehler-Behandlung: MS-RPC stellt einige Mechanismen zur Verfügung, die es erlaubt Fehler jedweder Art gebündelt zu behandeln, unter anderem ein eigenes Exception-Modell.Datenkompression: Der MS-RPC führt keine Datenkompression durch, sondern überlässt dies den darunterliegenden Netzwerkschichten.Verschlüsselung/Security: Der MS-RPC unterstützt keine eigene Security, sondern nur Windows- und Third-Party-Security-Dienste. Mehr dazu im Abschnitt über Security. Eine Überprüfung der Beispiel-Kommunikation in Kapitel 6.3 mit tcpdump (Paket-Sniffer für Unix) ergab aber, dass der übertrage String zumindest auf TCP-Ebene auf der Linux-Maschine tatsächlich im Klartext zu lesen war, obwohl auf beiden (!!) Maschinen Packet-Privacy (beinhaltet Verschlüsselung) als minimales Security-Level aktiviert war!

Page 41: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

40

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

4.3.2 COMTICOMTI (COM Transaction Integrator) ist die Alternative zum MS-RPC auf der Kommunikations-Dienst-Ebene. Seine Aufgabe ist die Kommunikation mit CICS (Customer Information Control System) und IMS (Information Managment System). Beides sind TP-Monitore von IBM, entwickelt für Mainframes und heute auch auf einigen Midrange-Systemen (AS/400, RS/6000, ...) verfügbar.Aber wozu braucht man das? Durch seine DCE-RPC-Konformität ist der MS-RPC doch schon Cross-Plattform fähig!? Und wie schon mehrfach erwähnt gibt es inzwischen doch DCOM-Implementierungen auch für die meisten Mainframe- und Midrange-Systeme!?Der Grund ist eigentlich einfach: Es gibt eine Unmenge von Business-Applikationen, die auf Mainframe-Systemen basieren. Die meisten sind in ihren Ursprüngen schon sehr alt, schließlich wurde vor etwa 10 Jahren die Mainframe-Plattform schon zu einem Auslaufmodell erklärt, hat aber dennoch überlebt. Und zwar einfach deshalb, weil so viele große Firmen auf solchen Systemen wichtige und komplexe Business-Applikationen fahren, deren Portierung auf kleinere Server Unsummen verschlingen würde. Heute aber – getrieben von eBusiness-, B2B- und TBI-Anwendungen – erfahren diese „Urgesteine der EDV“ eine Renaissance.Es wäre zwar möglich, die ganzen Legacy-Applikationen auf DCOM-Komponenten umzustellen, aber zum einen wären die Kosten immens, zum anderen sind die meisten Entwickler auf diesen Plattformen nicht unbedingt erfahren im Umgang mit objektorientierten Ansätzen. Entweder müssten sie sich mit dem DCOM-Konzept vertraut gemacht werden oder aber DCOM-erfahrene Programmierer sich auf Mainframe-Konzepte geschult werden. Hier prallen einfach zwei Welten aufeinander. Auf diesen Plattformen wird hautpsächlich unter COBOL in vielen Dialekten entwickelt. Auch heute noch ist COBOL, was die Anzahl der laufenden Applikationen angeht, die verbreitetste Programmiersprache überhaupt!Und da die meisten Systeme in Jahren entstanden, gut integriert und getestet und – dies nicht zuletzt – meist hoch-performant sind, gibt es zunächst einmal nicht wirklich viele Gründe für eine Umstellung auf DCOM. Ein weiterer Grund ist, dass nicht auf allen Mainframe-Systemen über TCP/IP zur Verfügung steht, was für die bestehenden DCOM-Implementierungen auf anderen Plattformen aber Voraussetzung ist. Außerdem mögen von Microsofts Seite auch Marketing-Strategien dahinter stehen. Wenn erst einmal eine Anbindung an bestehende Anwendung mit DCOM-Client-Komponenten geschaffen ist und diese Komponenten ein akzeptiertes, modernes User-Interface bieten, könnte es vielleicht interessant werden, auch einzelne Server-Komponenten für diese Anwendungen, wenn sie ohnehin überarbeitet werden müssen, auf DCOM umzustellen. Und wenn – warum dann nicht gleich auf Microsoft-Server-Plattformen! Zumal mit COM TI recht einfach über Web-Server-Komponenten eine Anbindung von bestehenden Mainframe-Systemen an den Microsoft IIS (Internet Information Server auf NT-Plattformen) und damit das Internet möglich ist.Aber zurück zur Technik. COMTI besteht aus drei Kompontenten: den Laufzeit-Biliotheken, die DCOM-Aufrufe und deren Parameter in CICS und IMS-Konventionen umformen und die nötigen Datenkonvertierungen über das übliche Marshalling-Verfahren durchführen, dem Interface Builder, mit dem man GUI-geführt die Interfaces deklarieren oder von COBOL-

Page 42: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

41

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Datenstrukturen importieren kann und Administrations-Tools, mit denen ein NT-Server auf die jeweilige MVS-Umgebung eingestellt werden.Die gesamte Verarbeitung der Calls an die TP-Monitore wird auf NT-basierten Servern ausgeführt, so dass auf den Mainframe-Systemen weder eine Zeile Code geändert noch administrativ etwas umgestellt werden muss. Für das Mainframe-System erscheint der COM TI wie ein normaler Client. Für die Kommunikation zwischen Mainframe und Windows wird das Standard-Protokoll LU 6.2 genutzt [rock-evans].

CICS- und IMS-Calls können in Transaktionen integriert werden und das 2-Phase-Commit-Verfahren des MTS (MS Transaction Service, den ich noch erläutern werde) kommuniziert mit dem auf den MVS-Systemen üblichen Sync Level 2-Verfahren, das in etwa die selben Aufgaben erfüllt wie das 2-Phase-Commit. Die Integration erfolgt über den SNA-Server (der allerdings inzwischen vom MS Host Integration Server 2000 abgelöst wurde).

4.3.3 MSMQDer MSMQ (Microsoft Message Queuing Service) wird immer dann benötigt, wenn Nachrichten an entfernte Objekte geschickt werden müssen, die man nicht über RPC (synchron) sondern asynchron und verbindungslos schicken möchte. MSMQ implementiert das Verhalten einer MOM (siehe 3.2.2). Wie viele andere DCOM-Dienste wird MSMQ vor allem indirekt von Funktionen höherer Ebene und selten direkt benutzt.Er stellt Funktionalität bereit, über die es möglich ist, Nachrichten an einzelne (Punkt-zu-Punkt) oder viele (Broadcast, Publish-Subscribe) Empfänger zu verschicken. Dabei stellt er Queues zur Verfügung, in denen die Nachrichten gepuffert und gespeichert werden können. Außerdem unterstützt er verkettete Queues, das heüßt den Versand von Nachrichten über Zwischenstationen, zum Beispiel an Netzwerk-Knotenpunkten, die dann wie ein Router funktionieren. MSMQ bietet Verschlüsselungs- und Authentifizierungs-Schnittstellen.Es gibt im generellen zwei Arten von Message Queues, die der MSMQ bereit stellt: Private Queues, die von einzelnen Prozessen abgefragt werden können, und Public Queues, auf die mehrere Prozesse zugreifen können. Innerhalb dieser bietet er Directory Services an, die für das Publish-Subscribe-Verfahren notwendig sind. Außerdem ist es möglich, Public Queues zu replizieren, also Spiegelungen der Queues auf mehreren Servern bereitzustellen.Über ein Acknowledgement-Verfahren bietet MSMQ Guaranteed Delivery an, ebenso Deferred Delivery (Zustellung von Nachrichten an einen Empfänger, der noch gar nicht aktiv ist; die Nachrichten werden so lange gepuffert, bis der Empfänger „online“ ist).

Client-Applikation

Windows NT/2000 ServerTransaction

ServerSNA/H.I.

Server

MVS

TPMonitor

Appl.

DBMS

Page 43: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

42

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Die Empfänger haben mehrere Möglichkeiten, ihre Queues abzufragen: Polling (der Empfänger prüft in Abständen, ob Nachrichten für ihn eingegangen sind; er wird bei leerer Empfangsqueue nicht blockiert, sondern erhält eine Meldung, dass keine neuen Nachrichten vorhanden sind), Pulling (wie Polling; ist die Empfangsqueue aber leer, wird der Empfänger so lange blockiert, bis eine Nachricht für ihn eintrifft) und Notification (ein neuer Empfänger-Prozess oder -Thread wird getriggert, sobald eine neue Nachricht eingeht).Über Gateways auf NT/2000-Servern kann MSMQ mit anderen Plattformen kommunizieren. MSMQ Public Queues stehen nur auf Windows-Server-Betriebssystemen zur Verfügung.

4.3.4 MTSDer MTS (Microsoft Transaction Service) unterstützt das Konzept von Transaktionen (siehe DTPM, 3.2.4). Er unterstützt dabei alle wichtigen üblichen Verfahren, insbesondere das Triggern von Server-Prozessen/-Threads, asynschrone Verarbeitung, Lock Managment, Logging über einen Bufferpool und das verteilte 2-Phase-Commit. Diese Verfahren sind hinlänglich in Kapitel 3.2.4 beschrieben. Mit COM+ bzw. Windows 2000 unterstützt der MTS auch Load Balancing, also die Verteilung von einzelnen Transaktions-Schritten auf mehrere Server-Instanzen.Mit DCOM-Komponenten und dem MS SQL-Server kommuniziert er dabei über das OLETX (OLE Transactions) Protocoll. Ein weitverbreitetes – aber nicht Komponenten-orientiertes – Protokoll für Transaktionen das von vielen transaktions-unterstützenden Systemen verwendet wird ist XA, das über einen OLETX-XA-Mapper unterstützt wird. Über COMTI kann der MTS auch mit MVS-Plattformen und -Datenbanksystemen kommunizieren.

4.3.5 OLEMessagingOleMessaging ist ein Translation Service, der es erlaubt unter Nutzung von COM-konformen Schnittstellen, also über COM-Komponenten, auf eMail-Dienste zuzugreifen, die vorher nur über das MAPI (Mail API) Protokoll zugänglich waren. Dieser Dienst ist, wie die meisten anderen Translation Services, spezifisch für das Windows-Betriebssystem entwickelt worden.Im Prinzip besteht es in der aktuellen Version in Windows 2000 nur noch aus 2 ActiveX Controls (Microsoft MAPI Message Control und Microsoft MAPI Session Control). Es ist über OLEMessaging möglich, mit dem in Windows registrierten Standard-eMail-Programm eMails zu versenden, zu empfangen, zu dekodieren und Funktionalität des Adressbuches zu nutzen.

SNA / HI-Server

COMTI

OLETX-XA-Bridge MTS

Client-Applikation

Transaktions-Unterstützendes

DBMS

MS SQL-Server

CICS / IMSauf MVS

SQL/DML

XA

OLETX

LU 6.2 / Sync Level 2

Page 44: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

43

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Erstaunlicher Weise ist dieses recht brauchbare Control praktisch unbekannt! Selbst im Internet ist nur wenig Information darüber zu finden und einige Programme implementieren offenbar lieber ihren eigenen kleinen eMail-Client als diesen Dienst zu nutzen.

4.3.6 OLE DBOLE DB ist der wohl mächtigste und wichtigste Translation Service. DB steht für „Database“, damit ist seine eigentliche Zielsetzung schon klar. OLE DB ist ein auf COM-Schnittstellen basierendes DBCP und „übersetzt“ Daten-Anfragen, die es über die COM-Schnittstelle erhält in spezifische Calls des Datenspeichers bzw. DBMS. Dabei stellt es zunächst einmal keine Konkurrenz sondern eine Erweiterung für ODBC (siehe Kapitel 3.2.1) dar: über OLE DB ist es auch möglich auf den ODBC-Manager zuzugreifen. Daneben bietet es aber auch den Zugriff auf COM-basierte OLE DB-Treiber, sogenannte OLE DB-Provider. Auf der anderen Seite stehen so genannte „OLE DB-Consumer“, das sind COM-Komponenten, die die vom Provider gelieferten Daten darstellen. Ein Applikationsentwickler erstellt solche Consumer als „Ansicht“ der Daten, die der Provider ihm liefert, und kann dann direkt mit den Consumern arbeiten. Auf der anderen Seite kann er aber auch seinen eigenen Provider erstellen, z.B. um auf Daten, die in einem Applikationsspezifischen Datei-Format abgelegt sind, zugreifen zu können. Über diesen Mechanismus ist OLE DB nicht nur in der Lage, Zugriffe auf klassische Datenbanken durchzuführen, sondern auch auf Daten, die in allen möglichen Formen gespeichert sein können: in relationalen DBMS, in hierarchischen DBMS, in OO-DBMS, in Spreadsheets, im Dateisystem, im eMail-System, im Hauptspeicher eines Servers usw.OLE DB ist eng verknüpft mit ADO (ActiveX Data Objects, gemeinsamer Nachfolger von DAO und RDO), einer Menge von COM-Komponenten, die übliche Datenbank-Strukturen darstellen, zum Beispiel Datenbanken, Tabellen, Recordsets (Rowsets, eine Menge von Datensätzen oder -Zeilen, z.B. das Ergebnis einer SQL-SELECT-Abfrage), Records, Felder, Commands (Datenbank-Kommandos wie SQL-Abfragen oder -Kommandos, Stored Procedures ...), Command-Parameter. ADO bietet neben der Unterstützung der Cursor-Enginges der DBMSs auch eine eigene (Client-Side) Cursor-Engine an.Über die üblichen Datendarstellungen hinaus beinhaltet ADO aber weitere COM-Komponenten für die Unterstützung hierarchiescher Daten-strukturen und von Streams und Storages (siehe [sceppa]).Streams sind zu vergleichen mit einer Datei im Dateisystem, während ein Storage mit einem Verzeichnis im Dateisystem vergleichbar ist und Substorages und Streams enthalten kann. Jedes Datenobjekt kann in einen Stream umgewandelt und in einem Storage abgelegt werden. Die Objekte sind zwar selbst für ihre Umwandlung in Streams zuständig, aber OLE DB

Stream-und

Storage-Objekte DBMS

OLE DB-Consumer

OLE DB Treiber-Manager

ODBCTreiber

OLE DBProvider

ADO

Client-Applikation

Page 45: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

44

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

übernimmt automatisch ihre physikalische Speicherung in Dateien auf dem Speichermedium und kümmert sich dabei um die Verwaltung des unbenutzten Plattenplatzes. Über diesen Mechanismus ist es sehr einfach möglich, Daten-Objekte persistent auf fast jedem Medium zu speichern [rock-evans, sceppa]Der Zugriff auf die Daten über die Schichten unterhalb von ADO ist für Anwendungsentwickler dafür absolut transparent. Dies ermöglicht es zum Beispiel, dass eine Applikation komplexe Daten aus einer großen Datenbank abfragt und diese zur weiteren Bearbeitung lokal auf dem Dateisystem ablegt. Später können geänderter Daten wieder in die Datenbank zurückgeschrieben werden. ADO und OLE DB bieten dafür komplexe Synchronisations- und Locking-Unterstützungen an [sceppa]. Dieses Modell ist z.B. optimal für Applikationen für Versicherungsvertreter im Außendienst, die Daten über einen Kunden auf ihrem Notebook speichern und später wieder mit der Unternehmensdatenbank synchronisieren wollen.Ein weiteres besonderes Feature von OLE DB ist das „Advise Sync“- (bzw. Outgoing-) Interface, über dass Applikationen über Änderungen am Datenbestand benachrichtigt werden können. Das heißt, eine Applikation die ständig aktuelle Daten anzeigen soll, muss nicht in regelmäßigen Abständen die Datenbank prüfen, ob eine andere Komponente Änderungen an bestimmten Datensätzen vorgenommen hat, sondern kann sich über eine Art Callback-Mechanismus benachrichtigen lassen, sobald solche Änderungen erfolgt sind und kann dann die geänderten Daten zur Anzeige abfragen [rock-evans].Über die Erweiterung ADOX ist eine Applikation auch in der Lage, komplexe Änderungen an der Struktur von Datenbanken vorzunehemn und Managment-Aufgaben wie Reorganisation, Replikation oder Backup zu steuern [sceppa].

4.3.7 Security in DCOMSicherheitsaspekte spielen bei der verteilten Kommunikation ein große Rolle. Potentielle Risiken in kommunizierenden Systemen sind vor allem:- Unbefugte verschaffen sich Zugang zu Daten (durch Zugriff auf ungeschützte Komponenten,

Vorspiegelung falscher Identität) und lesen, verändern oder löschen diese.- der Datenverkehr wird abgehört- Daten werden (absichtlich oder durch Kommunikationsfehler) verändert- Daten werden (absichtlich oder versehentlich) blockiert bzw. unterdrücktUm diesen Risiken vorzubeugen ist ein ganzes Paket von Maßnahmen notwendig:- Authentifizierung: ein Benutzer (oder eine Komponente) muss sich dem System gegenüber

ausweisen um sicher zu stellen, dass er auch wirklich derjenige ist, der er vorgibt zu sein.- Integritätsprüfung: es muss sichergestellt werden, dass ein Objekt (Daten oder Programm-

Code) nicht verändert wurde.- Authorisation: einem Benutzer, einer Gruppe oder einer Rolle werden gewisse Rechte

eingeräumt.- Geheimhaltung: die Kommunikation darf an keiner Stelle von Unbefugten abhörbar sein.- Empfangs- und Annahmebestätigung: es muss sichergestellt werden, dass eine Nachricht

(Daten, Kommando, ...) beim Empfänger sowohl angekommen ist als auch, dass sie nicht

Page 46: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

45

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

von diesem abgelehnt wurde.Da kein Entwickler und damit auch kein System perfekt ist, ist noch ein weiterer Punkt wichtig:- Auditing (Kontrolle): Es muss nachprüfbar gemacht werden, ob alle Sicherheitsmaßnahmen

richig funktionierten und wirksam waren. Dazu müssen Protokolle erstellt werden und Funktionen zu deren Auswertung vorhanden sein. Die Protokolle selbst müssen auch gegen unbefungten Zugriff – insbesondere Manipulation oder Löschung – geschützt sein.

Kompliziert in Bezug auf DCOM ist, dass das DCOM-Konzept zwar einen Security-Service vorsieht und auch in seinen API-Strukturen (z.B. RpcBindingSetAuth()) unterstützt, aber keine eigenen Security-Mechanismen bietet, sondern auf Windows-Betriebssystem-Dienste zurückgreift. Das Herstellen von DCOM für andere Plattformen wird dadurch schwieriger, weil die Security-Facilities dort nachgebildet werden müssen. Unter Windows-NT stehen folgende Mechanismen des Betriebssystems zur Verfügung, die allerdings teilweise durch Third-Party-Software (SSL, CSP, Kerberos) gewährleistet werden:Authentizität: über Benutzernamen und Passwort mit Prüfung beim Domain-Server (oder der lokalen Passwort-Datei) über NTLM-Mechanismus sowie (ab Windows 2000) über Kerberos v. 5; Microsoft Certificyte Server als PKI für Digital Certifikate nach X509-Standard, Smart-Card-Services, Authenticode (Public-Key-Verfahren, über das insbesondere Komponenten, die aus dem Internet geladen werden, daraufhin überprüft werden können, ob sie tatsächlich vom angegebenen Absender bzw. Hersteller stammen).Authorisation: ACL (Access Control Lists) global für DCOM und pro Komponente über DCOMCNFG, aber nur je Maschine. In COM+ außerdem über Active Directory Services.Geheimhaltung: ??? Situation unklar, siehe unten. Es kann aber zumindest über SSL (heißen unter Windows „Secure Channel“ bzw. SChannel) sowie CSPs von Drittanbietern kommuniziert werden. Integritätsprüfung: Authenticode beinhaltet 160-bit Hash-Funktionen.Auditing: Das Ereignisprotokoll („EventLog“) ermöglicht ein Auditing. Die Ereignisse werden zwar nur lokal je Rechner gespeichert, über SNMP ist jedoch eine Abfrage des Ereignisprotokolles über Netzwerk möglich. Außerdem bietet die Ereignisanzeige Funktionen zur Filterung und Analyse der Informationen.Damit stehen unter Windows offenbar ausreichende Schutzmechanismus für DCOM zur Verfügung, zu beachten ist allerdings die Situation auf anderen Plattformen, wo die Implementierung der Security-Dienste unterschiedlich ausgeprägt sein könnten.

Erwähnenswert ist allerdings noch ein Verwirrspiel, das Microsoft in seinen Dokumentationen bezüglich Verschlüsselung betreibt (z.B. [msdnlib]): Ist in der Literatur bei [rock-evans] noch nachzulesen, dass DCOM keinerlei Verschlüsselung bietet (und MS genau zu diesem Zweck dem Entwickler die CryptoAPI bietet) und auch keine der Security-Dienste des DCE-Standard unterstützt, so ist in [msdnlib] zur Plattform-SDK unter dem Stichwort RPC_C_AUTHN_XXX, wo die Authentifizierungs-Varianten aufgeführt sind, zu lesen, dass DCE-Verfahren sehr wohl unterstützt werden. Außerdem ist dort unter RPC_C_AUTHN_LEVEL_XXX (Sicherheits-

Page 47: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

46

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Level, unter anderem auch RPC_C_AUTHN_PKT_PRIVACY = Verschlüsselung der RPC-Parameter eines jeden RPC-Calls) einschränkend nur aufgeführt, dass „Windows 95 nur das erste Level unterstützt“, welches kaum Sicherheit bietet. Im Umkehrschluss würde dies bedeuten, dass NT-Varianten alle Level unterstützen.Zunächst kam mir bei Erkennen dieses Wiederspruchs die Idee, dass [rock-evans] einfach falsch liegt, oder sich dies inzwischen ([rock-evans] ist von 1998) geändert hat. [najjar] scheint diese Theorie zu unterstützen. Ein Blick in [w2ksspi], die White Papers zu Windows 2000 Server SSPI (Security Support Provider Interface), zeigt im Gegensatz dazu allerdings, dass Authentifizierungen im DCE-Stil nicht unterstützt werden („not currently supported“). Zum Thema „Privacy“ war dort allerdings auch keine Einschränkung zu finden. Selbst nach langer Suche konnte ich keine endgültige, verlässliche Information darüber finden, ob und wie DCOM bzw. Windows die Verschlüsselung bzw. DCE-Authentifizierung der übertragenen Daten tatsächlich ausführt oder ob es sie nur prinzipiell auf API-Ebene unterstützt. EMail-Anfragen bezüglich dieses Themas hat Microsoft leider nicht beantwortet.Fest steht aber, dass Windows 2000 IPSec (Verschlüsselung von Daten auf IP-Ebene) anbietet. Ein Microsoft-Artikel ([platt]) lässt mich vermuten, dass DCOM über diesen Mechanismus eine verschlüsselte Übertragung sicherstellt: Der Autor erwähnt zum Thema Security, dass man die Paketverschlüsselung bei COM+ mit dem Konfigurationstool aktivieren könne (diese Einstellung entspricht dem RPC_C_AUTHN_PKT_PRIVACY-Modus), dass dies aber hohe Prozessorlast verursache und schlägt zur Verbesserung dieser Situation vor, man solle Netzwerkkarten mit Hardware-Verschlüsselung einsetzen, die diese Prozessorlast drosseln. Das wiederum lässt darauf schließen, dass IPSec-Encryption benutzt wird. Ein weiterer Hinweis des Autors in einem Nebensatz könnte erklären, warum Microsoft in keiner Publikation, die ich fand, explizit und ausführlich auf das Thema Verschlüsselung eingeht: Er hält den Einsatz der Hardware-Verschlüsselung von Drittanbietern (am besten von außerhalb der USA) deshalb noch für empfehlenswert, weil die Software-Routinen für Strong-Encryption in Windows unter ein US-Export-Verbot fallen* und deshalb nur in den US-Versionen von Windows zur Verfügung stehen, während die internationalen Versionen schwächere Verschlüsselungs-Verfahren einsetzen. Möglicherweise möchte Microsoft diesen Punkt nicht an die große Glocke hängen und geht deshalb spärlich mit Informationen um.Stutzig machen sollten andererseits die in 4.3.1 schon angedeuteten und in 6.3 noch einmal deutlich ausgeführten Ergebnisse der RPC-Testverbindung, die jedoch auch bedeuten könnten, dass die Verschlüsselung tatsächlich auf IP-Ebene stattfindet.Ich möchte den (sicherlich hochinteressanten!!!) Punkt „Verschlüsselung und DCOM“ nicht noch weiter vertiefen, er könnte bestimmt eine eigene Bachelor- oder Diplomarbeit füllen und ist nicht mein Schwerpunkt. Ich finde allerdings, dass man sich der Problematik in diesem Punkt bewusst sein sollte, bevor man mit DCOM hoch sicherheitsrelevante Applikationen implementiert! Auf höherer Ebene stehen ja SSL-Dienste zur Verfügung, die wohl derzeit als sicher betrachtet werden können.*) Der einzige gebräuchliche Secret-Key Verschlüsselungs-Algorithmus, der mir im Zusammenhang

mit US-Export-Beschränkungen bekannt ist, ist Tripple-DES, der üblicherweise auf sehr niederigen

Ebenen eingesetzt wird, was meine Theorie von der Verschlüsselung auf IP-Ebene stützen könnte.

Page 48: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

47

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

4.4 DCOM auf anderen PlattformenWie nun schon mehrfach erwähnt ist DCOM im Prinzip plattformunabhänging konstruiert und es gibt auch einige Third-Party-Umsetzungen von DCOM auf anderen Betriebssystemen, zum Beispiel EntireX DCOM von der Software AG sowie von Digital und HP für deren eigene Plattformen.Microsoft wird aber nicht müde zu betonen, dass die Umsetzung auf Windows-Betriebssystemen die einzige vollständige ist [rock-evans]. Begründet ist dies darin, dass DCOM schon im Konzept an vielen Stellen und ganz besonders im Security-Bereich auf bestehende Windows-NT-Dienste aufsetzt. Ein weiterer Punkt, wo dies der Fall ist, ist im Bereich Thread- und Speichermanagment. Typische Struktur und Umfang einer DCOM-Umsetzung auf einer anderen Plattform zeigt die folgende Grafik, die man mit der Windows-DCOM-Darstellung in Kapitel 4.1 vergleichen sollte. Eine beispielhafte Betrachtung einer konkreten Umsetzung, nämlich EntireX DCOM für Linux, wurde (wie schon zuvor in diesem Kapitel erwähnt) in Kapitel 6.3 vorgenommen.

Es steht also auf der Kommunikationsschicht nur ein DCE-konformer RPC zur Verfügung. Die Umsetzung auf der Managment-Schicht bleibt jeder Implementierung selbst überlassen. Ein Pendant zur die Registry muss aber jede Umsetzung mitbringen. Translation-Services wie OLE DB sind in keiner Implementierung zu finden, ebenso wenig eine Unterstützung für COM-konforme GUI-Komponenten. Damit ist eigentlich klar, dass die DCOM-Implementierungen auf Server-Dienste und nicht auf Client-Dienste oder gar Applikationen abzielen.Es ist nicht zu erwarten, dass DCOM jemals in vollem Umfang auf einer anderen Plattform als der Microsoft-eigenen zur Verfügung steht. Das wäre aber auch nicht im Sinne von Microsoft, denn schließlich soll DCOM nicht dazu führen, das Windows-Server überflüssig werden oder es vollwertige Alternativen dazu gibt. Aber Windows soll in der Lage sein, auf bestehende Applikations-Komponenten auf anderen Plattformen zuzugreifen. Wenn diese dann teilweise in DCOM-Komponenten umgebaut werden, ist dies sicher ganz im Sinne von Microsoft. Schließlich lassen Sie sich dann relativ einfach auf Windows-Server migrieren.

DCOM

COM-Schnittstelle

Administrations-D

iensteManagment-Dienst-Schicht

ActiveX-Kompon.

ActiveX-Kompon.

ActiveX-Kompon.

ActiveX-Kompon.

ActiveX-Kompon.

Kommunikations-Dienst-Schicht

DCE-RPC

Registry

Page 49: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

48

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

CORBA

Page 50: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

49

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

5. CORBAIm folgenden Kapitel werde ich relativ kurz auf CORBA eingehen. CORBA darf wegen seiner Verbreitung und Bedeutung in einer Betrachtung von Middlewares nicht fehlen. Es ist allerdings so komplex, dass ich es hier nur kurz anreißen möchte, um einen Überblick zu geben. Es gibt genügend Literatur, die sich ausführlich und vertieft mit CORBA beschäftigt.

5.1 Entstehung und EinordnungCORBA (Common Object Request Broker Architecture) ist kein Middleware-Produkt, sondern ein plattform- und sprachunabhängiges Middleware-Konzept, das Übertragungs-Standards definiert. 1991 verabschiedete die OMG (Object Managment Group) den ersten Standard CORBA 1.0. CORBA ist als Teil des des Gesamtkonzeptes OMA (Object Managment Architecture) zu verstehen. Technische Implementierungen von CORBA werden als ORBs (Object Request Broker) bezeichnet. Es gibt inzwischen einige ORB-Implementierungen von vielen verschiedenen Herstellern. Zunächst waren diese nicht interoperabel. Interessant wurde CORBA mit der Version 2, die ein konkretes Protokoll für die Kommunikation zwischen den ORBs definierte. Seit 2001 gibt es CORBA 3, für das aber noch recht wenige Implementierungen bestehen. CORBA 3 bringt vor allem einen neuen Satz von API-Schnittstellen, die es dem Programmierer erlauben sollen, auf einer höheren Abstraktionsebene mit weniger Aufwand CORBA-Programme zu erstellen, denn vorweg schicken kann man, dass die Programmierung von CORBA-Komponenten einen enormen Aufwand für den Entwickler bedeutet. Außerdem bietet es eine Objektübertragung by-value statt der üblichen by-reference Übertragung an.Zu den Stärken von CORBA gehört aber auf der anderen Seite die konsequent objekt-orientierte Ausrichtung, die insbesondere eine gut strukturierte OO-Analyse erlaubt. Nicht umsonst beschäftigt sich die OMG im Rahmen von OMA auch mit UML und OO-Analyse-Verfahren.

5.2 Die ArchitekturÄhnlich wie DCOM basiert auch die Kommunikation in CORBA auf RPCs, die in diesem Zusammenhang auch als ORPC (Object RPC) bezeichnet werden. Es setzt ebenso auf eine von der Programmiersprache der zu erstellenden Objekt unabhängige IDL zur Definition der Schnittstellen. Aus der IDL wird ein Client-Stub und ein Server-Skeleton erzeugt. Die Serverprogramme werden in CORBA, wohl zur Abgrenzung des Begriffes von „Server“ als Hardware-Komponente, auch als Servants bezeichnet. Über Stub bzw. Skeleton kommunizieren die Clients bzw. Server mit den ORBs.Neben den Protokollen zur Kommunikation und IDL definiert CORBA auch Dienste und Einrichtungen, die diese Dienste ausführen (CORBAservices und CORBAfacilities), die zur Implementierung der ORBs gehören.

Page 51: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

50

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Object Request Broker (ORB)

Client

POA

Server

ORB-Interface

DII

Skeleton

Stub

DSI

Interface Repository

Implem

entation Repository

CORBAservices CORBAfacilities

5.2.1 Stub und SkeletonStubs und Skeletons werden aus der Implementierungs-unabhängigen IDL in die Programmiersprache für die Komponenten-Entwicklung compiliert. Client und Server können dabei natürlich wieder in verschiedenen Sprachen realisiert sein, für CORBA bieten sich aber besonders Java und C++ zur Komponenten-Realisierung an.Die erzeugten Stubs und Sekeltons werden wie üblich bei der Komponenten-Erzeugung mitcompiliert.

5.2.2 IDLDie IDL, deren Syntax stark an die von C++ angelegt ist, bietet viele Datentypen an, neben den üblichen Integer, Float- und Stringvariablen auch Strukturen, Unions, Arrays und Sequences (Arrays mit variabler Länge). Daneben gibt es die Datentypen Octet (Binärdatenm die nicht konvertiert werden) und Any (jeder Typ erlaubt) und Enumerations (wie in C++). In der IDL kann mit dem Typedef-Operator (verhält sich wie in C++) gearbeitet werden.Die Deklaration für Methoden erlaubt es „normal“ (blockierende) Methoden und „Oneway“ (assynchron ausgeführte Methoden ohne Rückgabewert) zu deklarieren. Damit kann ein Nachrichten-Verhalten erzeugt werden.Interfaces können Module (Packages) enthalten, die wiederum aus mehreren Interfaces bestehen. Damit ist eine Verschachtelung von Interfaces möglich (vergl. IMPORT bei COM-IDL).

Page 52: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

51

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

5.2.3 DII und DSIDie Idee der DII (Dynamic Invocation Interface) und DSI (Dynamic Skeleton Interface) entsprechen dem Automatisierungs-Ansatz in COM/DCOM.Ein Client kann, ohne dass ein Stub mitcompiliert oder mitgelinkt wird, über das DII auf zur Compilezeit nicht feststehende Interfaces zugreifen. Dazu implementiert CORBA ein Interface Repository, in dem verfügbare Interfaces abgelegt werden. Der Mechanismus funktioniert insgesamt sehr ähnlich wie in COM (die Methode im DII zum Aufruf einer Methode in einem dynamischen Interface heißt sinnigerweise ebenfalls invoke()).DSIs sind das Gegenstück zu DIIs auf der Serverseite, das heißt Methoden einer Serverkomponente werden nicht über eine festes Skeleton, sondern dynamisch über das DSI aufgerufen.

5.2.4 POA (Portable Object Adapter)In früheren CORBA-Spezifikationen wurden diese als BOA (Basic Object Adapter) bezeichnet. Der POA hat die Aufgabe, abstrakter Serverobjekte mit konkreten Objektimplementierungen zu verknüpfen. Sie managen auch Aufruf und Deaktivierung von Server-Objekt-Instanzen. Dazu steht ihnen ein Implementation Repository zur Verfügung, in dem Informationen über die verfügbaren Server-Objekte gespeichert sind.Ein Methoden-Request von einem Client wird zunächst über den ORB an den POA geschickt, der den Aufruf an eine Server-Instanz weiterleitet (wofür er unter Umständen je nach Servermodell eine weitere Instanz startet).Die POAs sind in einer Baumstruktur aufgebaut, es gibt einen Root-POA. Der Aufbau der POAs selbst ist in CORBA spezifiziert, ein Entwickler kann eigene POAs erzeugen.POAs identifizieren Server-Objekte über eine Objekt-ID. Sie verfügen dazu über eine Active Object Map, die die IDs der laufenden Instanzen enthält. Über die POAs kann auch ein Load-Balancing-Mechanismus implementiert werden.

5.2.5 ORBDie ORBs (Object Request Broker) sind das Herzstück von CORBA. Ein ORB hat die Aufgabe, die Kommunikation und das Routing der Nachrichten zwischen Clients und Servern zu gewährleisten. Er funktioniert ähnlich wie ein Message Broker (Kapitel 3.2.2). Eine ORB kann eine Server-Location, an den ein Request geschickt wird, anhand einer Tabelle identifizieren, in der die Adresse der Hardware, auf der der Server verfügbar ist, eingetragen ist.ORBs sind aber dezentral, meist ist auf jedem beteiligten Rechner ein eigener ORB aktiv, unter Umständen besteht ein Verteiltes System also aus den ORBs mehrerer Hersteller. Die ORBs kommunizieren untereinander über das sogenannte GIOP (General Inter-ORB Protocol).

Page 53: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

52

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

5.2.6 GIOP, IIOPDie größte Schwäche von CORBA 1.x war, dass es zwar das GIOP definierte, dieses aber wenig konkret ist und in Abhängingkeit vom verwendeten Netzwerkprotokoll unterschiedlich implementiert werden muss. Dies hatte zur Folge, dass viele ORBs verschiedener Hersteller nicht interoperabel waren.Dieses Problem löste CORBA 2.0, indem es spezielle Ausprägungen des GIOP für verschiedene Netzwerkprotokolle fest vorschrieb. Das wichtigste ist das IIOP (Internet Inter-Orb Protocol), das auf TCP/IP aufsetzt. Jede CORBA-Implementierung, die sich CORBA-konform nennen darf, muss mindestens das IIOP implementieren. Damit ist nun gewährleistet, dass die ORBs untereinander kommunizieren können.

5.2.7 CORBAservicesCORBAservices sind Interface Definitionen, die beschreiben, wie ein Service in CORBA angesprochen wird. Dies erlaubt es, dass die Services, die von verschiedenen Herstellern Implementiert werden, von jedem CORBA-Programm genutzt werden können. Die wichtigsten zwei Services sind der Naming- und der Trading-Service.

Naming ServiceDer Naming-Service ist mit dem DNS (Domain Name Service) im WWW vergleichbar. Er erlaubt es, das CORBA-Objekte mit ihrem Namen angesprochen werden können und nicht nur über ihre Objekt-ID, was sehr unhandlich wäre (analog Domain-Name statt IP-Adresse). Der Naming Service ist hierarchisch aufgebaut. Es existieren Naming Contexts (vergleich: Domains), die Name Bindings enthalten (analog Subdomains). Ein Binding wiederum kann die Zuordnung zu einem Objekt sein oder seinerseits ein Naming Context.Als Konsequenz sehen die Namen von CORBA-Objekten denen von Internet-Hosts sehr ähnlich (z.B. org.omg.CORBA.ORBa.serverxy).CORBA-Objekte nutzten den Naming Service, indem ein Server-Objekt sich mit „bind()“ beim Naming-Service bekannt macht, also seinen Namen und seine Objekt-ID übermittelt. Diese wird vom Naming-Service in die Baumstruktur der bekannten Objekte als Name Binding eingetragen.Ein Client kann mit resolve() den Namen in eine Objekt-ID auflösen und mit dieser über den ORB mit dem Server eine Verbindung aufbauen.

Trading ServiceDer Trading Service ist so etwas wie die „gelben Seiten“ von CORBA. Auch er erlaubt es Objekte aufzufinden, aber nicht anhand ihres Namens sondern anhand ihres Typs und bestimmter Eigenschaften. Ein Objekt, dass seine Dienste über den Trading Service anbieten möchte, wird als Exporteur bezeichnet, ein Objekt, das Dienste über den Trading-Service suchen und nutzen möchte, als Importeur.Der Typ eines Exporteurs wird durch die Schnittstelle definiert, die er implementiert. Exporteure des selben Typs besitzen also das selbe Interface. Die Eigenschaften bezeichnen

Page 54: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

53

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

bestimmte Implementierungsdetails oder auch Zustandsformen des Servers.Ein Importeur sucht nach einem Exporteur, indem er einen bestimmten Importeur-Typ angibt und bestimmte Eigenschaftswerte, die dieser erfüllen soll. Der Trader (die Software-Komponente, die den Trading Service bereitstellt) übergibt dann dem Importeur eine Liste von Objekten, die diese Eigenschaften erfüllen.Als Beispiel möchte ich einen Druck-Service aufführen. In einem Netzwerk stünden mehrere Drucker bereit, die jeweils über einen CORBA-Server verfügen. Die Server-Komponenten melden sich beim Trader an. Alle Druck-Server implementieren die gleiche Schnittstelle, haben aber unterschiedliche Eigenschaften. So könnte eine Eigenschaft der Standort des Druckers sein, andere Eigenschaften bestimmen den Drucker-Typ (Laser, Tintenstrahl, Farbe, SW)Ein Client kann nun zum Beispiel eine Liste aller Druck-Server anfordern (die Schnittstelle sei ihm bekannt), die SW-Laserdrucker sind und im ersten Stock stehen.

5.2.8 CORBAfacilitiesCORBAfacilites sind Spezifikationen für Domänen-spezifische (vertikale) oder Domänen-übergreifende (horizontale) Dienste. Es gibt eine Unterscheidung in horizontale und vertikale Facilities.Die horizontalen Facilities werden wiederum in vier Typen unterteilt: Benutzeroberflächen, Informationsverwaltung, Systemverwaltung und Aufgaben-Verwaltung. Horizontale Facilities zeichnen sich dadurch aus, dass sie Branchen-Unanbhängig sind.Die vertikalen Facilities sind branchenspezifische Einrichtungen, zum Beispiel zur Bilddaten-Verarbeitung, zur Buchhaltung, für Fertigungsprozesse.

Facilitites sind so etwas wie fertige Komponenten, die über CORBA kommunizieren und „verkauft“ werden können. Das Facility-Konzept ist in der Zielsetzung dem von ActiveX zu vergleichen: Es soll ein Komponenten-Markt entstehen, auf dem man fertige Komponenten für bestimmte Aufgaben einkaufen kann.

Page 55: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

54

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

EntireX

Page 56: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

55

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

6. EntireXDas folgende Kapitel behandelt die EntireX-Produktfamilie und einige Voraussetzungen für die praktische Andwendung in Kapitel 7.

Was ist EntireXEntireX ist eine Middleware-Architektur der Software AG, die aus mehreren einzelnen Middleware-Produkten besteht. Zielgruppe sind insbesondere große Unternehmen. EntireX soll die heterogene Architekturen, Middlewareprodukte und Applikationen, die in den Unternehmen über Jahre gewachsen sind, verbinden.EntireX bietet dafür auf der einen Seite Möglichkeiten, die einzelnen Komponenten der Applikationen erlaubt, auf niedrigen Abstraktionsebenen hochperformant miteinander kommunizieren zu können, auf der anderen Seite auch Modelle auf hoher Abstraktionsebene, mit denen kompletten Applikationen und Datenbanken einfach und schnell Verknüpfungs- und Synchronisationsmöglichkeiten angeboten werden.EntireX ist auf vielen typischen Business-Plattformen im PC-, Midrange- und Mainframebereich verfügbar. In der Software AG Marketing-Strategie definiert sich EntireX Schlüsselprodukt zur „TBI“, der Total Business Integration. Es bietet Anknüpfungspunkte an andere in der Praxis häufig auftretende Middlewares.

6.1 Architektur der EntireX-FamilieEntireX besteht aus einer Anzahl einzelner Produkte die im Zusammenspiel die Kommunikation in und zwischen Unternehmen auf mehreren Ebenen ermöglichen soll.

CommunicatorDer Communicator (früher nur „EntireX“) ist ein Kommunikations-Broker der die Dienste von MOM- und RPC-Middleware bietet. Auf ihn werde ich im nächsten Abschnitt noch genauer eingehen.

Que

lle: [

exxw

p]

EntireX White Paper *** Final Draft ***

February 2002 Page 8 of 8

EntireX � Covering All the Bases for TBI Companies looking for TBI software need look only as far as Software AG�s EntireX. EntireX is a suite of integration tools based on leading edge technology and open industry standards. It has enabled over 1000 enterprises around the world to integrate e-business, packaged, custom-developed, and legacy systems. As an XML pioneer, Software AG has built EntireX to uniquely leverage XML, with extensive support for Web services.

EntireX provides integration up to ten times faster than traditional technology and eliminates up to 80 percent of traditional coding requirements with flexible, graphical point-and-click capabilities. EntireX provides companies with a comprehensive infrastructure to create a service-oriented architecture that integrates business processes both within and beyond company boundaries.

OrchestratorOrchestrator

EnterpriseSystems

EnterpriseSystems

Adapters for Enterprise System

sA

dapters for Enterprise Systems

ERP & CRM

Mainframe Applications

Databases & Files

Other Technologies

Other ApplicationsXM

L M

edia

tor

XML

Med

iato

r

Platforms: OS/390, VSE, BS2000, OS/400, OpenVMS, UNIX, WindowsPlatforms: OS/390, VSE, BS2000, OS/400, OpenVMS, UNIX, Windows

App

Ser

ver

Ada

pter

sA

pp S

erve

r A

dapt

ers

Business Manager*

CommunicatorCommunicator

Web / App

Server

Web / App

Server

B2BChannels

EDI, ebXML,

RosettaNet, etc.

B2BChannels

EDI, ebXML,

RosettaNet, etc.

EntireX Architecture

*) announced

Components of EntireXTBI solutions need to offer a mix of communication methods, adapters, easy-to-use graphical interfaces, and other tools covering the full range of integration possibilities. The EntireX product suite, consisting of three major components, meets and exceeds these requirements.

EntireX Communicator is a robust, high-performance communication broker supporting simultaneous request and reply messages while also managing interactions for

Page 57: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

56

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

EnitreX AdapterDie EntireX Adapter sind vorgefertigte Software-Adapter, die EntireX direkt Zugang zu Standard-Software wie SAP, Datenbanken wie Oracle, DB/2 oder Adabas sowie anderen Middlewares wie IBM‘s MQSerie oder CICS bieten. Auf die Commincator-Adapter werde ich im Kapitel über den Communicator genauer eingeher.

OrchestratorOrchestrator (früher „SAGAvista“) ist ein Integrations-Broker, der Datenquellen vieler Art den Geschäftsregeln des Unternehmens und der Applikationen entsprechend automatisch miteinander verbindet und synchronisiert. Das ganze wird mit dem Begriff „Back-End-Integration“ bezeichnet. Es sorgt für Applikations-übergreifende Datenkonsitenz. Der Dienst-Server ist zu 100% in Java implementiert, was ihn plattformunabhängig macht.Was genau der Orchestrator leistet, lässt sich aber am besten an einem Beispiel festmachen: Eine Software-Firma hat im internen Gebrauch mehrere Applikationen, die Kundendaten enthalten. Die Buchhaltung hat einen Datensatz für den Kunden in SAP R/3 (neben der Adresse liegen dort sicherlich auch Daten über Bankverbindungen vor), der Kundenservice arbeitet mit einer eigenen Lösung, die Kundendaten (neben der Adresse und Kontaktinformationen auch Informationen über die eingesetzte Hardware) in einer Adabas-Datenbank speichert, der Vertrieb arbeitet mit einer Fremdlösung, die Kundendaten in einer Oracle-Datenbank ablegt und die Marketing-Abteilung arbeit mit einer Lotus-Nodes-Lösung.Nun ist der Kunde umgezogen und hat neben einer neuen Anschrift für Rechnungen und Lieferungen auch eine neue Bankverbindung. Als langjähriger Großkunde unserer Software-Firma hat er über ein Webportal Zugang zu einem eingeschränkten Bereich, der es ihm unter anderem erlaubt, Änderungen an seinen eigenen Daten über dieses Webportal mitzuteilen.Früher ging die Änderungsmitteilung in unserer Softwarefirma per eMail an die Buchhaltung, den Kundendienst, das Marketing und den Vertreib, damit diese ihre Daten aktualisieren konnten. Lediglich im Marketing bestand schon eine Lösung, die die eMail, die in Formularform vorlag, analysierte und im Nodes-System die nötigen Änderungen vollautomatisch vornahm. Im Vertrieb gab es vorher auch eine ähnliche Lösung (er erhielt die Information nicht per eMail, sondern ein CGI-Script im Webserver nahm die Änderung automatisch vor), aber seit der Umstellung auf eine neue Version der Vertriebssoftware hat noch niemand Zeit gehabt, auch das Script an diese neue Version anzupassen.Der Orchestrator kann nun folgendes leisten: er nimmt die Änderungsmitteilung entgegen und kann anhand von Geschäftsregeln automatisch die Änderungen im Nodes-System, in der Oracle- und der Adabas-Datenbank und am SAP-System vornehmen. Er nimmt dabei Transaktionsüberwachungen vor und kommunziert via jeweiligem Protokoll (egal ob DBMS-spezifische DML, Applikationsspezifischen RPC oder XML-Bridge) der Zielapplikation. Er unterstützt dabei Industriestandards wie JMS, JNDI, JDBC, XML, SNMP und eMail-Gateways. Er kann über den EntireX Communicator alle dessen Adapter nutzen.Außerdem können natürlich auch der interne Data-Flow, der früher typischerweise von nächtlichen Batchjobs abgearbeitet wurde und deren Ergebnisse dann am nächsten Tag

Page 58: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

57

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

sichtbar waren, just-in-time vorgenommen werden.Dazu ist (nach SAG-Angaben) keine einzige Zeile Code nötig, denn die Geschäftsregeln können mit der Integration Workbench, einer grafischen Oberfläsche, einfach per Point-and-Click zusammengestellt werden.

XML MediatorDer XML Mediator stellt eine Schnittstelle zur XML-Welt und damit nach außen zum Internet zur Verfügung. Der XML-Mediator wird an den Web-Server gekoppelt. Anfragen, die in Form von XML-Dokumenten von außen kommen, können verifiziert und validiert werden. Im Fehlerfall wird eine entsprechende Meldung zurückgeschickt (z.B. Hinweis auf fehlende Daten), ansonsten kann an interne Ziele weitergeleitet werden. Dafür stehen zum Beispiel Gateways nach HTTP, eMail oder auch Gateways zu Communicator XML-Wrappern zur Verfügung. Diese XML-Wrapper können die Anfrage z.B. in RPC-Calls umwandeln, die vom Communicator weiter verarbeitet werden. Evtl. werden Ergebnisse dieser RPC-Calls wieder als XML-Dokumente vom Wrapper entgegengenommen und weiterverarbeitet.

Business ManagerDer EntireX Bussiness Manager ist eine neue Technologie, die erst Ende 2002 auf den Markt kommt und Managment-Funktionen für Geschäftsprozesse bietet und als Schnittstelle für B2B-Anwendungen (wie EDI) dienen soll.Näheres ist leider noch nicht zu erfahren.

EntireX White Paper *** Final Draft ***

February 2002 Page 15 of 15

facilities for automated system installation and remote management across all participating clients and servers. A graphical console enables convenient configuration, management and monitoring of the distributed runtime environment.

Creating an Integration Flow Data moves from one application to another through integration flows, made up of Orchestrator objects and links among those objects, created using the Integration Workbench. Integration flows use Orchestrator messages represented as Java objects, providing platform independence and type-safety. Integration flows are designed by creating and configuring Orchestrator objects guided by graphical wizards. All configuration data is stored in the Orchestrator�s repository.

In summary, the process for integrating applications with an integration flow: • Business objects are defined as messages; • Messages are associated with an application; • Integration is described as integration flows; • Integration flows are associated with application integration

by defining processing, routing and delivery rules for messages

This screenshot shows an integration flow in the Integration Workbench

Que

lle: [

exxw

p]

Page 59: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

58

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

6.2 EntireX CommunicatorDer EntireX Communicator behandelt die klassischen Middleware-Aufgaben und ist das, was bis vor kurzem „EntireX“ als ganzes war. Ende 1997 kam die erste Version von EntireX auf den Markt, entstanden aus einzelnen Middleware-Lösungen der Software AG wie Entire Net-work, was eher einem Netzwerk-Protokoll (Layer-4) als einer echten Middleware entsprach und Anbindungen der Windows- und Unix-Welt an Mainframes ermöglichte, die damals noch kein TCP/IP „sprachen“. Die Wurzeln dieser Middlewarelösungen liegen Ende der 80er Jahre.Als die ersten konkreten Überlegungen zu EntireX begannen, erblickte gerade die erste CORBA-Spezifikation das Licht der Welt. SAG beschäftigte sich eingehend mit den CORBA-Spezifikationen als Grundlage zu einer Middlewarelösung für den eigenen Bereich. Man stellte aber fest, dass es für den eigenen Geschäftsbereich, der zum großen Teil Mainframe- und Entireprise-Lösungen beinhaltet, nicht geeignet war. Ziel war eine solide und transparente, aber auch effektive Anbindung der Mainframewelt zu ermöglichen – insbesondere der eigenen Adabase-Datenbank und der in Adabase-Umgebungen angesiedelten 4GL Natural. Da weder Natural noch Legacy-Applikationen objektorientierte Konzepte kennen, wäre eine CORBA-Lösung für Kunden zu aufwendig zu implementieren gewesen, da überall Knotenpunkte zwischen der prozeduralen und objektorientierten Welt enstehen hätten müssen. Außerdem empfand man das Konzept als zu kompliziert, um damit RAD (Rapid Application Delevopment) betreiben zu können.Stattdessen entschied man sich dafür, eine eigene Lösung bereitzustellen, die einfach und flexibel sein und ein breites Spektrum an Anbindungen ermöglichen sollte. Von Anfang an floss der Aspekt der Anbindung anderer weit verbreiteter Middleware-Produkte in das Konzept ein.Hieraus entstand der EntireX Broker, ein zunächst Mainframe-basierter Message Broker.

6.2.1 EntireX BrokerDer EntireX Broker – das Herz des Communicators – ist ein Message Broker, über den die gesamte Kommunikation im EntireX Communicator abläuft. Er ist ein eigener Server, der von den Applikationen angesprochen wird. Im Gegensatz zu anderen Message Brokern oder Medssage Queueing Systemen erlaubt er aus Applikationssicht assynchrone (reine Nachrichten, Request-Reply) als auch synchrone (blockierender Request-Reply, Grundlage für RPC) Kommunikation, sowohl in Form von Conversations als auch non-conversational, und peer-to-peer-Kommunikation (beide Kommunikationspartner können sowohl die Rolle des Clients als auch des Servers übernehmen). Die Conversations können auf zwei Arten beendet werden: Schließen und Abbrechen. Dies erlaubt eine direkte Implementierung eines Transaktions-Modells auch für „normale“ RPC-Calls.Der Broker wird über ACI (Advanced Communication Interface) angesprochen, einer Low-Level-API, die Nachrichten-orientert funktioniert. Dieses ACI ist rein Nachrichten-orientiert. Der Broker selbst kennt keine andere Art der Kommunikation. Jedes übertragene Datenpaket enthält als Header einen ACI-Kontrollblock, der vom Broker ausgewertet wird. Dieser enthält

Page 60: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

59

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

unter anderem Informationen für: Security (Benutzername, Passwort, Token), die Art der Verbindung (neue Conversation, vorhandene Conversation, keine Conversation), der Nachricht (Anfrage, Antwort, ...) und natürlich den Empfänger (logische Adressierung der Gegenstelle).Sämtliche Kommunikation läuft über den Broker ab, das heißt tatsächlich („physikalisch“) tauscht eine Anwendung nur Daten mit dem Broker aus, auch wenn aus Sicht der Anwendungskomponente selbst („logisch“) mit einer anderen Komponetente, je nach eigener Rolle einem Client oder Server, kommuniziert.

Die Kommunikation selbst läuft auf Netzwerkebene entweder über TCP/IP oder über Entire Net-work.

AdapterHöhere Funktionalität (RPC, DCOM, XML, Zugriff auf SAP, ...) wird von den Adaptern zur Verfügung gestellt. Es gibt eine große Anzahl vorgefertigter Adapter:Basic-Adapter (File-System-Adapter, Programm-Adapter [kommunizieren über stdin- und stdout-Streams von externen Programmen], Socket-Adapter); Datenbank-Adapter (RDBMS-Adapter [SQL-Bridge für relationale DBMSs], spezifische High-Performance Adapter für Adabas und Tamino); Mainframe-Adapter (CICS-Transaktions-Adapter, APPC-Adapter [für LU 6.2-Protokoll -Kommunikationen mit CICS, IMS, SAP R/2], CICS/Natural 3270-Adapter [Terminal-Protokolle, sehr interessant, weiter unten näheres]); ERP- und CRM-Adapter (SAP-Adapater [SAP-IDOCs, SAP R/3-B(usiness)AP], PeopleSoft-Adapter [OODBMS-System], Siebel-Adapter); Middleware-Adapter (Websphere MQ / MQSeries, Corba-Wrapper, DCOM-Wrapper, EJB [über Java-Wrapper]), XML-Adapter (XML/SOAP Wrapper [erlaubt auch nicht-XML-Applikationen als Webservice aufzutreten], Tamino-

EntireXBroker

Client-Anwendung

Client-Anwendung

Adapter

Server-Anwendung

Adapter

DBMS

Adapter

Adapter

Logische Verbindung(RPC, DCOM, XML ...)

Physikalische Verbindung(ACI)

Page 61: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

60

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Adapter, XML-Mediator (siehe oben); ASPL (Application Server and Programming Language)-Adapter (Orchestrator-Adapter [kann Orchestrator-Transaktionen triggern], Java-Wrapper [Mainframe-Applikationen können wie Java-Klassen angesprochen werden, RPC-Aufrufe an Java und JAva-Applets] und Natural RPC Adapter [Natural Subprogramme als RPC ausführen, spielte in meinem Praktikum die entscheidene Rolle, siehe Kapitel 6], ActiveX und DCOM-Wrapper.Die Adapter laufen auf den jeweiligen Rechnern, auf denen die Applikationen, für die sie zuständig sind, ablaufen.Die Adapter sind die Übersetzer zwischen dem ACI des Brokers und der jeweiligen API der Komponenten, denen sie als Adapter dienen. Sie enthalten einen „Broker Stub“ (der eigentlich ein Broker-Proxy ist), der als Stellvertreter (Proxy) des Brokers auf der jeweiligen Maschine dient. Logisch ist der gesamte Adapter als Stellvertertreter der Gegenstelle (z.B. des Servers auf dem Client) anzusehen.

Den Broker-Stub auf dem Client* in Verbindung mit den SDK-Funktionen, die einem Entwickler zur Verfügung stehen, bezeichne ich im folgenden auch als „EntireX Runtime“, obwohl er eigentlich nur im RPC-Fall so bezeichnet wird. Zusammen mit den SDK-Funktionen stellt er nämlich typische Runtime-Dienste auf dem jeweiligen Rechner zur Verfügung: Datenkonvertierung und EntireX Services, d.h. die Funktionalität der Adapter.

Server

Broker-Server (z.B. Mainframe)

EntireXBroker CICS-

Adapter

Adabas-Adapter

Adabas

CICS

Legacy

LegacyLegacy

EntireX-Runtime

SAP-Adapter SAP

Appli-kation

NT-Server

XML-Adapter

EntireXRuntime

Web-Server

DCOMKompon.

CICSDCOM-

Wrapper

Client

App.

DCOM-Wrapper EntireX-Runtime

App. App.

ACI

ACIACI

ACI

COM ACI-SDK

RPC-SDK

Page 62: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

61

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Der (Client-*)Broker-Stub ist transparent für die Anwendungen und muss nicht mitkompiliert oder eingelinkt werden.Auch der Broker selbst enthält einen (echten) Broker-Stub, mit dem der „Broker-Stub“ auf dem jeweiligen Client* kommunziert und von ihm die Daten entgegen nimmt bzw. an ihn sendet.Der innere Aufbau des Brokers ist recht komplex, aber transparent für den Programmierer, weshalb ich nicht mehr näher darauf eingehen werde:

Der Broker (ebenso die Runtime) ist für viele Plattformen erhältlich: Mainframes, Unix-Derivate und Windows NT. Für große Unternehmen, in denen ein hohes Kommunikationsvolumen bewältigt werden muss, bietet sich die Mainframe-Lösung an, zumal der Broker dann auch lokal sehr schnell auf bestehende MF-Datenbanken oder Applikationen zugreifen kann.

Wie die Kommunikation zwischen einem Client* und dem Broker abläuft, ist im folgenden Abschnitt ersichtlich:

*) Die Bezeichnung „Client“ ist hier aus Sicht der Broker-Kommunikation zu verstehen. Ein Client

des Brokers kann im Applikationszusammenhang sowohl ein Client als auch ein Server sein.

Overview of Components

In the figure below, EntireX Broker is installed on an OS/390 mainframe, with special APIs (Broker Stubs) installed on the Windows Workstation and on the mainframe.

Broker Stub

The Broker Stub is transparent to application programs and does not require that existing programs be recompiled or relinked.

Seite 1 von 1Concepts of EntireX Broker

09.04.2002file://D:\Daten\fh\semester6\BA\texte\erx\exxwin\broker\cnf.htm

Quelle: [exx611]

Page 63: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

62

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Kommunikation mit dem / über den BrokerBeispiel: Asynchrone Kommunikation (z.B. RPC) mit / ohne Conversation.

REGISTER: Client/Server „registriert“ sich bei seiner Runtime, d.h. er startet sie.UNREGISTER: Client/Server beendet seine Runtime.LOGON: Client/Server führt einen Logon zum Broker durch, baut also eine

Verbindung zu ihm auf. Dabei werden seine Rolle (Client oder Server) und Authentifizierungsdaten* für den Broker übertragen und der Broker prüft, ob der Benutzer berechtigt ist, den Broker überhaupt zu nutzen.

LOGOFF: Client/Server trennt die Verbindung zum Broker.CONNECT: Client baut eine Verbindung zum Server auf, dabei überträgt er die

logische Adresse (Name) des Servers, die Art des Calls (synchron, asynchron, ...) sowie seine Server-Authentifizierungsdaten*. Der Broker sucht die Gegenseite und baut eine Verbindung auf, falls der Benutzer dazu berechtigt ist und der Server die angeforderte Art des Calls unterstützt.

DISCONNECT: Client baut die Verbindung zum Server ab. Es gibt zwei Ausprägungen: Cancel (Rollback) oder Commit. Der Server kann darauf entsprechend reagieren, was ein Transaktionsmodell ermöglicht, auch bei RPC- oder assynchroner Kommunikation.

CALL: Client überträgt eine Nachricht an den Broker der diese an den Server weiterleitet. In zwei Varianten möglich: a) asynchron, d.h. der Client wartet nicht auf eine Antwort (für Kommunikation nach den MOM-Modell) oder b) synchron, d.h. der Client wartet auf eine Antwort des Servers (RPC-Modell).

Clien

t-Kom

ponen

te

Broker-Stu

b(�En

tireX R

un

time�)

REGISTER

LOGON

CONNECT

Broker-Stu

b

Broker-Stu

b(�En

tireX R

un

time�)

Server-Kom

ponen

te

REGISTER

LOGON

WAITCALL1

(Reply1)WAIT

CALL2(Reply2)WAIT

DISCONNECT

LOGOFF

UNREGISTER

Client ServerBroker

UNREGISTER

LOGOFF

läuft

blockiertVerbunden mitClient/Server

immerNur bei Conversation

Page 64: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

63

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

WAIT: Server wartet bis eine Nachricht (CALL) vom Client eintrifft. Die Nachricht kann asynchron sein (der Server verarbeitet diese dann nur) oder synchron (der Server verarbeitet sie und antwortet dem Client).

CONNECT und DISCONNECT werden nur für Conversations benutzt. Wenn eine non-Conversational-Kommunikation erfolgt, so werden diese Schritte vor und nach jedem CALL implizit durchgeführt. WAIT wird nur bei Conversations (auf Serverseite) oder bei assynchronen Calls (auf beiden Seiten) unterstützt.

*) Siehe: EntireX Communicator Security

6.2.2 SDKs und WrapperDer Communicator stellt für folgende Sprachen/Plattformen ACI- und RPC-SDKs zur Verfügung, mit der man (aus Sicht des Brokers) Anwendungs-spezifische Adapter erstellen bzw. (aus Sicht der Anwendung) Broker-Dienste nutzen kann:Assembler (ACI), C (ACI und RPC), C++ (SDKs für C oder BOM=Broker-Object-Model), COBOL (ACI und RPC), CORBA (ACI und RPC), COM/DCOM (DCOM-Wrapper, ACI ActiveX Control, BOM, Microsoft Transaction Server API), Java (RPC-Wrapper und ACI), Natural (RPC und ACI), XML (XML-Wrapper).

Der Unterschied zwischen einem Wrapper und einer klassischen SDK ist dabei, dass die SDKs „flache“ Funktionen zur Verfügung stellen, die Wrapper ein objektorientiertes Modell des Brokers, der Gegenseite und der Verbindungen darstellen.Der XML-Wrapper ermöglicht – insbesondere im Zusammenspiel mit dem XML Mediator – die Erstellung von Web-Services.Auf eine SDK, die RPC-SDK für C, gehe ich in Kapitel 7.2 als einer der Grundlagen meines Praxissemesters genauer ein.

6.2.3 RPC, Workbench und IDL-CompilerBei der RPC-Programmierung übernimmt die Runtime auf dem jeweilgen Rechner die Konvertierung der RPCs in ACI-Nachrichten und das Handling der Nachrichten (blockieren des Aufrufers bis Antwort eingeht, ...). Auf die Funktionen der RPC-SDK für C gehe ich später noch genauer ein, weil sie – ebenso wie der Natural RPC-Adapter – von wesentlicher Bedeutung für meine Praxisphase waren.Zur RPC-Kommunikation zwischen einem Client und einem Server wird natürlich wieder ein Stub für den Server bzw. ein Proxy für den Client benötigt, wenn kein spezieller Adapter vorhanden ist (diese Stubs und Proxies sind nicht mit dem Broker-Stub zu verwechseln!!!).Im Falle von Natural nimmt der Natural-Compiler und die Natural-Runtime dem Entwickler dies komplett ab, ein Natural-RPC funktioniert völlig identisch wie ein lokaler Funktionsaufruf, es sei denn es muss von Standardeinstellungen des RPC-Servers oder des Brokers abgewichen werden, die in Configurationsfiles vorliegen (näheres siehe: Kapitel 5.3).Aber für die Nutzung der SDK in einer anderen Programmiersprache oder auch die Nutzung

Page 65: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

64

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

der DCOM-, CORBA-, Java- oder XML-Wrapper ist es nötig, die Interfaces festzulegen. Daraus erzeugt der EntireX IDL-Compiler automatisch fertige DCOM-, Java-, Corba- oder XML-Wrapper oder einen Proxy-/Stub-Quellcode, der (z.B. bei C/C++) nach dem klassischen Ansatz mitkompiliert werden muss.Dabei wird der Entwickler von der graphischen EntireX Workbench unterstützt. Dort kann man entweder die Schnittstellen-Definition (in- und output-Parameter, Namen des Servers bzw. der Server-Komponente, ...) eingeben und compilieren lassen oder sogar aus vorhanden COBOL- oder Natural PDAs (Parameterlisten für einen Unterprogramm-Aufruf, siehe 7.1.1) importieren.Der Output besteht – wie schon gesagt – entweder aus fertigen Komponenten oder aus Stubs und/oder Proxies, die mitcompiliert werden müssen

Konvertierung der DatenDie Konvertierung der Daten bei einem RPC-Call übernimmt die EntireX-Runtime anhand der Parameter-Definitionen wie sie in der IDL vorgenommen wurden. EntireX erkennt dabei folgende Datenformate für die Felder (= Parameter):- Alphanummerisch oder Kanji (Codierung für asiatischen Zeichensatz)- Datum, Uhrzeit- binär (Wird nie konvertiert! z.B. für Musik-, Video- oder Bilddaten)- Fließkommazahlen- i1-, i2- oder i4-Integer (= 8, 16, 32 Bit)- Packed oder Unpacked nummerisch (Nummerische Ziffern als Strings)- Logische Variablen (= Boolean)- Strukturen von all diesen Datentypen- 1- bis 3-dimensionale Arrays (feste oder variable Größe) aller obigen DatentypenAll diese Formate werden automatisch entsprechend der Darstellung auf den beiden kommunzierenden Plattformen konvertiert. Problematisch – das liegt aber nicht an EntireX sondern an der Natur dieser Darstellung – sind lediglich „redefinitierte“ Daten. Redefinitionen entsprechend Unions in C. Wenn natürlich ein Byte einmal als alphanummerisches Zeichen, einmal als Integer interpretiert wird – wie sollte die Runtime dies auch behandeln können? Sie nutzt daher die Definition auf oberster Ebene (zu dieser Problematik komme ich noch einmal in Kapitel 7.4.1 zurück).

6.2.4 Besondere ServicesRPC ist nur einer der „Broker Services“ die der Communicator anbietet. Durch die vorgefertigten Adapter kann man aus Sicht eines Clients jede spezielle Verbindung als „Broker-Service“ bezeichnen (z.B. SAP-Service, Adabas-Service, ...), da sich der Client um die speziellen Gegebenheiten auf der Gegenseite nicht mehr kümmern muss, sondern der Broker zusammen mit dem Adapter ihm das abnehmen.Auf zwei solcher Services möchte ich jedoch noch explizit eingehen: „cicX“ (CICS / Natural 3270 Bridge) und den Attach Service.

Page 66: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

65

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Attach ServiceDer Attach-Service erlaubt es über einen auf der Serverplattform (derzeit nur für OS/390 verfügbar) installierten Attach-Server Instanzen eines Servers zu starten, völlig transparent für den Client, der nur eine Verbindung anfordert oder einen Call absetzt. Nach Beenden der Verbindung wird der Server wieder heruntergefahren.Einen ähnlichen Service (Remote Attach Manager) gibt es speziell für Natural-Programme auf Mainframes, der über CICS / LU 6.2 abläuft. Hier wird über ein Natural Server-Programm, das als Attach-Manager läuft, der vom Client angeforderte Server (der ebenfalls ein Natural-Programm sein muss) gestartet.

cicX (CICS / Natural 3270 Bridge)CICS 3270 ist ein spezielles Protokol des TP-Monitors CICS, das es erlaubt, direkt mit Terminals (oder in Zeiten des PCs mit Terminal-Emulationen) auf den TP-Monitor zuzugreifen. Es definiert eine Datenübertragung zwischen dem Terminal und dem TP-Monitor. CICS 3270 ist ein verbreitetes Protokoll für diesen Zweck und wird auch von anderen Monitoren oder Terminal-basierten Applikationen genutzt.Natural 3270 ist eine spezielle Implementierung (Verschärfung) dieses Protokolls: Natural-Mainframe-Applicationen benutzen dieses zur Kommunikation mit Terminals bzw. mit Entire Connection, einem erweiterten Terminal-Emulator der SAG.

Der Service cicX erlaubt es nun, dieses Protokoll zur Datenübertragung zu nutzen, entweder mit generischen CICS 3270-Applikationen, die den Darstellungskanal zum einfachen hin- und hersenden von Daten nutzen. Damit können auf der Mainframe-Seite Applikationen in beliebigen Programmiersprachen und Umgebungen Daten mit Communicator-Clients austauschen, in dem sie diese Daten einfach in den Textausgabe-Kanal schreiben und vom Tastatureingabe-Kanal lesen.

Einen Schritt weiter geht der Service, wenn die Applikation auf der Serverseite Natural 3270 unterstützt. Dann bietet cicX Funktionen an, mit denen die Original-Bildschirmseiten über einen Screenhandler interpretiert werden. Die Datenfelder können dann als In- und Output für Messages oder gar RPC-“Emulationen“ genutzt werden. cicX verhält sich dann gegenüber dem Server wie ein menschlicher Benutzer, der Daten liest und eingibt, und dem Client gegenüber wie ein RPC- oder MOM-Server. Damit können Legacy-Applikationen aus der Terminal-Zeit direkt an moderne Client-Applikationen oder gar Web-Services angebunden werden, ohne das eine Zeile Code oder neue Funktionalität auf der Serverseite geändert werden muss.Zwar ist natürlich die Performance nicht mit der eines echten RPC- oder ACI-Calls vergleichbar, aber für nicht zeitkritische Anwendungen stellt dies ebenso eine sehr einfache Alternative dar wie für den Fall, dass der Quellcode der Server-Applikation nicht (mehr) zur Verfügung steht oder man keine Rechte daran hat.

Page 67: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

66

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

6.2.5 EntireX SecurityDer EntireX Broker verfügt über ein einfaches, aber effektives Security-Modell, das auf zwei Schichten arbeitet. Zum einen muss sich ein Benutzer (bzw. eine Komponente im Namen eines Benutzers) beim LOGON dem Broker gegenüber identifizieren. Dies geschieht in der Regel mit Benutzername und Passwort, die verschlüsselt übertragen werden. Alternativ kann aber auch ein vorher erzeugtes Token (Challenge-Response-Verfahren ähnlich wie beim Kerberos-Protokoll) übertragen werden. War die Authentifizierung erfolgreich, dann gibt der Broker ein Security-Token zurück, das für die restliche Sitzung gilt (oder nach einer gewissen Zeit oder Anzahl von Calls abläuft und erneut authentifiziert werden muss). Dieses Security-Token wird als „Ticket“ bezeichnet und ist nicht das gleiche, wie das Ersatztoken für Benutzername und Passwort!Bei folgenden Calls oder Aufrufen von Funktionen zur Administration des Brokers (die ich hier nicht näher erläutern will) prüft der Broker die Gültigkeit des Tickets und anhand seiner Rechte-Liste, ob der Benutzer zur Ausführung der angeforderten Aktion berechtigt ist.Handelt es sich um eine Connect-Anforderung oder einen Non-Conversational Call (und damit um ein implizites Connect), so muss sich der Client unter Umständen dem Server gegenüber noch einmal nach einem ähnlichen Verfahren authentifizieren. Auch hier erhält er ein „Ticket“, dass für den Rest des Connects – oder auch noch für n folgende Connects oder m Sekunden, je nach Sicherheitsstufe des Servers – gültig ist.Es kann vorkommen, dass ein Benutzer sich dem Broker gegenüber mit einer anderen User-ID und/oder Passwort identifizieren muss als dem Server gegenüber. Der Broker bietet zwar Services zur Anbindung an gängige Server- und Domain-Security-Dienste (z.B. SAC, RACF, AC2, TOP SECRET), aber ob die Security-Einrichtung der Server-Komponente auf der Gegenseite diese Anbindung auch besitzt oder dieses Feature im jeweiligen Umfeld genutzt wird, ist nicht gewiss.Auch dieser gesamte Vorgang ist für den Entwickler in der Regel transparent, er muss nur die SDK-Aufrufe mit Benutzernamen und Passwort versorgen. Unter Natural wird ihm im Regelfall sogar dies wieder einmal von der Runtime abgenommen. Es kann aber Situationen geben, wo der Entwickler von dem Standardverfahren abweicht und – z.B. über das Token – in das Authentifizierungsverfahren eingreift.

EntireX unterstützt außerdem Verschlüsselung der übertragenen Daten. Jeder Kommunikationspartner (Client und Server) ist selbst dafür verantwortlich, ob seine Kommunikation zum Broker verschlüsselt wird oder nicht. So ist es zum Beispiel möglich, dass der RPC-Call unverschlüsselt vom Client zum Broker, aber verschlüsselt vom Broker zum Server geht oder umgekehrt. Die Verschlüsselung übernehmen – genau wie die Konvertierung – die Broker Stubs. Ein Client oder Server kann aber die Verbindung ablehnen, wenn die Gegenseite nicht verschlüsselt mit dem Broker kommuniziert. Dazu stehen im ACI-Block drei Verschlüsselungslevel zur Verfügung: 0 (unverschlüsselt), 1 (verschlüsselt) und 2 (verschlüsselt und Gegenseite muss ebenfalls Verschlüsseln).Die Verschlüsselung funktioniert über SSL (Secure Socket Layers).

Page 68: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

67

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

6.2.6 EntireX DCOMWie schon mehrfach in dieser Arbeit geschrieben bietet die Software AG DCOM-Implementierungen für nicht-Windows-Plattformen an. Seit kurzem gehört EntireX DCOM zu den EntireX Communicator Komponenten, vorher war es ein eigenständiges Produkt.

EntireX DCOM ist verfügbar auf IBM OS/390 USS, Solaris V7 (32 Bit), Solaris V8 (64 Bit), HP UX V11 (32 + 64 Bit), Linux (Redhat 7.1, SuSE 7.2), AIX V4.3 (RS/6000), AIX 5L 5.1 und weitere UNIX-Derivate. Die Implementierungen unterscheiden sich ein wenig im Funktionsumfang, orientieren sich aber in der Grundlage an dem in Kapitel 4.4 umrissenen Funktionsumfang.

Im nächsten Abschnitt nehme ich EntireX DCOM für Linux 6.1.1 – eine 180-Tage-Lizenz ist kostenlos erhältlich – ein wenige genauer unter die Lupe.

Page 69: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

68

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

6.3 EntireX DCOM für Linux EntireX DCOM 6.1.1 für Linux ist zu nicht-kommerziellen Zwecken frei (180-Tage-Lizenz) erhältlich. DCOM Runtime und SDK können auf der Website der Software AG heruntergeladen werden: http://www.softwareag.com/entireX/download/free_download.htmEin entsprechendes Lizenz-File erhält man nach Registrierung per eMail zugeschickt.

Die Umsetzung ist erstaunlich umfangreich. So wird folgende Funktionalität geboten:• Win32 System-Dienst API (Thread-Synchronisation, File-I/O, DLL-Unterstützung,

System-Registrierungs-API [inkl. einer Registry und dem Regedit-Tool], Security API ).• Microsoft IDL-Compiler MIDL• DCOM Basis-Funktionalität (COM Task Allocaltor, Single- und Multithreaded

Apartment Modelle), Objekt-Instanzierung (Prozess-Intern und Prozess-Extern, local und remote), Connection Points, MS-RPC (mit statischen Endpunkten oder dynamisch über Enpoint-Mapper), Unterstützung für Remote-Aktivierung von in-process Server DLLs (z.B. für Surrogate Server).

• Unterstützung für Structured Storage und Compound Files (IStream Interfaces)• Monikers• Automatisierung (IDispatch-Interfaces)• Active Template Library (ATL) Version 3.0 (erstaunlich ist, dass wirklich die

komplette ATL 3.0, soweit sie sich nicht auf Windows-GUI Funktionen bezieht, unter Linux implementiert ist!)

• COBOL-Interface• Verschiedene Utilities (z.B. uuidgen und guidgen zur Generierung von GUIDs, ein

textbasiertes dcomcnfg zur Konfiguration der DCOM-Umgebung, Regefit, ...)

Außerdem enthält die Developer-Version von EntireX für Windows ein Add-In für MS Visual Studio, das es erlaubt, vorhandene Windows DCOM-Appliaktionen nach UNIX zu portieren. Es überträgt automatisch den Code auf die Unix-Maschine, erzeugt ein angepasstes Makefile und führt remote einen Erstellungs-Prozess auf dieser Maschine aus.

Nicht oder eingeschränkt verfügbar sind folgende DCOM-Features [exxdcx]:• Asynchrones Speichern, PropertySetStreams und -Storages für Compound Files.• Kommunikation mit Windows 98- DCOM• Es werden nur Interfaces unterstützt, die mit dem MIDL Compiler generiert wurden.• RPC-Transport ist nur nur mit TCP over IP gut getestet und empfohlen (Übertragungen

über die Protokolle NetBIOS, DECnet, Banyan Vines SPP, MS Messagig Queuing Services und IPX, die unter Windows zur Verfügung stehen, entfallen damit, was in der Praxis eher unproblematisch ist; für Linux ist TCP/IP ohnehin das Standard-Netzwerk-Protokoll)

• EntireX DCOM enthält keine API für das Grafische User Interface• Der MIDL-Compiler unterstützt weder hochoptimierten Code noch stubless Proxies.

Page 70: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

69

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

EntireX DCOM sorgt automatisch für die folgenden Daten-Konvertierungen bei RPC-Aufrufen zwischen verschiedenen Maschinen [exxdcx]:• Big-Endian / Little-Endian Konvertierung• ASCII- / EBCDIC-Konvertierung (wegen einer Einschränkung der MSRPC-Header wird

keine Codepage-Konvertierung vorgenommen; es wird implizit davon ausgegangen, dass ASCII-ISO-8559-1 bzw. EBCDIC Codepage 1047 benutzt werden)

• Single-Byte / Multi-Byte Charakter-Konvertierung (es wird implizit davon ausgegangen, dass Multibyte-Charakter nach UNICODE-Standard benutzt werden. 4-Byte UNICODE wird auf 2 Byte gekürzt, die oberen 2 Byte gehen verloren.)

• IBM Fließkommadarstellung (OS/390) wird nach IEEE-Darstellung konvertiert

Installation und Nutzung von EntireX DCOM für Linux sind erstaunlich einfach. Die Auslieferung erfolgt in RPM-Packages.

EntireX DCOM für Linux enthält einige Beispiel-Programme in C++-Code, die die Funktionalität von DCOM unter Beweis stellen. Diese können mit vorgefertigten makefiles direkt mit „make“ erstellt werden.

Um Details über die Programmierung von DCOM-Komponenten vorzulegen, müsste ich hier weiter ausholen, als Aufgabenstellung und Umfang der vorliegenden Arbeit es erlauben. Um aber einen kurzen nachvollziehbaren Nachweis für die Funktionalität zu geben, sei hier noch ein Beispiel gezeigt. Ich gehe mit Hilfe dieses Beispiels auch noch einmal auf die Verschlüsselungs-Thematik von DCOM ein, die ich in Kapitel 4 schon angesprochen habe.

DCOM-RPC-Verbindung zwischen Windows 2000 und Linux Um möglichst nahe am Thema zu blieben, zeige ich die Funktion des MSRPC-Beispiels „Hello Client/Server“, das sowohl in der MSDN Library für Visual C++ 6 unter Windows („RPC samples“) als auch in EntireX DCOM für Linux („/opt/sag/exx/v611/examples/msrpc/hello/“) mitgeliefert wird. Es zeigt die Datenkommunikation über den MS-RPC, indem es einen Server und einen Client erzeugt. Der Server wartet auf einen Client. Der Client schickt einen String zur Ausgabe an den Server und fährt den Server herunter.

Es folgen nun einige Screenshots einer erfolgreichen RPC-Kommunikation zwischen einem PC unter Linux (Suse 7.0, Hostname: „S02“) und einem PC unter Windows 2000 Professional (Hostname: „W01“) über TCP-IP mit dem „Hello“-Example.Die Quellcodes, die dieser Anwendung zu Grunde liegen, befinden sich als Anhang auf der beiliegenden CD.

Page 71: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

70

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

1. Hello RPC Server (hellos) wird auf der Linux-Maschine gestartet und wartet auf Client-Verbindung (statische Endpunkt-Auflösung aktiviert, Rechnername ist S02, Protokoll TCP/IP und Port 3456 sind als Standard definiert):

2. Hello RPC Client (helloc.exe) wird auf der Windows-Maschine mit den Parametern: Tansportrotokoll „TCP über IP“, Server-Hostname „S02“, Endpunkt „Port 3456“ und String „Hallo von W2K an Linux !!!“ ausgeführt:

3. Das Ergebnis wird vom Server ausgegeben und der Server beendet:

Das Ganze funktioniert natürlich auch umgekehrt mit der W2K-Maschine als Server:

printf("Calling the remote procedure 'HelloProc'\n");printf("Print the string '%s' on the server\n", pszString);

RpcTryExcept { HelloProc(pszString); // RPC 1: Stringausgabe auf Server printf("Calling the remote procedure 'Shutdown'\n"); Shutdown(); // RPC 2: Server-Shutdown}RpcExcept(1) { ulCode = RpcExceptionCode(); printf("Runtime reported exception 0x%lx = %ld\n", ulCode, ulCode);}RpcEndExcept

Das entscheidende Code-Fragment des Clients lautet:

Page 72: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

71

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Die DCOM-Verschlüsselungs-ProblematikUm ein wenig Licht ins Dunkel der integrierten Verschlüsselung von DCOM zu bringen, nutzte ich dieses Beispiel um einen Trace der übertragenen Datenpakete zu erhalten.Dabei benutzte ich auf der Linux-Maschine das Tool tcpdump, einen Packet-Sniffer, der auf TCP-Ebene (OSI Layer 3) das Tracen von Daten erlaubt.Beide Maschninen wurden zunächst mit der jeweiligen Version von DCOMCNFG (Bild rechts: das grafische DCOMCNFG.EXE von Windows 2000, Bild unten: das Text-basierte dcomcnfg von EntireX DCOM unter Linux) auf die maximale Sicherheitsstufe (RPC_C_AUTHN_PKT_PRIVACY = Daten-Pakete verschlüsselt übertragen) eingestellt, so dass sie keine Verbindungen akzeptieren dürfen, die nicht verschlüsselt sind.

Nun habe ich tcpdump mit den Parametern „-x“ (Dateninhalt des TCP-Paketes ausgeben), „-i eth0“ (TCP-Dump auf Netzwerkgerät eth0, über das die beiden Rechner verbunden sind) und dem Filterausdruck „dst port 3456“ (nur TCP-Pakete anzeigen, die für Port 3456 – auf dem hellos auf Verbindung wartet – bestimmt sind) gestartet.Sobald der Client ausgeführt wurde, der einen Datenstring (in unserem Fall: „HALLO von W2K an Linux !!!“) an den Server schickte, erschien der TCP-Dump auf dem Bildschirm. Überraschung: der übertragene String ist, wie im Bild auf der nächsten Seite zu sehen, im Klartext (Hexadezimal-Kodierung) zu lesen! Entweder die Kodierung findet auf einer Ebene unterhalb von TCP (ich vermute mit IPSec auf IP-Ebene) statt, oder DCOM übertragt ganz und gar unverschlüsselt! Leider hatte ich in meinem Netzwerk keinen dritten Rechner zur Verfügung, um dies zu überprüfen. Findet tatsächlich eine Verschlüsselung auf IP-Ebene statt, dann könnte ein dritter Rechner im gleichen physikalischen Netz die Daten nur verschlüsselt mitprotokollieren.

So oder so – in meinen Augen ein klares Sicherheitsrisiko! Bekanntermaßen gehen die meisten Hacker-Angriffe auf Firmen ohnehin von innen aus. Ein Administrator, der auf einem Server (oder auch Client) einen Packet-Sniffer installiert, könnte bequem und ohne von einer Verschlüsselung daran gehindert zu werden die übertragenen Daten (gerne auch

Page 73: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

72

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

mal die Gehaltsabrechnung vom Chef oder auch viel viel brisanteres) mitlesen. Gleiches gilt natürlich für einen Virus oder Trojaner auf einer der beiden beteiligten Maschinen, der die Daten dann auch gleich irgendwo anders hin ins weite Internet verschicken könnte.

Sicherlich kann man durch zusätzlichen Einsatz von SSL unter DCOM oder eigener Datenverschlüsselung in Client und Server z.B. über die CryptoAPI dem vorbeugen. Aber dies bedeutet beides deutlich erhöhten Implementierungsaufwand und wird wohl selten gemacht; zumal, wenn sich ein Entwickler aus Unkenntnis auf die „automatische Verschlüsselung“ durch DCOM verlässt. Man muss es eben erst mal wissen!In meinen Augen fehlen hier deutliche Warnhinweise von Seiten Microsofts. Die DCOM-Security-Lösungen werden jedoch gerne als sicher dargestellt. Was sie ohne Beachtung zusätzlicher Sicherheitsvorkehrungen offenbar aber nicht sind!

Page 74: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

73

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Programmierung:RPC mit EntireX

undCOM mit der ATL

Page 75: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

74

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

7. Programmierung von RPC mit EntireX und COM-Interfaces mit der ATLDas folgende Kapitel widmet sich der praktischen Anwendung von Middleware sowie (kurz gefasst) der gesamten Tätigkeit während meiner Praxisphase.Es geht vorrangig um die RPC-Programmierung mit EntireX, zum einen mit C++ bei der Implementierung eines ActiveX Controls, zum anderen mit Natural. Daneben spielen aber auch Aspekte von COM (Kapitel 5) eine Rolle, die benötigt werden, um das ActiveX Control zu erstellen. Zwar ist DCOM kein Aspekt, in der Praxis hat ein DCOM-Programmierer aber, wie schon gezeigt, ohnehin nur mit den COM-Interfaces zu tun.

7.1 Motivation aus meiner PraxisphaseWie schon in der Einleitung dargestellt, bestand meine Tätigkeit in der Praxisphase aus der Mitarbeit an dem Projekt „ESM GUI Framework“ bei der Software AG. Dieses Projekt behandelt die Erstellung eines Application-Frameworks, mit dem Applikationen der ESM-Gruppe einheitlich erstellt werden können. Die ESM-Gruppe entwickelte bisher im Schwerpunkt nur Applikationen, die auf Mainframe-Rechnern und im Unix-Server-Umfeld laufen. Dabei kommt fast immer die Programmiersprache Natural zum Einsatz. Auf Natural werde ich gleich noch näher eingehen.Das User-Interface der bestehenden Applikationen ist charakterbasiert, die Benutzer setzen dabei Terminal-Emulatoren ein. Das GUI Framework soll es erlauben, diese Applikationen auf Windows-PCs mit einem graphisches Front-End zu versehen. Es beinhaltet dafür Standard-Fenster, in denen Daten und Funktionen dargestellt werden können.Ich stieg in das laufende Projekt ein, das heißt, meine Aufgabe bestand darin, das Framework zu erweitern und zu pflegen.

7.1.1 Das Umfeld: NaturalNatural ist eine 4GL, wie zum Beispiel auch Visual-Basic. 4GLs zeichnen sich insbesondere dadurch aus, dass sie in ihrer Syntax der menschlichen Sprache näher kommen als 3GLs wie C, C++ und Java. Sie sind auch in ihrer gesamten Logik weiter von der Plattform entfernt und stärker an der Problemstellung orientiert. Dies spiegelt sich zum Beispiel auch in den verfügbaren Datentypen wider, die oft nicht oder nicht so genau die Gegebenheiten auf der Hardware berücksichtigen.Natural ist eine interpretierte Sprache und besitzt dennoch einen Compiler. Man kann sich das Konzept ähnlich wie bei Java vorstellen: der Quellcode wird compiliert und es wird ein Objektcode erzeugt, der von der Runtime (vergleichbar mit der Java Virtual Machine) ausgeführt wird. Durch dieses Konzept – das man sich keinesfalls bei Java abgeschaut hat, höchstens umgekehrt, denn Natural ist schon deutlich vor Java entstanden – erreicht man einen vergleichsweise schnellen Code. Natural ist allerdings, wie jede 4GL, nicht so restriktiv im Umgang mit Datentypen und Parameterlisten von aufgerufenen Funktionen, die teilweise erst zur Laufzeit und nicht während des Compilierens überprüft werden.

Page 76: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

75

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Natural ist ursprünglich als Sprache zur Abfrage und Behandlung von Adabas-Datenbanken entstanden. Die Syntax und die Grammatik ähneln stark der von Cobol - um nicht zu sagen sind in weiten Teilen identisch!In Natural werden Programme in Bibliotheken (Libraries) erzeugt. In der Regel entspricht eine Library einer Applikation, eine Applikation kann aber auch in mehrere Libraries unterteilt sein oder eine Library kann mehrere Applikationen oder Elemente mehrerer Applikationen enthalten. Vielleicht sollte man eine Library am ehesten mit einem Package in Java oder einem Projekt im Visual Studio vergleichen.Eine Library kann aus folgenden Teilen bestehen: Programme (Programs), Unterprogramme (Subprograms), Dialogen, Subroutinen, Copycodes, GDAs, PDAs, LDAs, Maps, Message-Files. Daneben gibt es noch Teile, die Datenbanken oder Tabellen in Datenbanken repräsentieren, auf die ich mangels Notwendigkeit in Bezug auf mein Projekt nicht eingehen will.Programme sind direkt ausführbare Module, die vielleicht am besten mit eigenständigen Programmen in Maschinencode zu vergleichen sind. Sie können Eingabeparameter auf ein ähnliches Konzept wie Kommandozeilen-Parameter erhalten. Nicht angegebene Parameter-Werte (bei direkter Ausführung sind dies alle) werden jedoch automatisch von der Konsole (bzw. in graphischen Natural-Varianten wie unter Windows in einem automatisch erzeugten Dialog) abgefragt. Programme können aber auch aufgerufen werden, z.B. von anderen Programmen, Unterprogrammen, Subroutinen oder Dialogen. In diesem Fall können sie die Parameter, die ansonsten durch die Runtime von der Konsole erfragt werden, direkt übergeben bekommen, als wären sie eine Funktion.Unterprogramme sind mit Funktionen in 3GLs vergleichbar. Sie haben Ein- und Ausgabeparameter und können nur indirekt aufgerufen werden, zum Beispiel von Programmen, anderen Unterprogrammen usw.Subroutinen sind mit Prozeduren in einigen 3GLs oder in Assembler vergleichbar. Sie haben keine Parameterliste, können aber auf globale Variablen zurückgreifen. Daneben gibt es auch Inline-Subroutines, die innerhalb von Programmen, Unterprogrammen oder Dialogen definiert werden und auf deren lokale Variablen zugreifen können.Dialoge sind nicht in allen Natural-Varianten verfügbar, sondern nur unter solchen, deren Runtime eine Unterstützung für graphische Oberflächen bietet. Soweit ich weiß, ist dies zur Zeit nur unter Windows der Fall. Dialoge können Rahmenfenster (MDI-Frames), Kindfenster (MDI-Childs) und echte Dialoge (Dialog Windows) sein, letzteres Modal oder Nicht-Modal. Dialoge haben Events und können Controls beinhalten. Controls können (fast) alle typischen Windows-Controls sein, z.B. Eingabefelder, Labels, List-Boxen, Combo-Boxen usw. aber auch alle ActiveX Controls sein. Rahmenfenster können Menü-, Toolbar- und Statusbar-Controls beinhalten. Alles eben, was man braucht, um ein GUI zusammenzustellen. Dialoge können auch Parameterlisten haben, um Daten vom Aufrufer entgegen zu nehmen. Dialoge, die keine Parameterliste haben, sind direkt ausführbar wie Programme.Copycodes sind Codefragmente, die vom Compiler textuell an der aufgerufenen Stelle eingesetzt werden. Sie sind mit Macros in C vergleichbar und haben einen ähnlichen Mechanismus, der Pseudo-Parameter erlaubt.

Page 77: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

76

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Message-Files sind sprachabhängig definierbare String-Tabellen. Man kann sie in etwa mit String-Ressourcen in Visual C++ vergleichen, außer dass sie nur über ihre Nummer und nicht über einen symbolischen Namen abfragbar sind. In einer Library können je Sprache 9999 solcher Text-Strings definiert werden.Maps sind „Bildschirmseiten“, die eine Formulardarstellung auf einem textbasierten Terminalsystem darstellen (Ausgabe-Text und Definitionen für Eingabefelder mit Mapping-Rules). Sie werden aber unter grafischen Natural-Umgebungen in Form von Dialogen emuliert (die nicht wirklich schön oder benutzerfreundlich sind, weshalb sie dort nicht genutzt werden).GDAs, PDAs und LDAs (Global / Parameter / Local Data Areas) sind mit Strukturen in C zu vergleichen. Sie enthalten in strukturierter Form Variablendeklarationen. Ihr Bestimmungszweck ist aber festgelegt: GDAs enthalten globale Variablen (in der ganzen Applikation bzw. zur gesamten Laufzeit einer Natural-Runtime gültige Variablen), LDAs sind lokal (innerhalb des Programmes, Unterprogrammes oder Dialoges) gültig, PDAs sind Parameterstrukturen für aufgerufene Programme, Unterprogramme oder Dialoge. Sie können aber auch (in aufrufenden Programmen zum Beispiel) wie LDAs genutzt werden.In allen Programmen, Unterprogrammen und Dialogen müssen zu Beginn die benutzten Variablen und ihr Gültigkeitsbereich bzw. ihre Parameter deklariert sein. Dies kann explizit geschehen oder indem definierte GDAs, PDAs und LDAs genutzen werden oder beides gemischt. So kann beispielsweise die Parameterliste in einem Subprogramm mehrere PDAs und einen weiteren Satz von Variablen enthalten, ein Umstand, der noch eine Rolle spielen wird.Verfübare Datentypen sind Alphas (entspricht Strings) von fester Länge zwischen 1 und 253, sowie variabler (unbegrenzter) Länge, Integer mit 1-, 2 und 4 bit, Numerische Festkomma-Werte (Angabe durch Länge und Nachkommastellen), Binaries (feste und variable Länge, vergleichbar char oder void*), Arrays (maximal 3-dimensional, feste und variable Länge) aller anderer Datentypen und Strukturen. Daneben ist es möglich, Speicherplatz von Variablen zu „re-definieren“ (Redefines), was in etwa einer Union in C entspricht; zum Beispiel kann ein Alpha-Feld der Länge 120 als 2 Numerische Felder der Länge 10 und einem Array von 25 Integern a 4 Byte redefiniert werden. Auch dies spielt im weiteren Verlauf noch eine entscheidende Rolle.

Variablen einer Struktur können bei Eindeutigkeit mit ihrem Namen ohne Angabe des Strukturnamens referenziert werden. (Beispiel: eine LDA enthält die Struktur „Person“ mit den Feldern (Variablen) „Name“, „Vorname“, „Gebdatum“. Auf das Feld „Vorname“ kann im Code durch die Angabe „Person.Vorname“ oder bei Eindeutigkeit auch direkt durch „Vorname“ zugegriffen werden. Dieser Umstand und die Tatsache, dass lokale Variablen im ganzen Modul gültig sind und nur an dessen Kopf deklariert werden können, hat zur Folge, dass umfangreiche Module sehr schnell sehr unübersichtlich werden können und man unter Umständen einen Wulst von Variablen (zum Beispiel diverse Laufvariablen für Schleifen oder andere Temporaräre Variablen) deklarieren und sehr stark auf mögliche Seiteneffekte bei deren Nutzung achten muss!!! Auch ist die Strukturierung von Applikationen dadurch

Page 78: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

77

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

erschwert, dass die Namen aller Objekttypen (Programme, Unterprogramme, LDAs ...) mit Ausnahme von Inline-Subroutines auf lediglich 8 Zeichen begrenzt ist. Die Lesbarkeit großer Applikationen ist dadurch enorm schwierig, insbesondere wenn man sich in ein bestehendenes, komplexes Coding einarbeiten muss, so wie es bei mir - noch dazu Natural-Neuling - der Fall war.

Natural bietet - wiederum wichtig für das Verständnis des Folgenden - keine Möglichkeit auf Betriebssystem-Funktionen zuzugreifen. So kann man weder (direkt) Files schreiben und lesen, noch kann man Hauptspeicher-Operationen durchführen, die für ein Pointer-Konzept nötig wären. Ebenso hat man keine Möglichkeit Threads, Prozesse oder ähnliches zu erzeugen oder zu steuern.Auch die oben angesprochene Plattformunabhängigkeit von Natural muss in gewissen Punkten relativiert werden. Zwar ist es zum größten Teilen wirklich plattformunabhängig, aber gewisse Funktionalitäten stehen nur auf einigen Plattformen zur Verfügung. Dialoge und graphische Elemente zum Beispiel nur unter Windows, bestimmte Umgebungs- (bzw System-)Variablen nur unter bestimmten Betriebssystemen.

Unterprogramm-Aufrufe in Natural haben wiederum einige Besonderheiten, die hier unbedingt noch Erwähnung finden müssen. Ein Unterprogramm wird (wie auch Programme, Dialoge) durch seinen Namen und nicht, wie unter voll-kompilierten Sprachen wie C, über die Adresse aufgerufen. Das heißt, der Name eines aufgerufenen Unterprogrammes kann zur Laufzeit berechnet werden. Dies ist vergleichbar mit dem Automatisierungs-Konzept in COM. Die Natural-Runtime sucht bei Aufruf nach einem Unterprogramm, das den entsprechenden Namen hat. Dieses muss allerdings nicht zwangsweise in der gleichen Library liegen, wie der Aufrufer. In Parametern der Runtime kann man eine Suchreihenfolge für Libraries angeben, in denen das Unterprogramm gesucht werden soll, wenn es in der aktuellen nicht vorhanden ist. Diese definierten Libraries werden als „Steplibs“ bezeichnet.Ebenfalls ist es möglich in der Runtime-Konfiguration einen EntireX-Broker und einen Servernamen anzugeben. Wenn EntireX auf dem lokalen System installiert ist, wird – falls das Unterprogramm auch in den Steplibs nicht gefunden wurde – der Aufruf automatisch an diesen Server weitergeleitet, falls dieser ein Natural-Unterprogramm mit dem entsprechenden Namen zur Verfügung stellt. Der Proxy dafür wird von der Natural-Runtime zur Laufzeit erzeugt, diese nimmt auch das Marshalling und Unmarshalling der Parameter vor. Liste der Parameter beim Unterprogrammaufruf wird dabei als IDL für die Proxy-Erzeugung genutzt. Das bedeutet, dass ein RPC-Aufruf für den Programmierer völlig transparent und ohne den geringsten Aufwand möglich ist. Eine, muss man anerkennend sagen, wohl einmalige Sache, die sehr einfach und sehr schnell die Erstellung von Client-Server-Applikationen mittels RPC möglich macht. Die Security-Aspekte werden dabei – je nach Runtime-Konfiguration – in der Regel implizit übernommen; es ist aber auch möglich, explizit eine Authentifizierung (durch Ticket-Generierung) vorzunehmen oder andere Aspekte des RPC-Calls (z.B. Conversation einleiten oder beenden) zu steuern, wenn man von vornherein weiß, dass es sich bei dem Unterprogramm-Aufruf um einen RPC handelt.

Page 79: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

78

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Da ich vor meiner Praxisphase von Natural noch nie etwas gehört hatte, begann diese mit einem einwöchigen Natural-Kurs im Software AG - Systemhaus in Darmstadt. Das Thema war „Natural GUI Programmierung“ und Kenntnisse in Natural-Syntac waren Voraussetzung, aber aufgrund des relativ geringen Sprachumfangs und meiner Erfahrung mit vielen verschiedenen Programmiersprachen (darunter auch einige nicht objektorientierte 4GLs aus dem Datenbankbereich, wie Clipper) fiel mir das grundsätzliche Verständnis nicht schwer. In der Praxis lag jedoch der Teufel im Detail und es war für mich zunächst schwer (eben gerade wegen dem Einstieg in ein laufendes Projekt mit bestehedem umfangreichen Coding), mich in den Codings von Programmierern mit jahrelanger Natural-Erfahrung zurecht zu finden.

7.1.2 Praxis-Projekt: ESM GUI FrameworkDamit wieder zurück zum Projekt.Das ESM GUI Framework bietet den Programmierern der zu erstellenden Applikationen ein API, das es erlaubt, diese fast ausschließlich durch Definition von Applikations-Objekten und deren Verknüpfung mit Funktionen die das Framework bietet, zu erstellen. Die gesamte API ist ohne Hintergrundwissen schwer in Kürze zu erklären, die genaue Spezifikation füllt Dokumente, deren Umfang in etwa den dieser Arbeit haben, aber man kann sich das ganze in etwa so vorstellen:- Es wird eine Client-Applikation als Natural-Library erzeugt - In einem Message-File wird die Applikation beschrieben (Name, Kürzel)- Es werden dort auch „Objekte“ beschrieben, indem ihr Name, ein internes Kürzel, der

Name von Icons für ihre Darstellung, Verknüpfung mit Funktionen (die im Framework deklariert sind, z.B. „neu Anlegen“, „Bearbeiten“, „Auflisten“, „Löschen“) und weitere ähnliche Parameter angegeben werden. Objekte können Applikations-Objekte (z.B. „Artikel“, „Kunde“, „Rechnung“, ...), Gruppierungen von Applikations-Objekten (z.B. „Einkaufskunden“, „offene Rechnungen“) u.ä. sein. Auch Beziehungen von Datenobjekten können so festgelegt werden (z.B. dass eine Rechnung Posten hat). Das Framework kennt die interne Datenstruktur solcher Objekte nicht.

- In dem Message-File können auch Listen definiert werden (z.B. das Format von Spalten einer Artikel- oder Kundenliste).

- Ebenso kann das Messagefile „Menüpunkte“ enthalten, die hierarchisch aufeinander aufbauen.

- In der Client-Library werden einige Dialoge erzeugt, die das Bearbeiten von Daten-Objekten erlauben (z.B. ein Dialog zum ändern der Kundendaten). Außerdem werden Dialoge für weitere Benutzerinteraktionen erstellt (wie zum Beispiel ein Dialog zur Eingabe von Filterkriterien in einer Kundenliste). Diese Dialoge müssen bestimmten Namenskonventionen entsprechen.

- Die Client-Library enthält außerdem Strukturen, die die Daten der Objekte aufnehmen können.

- Es wird eine Server-Library erzeugt, die die Daten für den Client bereitstellt. Sie enthält gegebenenfalls Unterprogramme, um diese Daten aus Datenbanken abzufragen oder von

Page 80: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

79

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Komponenten der bestehenden Alt-Applikationen (die auf dem Server ablaufen) erfragt. Die Unterprogramme, die per RPC aufgerufen werden können, müssen einer bestimmten Namens- und Schnittstellenkonvention folgen.

Das Framework selbst besteht aus einer Client- und Server-Komponente (jeweils eine Library).

Wird nun die Applikation auf dem Client gestartet, so erscheint das im Framework vorhandene Rahmenfenster mit Menü, Toolbar, Statusleiste und einer TreeView, in der die in der Definition der Client-Applikation (im Message-File) vorgegebene Baumstruktur mit „Menüpunkten“, Datenobjekt-Gruppen und Datenobjekten erscheint.Für jedes Element in dieser TreeView sind die im Message-File zugeordneten Funktionen über die Menuzeile, die Toolbar oder ein Kontext-Menu verfügbar. Diese werden also dynamisch mit der neuen Auswahl eines Elements in der TreeView (oder einer geöffneten Liste) verändert.

Das Bild oben zeigt einen Screenshot des ESM-Framework, indem hier zwei Applikationen laufen: NOM („Output Managment“) und Andorra, das jetzt unter dem internen Namen

„Mainframe Explorer“ weiterentwickelt wird. In der Tree-View links sind die Darstellung derim Message-File definierten Srukturierungsebenen sowie einige Datenobjekte vom Typ

Verteilerliste (Distibution List) zu sehen, deren Namen schon vom RPC-Server geladen wurden.

Page 81: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

80

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Bei Ausführung von bestimmten Funktionen („List“, „Browse“, ...) kann das Framework selbstständig Fenster öffnen und die angeforderten Daten anzeigen.Die Funktion „List“ beispielsweise öffnet ein Fenster, das eine ListView enthält, die entsprechend den Vorgaben im Message-File formatiert wird (Anzahl von Spalten, deren Überschrift, Breite und Ausrichtung). Das Framework ruft nun eine bestimmte Funktion seiner eigenen Server-Komponente auf, die einen bestimmten Namen und eine bestimmte Schnittstelle (Parameterliste) hat. Diese verzweigt weiter an eine Funktion der Server-Komponente der Applikation (die, wie oben beschrieben, auch einen bestimmten Namen und eine bestimmte Parameterliste hat, die in der API des Frameworks beschrieben ist) und die Daten, die angezeigt werden sollen, zurückliefert. Alternativ kann die Formatierung der Liste übrigens auch vom Framework bei dieser Server-Funktion erfragt werden.Eine weitere Funktion die das Framework direkt ausführt ist „Browse“, das den vollständigen Inhalt von bestimmten Datenobjekten anzeigen kann. Von „bestimmten“ Objekten deshalb, weil das Frame die interne Datenstruktur des Objektes ja nicht kennt. Über Browse ist es aber zum Beispiel möglich, den Inhalt von Dateien, Berichten oder ähnlichen Datenobjekten anzuzeigen, die flach und zeilenorientiert sind.Da es in den Anwendungen des ESM-Teams nicht wirklich um „Kunden“ und „Rechnungen“ geht, sondern um Datenobjekte wie Reports oder Files in einem Dateisystem, die potentiell sehr groß sind, gibt es an dieses Browse eine besondere Anforderung, weshalb ich später noch auf die Implementierung dieses „Browse-Controls“ sehr ausführlich zurückkomme.

Im Bild oben ist das Framework mit laufnder Applikation NOM und einem geöffnetenBrowse-Fenster zu sehen. Die angezeigten Daten (Inhalt eines „Aktiven Reports“) wurden

per RPC von einem Natural-Server auf einer OS/390-Maschine geladen.

Page 82: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

81

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Für die Ausführung von anderen Applikations-Funktionen, die Kenntnis über die Struktur eines Datenobjekts voraussetzen, wird ein Unterprogramm aus der Client-Library der Applikation aufgerufen. So wird zum Beispiel, wenn der Benutzer auf ein selektiertes Kunden-Objekt die Fuktion „Bearbeiten“ ausführt vom Framework ein in der Library der Client-Applikation definierter Dialog aufgerufen, der (unter anderem) die ID des Objektes (also hier z.B. die Kundennummer) übergeben bekommt. Das Dialog-Fenster kommuniziert mit einer Server-Komponente der Applikation um von ihr die Daten der Felder zu erhalten und eventuelle Änderungen später zurückzuschreiben.Dieser ganze Mechanismus ist so nur durch den Umstand möglich, dass in Natural Unterprogramme eben mit ihrem Namen aufgerufen werden. Auch diesen Vorgang möchte ich noch einmal an einem verständlichen Beispiel erklären:Eine Applikation „Kundenverwaltung“ wurde mit dem Kürzel „KV“ definiert. Von dieser Applikation wurde auch ein Daten-Objekt Kunden (Kürzel KU) definiert. Im Framework gibt es unter anderem Funktionen List (Kürzel LI), Bearbeiten (Kürzel OP für „Open“).Wenn nun ein Benutzer auf dem Knoten „Kunden“ die Funktion „List“ ausführt, so wird das Framework ein Fenster mit einem ListView öffnen, es formatieren und das Unterprogramm „KVKULI-N“ aufrufen. Dieses wird auf dem Server liegen, weshalb der Aufruf als RPC ausgeführt wird.Die Namenskonvention für Unterprogramme des Frameworks lautet nämlich „AAOOFF–T“, wobei AA für den zweistelligen Applikationscode, OO für den zweistelligen Objektcode und FF für den zweistelligen Funktionscode steht. T steht für den Modultyp und ist eine Natural-Konvention (die hier vielleicht wichtigsten sind „P“ für Programme, „N“ für Unterprrogramme, „C“ für Copycodes, „A“ für PDAs, „L“ für LDAs, „D“ für Dialoge).So kann das Framework für jede Funktion auf jedem Objekt einer jeden Applikation, die ein Benutzer ausführt, ein Unterprogramm oder einen Dialog (welches von beiden, das ist in den Funktionsdefinitionen hinterlegt) aufrufen.

RPC-Kommunikation im FrameworkDie RPC-Kommunikation mit dem Server geht dabei übrigens immer über das Framework. Wenn eine Client-Komponente einer Applikation eine Anfrage an ihre Server-Komponte richtet, so ruft sie ein bestimmtes Unterprogramm der Client-Bibliothek des Frameworks auf und übergibt neben den Parametern für den Server auch den Namen des Serverprogramms. Die Framework-Client-Komponente ruft eine Framework-Server-Komponente auf, diese wiederum verzweigt zur per Namen übergebene Applikations-Server-Komponete. Dadurch definiert das Framework über die Parameterliste seiner eigenen Server-Komponente eine Anzahl (derzeit 5) feststehender Schnittstellen, über die die Client- und Server-Applikationen ihre Daten austauschen können. Es gibt dabei die Route vor und kann sich, unter anderem, nach einem vorgegebenen Schema um applikationsspezifische Security-Aspekte kümmern (wie: darf der Benutzer „Hugo“ überhaupt für die Applikation AA die Funktion FF auf Objekt OO ausführen ?)

Page 83: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

82

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Meine Aufgaben im ProjektAls ich im September 2001 meine Arbeit an dem Projekt aufnahm, existierte schon ein funktionsfähiger Prototyp (schon der zweite, ein Entwicklungs-Prototyp, nachdem der erste, ein Labor-Prototyp die Machbarkeit zeigen sollte und dann wieder weggeworfen und mit den gemachten Erfahrungen bei Null angefangen wurde), der erweitert und verbessert werden musste.

Meine konkreten Aufgaben in diesem Projekt waren:(a) Überarbeitung einiger Komponenten der graphischen Oberfläche, insbesondere

Umstellung auf Controls der neuen Natural-Version 5.1.1(b) Erstellung eines Konzeptes, wie objekt- und funktionsbezogene kontext-sensitive Hilfe

angeboten werden kann und dessen Implementierung(c) ein Applikations-Security-Konzept, das Authentifizierung gegenüber der Server-

Applikation in verschiedenen Szenarien erlaubt und Authorisation einzelner Benutzer auf Ebene des GUI widerspiegelt (z.B. durch Ausgrauen von Funktionen auf bestimmten Objekten, wenn diese dem Benutzer nicht erlaubt sind) und die damit verbundene Implementierung neuer Applikationsdialoge

(d) Erstellung der Browse-Funktionalität.

Meine Tätigkeiten im ProjektWährend (a) eher eine fortlaufende Aufgabe war, auf die ich hier nicht näher eingehen möchte, waren die anderen Aufgaben durchweg interessant und anspruchsvoll. Zumal ja auch für die Mitglieder meines Teams dies alles Neuland war, weshalb mir manchmal bei Fragen nicht direkt geholfen werden konnte und wir uns mit einiger Funktionalität auch immer haarscharf am Rande des Machbaren bewegten. Dabei kamen mir insbesondere zwei Umstände zur Hilfe. Erstens war mein Büro etwas abseits der restlichen Mitglieder meines Teams gelegen, dafür aber direkt im Bereich der Natural-Entwicklung. Alle Programmierer, die mit der Erstellung von Natural Windows zu tun haben, waren quasi direkt um die Ecke zu finden, so dass ich mich mit Fragen (und Verbesserungsvorschlägen für die nächste Version) direkt an diese wenden konnte. Zum anderen saß in meinem Raum ein Mitglied der Natural-Qualitätssicherung, der mit Tests der tagesaktuellen Natural-Versionen beschäftigt war. So hatte ich auch immer einen Ansprechpartner, wenn Natual einmal - insbesondere bei neuen Funktionen - nicht das tat, was es sollte. Oftmals lag es allerdings auch daran, dass ich offenbar Natural nicht richtig klar machte, was ich wollte.An einigen Stellen konnte ich jedoch durch meine Arbeit Fehler in der Runtime oder der Entwicklungsumgebung aufdecken. In anderen Fällen hatten wir auch konkrete Anforderungen an die Natural Entwickler, was noch zu implementieren sei.

Funktionalität für Online-HilfeSo war zum Beispiel für die Help-Konzeption eine Sache von wichtiger Bedeutung: Laut Natural-Dokumentation stehen für die Help-IDs (wie unter 32-bit Windows allgemein) Werte

Page 84: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

83

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

im 32-Bit Bereich zur Verfügung. Tatsächlich erlaubte Natural aber nur 16-bit Help-IDs. Das von mir entwickelte Help-Konzept sah aber nun vor, dass die Help-Kontext-IDs aus Namen der Objekte und Funktion berechnet wurden, die jeweils zweistellige alphanumerische Felder sind. Eine Konventionserweiterung von mir sah vor, dass das erste Zeichen nur ein Buchstabe, das zweite ein Buchstabe oder eine Zahl sein darf. Das ergibt einen Ergebnisraum von (26*36)² = 876096 möglichen IDs, was von 16-Bit-Werten {0...65535} nicht abgedeckt wird. Die Abweichung der Natural-Funktionalität von der Dokumentation stellte ich aber erst bei der Implementierung fest. Dies wurde von der Natural-Entwicklung allerdings nicht als Fehler in Natural, sondern „nur“ als Fehler in der Dokumentation eingestuft, was wiederum bedeutet hätte, dass eine Erweiterung auf 32-Bit frühestens mit dem nächsten Release 5.2.1 Mitte 2002 in Frage gekommen wäre. Dank der Tatsache, dass der zuständige Entwickler nur 20 Meter entfernt von mir saß und ich ihn von der Sinnhaftigkeit meines Help-Konzeptes überzeugen konnte (und der Änderungsaufwand offenbar gering war), konnte ich schon 2 Tage später eine Version von Natural 5.1.1 vom File-Server der Natural-Entwicklungsabteilung ziehem die 32-Bit Help-IDs unterstützte.

Das Security-KonzeptUnerwartet kompliziert wurde der Entwurf eines Security-Modells für die Apllikationen, die das Framework nutzen. Dies lag vor allem daran, dass einige unterschiedliche Szenarien zu beachten waren. Zwar gibt es sowohl für Natural als auch den EntireX Broker Security-Facilities, die eine gesicherte Authentifizierung erlauben, es ist aber nicht so, dass diese zwangsweise immer aktiv sind. Einige Kunden und damit potentielle Abnehmer der Applikation haben diese Security-Dienste, die quasi ein Add-On zur jeweiligen Runtime darstellen, möglicherweise nicht installiert oder deaktiviert. Entsprechend unterschiedlich muss teilweise die Authentifizierung der Applikation vorgenommen werden. Außerdem gibt es drei Stellen, denen sich der Benutzer gegenüber ausweisen muss: die lokale Natural-Umgebung, der EntireX Broker und die entfernte Natural-Umgebung (der RPC-Server). Weiterhin gibt es zumindest eine Applikation, die mit dem Framework entwickelt werden soll, die Authentifizierung gegenüber dem Betriebssystem auf Drittrechner (unter möglicherweise verschiedenen Plattformen mit verschiedenen Gegebenheiten) benötigt. Auch dafür sollte das Framework eine rudimentäre Unterstützung vorsehen.Diese Authentifzierungen können synchronisiert sein (EntireX und Natural bieten diese Möglichkeit), sodass nur ein Benutzername und ein Passwort nötig ist. Da die genaue System-Konfiguration bei den Kunden aber unterschiedlich ist, können dafür im Extremfall vier verschiedene Kombinationen von Benutzernamen und Passwörtern (und weiteren Informationen wie Domain- oder Gruppennamen für den vierten Fall) nötig sein. Dies erwies sich sowohl in Analyse als auch in Implementierung als komplizierter als gedacht. Zumal ich bei der Implementierung einmal mehr auf einen störenden, wenn auch nicht kritischen, Fehler im Security-Bereich der Natural-Runtime unter Windows stieß. Da dieser offenbar noch keinem Natural-Kunden oder auch -Entwickler im Haus aufgefallen war, darf man davon ausgehen, dass wir innerhalb des Projektes hier wirklich Neuland betreten haben.

Page 85: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

84

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

ActiveX Browse ControlAls letztes möchte ich mich noch ausführlich der interessantesten Teilaufgabe meiner Praxisphase widmen, der Bereitstellung der Browse-Funktionalität. Wie schon gesagt geht es hier darum, große (!!) Datenmengen anzuzeigen. Ausgangspunkt der Überlegungen waren „Reports“, die eine Applikation betreffen. Diese bestehen aus mehreren Zeilen, die jeweils maximal 253 Zeichen lang sind. Die Reports können im Extremfall einige Millionen Zeilen lang sein. Der klassiche Ansatz wäre, das gesamte Objekt vom Server zu laden und anzuzeigen.Das Problem daran ist allerdings, das der Client während des gesamten Ladevorgangs (RPC, mit dem wir hier arbeiten, ist wie schon gezeigt asynchron) blockiert ist, da Natural keine Möglichkeit bietet einen Hintergrund-Thread zu erzeugen, der die Daten nachladen könnte. Der Ladevorgang kann unter Umständen – je nach Umfeld und Datenmenge – bis zu mehreren Minuten dauern. Ein Benutzer ist in der Regel nicht bereit, länger als 5 Sekunden nach auslösen einer Funktion auf eine Reaktion oder wenigstens eine Statusanzeige zu warten. Außerdem müsste bei diesem Ansatz immer der gesamte Inhalt eines Reports (oder allgemein Objekts) übertragen werden, auch wenn sich der Benutzer vielleicht nur für einen bestimmten Ausschnit interessiert.Bei dem Ausgangsproblem Reports ist im übrigen die Länge, also die Anzahl der Zeilen, a priori bekannt. Die Daten liegen entweder in Files oder in Datenbanken.Mit diesem Problem konfrontiert hatte ich einen zunächst umstrittetenen Vorschlag zur Lösung: Ein in C++ implementiertes ActiveX Control, das als GUI-Element aus einem Windows List-View-Control im Report-View-Stil besteht und „selbstständig“ die Daten via RPC vom Server lädt. Das Control sollte dazu nach seinem Start zunächst die Anzahl der Zeilen des Objekts über einen RPC-Call ermitteln, die ListView auf diese Zeilen-Anzahl initialisieren. Dann sollte ein Ladevorgang in einem zweiten Thread angestoßen werden, der Blockweise die Daten via RPC lädt, die geladenen Zeilen sollte direkt im List-Control angezeigt werden. Zunächst war vorgesehen, dass alle Blöcke sequentiell geladen werden.Der Vorschlag war deshalb umstritten, weil eine der Maßgaben für das Projekt die Implementierung in Natural war. Dahinter standen wohl zum einen ein Marketing-Aspekt (die SAG wollte zeigen, was mit Natural für Windows möglich ist) zum anderen ein praktischer: nach Beendigung meiner Praxisphase muss das Control schließlich unter Umständen weiter gepflegt werden. Außerdem gab es noch Bedenken bezüglich der Machbarkeit, es sollten auf keinen Fall auf der Serverseite Sonderbehandlungen (wie EntireX Broker ACI Calls oder eigene Schnittstellen-Definitionen) für das Control geben!Nachdem ich einen Prototypen erstellte, der zeigte, dass zum einen keine Sonderbehandlung auf dem Server nötig war, zum anderen argumentierte, dass man die Funktionalität von Natural Windows als Plattform zur Erstellung von GUI-Clients vielleicht besser dadurch zeigen kann, dass man ein schnelles, benutzerfreundliches Control integriert, das in einer anderen Programmiersprache geschrieben ist, als durch schlechte Funktionalität mit Natural-Mitteln, die den Benutzer im Endeffekt aufhält und dass andererseits C++-Programmierer mit COM-Kenntnissen leichter zu finden sind, als Programmierer, die Erfahrung mit Natural

Page 86: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

85

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

für Windows und GUI haben, wurde für die Implementierung einer endgültgen Fassung des Controls grünes Licht gegeben.Bei der Erstellung des Prototypen fand ich noch eine Option der ListView-Controls, die die endgültige Anforderung an das Control beinflusste: es gibt ab der Version 4.70 der Windows CommonControls die Möglichkeit, ein sogenanntes „virtuelles“ List-View zu erzeugen [msdnlib: „Virtual List-View Style“]. Dieses hat den Extended Style LVS_OWNERDATA. Im Unterschied zu einem „normalen“ List-View werden die anzuzeigenden Daten nicht im List-View gespeichert, sondern über eine Callback-Routine (genauer gesagt, über eine Windows-Notify-Nachricht: LVN_GETDISPINFO) jeweils angefordert, wenn sie gebraucht werden. Das heißt, dass die Daten im Vergleich zum ersten Konzept nicht in das List-View eingetragen werden müssen, sobald sie gelesen sind, sondern in einer lokalen Datenstruktur der Applikation, einem Cache, abgelegt werden können, aus dem sie dann jeweils geladen werden. Weiterer Vorteil ist, dass LVN_GETDISPINFO immer diejenigen Zeilen anfordert, die auf dem Bildschirm zu sehen sind. Dies ermöglicht nun dass der RPC-Call erst angestossen werden muss, wenn ein Benutzer (zum Beispiel über den Scrollbalken) einen Teil des Objekts anzeigen will, der noch nicht geladen ist. Überspringt er dabei einige Zeilen, so müssen diese nicht gelesen werden!Aus dieser Ausgangslage ergaben sich folgende Anforderungen an das ActiveX Control:- Zeilenweises Anzeigen von vorhanden Daten von Objekten, deren Größe von Beginn an

bekannt ist- Lesen der Daten je nach Benutzeranforderung im Hintergrund (extra Thread) über RPC-

Calls und Speicherung in einem lokalen Cache- Serverseitige Volltext-Suche in dem Datenobjekt ab einer Zeile x (wurde aus Performance-

Gründen später dahingehend erweitert, dass die Suche zunächst lokal stattfindet, erst wenn die Daten im lokalen Cache nicht gefunden werden die Suchanforderung an den Server geschickt wird).

- Volle Integration in das in Natural implementierte Framework- Kein spezielles serverseitiges Coding für das Control, keine speziellen SchnittstellenBevor hier auf die Implementierung eingegangen wird, zunächst noch eine wichtige Grundlage: die SDK für die EntireX RPC-Kommunikation mit dem Natural-RPC-Server.

7.2 EntireX RPC-SDK für CFür die Implementierung der RPC-Calls im Active-X-Control arbeitete ich mit der EntireX RPC-SDK für C. Sie bietet die notwendigen Funtionen, um die Runtime zu initialisieren, eine Verbindung mit dem Broker aufzunehmen und einen RPC-Call durchzuführen. Der eigentliche Call wird dabei von einem Stub übernommen, der in der Regel automatisch aus einer IDL erzeugt wird (aus Gründen, die ich noch näher erläutern werde, habe ich den Stub manuell implementiert). Der Programmierer muss ein Headerfile mitcompilieren und eine Library einlinken. Der Ablauf der Kommunikation folgt dabei dem Schema in 6.2.1. Im folgenden die von der SDK angebotetenen Funktionen, die in 7.3 benutzt wurden. (Details siehe [exxwin])

Page 87: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

86

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

7.2.1 API-FunktionenDie meisten API-Funktionen nutzen als Parameter Datenstrukturen, deren Inhalt im nächsten Abschnitt erläutert wird. Die Namen der Datenstrukturen sind hier in einer Kurzform in GROSSBUCHSTABEN angegeben, die Zuordnung zu den erklärten Datenstrukturen ergibt sich aber von selbst.

ERXGetMessage(): Zu einem Fehlercode die Beschreibung geben lassen. Parameter: [in] Fehlercode, [out] Text, Textlänge. Rückgabewert: int (=0: OK; !=0: Fehler).

Alle weiteren Funktionen haben als Rückgabewert den Fehlercode.ERXGetLastError(): Informationen über den letzten Fehlerstatus abrufen. Parameter: [out] ERROR_INFO.

Besonderheit: Fehlerstatus von Register und Unregister können nicht abgerufen werden, da GetLastError() eine Verbindung zur Runtime erfordert.

ERXRegister(): Bei der EntireX-RPC Runtime registrieren. Parameter: [in] <minimal benötitge Versionsnummer der Runtime>. Jeder Thread, der die RPC-Runtime ansprechen will, muss sich registrieren. Ist die Runtime noch nicht gestartet, so wird dies implizit durchgeführt.

ERXUnregister(): Die Registrierung des aktuellen Threads aufheben. Keine Parameter. Wenn kein Thread mehr registriert ist, wird die Runtime beendet.

ERXLogon(): Eine Verbindung zum Broker aufbauen und eventuell notwendige Authentifizierung vornehmen. Parameter: [inout] CLIENT_ID, [in] <Broker-Name>.

ERXLogoff(): Eine Verbindung zum Broker abbauen. Parameter wie Logon().ERXIsServing(): Prüfen, ob ein bestimmter Server bereit steht und im Erfolgsfall dessen „Hallo-Welt“-Text

zurückgeben. Parameter: [inout] CLIENT_ID, [in] SERVER_ADR, [out] IS_SERVING.ERXConnect(): Eine Conversation mit einem Server beginnen. Parameter: [inout] CLIENT_ID, [in] SERVER_

ADR, [out] SERVER_ADR (enthält Conversation-ID).ERXDisconnect(): Eine Conversation beenden. Falls der Server ein Natural-RPC-Server ist, zusätzlich ein

Transaction-Rollback() ausführen. Parameter: [in] SERVER_ADR.ERXDisconnectCommit(): Eine Conversation beenden. Falls der Server ein Natural-RPC-Server ist, zusätzlich ein

Transaction-Commit() ausführen. Parameter: wie Disconnect().ERXCall(): Einen RPC-Call durchführen. Parameter: [inout] CLIENT_ID, [in] SERVER_ADR (bei einer

Conversation der von Connect() zurückgegebene dritte Parameter), [out] CALL_ID (nur für asynchrone Kommunikation von Bedeutung), [in] CALL_INFO_BLOCK, [inout] <Parameter-Block-Array> [int] <Flag zur Parameter-Block Struktur>. <Parameter-Block-Array> (übergeben als Array von void*) ist ein reservierter Speicherbereich, der die Werte des RPC-Calls enthält. Üblicherweise als Struktur definiert, die die „Liste“ der einzelnen Parameter enthält.

7.2.2 SDK-DatenstrukturenIn der vorigen Darstellung wurden einige Datenstrukturen benutzt, die ich noch erläutern will, jeweils informell, Details siehe [exxwin].

ERX_ERROR_INFORMATION: Enthält Fehlercode und zugehörige Fehlerbeschreibung.

ERX_CLIENT_IDENTIFICATION: Enthält Security-Informationen über Identität des Clients (User-ID, Password, Token und Security Token für Broker; User-ID und Password für RPC-Server; Logon-Flag, gefordertes Verschlüsselungs-Level (siehe 6.2.5)

ERX_SERVER_ADDRESS: Enthält Informationen, die die Verbindung zum Server und die Behandlung durch den Broker beschreiben, z.B. Server-Name, Art des Servers, „Service“ den der Server anbieten muss, ob eine Verbindung zum Server conversational ist, Timeout-Zeit, Daten-Kompressions-Flag und EntireX-interne Informationen über die Verbindung.

Page 88: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

87

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

ERX_CALL_IDENTIFICATION: Name der aufzurufenden RPC-Funktion innerhalb des Servers. (Im Falle eines Natural-RPC-Servers der Name des Unterprogrammes und bei bestimmen Konfigurationen (Natural Server AutoLogon=OFF), deren Bedeutung ich nicht näher erläutern möchte, auch zwingend die Library in der das Unterprogramm liegt).

ERX_CALL_INFORMATIONBLOCK: Enhält ERX_CALL_IDENTIFICATION, ein Array von ERX_PARAMETER_DEFINITION_Vx sowie dessen Größe (= Anzahl der Parameter).

ERX_PARAMETER_DEFINITION_Vx: Enthält die Beschreibung eines Parameters: Name des Parameters, Datentyp, Größe in Byte, ggf. Informationen über Array-Dimensionen, falls der Parameter ein Array ist, Konvertierungsinformationen. x steht dabei für die Versionsnummer. In [exxwin] ist _V3 beschrieben, ich nutzte - da ich abwärtskompatibel zu EntireX 5.3.1 bleiben wollte, _V2, die sich aber für die hier genutzten Zwecke nicht von _V3 unterscheidet. Einziger wirklicher Unterschied ist, dass bei _V3 eine Konvertierung von Stringtypen (Festlängen- nach nullterminierten Strings) schon vom Broker-Stub erledigt wird, während sie mit _V2 im Code des RPC-Stubs erfolgt.

7.3 BOM (Broker Object Model)Speziell für C++ und DCOM gibt es noch ein weiteres SDK-Modell: das Broker Object Model. Es ist eine objektorientierte Darstellung des SCI und RPC-Kommunikationsmodell über den Broker und enthält Klassendarstellungen von folgenden Objekten: Broker, Session (Verbindung mit dem Broker), Service (Parent-Klasse von RealService und VirtualService), RealService (Server-Implementierung), VirtualService (Server auf der Gegenseite) und Conversation (die auch für non-Conversational-Verbindungen genutzt wird). Außerdem enthält das BOM ein eigenes Exception-Modell für die strukturierte Behandlung von Fehlern. Die BOM-Klassen stehen in zwei Varianten zur Verfügung: als „normale“ C++-Klassen, die direkt auf den Broker Strub zugreifen und als COM-Komponenten.

Ich erwähne dies aber nur der Vollständigkeit halber, denn ich habe es nicht benutzt. „Warum?“, wird der aufmerksame Leser fragen, schließlich erfolgte die Implementierung des ActiveX-Controls doch objektorientiert in C++. Außerdem habe ich (siehe nächsten Abschnitt) eigens eine Wrapper-Klasse geschrieben, die die Funktion der SDK für C kapselt.Nun, knappe Antwort: zu Beginn der Implementierung am ActiveX Control wusste ich noch nicht, dass das BOM existiert. Aus heutiger Sicht würde ich auf jeden Fall das BOM statt der C-SDK nutzen, unter anderem deshalb, weil das Exception-Modell den Code strukturierter und übersichtlicher gemacht hätte. Eine nachträgliche Umstellung wäre aber wenig sinnvoll, da die Code-Änderungen tiefgreifend wären. Außerdem ist es hier aus didaktischen Gründen sinnvoll, da die SDK-Funktionen eher die tatsächlichen Vorgänge des RPC-Calls widerspiegeln, das BOM davon teilweise abstrahiert (was aus Sicht des Programmierers sicher vorteilhaft ist).

7.4 ActiveX Control ESMBrowseDie Anforderungen an die Funktionalität des Controls wurden schon in 7.1.2 beschrieben. In diesem Kapitel möchte ich auf die Implementierung eingehen.Der eigentliche RPC-Call muss, abgeleitet aus den Anforderungen, drei Aufgaben erfüllen, die in Form von „Unterfunktionen“ implementiert wurden, das heißt durch einen Funktionscode,

Page 89: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

88

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

der an das per RPC aufgerufene Natural-Unterprogramm als String-Parameter (Länge: drei Zeichen) mit übergeben wird. Die drei Unterfunktionen sind:(1) Liefere die Anzahl der Zeilen eines gegebenen Objekts. Funktionscode: „GRO“ (Get

number of ROws).(2) Liefere einen Datenblock (= eine feste Anzahl von Zeilen als Array von Strings, in

der gegenwärtigen Implementierung 100 Zeilen) ab einer bestimmten Zeile aus dem gegebenen Objekt. Funktionscode: „ “ (drei Blanks bzw. leer).

(3) Suche einen String (Volltextsuche) in dem Objekt, beginnend bei einer bestimmten Zeile, Liefere die Zeilennummer des ersten Auftretens oder 0 (null), falls nicht gefunden.

7.4.1 Schnittstelle des ESM-GUI-FrameworkZum Verständnis muss ich natürlich kurz auf die Server-Schnittstelle eingehen, die Bestandteil der Server-Komponente des Frameworks ist. Diese werde ich hier durch ein Natural-Unterprogramm beschreiben, das zu Beginn der Implementierungsphase als Testserver diente und Dummy-Daten zurücklieferte. Die echte Implementierung verzweigt zu einem applikationsspezifischen Unterprogramm, das die angeforderten Daten aus dem entsprechenden Datenspeicher (Datenbank oder File) liefert.

0010 * --------------------------------------------------------------------0020 * Subprogram ESBROW-N0030 * Version 1.00040 * Function API Type: Browse0050 *0060 * User-Id Date Marked Comment0070 * WRKMFR 2001-11-20 created (test implementation)0080 ** --------------------------------------------------------------------0090 DEFINE DATA0100 PARAMETER USING ESMCNT-A0110 PARAMETER USING ESMINP-A0120 PARAMETER USING ESMWORKA0130 PARAMETER0140 1 #PARMS0150 2 #PARM-AREA(A253/1:100)0160 LOCAL0170 1 #PROG-NAME0180 1 #I (N3)0190 1 #LN (N10)0200 END-DEFINE0200 ** --------------------------------------------------------------------0210 /* #PROG-NAME: Name of Subprogramm that would be called in real impl.0220 COMPRESS ES-APPLICATION ES-OBJECT ES-FRAMEWORK-FUNCTION ‚-N‘0230 TO #PROG-NAME LEAVING NO SPACE0240 0250 DECIDE FOR FIRST CONDITION0260 WHEN ES-EXTEND-FUNCTION = „GRO“0270 ES-LINE-NUMBER := 3000 /* asume size of 3000 Lines0280 WHEN ES-EXTEND-FUNCTION = „FIN“0290 IF #PARM-AREA(1) = „1000“ /* #PARM-AREA(1) contains string to find0300 ES-LINE-NUMBER := 1000 /* return lineno 1000 if seeking „1000“0310 ELSE0320 ES-LINE-NUMBER := 0 /* return not found otherwise0330 END-IF0340 WHEN NONE0350 /* create „<progname> (<start line>) -> Zeile <Line-No.>“0360 /* as content of each line <Line-No.>0370 FOR #I := 0 TO 990380 #LN := #I + ES-LINE-NUMBER0390 COMPRESS #PROG-NAME ‚(‚ ES-LINE-NUMBER ‚) -> Zeile ‚ #LN0400 TO #PARM-AREA(#I+1)0410 END-FOR0420 END-DECIDE04300440 END

Page 90: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

89

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Die Funktion besteht darin, dass es auf eine „GRO“-Anfrage „3000 Zeilen“ zurückliefert, bei der Anfrage nach einem Datenblock den Programmnamen, der in der echten Implementierung aufgerufen werden würde, die angeforderte Start-Zeilennummer sowie die aktuelle Zeilennummer (Offset innerhalb des Blocks+ Start-Zeile). Ein „FIN“ liefert nur dann „gefunden“ (und zwar in Zeile 1000) zurück, wenn nach dem String „1000“ gesucht wird.Interessanter ist aber die Parameter-Definition für das Unterprogramm, die in den Zeilen 100 bis 150 erfolgt. Die Parameter bestehen zunächst aus drei PDAs (ESMCNT-A, ESMINP-A und ESMWORKA) sowie einer Struktur #PARMS, die nur #PARM-AREA() enthält, ein Array von Strings (Länge je 253 Zeichen, Arraygröße 100 Elemente, 1-basierte Element-Nummerierung).Nun muss man natürlich den Aufbau der PDAs kennen, den ich grob erläutern will:ESMCNT-A enthält einen String (253 Zeichen) namens ES-CONTROL. Dieser ist redefiniert (Zur Erinnerung: entspricht Union in C) als Struktur, die unter anderem Applikationscode, Funktionscode (hier „BR“), den Obejkttyp des anzuzeigenden Objekts, den auf der vorigen Seite erläuterten Unterfunktionscode (ES-EXTEND-FUNCTION), und hier wichtig eine Variable ES-LINE-NUMBER (nummerische Variable - Länge 10 Ziffern - für die Start-Zeilennummer. Dient gleichzeitig als Rückgabe-Variable für GRO und FIN), sowie variable RC (ResultCode für die interne Fehlerinformationen, nummerische Variable, Länge 3) enthält. Diese Werte finden sich - durch die Redefinition - an bestimmten Zeichenstellen in dem String ES-CONTROL wieder. Da der String das oberste Ordnungselement ist, behandelt EntireX bei der Parameterübertragung die gesamte Struktur nur als String. Da die darunter liegenden „Nummerische Werte“ nicht wie Integer binär, sonder quasi als Klartext definiert sind, lassen sie sich auf der Gegenseite (C++-Code) später aus ES-CONTROL extrahieren und wie eine Zahl in String-Darstellung behandeln - zumindest so lange die Werte positiv sind, bei negativen Werten gibt es ein Problem mit der Vorzeichen-Darstellung, die plattformabhängig ist, was EntireX aufgrund der Redefinition nicht interessiert!

� ������������� ����

� ���������� ���������� ���������� ���������

�������������������� �����������

Text (A20)

Beispiel einer Redefinition:

������������������������������������������������������������������������������������������������������������������������������������������������������������������������������

Variablen-Deklaration:<Ebene, Variable, (Typ)>

Programm-Code:(/* ist Kommentar)

ID (N4) XYZ (I2) NAME (A8) NR (N4)

Darstellung imHauptspeicher:

EntireX kann nur die Definition auf höchster Ebene - hier: Text (A20) -interpretieren, denn die darin redefinierte Variable XYZ als Integer würdeeiner anderen Konvertierungsregel unterliegen als das 5. und 6. Zeichenin �Text�, obwohl dies die selben Bytes sind!

Page 91: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

90

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Die beiden anderen PDAs sind ähnlich aufgebaut. ESINP-A enthält ein Array ES-INPUT (3 Elemente von Strings á 253 Zeichen), die ebenfalls redefiniert sind und Informationen zur Identifizierung des ausgewählten Objekts enthalten. ESWORKA enthält wieder einen redefinierten String von 253 Zeichen namens „ES-WORK“, dessen Redefinitionen interne temporäre Status-Daten des Server-Programms enthalten können, die bei non-conversational Calls zur Wiederherstellung des Zustandes der Server-Funktion dienen.Die #PARM-AREA ist nun das Array, das der Übetragung der Inhaltsdaten an den Client dient. Ausserdem wird bei „FIN“ im ersten Element der Suchstring an den Server übergeben.

Die Signatur der Serverschnittstelle könnte also beschrieben werden als:

ESBROW-N ( [inout] ES-CONTROL (A253), [in] ES-INPUT (A253/1:3), [inout] ES-WORK (A253), [inout] #PARM-AREA (A253/1:100) )

Ich gehe nur deshalb so genau darauf ein, dass man später die entsprechenden Quellcode-Stellen im Active-X Control verstehen kann! Dort werden z.B. ES-INPUT und ES-WORK nur, vom Framework kommend, durchgereicht, ES-CONTROL wird teilweise nach den benötigten Daten geparsert, das Array #PARM-AREA wird komplett genutzt.

7.4.2 Funktion und Nutzung des ControlsDas Control wird im Natural-Code der Client-Komponenten des Frameworks als sichtbares Control in ein leeres MDI-Child Fenster eingebunden. Die Größe wird dabei jeweils der Größe des Client-Bereiches des Fensters angepasst. Das Fenster bekommt ein Kontext-Menü mit den Funktionen „Gehe zu Zeile“, „Suchen“, „Weitersuchen“, die jeweils einen Natural-Dialog öffnen, in denen der Benutzer die Such- oder Sprungparameter (Suchtext, Zeilennummer) angeben kann.

Im „After-Open“-Event des Fensters (wird ausgeführt, sobald das Fenster und seine Controls erzeugt sind) wird das ActiveX Control initialisiert, also mit Daten versorgt. Dies geschieht über Aufruf der Put-Property-Methoden im COM-Interface des ActiveX Controls (deren Definition folgt). Wichtige Daten hierbei sind zum Beispiel der Name des Brokers, des Servers und des Benutzers, sowie sein Passwort. Dies alles sind Daten, die dem Framework bekannt sind.Außerdem wird das Control mit den von der Serverseite schon bekannten Parameterwerten ES-CONTROL, ES-INPUT und ES-WORK versorgt, die ja bekanntlich neben der Kennung des Objektes auch die ID des aktuell (also zum Zeitpunkt der ausführen der Funktion „Browse“) im Framework ausgewählten Objekts beinhalten. Diese Strukturen werden jeweils einfach als String übergeben.

Page 92: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

91

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Dann wird die „StartBrowsing“-Methode des ActiveX-Controls über das COM-Interface aufgerufen (1a, 1b). Die sorgt zunächst dafür, dass der Workerthread gestartet wird. Dabei (2) wird dieser bei der EntireX-Runtime registriert, macht einen Broker-Logon() und führt den ersten RPC-Call aus (3), der die Anzahl der anzuzeigenden Zeilen zurückliefert. Aufgrund dieser Zahl wird die Anzahl der Zeilen im virtuellen List-View gesetzt (4).Dieses wird daraufhin umgehend eine LVN_GETDISPINFO-Benachrichtigung an den ihr zugeordneten Notify-Handler schicken (5), um den Inhalt zu erfahren, den es anzeigen soll (zunächst für die Zeile 0 = 1.Zeile). Der Eventhandler stellt fest, dass der Block, der die Zeile enthält, nicht im Cache liegt (6a). (Ein Block sind jeweils 100 Zeilen, die auf einen „Rutsch“ mit einem RPC-Call vom Server gelesen werden; die Zuordnung einer Zeilennummer zu einer Blocknummer ist einfach: Blocknummer („Key“) = Zeilennummer / 100 - 1; Position innerhalb des Blocks („Offset“) = Zeilennumer modulo 100).Da der Block nicht im Cache liegt, wird an das Listcontrol zunächst ein Dummy-Text zurückgegeben (6b), der in jeder noch nicht gecachten Zeile angezeigt wird (etwas wie „>> Zeile wird gelesen <<“), gleichzeitig wird das Lesen des Blocks (und einer einstellbaren Anzahl von Blöcken davor und danach: Read-Ahead- bzw. Read-Backward-Verfahren) getriggert (6c, 6d).„Getriggert“ heißt, das ein Worker-Thread, der in einem suspendierten Zustand ist, angestossen wird (6d); er liest die angeforderten Blöcke mit jeweils einem RPC-Call (7a, 7b). Nach der Rückkehr des RPC-Calls legt er den Block in dem Cache ab (8a). Da LVN_GETDISPINFO vom List-View nur angestoßen wird, sobald sich die Ansicht auf das List-View verändert wird (Cursor-Tasten, Scrollbar), muss es nach Rückkehr des RPC-Calls dazu aufgefordert werden, die Inhalte derjenigen Zeilen, die im gerade gelesenen Block liegen (Dies sind die Zeilen: Key*100 bis Key*101-1) zu aktualisieren (8b).

ActiveX ControlMain-Thread Worker-Thread

Speicher (Prozess-Adressraum)Virt. List-

View-Control

Ringpuffer Cache

OnGetDispInfo(Notify-Handler)

StartBrowsing(Methode)

ReadBlock

GetRowCount

RPC-Server

Natural-Code

1a1b

2 3

4

5,96b,10b

6d

6c7a

7b

8a

8b

6a, 10a

COM-Interface

Page 93: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

92

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Aufgrund dieser Aufforderung wird LVN_GETDISPINFO verschickt (9), der Notify-Handler erneut ausgeführt, diesmal stellt er fest, dass der Block mit der Zeile schon im Cache liegt (10a), liest ihn und gibt die angeforderte Zeile zur Ausgabe an das List-View Control weiter (10b). Der Benutzer sieht die Daten! Nun kann durch Benutzer-Aktionen die Kette wieder bei (5) von Neuem losgehen. Oder auch bei (9), je nachdem, ob die angeforderte Zeile schon gecachet ist.Ich möchte noch auf das Read-Ahead- bzw. Read-Backward-Verfahren eingehen. Dies dient dazu, dass ein Benutzer, der z.B. eine Bildschirmseite nach unten blättert, nicht jedesmal warten muss, bis der nächste Block gelesen wird, sondern dass das Control selbstständig schon mehrere Blöcke im voraus liest; das gleiche gilt auch für rückwärts. Allerdings hat das Lesen eines aktuell angezeigten Blockes immer höhere Priorität.Hat der Worker-Thread nichts mehr zu tun (alle angeforderten Blöcke gelesen) so geht er wieder in den suspendierten Zustand und wartet, bis eine neue Anforderung kommt und er wieder getriggert wird. Die Übergabe der Blocknummern, die gelesen werden sollen, erfolgt durch zwei Ringpuffer, (6c, 7a) die jeweils mit einem Semaphore (Zugriffszahl 1) synchronisert sind, um Inkonsistenz durch überlappende Schreibzugriffe des Main-Threads (6c) und Lesezugriffe des Worker-Threads (7a) zu vermeiden. Ein Ringpuffer verhält sich dabei eigentlich wie ein Stack, die zuletzt angeforderten Blöcke werden zuerst gelesen (man kann davon ausgehen, dass der Benutzer die aktuell auf dem Bildschirm befindlichen Zeilen eher lesen möchte, als die, die er einige Sekunden zuvor einmal auf dem Bildschirm hatte ...). Da natürlich ein Benutzer durch gedrückte Bild auf/ab Taste oder Bedienen des Scrollbalkens dafür sorgen kann, dass das List-View Control in kurzer Folge viele Zeilen anfordert (also auch Blöcke via RPC angefordert werden), die der Benutzer eigentlich gar nicht sehen möchte, ist der Ringpuffer recht klein dimensioniert. Wenn er voll ist, werden die ältesten Anforderungen überschrieben (man kann davon ausgehen, dass er diese nicht mehr braucht). Der erste Ringpuffer (hohe Priorität) enthält die direkt anzuzeigenden Blöcke (RDKeyBuffer, RD = Read Directly), der zweite (niedrige Priorität) enthält die Read-Ahead-Blöcke (RAKeyBuffer, RA = Read Ahead). Die vorangegangene Grafik stellt nur den Vorgang für Blöcke der ersten Kategorie dar.

Als weitere Funktion (grafische Darstellung siehe nächste Seite) steht an der COM-Schnittstelle „Find“ zur Verfügung (1a). Diese (1b) führt eine Volltextsuche auf den Inhalt des Datenobjekts durch, und zwar ab der Zeile nach der aktuellen. In den neueren Varianten des ActiveX-Controls wird dazu zunächst eine lokale Suche im Cache durchgeführt (2, 3, 4), und zwar so lange, bis entweder ein Ergebnis gefunden oder ein „Loch“ im Cache entdeckt wurde oder das Ende des Datenbereiches erreicht wurde. Falls die Suche auf ein „Loch“ im Cache gestoßen ist, wird eine serverseitige Suche per RPC angestoßen (b5-b7), die wieder einmal vom Worker-Thread (mit maximaler Priorität) durchgeführt wird. Ursprüngliche Varianten, in denen der Main-Thread blockiert wurde, bis die RPC-Suche beendet war, um dann in die gefundene Zeile zu springen, führten unter bestimmten, hier schwer darstellbaren Fällen (in denen zwischenzeitliche Nachrichten vom List-View-Control involviert waren) zu

Page 94: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

93

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

einem Deadlock, der nur schwer zu umgehen gewesen wäre. Daher wurde an der COM-Schnittstelle noch ein ActiveX-Event eingeführt, das die Natural-Komponente davon unterrichtet (8a, 8b), dass die Suche beendet wurde. Im Erfolgsfall führt der Code der Fire-Event-Methode gleich die Positionierung auf die gefundene Zeile durch.Das Event enthält noch einen Bool‘schen Parameter der Erfolg oder Mißerfolg der Suche vermeldet.

Daneben gibt es noch eine Funktion „Find Again“, die genauso funktioniert, allerdings nicht mehr nach einem neuen Suchstring fragt, sondern einfach den letzten Suchstring noch einmal ab der nun auf die aktuelle folgenden Zeile sucht.

7.4.3 Die Implementierung

UML DiagrammeIm Folgenden möchte ich den Aufbau des Codes beschreiben, und zwar mit Hilfe einiger UML-Diagramme. Zunächst (ab der nächsten Seite) ein paar Worte zum Umfeld, insbesondere zur ATL, der Active Template Library, die zur Implementierung von ActiveX Controls ohne MFC dient. Dabei gehe ich auf die zentrale Klasse der Implementierung ein und zeige, von wievielen Klassen und Schnittstellen sie abhängig ist, um die COM-Funktionalität zu implementieren (was das ganze ja erst zu einem ActiveX-Control macht).

Danach eine Darstellung der COM-Schnittstelle, wie sie nach außen angeboten und von der Natural-Client-Komponente genutzt wird. Dann ein (umfangreiches) UML-Klassendiagramm, das den inneren Aufbau und das Verhältnis der C++-Klassen zeigt, die die Funktionalität kapseln, versehen mit einigen Anmerkungen zur Implementierung.

ActiveX ControlMain-Thread Worker-Thread

Speicher (Prozess-Adressraum)

Cache

FindLocal

Find

FindRemote RPC-Server

Natural-Code

1a

1b

4

b5

b6

COM-Interface2

Fire_FindFinished

3

b7

a58b

8a

a5 Falls lokal gefundenoder Cache vollständig

b5 b6 b7Falls Remote-Find notwendig

?

Page 95: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

94

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

IViewObjectExImpl<CESMBrowser>

IOleControlImpl<CESMBrowser>

CComControl<CESMBrowser>

IDataObjectImpl<CESMBrowser>

IPersistStorageImpl<CESMBrowser>

CComObjectRootEx<CComSingleThreadModel>

CStockPropImpl<CESMBrowser,IESMBrowser,&IID_IESMBrowser,&LIBID_ESM_COMLib>

IPersistStreamInitImpl<CESMBrowser>IOleObjectImpl<CESMBrowser>

IOleInPlaceActiveObjectImpl<CESMBrowser>

IOleInPlaceObjectWindowlessImpl<CESMBrowser>

ISupportErrorInfo(from COM SDK Base Classes)

IConnectionPointContainerImpl<CESMBrowser>

ISpecifyPropertyPagesImpl<CESMBrowser>

IQuickActivateImpl<CESMBrowser>

IProvideClassInfo2Impl<&CLSID_ESMBrowser,&DIID__IESMBrowserEvents,&LIBID_ESM_COMLib>

IPropertyNotifySinkCP<CESMBrowser>

CComCoClass<CESMBrowser,&CLSID_ESMBrowser>

CProxy_IESMBrowserEvents<CESMBrowser>

IConnectionPointImpl<T,&DIID__IESMBrowserEvents,CComDynamicUnkArray>

T

CProxy_IESMBrowserEvents

Das enthaltene "sichtbare" List-View

TBaseTWinTraits

CContainedWindow

m_dwMsgMapID : DWORDm_lpszClassName : LPTSTRm_pfnSuperWindowProc : WNDPROCm_pObject : CMessageMap*

CContainedWindow()CContainedWindow()CContainedWindow()Create()DefWindowProc()<<const>> GetCurrentMessage()RegisterWndSuperClass()SubclassWindow()SwitchMessageMap()UnsubclassWindow()<<static>> WindowProc()

(from Windows Support)

CESMBrowserm_maxRowSize : intm_nAppearance : shortm_bEnabled : BOOLm_cacheReadAheadForward : unsigned longm_cacheReadAheadBackward : unsigned longm_ES_CNT[254] : charm_ES_INP[3][254] : charm_ES_WORK[254] : charm_BrokerName[64] : charm_ServerName[64] : charm_UserName[64] : charm_UserPassword[64] : charm_NatLogon : BOOLm_BrokerLibName[64] : charm_textRowUncached[256] : TCHARm_ColumnTitle_Row[256] : TCHARm_ColumnTitle_Content[256] : TCHARm_BkColor : COLORREFm_TextBkColor : COLORREFm_TextColor : COLORREFm_Font : HFONTm_lastFindString[254] : char

CESMBrowser()~CESMBrowser()PreTranslateAccelerator()OnSetFocus()OnCreate()<<stdmethod>> SetObjectRects()<<stdmethod>> InterfaceSupportsErrorInfo()SetColumn_Row()SetColumn_Content()HandleRPCError()<<stdmethod>> get_ReadAheadBackwardBlocks()<<stdmethod>> put_ReadAheadBackwardBlocks()<<stdmethod>> get_ReadAheadForwardBlocks()<<stdmethod>> put_ReadAheadForwardBlocks()<<stdmethod>> FindAgain()<<stdmethod>> Find()<<stdmethod>> get_PDA_ESMInput3()<<stdmethod>> put_PDA_ESMInput3()<<stdmethod>> get_PDA_ESMInput2()<<stdmethod>> put_PDA_ESMInput2()<<stdmethod>> get_PDA_ESMWork()<<stdmethod>> put_PDA_ESMWork()<<stdmethod>> get_PDA_ESMInput1()<<stdmethod>> put_PDA_ESMInput1()<<stdmethod>> get_PDA_ESMControl()<<stdmethod>> put_PDA_ESMControl()<<stdmethod>> get_BkColor()<<stdmethod>> put_BkColor()<<stdmethod>> get_CurrentRow()<<stdmethod>> put_CurrentRow()<<stdmethod>> get_RowCount()<<stdmethod>> get_Text_UncachedRow()<<stdmethod>> put_Text_UncachedRow()<<stdmethod>> get_ColumnTitle_Row()<<stdmethod>> put_ColumnTitle_Row()<<stdmethod>> get_ColumnTitle_Content()<<stdmethod>> put_ColumnTitle_Content()<<stdmethod>> get_NaturalLogon()<<stdmethod>> put_NaturalLogon()<<stdmethod>> get_UserPassword()<<stdmethod>> put_UserPassword()<<stdmethod>> get_UserName()<<stdmethod>> put_UserName()<<stdmethod>> get_ServerName()<<stdmethod>> put_ServerName()<<stdmethod>> get_BrokerName()<<stdmethod>> put_BrokerName()<<stdmethod>> get_BrokerLibraryName()<<stdmethod>> put_BrokerLibraryName()<<stdmethod>> StartBrowsing()OnGetDispinfo()OnUserMessage()calcColSize()OnEraseBkgnd()OnPaint()

<<atlobject>>

+m_ctlSysListView32

ESMBrowser(from ESM_COM.i......

<<coclass>>

<<Implements>>

Die COM-Schnittstellenach außen

_IESMBrowserEvents(from ESM_COM.i...

<<source, default>>

IESMBrowser(from ESM_COM.i...

<<default>>

File: (untitled) 21:33:56 Samstag, 13. April 2002 Class Diagram: ESM_COM / ESM_COM Model Update Overview Page 1

Die Komponente im ATL/COM-UmfeldDas folgende UML-Klassendiagramm zeigt das Umfeld der Komponente. Zentrale C++-Klasse der Implementierung des Interfaces ist „CESMBrowser“. Sie implementiert den Zugang zur Gesamt-Komponente, deren vollständige Implementierug aus weiteren C++-Klassen besteht. So sind die Implementierungen für alle Interface-Methoden und die Get-/Put-Methoden für Properties in ihr als Methoden (Stereotyp: <<stdmethod>>) enthalten. Daneben enthält sie ein „Contained Window“ (m_ctlSysListView32). Dieses kapselt das sichtbare Windows ListView-Control. Außerdem enthält „CESMBrowser“ alle notwendigen Handler-Methoden für Windows-Events und -Notifications, die von dem ListView-Control (LVN_GETDISPINFO, WM_CREATE, WM_SETFOCUS, WM_PAINT, WM_ERASEBKGND) sowie vom Worker-Thread (WM_USER) ausgehen. Sie enthält außerdem Member-Variablen für alle Attribute des Interfaces.Die Vererbung von allen Parent-Klassen in folgendem Diagramm wurden vom ATL-AppWizard des Visual Studio automatisch vorgenommen.

Page 96: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

95

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Die Anzahl der Klassen, deren wahre Funktion mir selbst nur teilweise klar ist und auf die ich auch nicht mehr eingehen will, zeigt die Komplexität, die tatsächlich hinter COM steht, und die ich in Kapitel 4 nur teilweise aufzeigen konnte. Die Deklaration des Klassentypus von CESMBrowser im Quellcode sieht dementsprechend lang aus:

class ATL_NO_VTABLE CESMBrowser : public CComObjectRootEx<CComSingleThreadModel>, public CStockPropImpl<CESMBrowser, IESMBrowser, &IID_IESMBrowser, &LIBID_ESM_COMLib>, public CComControl<CESMBrowser>, public IPersistStreamInitImpl<CESMBrowser>, public IOleControlImpl<CESMBrowser>, public IOleObjectImpl<CESMBrowser>, public IOleInPlaceActiveObjectImpl<CESMBrowser>, public IViewObjectExImpl<CESMBrowser>, public IOleInPlaceObjectWindowlessImpl<CESMBrowser>, public ISupportErrorInfo, public IConnectionPointContainerImpl<CESMBrowser>, public IPersistStorageImpl<CESMBrowser>, public ISpecifyPropertyPagesImpl<CESMBrowser>, public IQuickActivateImpl<CESMBrowser>, public IDataObjectImpl<CESMBrowser>, public IProvideClassInfo2Impl<&CLSID_ESMBrowser, &DIID__IESMBrowserEvents, &LIBID_ESM_COMLib>, public IPropertyNotifySinkCP<CESMBrowser>, public CComCoClass<CESMBrowser, &CLSID_ESMBrowser>, public CProxy_IESMBrowserEvents< CESMBrowser >{ ... /* Deklarationen und Definitionen von Methoden und Attributen ...}

Die Parent-Klassen sind allesamt ATL Template-Klassen, die interne COM-Interfaces oder COM-Funktionalität kapseln. Interessant ist der Macro ATL_NO_VTABLE, der zu„__declspec(novtable)“ expandiert wird. Dies wiederum weißt den Compiler an, für diese Klasse keinen Code zur Initialisierung der VTable (siehe 5.2.5) im Konstruktor zu erzeugen. Dies wird nämlich schon von der Parent-Klasse CComControl<CESMBrowser> übernommen. [msdnlib]

COM-InterfacesDas COM-Interface ist für ein ActiveX Control die Tür zur Welt. Beziehungsweise umgekehrt, für die Welt – im vorliegenden Fall das ansonsten in Natural geschriebene Framework – ist das COM-Interface das einzige Tor zur Funktionalität der ActiveX-Komponente. Dieses Interface muss also alle nötigen Methoden vorsehen, um die Properties (Eigenschaften) der Komponente setzen und Abfragen zu können, und um die Funktionalität aufrufen zu können.

Das folgende Klassendiagramm zeigt die Interface-Implementierung, ich will die Bedeutung der einzelnen Properties und Methoden hier noch erläutern. Die im Diagramm durch <<propput>> und <<propget>> gekennzeichneten Methoden zum Setzen und Abfragen der Properties werde ich allerdings dabei implizit erwähnen, indem ich die Properties mit [in] und [out] bezeichne. [in] bedeutet, dass der Wert gesetzt werden kann, [out], dass er abgefragt werden kann, [in, out] folglich sowohl als auch.

Page 97: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

96

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

_IESMBrowserEvents

FindFinished(found : BOOL) : void(from ESM_COM.idl)

<<interface>>

ESMBrowser(from ESM_COM.idl)

<<coclass>>

<<source, default>>

IESMBrowser

<<propput>> Enabled(vbool : VARIANT_BOOL) : HRESULT<<propget>> Enabled(pbool : VARIANT_BOOL*) : HRESULT<<propput>> Appearance(appearance : short) : HRESULT<<propget>> Appearance(pappearance : short*) : HRESULTStartBrowsing() : HRESULT<<propget>> BrokerLibraryName(pVal : BSTR*) : HRESULT<<propput>> BrokerLibraryName(newVal : BSTR) : HRESULT<<propget>> BrokerName(pVal : BSTR*) : HRESULT<<propput>> BrokerName(newVal : BSTR) : HRESULT<<propget>> ServerName(pVal : BSTR*) : HRESULT<<propput>> ServerName(newVal : BSTR) : HRESULT<<propget>> UserName(pVal : BSTR*) : HRESULT<<propput>> UserName(newVal : BSTR) : HRESULT<<propget>> UserPassword(pVal : BSTR*) : HRESULT<<propput>> UserPassword(newVal : BSTR) : HRESULT<<propget>> NaturalLogon(pVal : VARIANT_BOOL*) : HRESULT<<propput>> NaturalLogon(newVal : VARIANT_BOOL) : HRESULT<<propget>> ColumnTitle_Content(pVal : BSTR*) : HRESULT<<propput>> ColumnTitle_Content(newVal : BSTR) : HRESULT<<propget>> ColumnTitle_Row(pVal : BSTR*) : HRESULT<<propput>> ColumnTitle_Row(newVal : BSTR) : HRESULT<<propget>> Text_UncachedRow(pVal : BSTR*) : HRESULT<<propput>> Text_UncachedRow(newVal : BSTR) : HRESULT<<propget>> RowCount(pVal : long*) : HRESULT<<propget>> CurrentRow(pVal : long*) : HRESULT<<propput>> CurrentRow(newVal : long) : HRESULT<<propget>> BkColor(pVal : LONG*) : HRESULT<<propput>> BkColor(newVal : LONG) : HRESULT<<propget>> PDA_ESMControl(pVal : BSTR*) : HRESULT<<propput>> PDA_ESMControl(newVal : BSTR) : HRESULT<<propget>> PDA_ESMInput1(pVal : BSTR*) : HRESULT<<propput>> PDA_ESMInput1(newVal : BSTR) : HRESULT<<propget>> PDA_ESMWork(pVal : BSTR*) : HRESULT<<propput>> PDA_ESMWork(newVal : BSTR) : HRESULT<<propget>> PDA_ESMInput2(pVal : BSTR*) : HRESULT<<propput>> PDA_ESMInput2(newVal : BSTR) : HRESULT<<propget>> PDA_ESMInput3(pVal : BSTR*) : HRESULT<<propput>> PDA_ESMInput3(newVal : BSTR) : HRESULTFind(text : BSTR) : HRESULTFindAgain() : HRESULT<<propget>> ReadAheadForwardBlocks(pVal : long*) : HRESULT<<propput>> ReadAheadForwardBlocks(newVal : long) : HRESULT<<propget>> ReadAheadBackwardBlocks(pVal : long*) : HRESULT<<propput>> ReadAheadBackwardBlocks(newVal : long) : HRESULT

(from ESM_COM.idl)

<<interface>>

<<default>>

IDispatch(from COM SDK Base Classes))

File: (untitled) 21:18:55 Samstag, 13. April 2002 Class Diagram: Logical View / ESMBrowse Page 1

_IESMBrowserEvents ist die Schnittstelle für die Events, die das AktiveX Control auslösen kann. Es enthält nur ein Event: FindFinished( BOOL found ), das ausgelöst wird, wenn eine Suche beendet ist. Diesen Vorgang habe ich zuvor schon ausführlich beschrieben.

IESMBrowser ist das eigentliche Interface, das Properties und Methoden des Controls beschreibt und den Zugriff ermöglicht. Es ist von IDispatch abgeleitet. Die Bedeutung von IDispatch ist in Kapitel 5 beschrieben. IESMBrowser ist also ein Interface, das Automation unterstützt. Seine Properties sind:

A) benötigte Eigenschaften zum Aufbau des RPC-Calls[in, out] BSTR BrokerLibraryName: Name der Natural-Library, in das per RPC auzurufende Unterprogramm auf dem Server liegt. Muss wegen speziellen Anforderungen von Natural-Security bei RPC-Calls der selbe Library-Name sein, wie der der Library, in der die Framework-Komponenten auf dem Client liegen.[in, out] BSTR BrokerName: Logischer Name des Brokers, über den der RPC abgewickelt wird [in, out] BSTR ServerName: Name des (logischen) Servers, der den RPC-Call entgegen nimmt

Page 98: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

97

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

[in, out] BSTR UserName: Name des Benutzers (im Framework bekannt)[in, out] BSTR UserPasswort: Passwort des Benutzers[in, out] BOOL NaturalLogon: Flag für ein bestimmtes Verhalten (LogonToLibrary) beim RPC-Call, das mit Natural-Security auf dem Server zusammen hängt. Möchte ich hier nicht näher erläutern

B) Eigenschaften zum Durchreichen von RPC-Parametern aus dem Framework (s. 7.4.1)[in, out] BSTR PDA_ESMControl: Stringdarstellung der Parameter-Struktur ES-CONTROL.[in, out] BSTR PDA_ESMInput1...3: Stringdarstellung der Parameter-Struktur ES-INPUT. Wie in 7.4.1 erklärt, besteht ES-INPUT aus einem String-Array mit 3 Elementen. Da in Natural die Weitergabe von Arrays als COM-Parameter nicht trivial ist, habe ich mich für Aufteilung in drei String-Properties an der COM-Schnittstelle entschieden, die intern wieder als Array mit drei Elementen behandelt werden. [in, out] BSTR PDA_ESMWork: Stringdarstellung der ES-Work Struktur. Siehe 7.4.1

C) Eigenschaften für das Erscheinungsbild[in, out] BOOL Enabnled: Ist das Control aktiviert ? (Standard-Property für alle Controls)[in, out] short Apperance: FLAT oder 3D-Optik[in, out] long BkColor: Hintergrundfarbe des List-View-Controls[in, out] BSTR ColumnTitke_Row: Dieser Text wird als Überschrift der ersten Spalte (Zeilennummer) angezeigt[in, out] BSTR ColumnTitle_Content: Dieser Text wird als Überschrift der Zweiten Spalte (Zeileninhalt) angezeigt[in, out] BSTR Text_UncachedRow: Dieser String wird angezeigt, wenn der Inhalt einer Zeile, die auf dem Bildschirm zu sehen ist, noch nicht im Cache liegt

D) Eigenschaften, die Verhalten oder Status des Controls beinflussen[out] long RowCount: Anzahl der Zeilen, die das Textobjekt enthält[in, out] long CurrentRow: Aktuelle Zeile (Zeile auf der der Cursor steht)[in, out] long ReadAheadForwardBlocks: Anzahl der Blöcke nach dem aktuellen, die im voraus gecacht werden sollen, wenn ein neuer Block angefordert wird (falls sie noch nicht im Cache liegen). Siehe 7.4.2[in, out] long ReadAheadBackwardBlocks: Anzahl der Blöcke vor dem aktuellen, die im voraus gecacht werden sollen, wenn ein neuer Block angefordert wurde

Methoden (siehe auch 7.4.2):StartBrowsing(): Beginne das Browsen (alle Properties der Gruppe (a) und (b) müssen gesetzt sein).Find(BSTR Text ): Volltextsuche nach „Text“ innerhalb des Datenobjekts ab der Zeile nach der aktuellen.FindAgain(): Letzten Text noch einmal suchen (ab der Zeile nach der aktuellen).

Implementierung der InterfacesWie schon geschrieben ist CESMBrowser die zentrale C++-Klasse der Implementierung sie wird allerdings von weiteren Klassen unterstützt, die Teilfunktionalität kapseln (z.B. CBlockCache (der Cache mit einigen Methoden), CCacheBlock - ein einzelner gecachter Block (100 Zeilen des Datenobjekts), CRingpuffer (siehe 7.4.2), CErxWrapper (kapselt die RPC-SDK Funktionen und Methoden), CESM_RPC (davon abgeleitet, enthält spezielle Implementierung für den RPC-Call gegen das Server-Unterprogramm ESBROW-N, unter anderem den RPC-Stub und drei Pseudo-Stubs für die Unterfunktionen des RPC-Calls).Der Zusammenhang zwischen diesen Klassen geht aus dem foglenden UML-Klassendiagramm hervor. Leider sind die SDK-spezifischen Klassenattribute nicht im Diagramm enthalten.

Page 99: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

98

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

TBas

eTW

inTr

aits

CC

onta

ined

Win

dow

(from

Win

dow

s Su

ppor

t)

CES

MBr

owse

rm

_max

Row

Size

: in

tm

_nAp

pear

ance

: sh

ort

m_b

Enab

led

: BO

OL

m_c

ache

Rea

dAhe

adFo

rwar

d : u

nsig

ned

long

m_c

ache

Rea

dAhe

adBa

ckw

ard

: uns

igne

d lo

ngm

_ES_

CN

T[25

4] :

char

m_E

S_IN

P[3]

[254

] : c

har

m_E

S_W

OR

K[25

4] :

char

m_B

roke

rNam

e[64

] : c

har

m_S

erve

rNam

e[64

] : c

har

m_U

serN

ame[

64] :

cha

rm

_Use

rPas

swor

d[64

] : c

har

m_N

atLo

gon

: BO

OL

m_B

roke

rLib

Nam

e[64

] : c

har

m_t

extR

owU

ncac

hed[

256]

: TC

HAR

m_C

olum

nTitl

e_R

ow[2

56] :

TC

HAR

m_C

olum

nTitl

e_C

onte

nt[2

56] :

TC

HAR

m_B

kCol

or :

CO

LOR

REF

m_T

extB

kCol

or :

CO

LOR

REF

m_T

extC

olor

: C

OLO

RR

EFm

_Fon

t : H

FON

Tm

_las

tFin

dStri

ng[2

54] :

cha

r

CES

MBr

owse

r()~C

ESM

Brow

ser()

PreT

rans

late

Acce

lera

tor(p

Msg

: LP

MSG

, hR

et :

HR

ESU

LT&)

: BO

OL

OnS

etFo

cus(

uMsg

: U

INT,

wPa

ram

: W

PAR

AM, l

Para

m :

LPAR

AM, b

Han

dled

: BO

OL&

) : L

RES

ULT

OnC

reat

e( :

UIN

T, :

WPA

RAM

, : L

PAR

AM,

: BO

OL&

) : L

RES

ULT

<<st

dmet

hod>

> Se

tObj

ectR

ects

(prc

Pos

: LPC

REC

T, p

rcC

lip :

LPC

REC

T) :

HR

ESU

LT<<

stdm

etho

d>>

Inte

rface

Supp

orts

Erro

rInfo

(riid

: R

EFIID

) : H

RES

ULT

SetC

olum

n_R

ow(ti

tle :

LPTS

TR, w

idth

: in

t = -1

) : L

RES

ULT

SetC

olum

n_C

onte

nt(ti

tle :

LPTS

TR, w

idth

: in

t = -1

) : L

RES

ULT

Han

dleR

PCEr

ror(p

RPC

: C

ESM

_RPC

*) :

void

<<st

dmet

hod>

> ge

t_R

eadA

head

Back

war

dBlo

cks(

pVal

: lo

ng*)

: H

RES

ULT

<<st

dmet

hod>

> pu

t_R

eadA

head

Back

war

dBlo

cks(

new

Val :

long

) : H

RES

ULT

<<st

dmet

hod>

> ge

t_R

eadA

head

Forw

ardB

lock

s(pV

al :

long

*) :

HR

ESU

LT<<

stdm

etho

d>>

put_

Rea

dAhe

adFo

rwar

dBlo

cks(

new

Val :

long

) : H

RES

ULT

<<st

dmet

hod>

> Fi

ndAg

ain(

) : H

RES

ULT

<<st

dmet

hod>

> Fi

nd(te

xt :

BSTR

) : H

RES

ULT

<<st

dmet

hod>

> ge

t_PD

A_ES

MIn

put3

(pVa

l : B

STR

*) :

HR

ESU

LT<<

stdm

etho

d>>

put_

PDA_

ESM

Inpu

t3(n

ewVa

l : B

STR

) : H

RES

ULT

<<st

dmet

hod>

> ge

t_PD

A_ES

MIn

put2

(pVa

l : B

STR

*) :

HR

ESU

LT<<

stdm

etho

d>>

put_

PDA_

ESM

Inpu

t2(n

ewVa

l : B

STR

) : H

RES

ULT

<<st

dmet

hod>

> ge

t_PD

A_ES

MW

ork(

pVal

: BS

TR*)

: H

RES

ULT

<<st

dmet

hod>

> pu

t_PD

A_ES

MW

ork(

new

Val :

BST

R) :

HR

ESU

LT<<

stdm

etho

d>>

get_

PDA_

ESM

Inpu

t1(p

Val :

BST

R*)

: H

RES

ULT

<<st

dmet

hod>

> pu

t_PD

A_ES

MIn

put1

(new

Val :

BST

R) :

HR

ESU

LT<<

stdm

etho

d>>

get_

PDA_

ESM

Con

trol(p

Val :

BST

R*)

: H

RES

ULT

<<st

dmet

hod>

> pu

t_PD

A_ES

MC

ontro

l(new

Val :

BST

R) :

HR

ESU

LT<<

stdm

etho

d>>

get_

BkC

olor

(pVa

l : L

ON

G*)

: H

RES

ULT

<<st

dmet

hod>

> pu

t_Bk

Col

or(n

ewVa

l : L

ON

G) :

HR

ESU

LT<<

stdm

etho

d>>

get_

Cur

rent

Row

(pVa

l : lo

ng*)

: H

RES

ULT

<<st

dmet

hod>

> pu

t_C

urre

ntR

ow(n

ewVa

l : lo

ng) :

HR

ESU

LT<<

stdm

etho

d>>

get_

Row

Cou

nt(p

Val :

long

*) :

HR

ESU

LT<<

stdm

etho

d>>

get_

Text

_Unc

ache

dRow

(pVa

l : B

STR

*) :

HR

ESU

LT<<

stdm

etho

d>>

put_

Text

_Unc

ache

dRow

(new

Val :

BST

R) :

HR

ESU

LT<<

stdm

etho

d>>

get_

Col

umnT

itle_

Row

(pVa

l : B

STR

*) :

HR

ESU

LT<<

stdm

etho

d>>

put_

Col

umnT

itle_

Row

(new

Val :

BST

R) :

HR

ESU

LT<<

stdm

etho

d>>

get_

Col

umnT

itle_

Con

tent

(pVa

l : B

STR

*) :

HR

ESU

LT<<

stdm

etho

d>>

put_

Col

umnT

itle_

Con

tent

(new

Val :

BST

R) :

HR

ESU

LT<<

stdm

etho

d>>

get_

Nat

ural

Logo

n(pV

al :

VAR

IAN

T_BO

OL*

) : H

RES

ULT

<<st

dmet

hod>

> pu

t_N

atur

alLo

gon(

new

Val :

VAR

IAN

T_BO

OL)

: H

RES

ULT

<<st

dmet

hod>

> ge

t_U

serP

assw

ord(

pVal

: BS

TR*)

: H

RES

ULT

<<st

dmet

hod>

> pu

t_U

serP

assw

ord(

new

Val :

BST

R) :

HR

ESU

LT<<

stdm

etho

d>>

get_

Use

rNam

e(pV

al :

BSTR

*) :

HR

ESU

LT<<

stdm

etho

d>>

put_

Use

rNam

e(ne

wVa

l : B

STR

) : H

RES

ULT

<<st

dmet

hod>

> ge

t_Se

rver

Nam

e(pV

al :

BSTR

*) :

HR

ESU

LT<<

stdm

etho

d>>

put_

Serv

erN

ame(

new

Val :

BST

R) :

HR

ESU

LT<<

stdm

etho

d>>

get_

Brok

erN

ame(

pVal

: BS

TR*)

: H

RES

ULT

<<st

dmet

hod>

> pu

t_Br

oker

Nam

e(ne

wVa

l : B

STR

) : H

RES

ULT

<<st

dmet

hod>

> ge

t_Br

oker

Libr

aryN

ame(

pVal

: BS

TR*)

: H

RES

ULT

<<st

dmet

hod>

> pu

t_Br

oker

Libr

aryN

ame(

new

Val :

BST

R) :

HR

ESU

LT<<

stdm

etho

d>>

Star

tBro

wsi

ng()

: HR

ESU

LTO

nGet

Dis

pinf

o(ID

: U

INT,

pN

MH

DR

: N

MH

DR

*, lP

aram

: LP

ARAM

) : L

RES

ULT

OnU

serM

essa

ge(u

Msg

: U

INT,

wPa

ram

: W

PAR

AM, l

Para

m :

LPAR

AM, b

Han

dled

: BO

OL&

) : L

RES

ULT

calc

Col

Size

(key

: in

t) : v

oid

OnE

rase

Bkgn

d(uM

sg :

UIN

T, w

Para

m :

WPA

RAM

, lPa

ram

: LP

ARAM

, bH

andl

ed :

BOO

L&) :

LR

ESU

LTO

nPai

nt(u

Msg

: U

INT,

wPa

ram

: W

PAR

AM, l

Para

m :

LPAR

AM, b

Han

dled

: BO

OL&

) : L

RES

ULT

<<at

lobj

ect>

>

+m_c

tlSys

List

View

32

CR

ingp

uffe

rbu

ffer :

int*

curre

nt :

int*

size

: un

sign

ed lo

ngsi

zeU

sed

: uns

igne

d lo

ngem

ptyV

alue

: in

thS

ema

: HAN

DLE

CR

ingp

uffe

r(siz

e : c

onst

int,

empt

yVal

ue :

cons

t int

= -1

)<<

virtu

al>>

~C

Rin

gpuf

fer()

Add(

valu

e : c

onst

int)

: voi

dPo

p() :

int

Cle

ar()

: voi

d<<

cons

t>>

IsEm

ptyB

uffe

r() :

bool

<<co

nst>

> G

etSi

zeM

ax()

: uns

igne

d lo

ng<<

cons

t>>

Get

Size

Cur

rent

() : u

nsig

ned

long

goPr

ev()

: voi

dgo

Nex

t() :

void

isIn

Puffe

r(val

ue :

cons

t int

) : b

ool

<<co

nst>

> is

Empt

yCur

rent

() : b

ool

FIN

DST

RU

CT

exec

uteF

lag

: boo

lpS

tring

: ch

ar*

resu

lt : B

OO

Lro

w :

int

star

tRow

: in

tse

arch

Back

war

d : B

OO

Lse

arch

Cas

eSen

sitiv

e : B

OO

L

(from

CBl

ockC

ac...

<<st

ruct

>>

CES

M_R

PC

Rea

dBlo

ck(b

lock

: C

Cac

heBl

ock&

, key

: in

t, es

cnt[]

: ch

ar, e

sinp

[][25

4] :

char

, esw

ork[

] : c

har)

: BO

OL

Get

Line

Cou

nt(ro

ws

: lon

g&, e

scnt

[] : c

har,

esin

p[][2

54] :

cha

r, es

wor

k[] :

cha

r) : B

OO

LFi

ndLi

ne(L

ineF

ound

: in

t&, S

earc

hStri

ng[]

: cha

r, es

cnt[]

: ch

ar, e

sinp

[][25

4] :

char

, esw

ork[

] : c

har,

Begi

nFro

m :

long

= 0

, For

war

d : B

OO

L =

TRU

E) :

BOO

LC

ESM

_RPC

()<<

virtu

al>>

~C

ESM

_RPC

()ES

BRO

W_c

s(ex

tfunc

: ch

ar*,

lineN

o : l

ong&

, str

: CC

ache

Bloc

k*, r

c : l

ong&

, esc

nt[]

: cha

r, es

inp[

][254

] : c

har,

esw

ork[

] : c

har)

: BO

OL

CBl

ockC

ache

m_R

eadA

head

Bloc

ks :

unsi

gned

long

m_R

eadA

head

Bloc

ks_B

W :

unsi

gned

long

m_K

eyM

ax :

int

m_R

owM

ax :

int

m_h

Thre

ad :

HAN

DLE

m_c

rit :

CR

ITIC

AL_S

ECTI

ON

m_t

hrea

dRun

ning

: bo

olm

_ES_

CN

T : c

har*

(*m

_pES

_IN

P)[3

][254

] : c

har

m_E

S_W

OR

K : c

har*

m_h

Wnd

_Lis

tVie

w :

HW

ND

CBl

ockC

ache

()<<

virtu

al>>

~C

Bloc

kCac

he()

Trig

gerC

achi

ng(k

ey :

int)

: voi

dC

lear

Cac

he()

: voi

d<<

stat

ic>>

read

Bloc

ksAs

InLi

st(p

: vo

id*)

: D

WO

RD

read

Bloc

k(ke

y : i

nt) :

boo

lFi

ndLo

cal()

: BO

OL

Find

(find

Row

: in

t&, f

indS

tr[] :

cha

r, st

artR

ow :

cons

t int

) : B

OO

LIn

itThr

ead(

) : B

OO

LIn

it() :

BO

OL

SetP

aren

tCon

trol(h

Wnd

: H

WN

D) :

voi

dSe

tRea

dAhe

adBl

ocks

(ra :

unsi

gned

long

, rab

: un

sign

ed lo

ng) :

voi

dSe

tKey

Max

(key

Max

: in

t) : v

oid

#m_C

ache

#pR

DKe

yBuf

fer

#pR

AKey

Buffe

r

#m_F

ind

#m_R

PCO

bjec

t

map

<int

,CC

ache

Bloc

k,le

ss<i

nt>

>

CEr

xWra

pper

IsC

onve

rsat

ion(

) : B

OO

LC

lose

Con

vers

atio

n() :

voi

dSt

artC

onve

rsat

ion(

) : B

OO

LG

etLa

stEr

ror(e

rrorC

ode

: lon

g&, e

rrorC

lass

: lo

ng&,

erro

rNum

ber :

long

&, e

rrorM

sg[2

56] :

cha

r) : v

oid

CEr

xWra

pper

()<<

virtu

al>>

~C

ErxW

rapp

er()

Rep

ortE

rror()

: vo

idSe

tCon

nect

ionV

alue

s(st

rBro

ker :

con

st c

har*

, strS

erve

r : c

onst

cha

r*, s

trUse

r : c

onst

cha

r*, s

trPW

: co

nst c

har*

, bN

atLo

gon

: BO

OL,

strB

roke

rLib

Nam

e : c

onst

cha

r*) :

BO

OL

Reg

iste

rToE

ntire

X() :

BO

OL

Logo

nToB

roke

r() :

BOO

LLo

goffF

rom

Brok

er()

: BO

OL

Unr

egis

terF

rom

Entir

eX()

: BO

OL

Test

Serv

erC

onne

ctio

n(M

essa

geBu

ffer :

cha

r* =

NU

LL, B

uffe

rSiz

e : u

nsig

ned

long

= 0

) : B

OO

L

CC

ache

Bloc

km

_id

: int

m_p

Dat

a : T

CH

AR*

m_i

Line

Offs

et[B

LOC

K+1]

: un

sign

ed in

t

CC

ache

Bloc

k(or

ig :

cons

t CC

ache

Bloc

k&)

CC

ache

Bloc

k(si

ngle

Line

: LP

CTS

TR)

CC

ache

Bloc

k()

<<vi

rtual

>> ~

CC

ache

Bloc

k()

SetN

atur

alD

ata(

bloc

kNat

Str[]

[NAT

STR

ING

SIZE

] : u

nsig

ned

char

) : v

oid

Get

Line

(line

: un

sign

ed in

t) : T

CH

AR*

oper

ator

[](lin

e : u

nsig

ned

int)

: TC

HAR

*Is

Empt

y() :

BO

OL

getN

atSt

rLen

(nat

Str :

uns

igne

d ch

ar*)

: un

sign

ed in

t

File

: (un

title

d)

21:

16:3

2 Sa

mst

ag, 1

3. A

pril

2002

C

lass

Dia

gram

: ESM

_CO

M /

New

Dia

gram

Pag

e 1

Page 100: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

99

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Erläuterungen zur ImplementierungNun werde ich versuchen, die Funktion und Implementierung einiger Klassen genauer zu erläutern.

Fangen wir bei CErxWrapper an. Sie kapselt wie schon gesagt die Funktionalität der RPC-SDK in eine Klasse, so dass mit ihr die komplizierten ERX_*-Datenstrukturen durch eine handlichere Methode „SetConnectionValues(...)“ gefüllt werden. Sie enthält als Attribute die Strukturen zur Identifikation des Clients, die Server-Adresse und die Kennung einer eventuellen Conversation. Weitere Methoden kapseln die in 7.2.1 beschriebenen API-Funktionen der SDK. so dass beispielweise bei einem Logon() keine Parameter mehr übergeben werden müssen, denn die erforderlichen Parameter sind der Klasse bekannt. Das entlastet den restlichen Programmcode von spezifischen Internas der RPC-SDK.

Davon abgeleitet gibt es eine Klasse CESM_RPC. Sie stellt die RPC-Verbindung zum hier verwendeten Server dar; dazu implementiert sie in einer Methode ESBROW_cs den Client Stub für den RPC-Call gegen ESBROW-N. Diesen werde ich in 7.4.4 noch genauer erläutern. Er ist (unüblicherweise) größtenteils von Hand implementiert und basiert nur auf einem Prototypen, der mit dem IDL-Compiler der EntireX Workbench erstellt wurde. Der Grund liegt in den Redefinitionen der RPC-Parameter, die ich schon in Kapitel 7.4.1 erläutert habe. Der Client-Stub, der vom IDL-Compiler erzeugt wurde, enthielt eine Menge Overhead, der den Code nahezu unlesbar machte und daneben C-Strukturen zur Auflösung aller drei PDAs erzeugte, die als Parameter benutzt werden. Da diese aber nur vom Framework kommend durchgereicht werden und das ActiveX Control tatsächlich nur drei Variablen der ersten PDA selbst nutzt (insgesamt enthalten die PDAs 53 Variablen), erschien mir diese Lösung praktikabler. CESM_RPC enthält außerdem noch drei Methoden, die ich als Pseudo-Stubs bezeichnen möchte. Sie stellen die drei Unterfunktionen dar, die über den einen RPC-Call ausgeführt werden und bereiten die Control-Internen Parameter je nach Verwendungszweck vor und rufen dann den echten Stub auf, der im Code nie direkt genutzt wird, sondern nur über die drei Pseudo-Stubs.

Die Funktion der Klasse CRingpuffer habe ich schon kurz erläutert, es handelt sich hierbei um einen Ringpuffer für Integer-Werte, der intern durch ein Array, einen Positionszeiger auf dieses Array und eine Angabe zur Anzahl der enthaltenen Werte implementiert wurde. Wichtig sind die beiden Methoden void Add(const int value), mit der ein neuer Wert in den Puffer geschrieben wird und int Pop(), mit der der zuletzt eingefügte Wert ausgelesen und entfernt wird. Damit verhält sich der Ringpuffer wie ein Stack. Genauer gesagt, wie ein „unten offener“ Stack, wenn der Ringpuffer voll ist wird bei neuerlichem Einfügen kein Fehler ausgelöst, sondern der älteste darin enthaltene Wert überschrieben. Add() und Pop() sind durch ein Semaphore synchronisiert, da er zum Datenaustausch zwischen zwei Threads dient, anderenfalls käme es möglicherweise zu Inkonsistenzen im Ringpuffer.

Page 101: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

100

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Die Klasse CCacheBlock stellt einen Datenblock (100 Datenzeilen) dar, die über RPC gelesen wurden. Dieser Speicher ist darauf ausgelegt, möglichst platzsparend zu sein. Ein Block könnte theoretisch 100*254 Zeichen (253 Zeichen je Zeile + Terminierung) ≈ 25 kByte Speicherplatz belegen, wenn die Komponente in der Unicode-Variante kompilert ist sogar das Doppelte. Der Block ist nun darauf ausgelegt, dass er mit einem via RPC geladenen Array von 100 Strings a 253 Zeichen (nicht nullterminiert, da Festlängen-String nach Natural-Konventionen) versorgt wird und die nicht benutzten Füllzeichen (Leerzeichen) entfernt. Der Block wird in ein eindimensionales Array von Zeichen gespeichert, in der die Zeilen einfach aneinander gereit werden. Daneben wird eine Liste mit 100 Offset-Positionen erzeugt, die den Beginn einer jeden Zeile in diesem Array markiert. Dies alles wird von der Methode SetNaturalData() geleistet. Mit der Methode GetLine(int line) oder dem überladenen []-Operator (gleiche Funktion) kann nun eine Zeile als nullterminierter String gelesen werden. Diese Lösung vereint Performance mit einem möglichst geringen Speicheraufwand. Der tatsächliche Overhead zur Nutzdatenmenge beträgt 412 Byte für die 101 Offset-Positionen (jeweils 4-Byte Integer, 101.Offset-Position bezeichnet Ende der letzten Zeile) und die Zeiger auf die beiden Arrays.

Die einzelnen CacheBlocks werden von der Klasse CBlockCache verwaltet. Diese ist abgeleitet von der STL-Template „map“ und zwar als Map eines Integers „key“ auf eine CCacheBlock-Objekt. Die STL-Templates sind auf Performance und konsequente Speichernutzung ausgelegt. Damit können die Blöcke direkt über ihre Blocknummer (key) referenziert werden. Die (einfache) Berechnung der Blocknummer und des Offsets innerhalb eines Blocks aus der Zeilennummer habe ich schon in 7.4.2 erklärt.CBlockCache implementiert aber mehr als nur den physikalischen Speicher für die Blöcke. Der Cache ist quasi selbst für seine Füllung verantwortlich, daher habe ich in dieser Klasse auch die Funktionalität zum Laden der Blöcke, also den Aufruf der Pseudo-Stubs gekapselt (Methode readBlock). Dadurch ist in dieser Klasse ebenso die Implementierug des Worker-Threads (statische Methode readBlocksAsInList) zu finden. Ebenso werden hier zwei Objekte für die beiden Ringpuffer und das Objekt der Klasse CESM_RPC instanziert. Die Klasse dient weiterhin als Speicher für die durchgereichten RPC-Parameter und enthält die Find-Funktionalität (was nur konsequent war: der Cache kennt sich selbst am besten und „weiß“ wie er sich durchsuchen lassen kann). Im übrigen nimmt der Cache keine Rücksicht auf Speicherrestriktionen. Es gibt keine maximale Kapazität. Er überlässt es dem Betriebssystem, gegebenenfalls (bei vollem Hauptspeicher) Speicherbereiche auszulagern und zerstört nicht etwa selbst „lange nicht benötigte“ Blöcke im Speicher. Natürlich gibt er allerdings bei Zerstörung im Destruktor den belegten Speicherplatz wieder frei.

Damit bietet er der zentralen Klasse CESMBrowser, die das COM-Objekt darstellt, alle benötigten Dienste an: Ein intelligenter, sich selbstständig im Hintergrund füllender Cache. CESMBrowser braucht nun nichts mehr von einem RPC-Call zu wissen, sondern befragt den Cache nur noch bei Bedarf nach einzelnen Zeilen. Sind diese nicht vorhanden, weißt sie den Cache an, den entsprechenden Block doch bitte zu beschaffen ( CBlockCache::

Page 102: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

101

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

TriggerCaching( key ) ). Wird von außen ein Find, also die Suche nach Daten erwartet, so wird CBlockCache darum gebeten, sich selbst zu durchsuchen, was er auch tut und gegebenenfalls seinerseits den RPC-Server um Hilfe bittet. CESMBrowser muss sich also nur noch um die Schnittstelle nach außen und um die Darstellung im List-View kümmern. Damit werde ich auch bei der Betrachtung der Implementierung anfangen.

7.4.4 Codeauszüge

Implementierung der Methoden der COM-SchnittstelleMit dem Visual Studio 6 wird das Grundgerüst für die Schnittstelle und die Schnittstellen-Beschreibung (IDL) automatisch von einem Wizard erstellt, sobald man ein ATL/COM-Projekt erzeugt. Mit Hilfe des Wizards kann man auch weiterhin Methoden und Eigenschaften des Controls erzeugen, er fügt in der IDL einen neuen Eintrag ein und erstellt den Kopf der Methoden oder der Get/Put-Methoden selbstständig. Man muss sie nur noch mit Code füllen. Für Property-Put und Property-Get-Methoden genügen meist wenige Zeilen.Als Beispiel dafür die Get- und Put-Methoden für die Eigenschaft PDA_ESMControl:

STDMETHODIMP CESMBrowser::get_PDA_ESMControl(BSTR *pVal) { CComBSTR bstr(m_ES_CNT); *pVal = bstr.Copy(); return S_OK;}STDMETHODIMP CESMBrowser::put_PDA_ESMControl(BSTR newVal) { USES_CONVERSION; char* tStr = OLE2A( newVal ); int len = min( 254, strlen( tStr )+1 ); strncpy( m_ES_CNT, tStr, len ); return S_OK;}

Sie sorgen für die Konvertierung der intern benutzten char-Pointer zur Stringdarstellung in die Darstellung als OLE/COM-kompatible Strings und umgekehrt und das Kopieren der Daten in die Speichervariablen. Dazu benutzen Sie Konvertierungsmacros , die in atlconv.h deklariert sind. Auf den ersten Blick könnte man übrigens meinen, die Put-Methode würde ein Speicherloch erzeugen, da tStr nicht wieder freigegeben wird. Dem ist aber nicht so, siehe dazu auch [msdnlib: „String Conversion Marcos“].Des weiteren noch der Code einer Methode, nämlich „StartBrowsing“;

STDMETHODIMP CESMBrowser::StartBrowsing() { CESM_RPC* pRPC = &(m_Cache.m_RPCObject); m_Cache.SetReadAheadBlocks( m_cacheReadAheadForward, m_cacheReadAheadBackward ); m_Cache.ClearCache(); ZeroMemory( m_lastFindString, 254 ); if (! pRPC->SetConnectionValues( m_BrokerName, m_ServerName, m_UserName, m_UserPassword, m_NatLogon, m_BrokerLibName ) ) return S_OK;

m_Cache.m_ES_CNT = m_ES_CNT; m_Cache.m_pES_INP = &m_ES_INP; m_Cache.m_ES_WORK = m_ES_WORK;

if ( ! m_Cache.Init() ) HandleRPCError(pRPC); return S_OK;}

Page 103: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

102

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

StartBrowsing() setzt die über die COM-Schnittstelle erhaltenen Eigenschaften für die RPC Verbindung und startet mit m_Cache.Init() den Cache, der seinen Worker-Thread initialisert. HandleRPCError() ist eine Methode, die eventuelle Fehlerinformationen als Message-Box ausgibt.

Virtual List-View: Anforderung von AnzeigedatenÜber die Rolle der virtuellen List-View und des Notifiy-Handlers für die LVN_GETDISPINFO habe ich schon geschrieben. Hier die Implementierung:

LRESULT OnGetDispinfo(UINT ID, NMHDR* pNMHDR, LPARAM lParam) { static int maxCharsPerRow = 0, criticalCharsPerRow = 0; LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR; LV_ITEM* pItem= &(pDispInfo)->item; int iItemIndx= pItem->iItem; if (pItem->mask & LVIF_TEXT) { //valid text buffer?

switch (pItem->iSubItem) {

case 0: //fill in main text wsprintf( pItem->pszText, _T(„%d“), iItemIndx+1 ); break;

case 1: //fill in sub item 1 text int key = iItemIndx / BLOCK; int offset = iItemIndx % BLOCK; CBlockCache::iterator it = m_Cache.find( key ); if ( it != m_Cache.end() ) { // block is already in the cache (already read from via RPC) _tcscpy( pItem->pszText, (*it).second[offset] ); } else { // block isn‘t in the cache so far -> trigger caching and show standard-text m_Cache.TriggerCaching( key ); pItem->pszText = m_textRowUncached; } break;

} // end switch } return 0;}

Über den Parameter pNMHDR erhält der Handler einen Zeiger auf LV_DISPINFO-Struktur, die Informationen über den angeforderten Wert enthält, unter anderem einen Pointer auf LV_ITEM, das das geforderte Item beschreibt. pItem->iSubItem bezeichnet die Spalte, pItem->iItem die Zeile. Für die erste Spalte (0) wird nur die Zeilennummer als String in pszText abgelegt (dort erwartet das List-Control den angeforderten Anzeige-Text), für die zweite Spalte den Zeileninhalt. In diesem Fall prüft die Methode (mit m_cache.Find()) ob der entsprechende Block schon im Cache (implementiert als STL-Map) liegt, wenn ja, kopiert er den Zeileninhalt nach pszText. Wenn nicht wird dort der Standard-Text für nichtgecachte Zeilen hinkopiert und das Lesen des Blocks (und das entsprechende Read-Ahead) angestossen. TriggerCaching() schreibt dazu unter anderem die angeforderte Key-Nummer in den Ringpuffer und triggert den Worker-Thread (weckt ihn mit ResumeThread() auf), falls er „schlafen gegangen“ ist (SuspendThread()).

Page 104: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

103

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Ringpuffer: SynchronisationDer Ringpuffer muss synchronisiert sein, da der Main- und der Workerthread pseudogleichzeitig darauf zugreifen. Es muss gewährleistet sein, dass nicht gleichzeitig der Main-Thread einen Wert hineinschreibt (Add()) und der Workerthread einen herausnimmt (Pop()), denn man weiß nie, wann der Scheduler des Betriebssystem die Zeitscheiben wechselt.Dies wird mit einem Semaphore erreicht, das im Konstruktor des Ringpuffers erzeugt wird und maximal einen Zugriff zulässt:

CRingpuffer::CRingpuffer( const int size, const int emptyValue ) { this->size = size; this->emptyValue = emptyValue; buffer = new int[size];

Clear();

hSema = CreateSemaphore(NULL, 1, 1, NULL );}

Man sieht in der Methode wie das Array für den Ringpuffer nach gegebener Größe erzeugt wird. emptyValue enthält übrigens einen Integer-Wert, der als „dieses Puffer-Element ist leer“ interpretiert wird. Da der Puffer nur postive Werte und Null als Nutzdaten enthalten muss, ist der Standard hierfür -1. Danach wird dafür gesorgt, dass alle Werte des Puffers leer sind (mit emptyValue belegt). Dann wird das Semaphore erzeugt.

Die Nutzung des Semaphores erfolgt in Add() und Pop(). Ich zeige hier exemplarisch Add():

void CRingpuffer::Add(const int value) { // synchronize access to the buffer DWORD result = WaitForSingleObject( hSema, 2000 ); if (result == WAIT_TIMEOUT || result == WAIT_FAILED) { return; }

// from here on the access is synchronized

if ( ! isInPuffer(value) ) { goNext(); // move „current“-pointer to next Element *current = value; // set element value if (sizeUsed < size) sizeUsed++; // increment size if not already „full“ }

// end of synchronized section ReleaseSemaphore( hSema, 1 , NULL );}

Nachdem der Zugriff durch das Semaphore erlaubt wurde (2 Sekunden Wartezeit sollten in jedem Fall genügen!), wird geprüft, ob sich der Wert schon im Puffer befinden, in diesem Fall wird er nicht mehr eingetragen (ein Block, der schon zum Lesen getriggert wurde, muss nicht erneut getriggert werden!), dann wird der Zeiger auf das aktuelle Element auf das nächste gesetzt, der Wert in den Puffer eingetragen und seine aktuelle Größe (Füllung) inkrementiert (es sei denn, der Puffer war schon voll, denn dann wurde ein Element überschrieben, was die Anzahl der gepufferten Elemente nicht ändert). Danach wird das Semaphore wieder freigegeben.

Page 105: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

104

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Worker Thread: AblaufDie eigentliche Arbeit der Beschaffung notwendiger Daten über RPCs übernimmt der Worker-Thread. Dieser ist als statische Methode des CacheBlocks implementiert und bei seinem ersten Start (von CBlockCache::Init() aus) kümmert er sich um den Aufbau der RPC-Verbindungen: // Erster Teil des Worker-ThreadsDWORD WINAPI CBlockCache::readBlocksAsInList(void *p ) { static bool CONVERSATION = TRUE; CBlockCache* pThis = (CBlockCache*) p; FINDSTRUCT *pFind = &(pThis->m_Find); pThis->m_threadRunning = true; int key; // register this Thread at the EntireX Runtime an LogOn to the broker if ( pThis->m_RPCObject.RegisterToEntireX() ) { if ( ! pThis->m_RPCObject.LogonToBroker() ) { // HandleError(); pThis->m_RPCObject.UnregisterFromEntireX(); ExitThread( 1 ); return 1; } } else { ExitThread( 1 ); return(1); }

Da die Methode statisch ist (dies muss sie sein, um als Thread initialisiert werden zu können), kennt sie die aktuelle Objekt-Instanz des Caches nicht, die sie aber benötigt, weil daran wichtige Daten liegen. Daher bekommt sie einen Pointer auf das aktuelle Objekt der eigenen Klasse als Thread-Parameter (void* p) übergeben, der nach pThis gecastet wird. CONVERSATION ist statisches Flag, das angibt, ob in der Implementierung aufeinanderfolgende RPC-Calls innerhalb einer Conversation laufen sollen.Der Thread registriert sich bei der EntireX RPC-Runtime und führt ein Logon zum Broker durch, falls alles glatt geht.

// Zweiter Teil des Threads (Forsetzung) if ( pThis->InitThread() ) { int priority = 0;

// start a conversation ??? if ( CONVERSATION ) { if ( ! pThis->m_RPCObject.StartConversation() ) ::MessageBox( NULL, _T(„Could not open conversation“), _T(„XXX“), MB_ICONERROR|MB_OK ); }

while (pThis->m_threadRunning) { bool rpcresult; if ( pFind->executeFlag ) { // The user wants to find something ... do this now !!! pFind->result = pThis->m_RPCObject.FindLine( pFind->row, pFind->pString, pThis->m_ES_CNT, *(pThis->m_pES_INP), pThis->m_ES_WORK, pFind->startRow); ::PostMessage( pThis->m_hWnd_ListView, WM_USER, pFind->row>0?2:3, pFind->row); pFind->executeFlag = false; // Find is done now ! } if ( (key = pThis->pRDKeyBuffer->Pop()) != -1 ) priority = 1; // There is something in the high-priority ringbuffer to read else if ( (key = pThis->pRAKeyBuffer->Pop()) != -1 ) priority = 2; // There is something in the low-priority ringbuffer to read else priority = 0; // nothing to read, suspend thread

Page 106: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

105

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

InitThread() prüft, ob der RPC-Server läuft und führt dann einen RPC-Call durch um die Anzahl der Zeilen zu erfragen. Falls dies gut geht (der Server ist erreichbar) wird ggf. eine Conversation gestartet.Die beginnende Schleife ist die Arbeitsschleife des Worker-Threads. m_threadRunning ist eine Variable, die auf FALSE gesetzt wird, um dem Thread von außen zu signalisieren, dass er sich komplett beenden soll. In der Arbeitsschleife wird zunächst geprüft, ob ein Remote-Find durchzuführen ist, wenn ja, wird der Pseudo-Stub CESM_RPC::FindLine() aufgerufen. Informationen zu einem anstehenden Remote-Find sind in der Struktur FINDSTRUCT (pThis->m_Find) hinterlegt. Die WM_USER-Nachricht meldet das Ergebnis eines beendeten Finds an den Main-Thread, der daraufhin Fire_FindFinished aufruft. Die Werte 2 und 3 im wParm der Nachricht stehen dafür für „Suche erfolgreich beendet“ bzw. „Suche erfolglos beendet“ (siehe auch CESMBrowser::OnUserMessage()).Als nächstes prüft der Thread, ob Werte in den beiden Ringpuffern vorliegen, die zu ladende Blocks kennzeichnen. Der Puffer RDKeyBuffer hat dabei die höhere Priorität. Falls keine Werte vorliegen, wird priority auf 0 gesetzt (hat später zur Folge das der Thread in den Ruhezustand geht). // Dritter Teil des Threads (Forsetzung) if (priority) { rpcresult = pThis->readBlock( key ); // dies kostet Zeit if ( ! rpcresult ) { ::MessageBox( NULL, _T(„ERROR IN READ-BLOCK-CALL...“), [...] ); EnterCriticalSection( &(pThis->m_crit) ); if ( CONVERSATION ) { if ( pThis->m_RPCObject.IsConversation() ) pThis->m_RPCObject.CloseConversation(); else ::MessageBox( NULL,_T(„There is no conversation to close...“), [...]); } LeaveCriticalSection( &(pThis->m_crit) ); ::SuspendThread( GetCurrentThread() ); // start a new conversation if triggered again if ( CONVERSATION ) { if ( ! pThis->m_RPCObject.StartConversation() ) ::MessageBox( NULL, _T(„Could not open conversation“), [...]); } } else if ( pThis->m_hWnd_ListView ) { // Calc new column size for new Block ::PostMessage ( pThis->m_hWnd_ListView, WM_USER, 1, (LPARAM)key ); if ( priority==1 ) { // Update Display of newly fetched rows ::PostMessage( pThis->m_hWnd_ListView, LVM_REDRAWITEMS, key*BLOCK, (key+1)*BLOCK-1 ); } } }

Es folgt nun die Abarbeitung der Leseschritte. Wenn pritority != 0, dann wird readBlock(key) ausgeführt, was den Block via RPC anfordert und in den Cache ablegt. In dem Fall, dass dabei ein Fehler aufgetreten ist (rpcresult != 0) wird die Conversation geschlossen, der Thread schlafen gelegt (suspended), bis er erneut getriggert wird. Dies aus dem Grund, weil bei einem Fehlersignal in rpcresult damit zu rechnen ist, dass auch die folgenden Calls Fehler produzieren.Falls kein Fehler auftrat wird ein Breitenanpassung der zweiten List-View-Spalte über WM_USER-Nachricht getriggert und – falls der Block aus dem RDBuffer stammt (priortiy==1) – wird noch eine Aktualisierung der entsprechenden Zeilen durch das ListView angestoßen.

Page 107: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

106

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

// Vierter Teil des Threads (Forsetzung und Ende) if ( (!priority) && (!pFind->executeFlag) ) { EnterCriticalSection( &(pThis->m_crit) ); // currently nothing to do ... end conversation (if any) and suspend // thread until triggered again if ( CONVERSATION ) { if ( pThis->m_RPCObject.IsConversation() ) pThis->m_RPCObject.CloseConversation(); else ::MessageBox( NULL, _T(„There is no conversation to close...“),[...]); } LeaveCriticalSection( &(pThis->m_crit) ); ::SuspendThread( GetCurrentThread() ); // we have been triggered gain - start a new conversation if ( CONVERSATION && pThis->m_threadRunning ) { if ( ! pThis->m_RPCObject.StartConversation() ) ::MessageBox( NULL, _T(„Could not open conversation“), [...] ); } } } // end loop } // Ende von if(m_Cache.Init()) pThis->m_RPCObject.LogoffFromBroker(); pThis->m_RPCObject.UnregisterFromEntireX();

::ExitThread( 0 ); return 0;} // Ende der Methode

Wenn während des letzten Schleifendurchlaufs in den Ringpuffern keine Werte gefunden wurden (priority==0) und auch kein Remote-Find ansteht, dann wird die Conversation wieder beendet und der Thread geht schlafen. Wenn er erneut getriggert wurde, wird eine neue Conversation begonnen, es sei denn, der Thread wurde nur dazu getriggert, dass er sich selbst endgültig beendet (m_threadTunning == FALSE).

Falls m_threadRunning noich auf TRUE steht, dann beginnt die Arbsitsschleife von neuem um eventuelle Remote-Finds oder readBlock()s durchzuführen. Andernfalls wird die Schleife verlassen und die Verbindung zum Broker und der EntireX-Runtime beendet (dabei wird eine eventuell offene Conversation automatisch geschlossen).

Der Thread wird beendet.

Auf die benutzte CriticalSection möchte ich übrignes nicht zu tief eingehen, ihre Aufgabe ist es einen DeadLock, der unter bestimmten seltenen Umständen auftreten könnte zu unterbinden. Eine CriticalSection ist etwas ähnliches wie ein Semaphore, nur weniger flexibel, dafür einfacher zu benutzen.

Page 108: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

107

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Der RPC Client StubKommen wir endlich zum echten RPC-Aufruf. Im Worker-Thread wurde schon die Verbindung zur RPC-Runtime, zum Broker und zum Server aufgebaut, fehlt nur noch der eigentliche RPC-Call mit Parameter-Umwandlung. Dies leistet der Client-Stub, der, wie schon erwähnt, in der Klasse CESM_RPC implementiert wurde und größtenteils von Hand geschrieben wurde. In CBlockCache:readBlock() wird zunächst der Pseudo-Stub für das Lesen der Blöcke aufgerufen, der folgendes Aussehen hat:

BOOL CESM_RPC::ReadBlock(CCacheBlock &block, int key, char escnt[], char esinp[][254], char eswork[]) { long rc = 0; long startrow = key*BLOCK + 1; BOOL res = ESBROW_cs( „ „, startrow, &block, rc, escnt, esinp, eswork ); if ( (!res) || (rc) ) { REPORT_ERROR(); return FALSE; } return TRUE;}

Die Parameter von CESM_RPC::ReadBlock() sind die Refrenz auf einen CacheBlock, der gefüllt werden soll, der Key des zu lesenden Blocks und die Inhalte der drei durchgereichten PDAs.REPORT_ERROR() ist ein Macro, das eventuell aufgetretene Fehler ausgibt. Da das aufgerufene RPC-Server-Unterprogramm sich nicht für die Blocknummer, sondern für die Startzeile interessiert, wird diese noch berechnet (BLOCK ist ein Macro für die Zahl 100).Es erfolgt im Pseudo-Stub der Aufruf des echten Client-Stubs, als erster Parameter wird der Name der Unter-Funktion (drei Spaces, steht für „ReadBlock“, siehe 7.4.„Normalerweise“ wäre es das schon gewesen, denn der Client-Stub wird vom IDL-Compiler der EntireX-Workbench erzeugt, aus schon erläuterten Gründen habe ich den hier benutzten aber von Hand bearbeitet.

Er ist im Folgenden beschrieben:

// Erster Abschnitt des Client Stub// RPC CLient Stub für ESBROW-NBOOL CESM_RPC::ESBROW_cs( char* extfunc, long &lineNo, CCacheBlock* str, long &rc, char escnt[], char esinp[][254], char eswork[] ) { USES_CONVERSION; void ERXPTR *pParmBlock[1]; struct S_ESBROW { unsigned char ESControl[253]; unsigned char ESInput[3][253]; unsigned char ESWork[253]; unsigned char Block[BLOCK][NATSTRINGSIZE]; } parm;

Die Struktur S_ESBROW enthält die Variablen, die die Werte aufnehmen, die als Parameter an den RPC geschickt werden. Dort werden auch die Rückgabewerte gespeichert.Man sieht, dass die Struktur der in 7.4.1 erläuterten entspricht.

Der nächste enhält die Definition der Parameter für die EntireX Runtime, so dass Marshalling und die Konvertierung richtig durchgeführt werden können:

Page 109: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

108

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

// Zweiter Abschnitt des Client Stub (Forsetzung) static ERX_PARAMETER_DEFINITION_V2 ERXPTR PD_ESBROW_N[ 4 ] = { { „ES-CONTROL“, ERX_MAKE_TYPE(ERX_TYPE_A, ERX_INOUT_PARM, 0), ERX_ATTR_NOTHING, 253, sizeof(parm.ESControl), ERX_NO_PARENT_V2, { 0, 0, 0 }, ERX_BasedAt(S_ESBROW, ESControl), { 0, 0, 0 } }, { „ES-INPUT“, ERX_MAKE_TYPE(ERX_TYPE_A, ERX_IN_PARM, 1), ERX_ATTR_NOTHING, 253, sizeof(parm.ESInput), ERX_NO_PARENT_V2, { 3, 0, 0 }, ERX_BasedAt( S_ESBROW, ESInput), { ERX_DeltaOf(S_ESBROW, ESInput[0]), 0, 0 } }, { „ES-WORK“, ERX_MAKE_TYPE(ERX_TYPE_A, ERX_INOUT_PARM, 0), ERX_ATTR_NOTHING, 253, sizeof(parm.ESWork), ERX_NO_PARENT_V2, { 0, 0, 0 }, ERX_BasedAt(S_ESBROW, ESWork), { 0, 0, 0 } }, { „#PARM-AREA“, ERX_MAKE_TYPE(ERX_TYPE_A, ERX_INOUT_PARM, 1), ERX_ATTR_NOTHING, NATSTRINGSIZE, sizeof(parm.Block), ERX_NO_PARENT_V2, { BLOCK, 0, 0 }, ERX_BasedAt( S_ESBROW, Block), { ERX_DeltaOf(S_ESBROW, Block[0]), 0, 0 } }, };

Hier wird ein Array von ERX_PARAMETER-DEFINITIONs erzeugt und gefüllt, für jeden Parameter ein Element. Die Definition enthält jeweils den Namen, Typ, Übertragungsrichtung und Größe des Parameters in Byte, Angaben zur Array-Größe (0 falls kein Array, und die Speicheradresse in der Struktur S_ESBROW, auf die die Parameter-Werte gemappt werden.

// Dritter Abschnitt des Client Stub (Forsetzung) // Informationen über die RPC-Fuktion ERX_CALL_INFORMATION_BLOCK ERXPTR CIB_ESBROW_N[ 1 ] = { { { „IRGENDWO“, „ESBROW-N“, 0 }, 4, PD_ESBROW_N }, };

Hier wird nun der Call und seine Parameter beschrieben: „irgendwo“ ist der Name der Natural-Library in der das Unterprogramm liegt. Der Name dokumentiert eigentlich nur, dass bei den derzeit verwendeten Einstellungen der Natural-Server selbst die Library sucht. Hier könnte irgend ein anderer String stehen. Wichtig ist aber der Name des Unterprogrammes: ESBROW-N. Zum derzeitigen Stadium des Controls ist. Der dritte Wert (Versionsnummer) wird bei der derzeitgen EntireX Version nicht benutzt und muss 0 sein.Danach wird die Anzahl der Parameter und die Parameterdefinition angegeben (das oben definierte Array).

Page 110: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

109

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

// Vierter Abschnitt des Client Stub (Forsetzung) // „PDA“ auf null setzen ZeroMemory( &parm, sizeof(parm) ); pParmBlock[0] = &parm;

// Pointer to ES-EXTEND-FUNCTION inside ES-CONTROL unsigned char* pESControlExtendFunction = parm.ESControl + 8; // Pointer to ES-LINE-NUMBER inside ES-CONTROL unsigned char* pESControlLineNumber = parm.ESControl + 169; // Pointer to ES-RC inside ES-CONTROL unsigned char* pESControlRC = parm.ESControl + 60;

// Werte der Input-Parameter setzen CStringToNString( parm.ESControl, 253, escnt ); for (int i = 0; i < 3; i ++) CStringToNString( parm.ESInput[i], 253, esinp[i] ); CStringToNString( parm.ESWork , 253, eswork );

// Eigentlich nur fürs FIND benötigt if (str && ! str->IsEmpty() ) { // Falls StringBlock existiert und die erste Zeile nicht LEER ist ... for ( int i=0; i<BLOCK; i++) { CStringToNString( parm.Block[i], NATSTRINGSIZE, T2A( str->GetLine(i) ) ); } } // Extended-function eifügen CStringToNString( pESControlExtendFunction, 3, extfunc ); // Zeilennummer eifnügen// DoubleToUnpack( (double)lineNo, pESControlLineNumber , 6, 0 ); char Unpack[11]; sprintf( Unpack, „%010d“, lineNo ); memcpy( pESControlLineNumber, Unpack, 10 );

Im obigen Abschnitt des Stubs werden die Werte der Parameter vorbereitet, indem zunächst in den String für ES-CONTROL an die entsprechenden Stellen die Werte für ES-LINE-NUMBER und die ES-EXTEND-FUNCTION geschrieben werden. Außerdem wird der vierte Parameter (#PARM-AREA) gefüllt, was eigentlich in dieser Form nur für die Find-Unterfunktion benötigt wird. Die Strings werden außerdem von der C-Darstellung (nullterminiert) in die Natural- und EntireX-Darstellung (Festlänge) konvertiert.Alles in allem werden in diesem Abschnitt die Werte der Input-Parameter von der programminternen Darstellung in die EntireX-SDK-konforme Darstellung umgewandelt.

// Fünfter Abschnitt des Client Stub (Forsetzung) // EntireX RPC Call ERXCallId callId; if ( IsConversation() ) m_ERXErrorInfo.rc = ERXCall( NULL, m_pERXConnection, &callId, CIB_ESBROW_N, pParmBlock, ERX_CF_NOTHING|ERX_CF_STRUCTURED ); else m_ERXErrorInfo.rc = ERXCall( &m_ERXClient, &m_ERXServer, &callId, CIB_ESBROW_N, pParmBlock, ERX_CF_NOTHING|ERX_CF_STRUCTURED ); // Error-Handling if( ERX_FAILED(m_ERXErrorInfo.rc) ) { return FALSE; }

Endlich ist es soweit, der eigentliche RPC-Call wird durchgeführt. Der Client-Stub enthält zwei Varianten. Die erste wird benutzt, falls der Call innerhalb einer Conversation ausgeführt wird, der untere, falls nicht. Der Unterschied besteht darin, dass sich bei einer bestehenden Conversation der Client nicht mehr authentifizieren muss, dass hat er ja schon beim öfnnen der Conversation getan. Außerdem muss statt einer Server-Adressierung die Struktur übergeben werden, die die Conversation-ID beinhaltet (m_pERXConnection statt&m_ERXServer). im Falle eines Fehlers beim RPC-Call bricht der Stub hier ab.

Page 111: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

110

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

// Sechster Abschnitt des Client Stub (Forsetzung und Ende) // Werte Der Outout-Parameter setzen NStringToCString( escnt , 254, parm.ESControl, 253 );// NStringToCString( esinp , 254, parm.ESInput , 253 ); NStringToCString( eswork, 254, parm.ESWork , 253 ); // block if (str) str->SetNaturalData( parm.Block );

// Inhalte aus ES_CNT parsen lineNo = (int) UnpackToDouble( pESControlLineNumber, 10, 0 ); rc = (int) UnpackToDouble( pESControlRC, 3, 0 ); // Erfolg melden return TRUE;} // Ende des Client-Stubs

Der sechste Abschnitt ist das Gegenstück zum vierten. Die Output-Parameter werden wieder von der Middleware-Darstellung in die C++-Darstellung konvertiert (String-Terminierung). Außerdem werden die zwei Variablen ES-LINE-NUMBER und rc geparsert, die in ES-CONTROL enthalten sind. Der Inhalt des vierten Parameters #PARM-AREA wird in ein CCacheBlock-Objekt geschrieben (siehe 7.4, Seite 103).Der Client Stub meldet einen Erfolg an den jeweils aufrufenden Pseudo-Stub zurück.

Wie schon erwähnt wird ein ähnlicher, aber allgemeiner gehaltener Stub auch vom IDL-Compiler erzeugt. Dieser hätte aber allein durch die Tiefe der enstehenden Struktur S_ESBROW, die alle redefinierten Variablen abgedeckt hätte, eine solche Größe, dass der Quellcode wesentlich größer werden würde; außerdem würde der IDL-Compiler die Variablen in den Strukturen und Redefinitionen bis auf die unterste Ebene in die Parameter-Definiton einarbeiten.Zum einen ein unnötiger Overhead, zum anderen bot es sich an, hier schon ein wenig Funktionalität hineinzukodieren, wie zum Beispiel das Schreiben der #Pram-Area in den CCacheBlock.

Damit möchte ich die Betrachtung der Programmierung am ActiveX-Control und der Tätigkeit meiner Praxisphase abschließen.

Page 112: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

111

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Zusammenfassungund

Ausblick

Page 113: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

112

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

8. Zusammenfassung und AusblickSo wie dies schon im Mittelteil der vorliegenden Bachelor-Arbeit der Fall war, wird auch das Resumee in einen theoretischeren Teil zu den Middleware-Technologien und einen praktischeren Teil zu meiner Projektarbeit in der Praxisphase unterteilt sein.

a) MiddlewareWenn man theoretische Darstellungen von Middleware-Konzepten liest, dann klingen die dort angeführten Beschreibungen immer wie aus einem Guss. So ist es auch in dieser Arbeit. Die Konzepte scheinen schlüssig und auch in fast allen Bereichen vollständig zu sein. Sieht man ein paar aufreizende Grafiken, die den Datenfluss durch Pfeile zwischen Komponenten darstellen, scheint alles logisch aufgebaut und gut durchdacht zu sein, so dass man direkt damit anfangen kann, strukturierte, verteilte Applikationen zu entwickeln, wenn man sich erst einmal für eines der Middleware-Produkte entschieden hat. Schließlich sind alle Schnittstellen gut definiert und einfach zu benutzen.Wie man vielleicht schon in Kapitel 7 erkennen kann, sieht die Praxis dann etwas anders aus, denn der Teufel steckt im Detail. Meist sind erst einmal hunderte von Zeilen Code notwendig, bis man eine Komponente so weit erzeugt und mit den notwendigen Schnittstellen beschrieben hat, dass sie tatsächlich problemlos in einem Netzwerk kommunizieren können. Nicht selten ist der Code, der die Funktionalität einer Komponente nach außen sichtbar macht, bei weitem umfangreicher als der der eigentlichen Funktionalität.Es verlangt einen immensen Overhead an Programmcode, bis aus einem Stück Code, das eigentlich nur eine kleine Aufgabe erfüllen soll, von anderen Komponenten erkannt und genutzt werden kann. Viele einzelne Dinge sind bei der Implementierung zu beachten, das Konzept, das dahinter steht, muss wirklich gut verstanden sein. Und die Interoperabilität zwischen Plattformen, Programmiersprachen und teilweise auch Entwicklungsumgebungen muss teuer erkauft werden. Unter anderem durch die Nutzung von virtuellen Datentypen, die dann doch in kaum eine Programmiersprache 1:1 übersetzt werden können, sondern durch Konvertierungscode integriert werden müssen.Auch ist die Komplexität einiger Middlewares enorm. Wer zum Beispiel die RPC-SDK von EntireX noch als einfach empfand – und das ist sie im Verhältnis – dem möchte ich noch mitgeben, dass sie fast nur in der Lage ist, als Client eine Kommunikation mit einem Natural-Server zu betreiben. Möchte man z.B. in C++ einen Server implementieren, so ist man schon fast gezwungen, auf die ACI-SDK auszuweichen. Diese hat wesentlich komplexere API-Strukturen; die RPC-SDK-Strukturen decken nur einen kleinen Ausschnitt hiervon ab.Auch die komplizierten Definitionen an der COM-Schnittstelle in Kapitel 7 (Erzeugung einer IDL und Bereitstellung der Interfaces) wurden von der ATL und den Visual Studio-Wizards übernommen. Das Thema Thread-Modelle und Speicherverwaltung in COM habe ich in dieser Arbeit noch nicht einmal erwähnt. Wer den Hauch eines Einblickes in die echte Komplexität haben möchte, der schaue sich doch einmal die automatisch erzeugten Codes eines ATL-COM-Projektes im Visual Studio an. Und die Wizards bieten nur Lösungen für

Page 114: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

113

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

echte Standard-Vorgänge, für kompliziertere Dinge oder „Sonderfälle“ ist man gezwungen von Hand einzugreifen.COM und DCOM beinhalten eine enorme Anzahl von Interfaces, die ein Programmierer kennen muss, um COM- und DCOM-Services zu nutzen, diese wiederum haben eine riesige Anzahl eigener Methoden, die alle sehr low-level sind. Dazu sind viele mit eigenen Datenkonstrukten zu füttern.CORBA ist sogar noch schlimmer in diesem Punkt. Einige Implementierungen haben über 500 Interfaces, nur um auf CORBA-Services zuzugreifen, die Basis-Funktionalität anbieten.Einiges der Komplexität kann durch die Wahl bestimmter Programmiersprachen vermieden werden; so scheint CORBA besonders gut mit Java zu harmonisieren, für die möglichst schnelle und einfache Implementierung von DCOM-Komponenten ist wohl Microsofts Visual Basic erste Wahl und die Integration von EntireX und Natural ist geradezu ein Paradebeispiel. Die entsprechenden Vereinfachungen werden aber auch wieder mit Einschränkungen erkauft. Visual Basic ist relativ langsam, Java in einigen Fällen auch nicht gerade ein Musterbeispiel für Performance und bei Natural geht zwar vieles automatisch, aber einiges ist mit Natural-Mitteln gar nicht oder nur sehr aufwendig zu lösen.Bei EntireX hält sich die Komplexität allgemein noch halbwegs in Grenzen, wird aber im wahrsten Sinne des Wortes teuer erkauft. Zum einen weil der Broker, der als zentraler Kommunikationspartner dient, auch eine große Anforderung an die Hardware stellt, auf der er läuft. Zum anderen weil EntireX nicht gerade billig ist. Es gehört zwar zur Unternehmensphilosophie der Software AG, dass über Preise nicht oder nur selten öffentlich gesprochen wird, aber man kann davon ausgehen, dass es als Lösung nur für große Unternehmen finanzierbar ist. EntireX RPC-Calls sind in der Praxis bei vielen Unternehmen auch verpöhnt: Was vor dem Anwender versteckt bleibt, ist, dass der Broker allein zum Aufbau einer Verbindung einige Calls gegen eine interne Datenbank - üblicherweise Adabas - machen muss, um Daten zu erhalten (z.B. für die Authentifizierung). Bei einer großen Anzahl von angeschlossenen Clients muss der Broker schon fast zwangsweise auf einer entsprechend großen Plattform, einer Mainframelösung laufen. Oftmals haben aber Unternehmen ihre Rechenzentren ausgelagert und zahlen für die Nutzung ihrer Großrechner Gebühren je nach Datenvolumen oder, und das ist weit verbreitet, für einzelne Datenbank-Calls. Wenn man weiß, dass für einen einzigen RPC-Aufruf etwa 8 Adabas-Calls fällig werden, bekommt man vielleicht eine Idee davon, dass sich dies mit der Zeit zu signifikanten Kosten summiert.

Ein weiteres Problem ist die Integration der Middlewares in die Planungsansätze. CORBA-Komponenten lassen sich noch recht einfach mit den üblichen Mitteln für die objektorientierte Analyse modellieren. Dafür ist eben der Notwendige Overhead recht groß.Bei DCOM-Komponenten wird dies schon schwieriger, denn das, was man bei DCOM unter „Objekten“ und „Klassen“ versteht, liegt auf einer anderen Abstraktionsebene. Es sind dies die fertigen „Programmpaketchen“, nicht die Objekte und Klassen in einer Ausgangs-Sprache. Das Mapping zwischen diesen beiden Ebenen ist manchmal kompliziert. Man kann zwar durchaus jedes Objekt der Analyse als COM-Objekt implementieren, dann tritt aber

Page 115: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

114

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

auch wieder ein Overhead auf, der sowohl zur Implementierungs- als auch meist zur Laufzeit deutlich merkbar ist.EntireX liegt in seiner Gesamtheit auf einem noch höheren Abstraktionslevel und ist in seinem eigentlichen Aufbau voll auf die Integration vorhandener Legacy-Applikationen mit neuen Technologien ausgelegt, nicht auf die säuberliche objektorientierte Analyse einzelner Komponenten und deren Umbau zu echten Objekten.

Eines der drei Konzepte generell einem anderen vorziehen ist dadurch nicht möglich. Alle haben sie ihre eigenen Stärken und Schwächen. Je nach Anwendungsfall, manchmal aber auch nach persönlichem „Glaubensbekenntnis“ muss man sich für eine entscheiden. Java-Puristen (wen wunderts) tendieren dabei gerne zu CORBA, wegen dem konsequent objektorientierten Aufbau in der Programmierung.Windows-Programmierer, die ohnehin auch lokal schon zur Integration einzelner Bausteine COM-Funktionalität nutzen, werden sich schnell für DCOM entscheiden. Die meisten Schnittstellen und nötigen Grundlagen sind die gleichen, die DCOM-Komponenten lassen sich einfach integrieren und vor allem nach dem bekannten Strickmustern erzeugen. Nicht zuletzt ist DCOM ja „kostenlos“ in den neueren Windows-Versionen enthalten (oder besser gesagt: schon in deren Preis einkalkuliert).Unternehmen, die viele Legacy-Applikationen insbesondere im Mainframe-Sektor betreiben, tun gut daran, sich EntireX anzuschauen. Dort liegt seine Stärke, denn in der Praxis ist es einem Unternehmen im Endeffekt egal, ob seine Programmkomponenten nun auf Codeebene „richtig objektorientiert“ aufgebaut sind; sie stehen vor dem Problem, laufende und gut bewährte Applikationen für neue Herausforderungen und insbesondere eine Internetanbindung fit zu machen, ohne den Code, der vielleicht schon seit Jahrzehnten seine Dienste tut, an neue Paradigmen anzupassen.

Schwachstellen sind auch in allen Produkten enthalten. Von CORBA gibt es recht viele konkurrierende ORB-Implementierungen, die teilweise stark unterschiedliche Services anbieten und in einigen Fällen - trotz IIOP - nicht 100%ig miteinander auskommen.Bei DCOM sind es die in der Praxis enge Bindung an Windows, das Wirrwarr an Begriffen und Schlagwörtern die Microsoft produziert und tatsächlich ein echtes Hemmnis darstellen. Ich denke auch, aus Sicherheitsaspekten sollte man mit DCOM zumindest vorsichtig umgehen.Bei EntireX ist es die große Dimensionierung, die es zwar für große Unternehmen zu einer guten und preiswerten (nicht im Sinne von „billigen“) Lösung macht, aber eben nur dort. Außerdem sind die Dokumentationen der Software AG-Produkte gewöhnungsbedürftig und Dritt-Literatur so gut wie nicht erhältlich.

In der Praxis sieht es dann häufig auch so aus, dass verschiedene Middlewares nebeneinader laufen, was nicht unbedingt dazu führt, dass die Netze und Systeme homogener werden, sondern nicht selten dazu, dass die Verteilten Systeme immer noch mehr verschiedene Schnittstellen auf verschiedenen Abstraktionsebenen bekommen.

Page 116: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

115

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Ein besonderes Problem haben alle drei hier vorgestellten Middlewares noch gemeinsam: Sie haben alle Schwierigkeiten mit der Kommunikation durch Firewalls. Zwar kann man für alle drei eine Lösung finden, wie diese oder jene Firewall zu durchdringen ist, aber meist mit hohem Konfigurationsaufwand und oft trotz aller Konfigurationsarbeit mit Einschränkungen oder gar Leistungseinbußen.

Auf Ebene der Kommunikation und der Security ist für mich persönlich das Modell des EntireX Brokers das überzeugendste: eine einfach strukturierte aber leistungsfähige, zentrale Kommunikationsstelle. Ein Client braucht sich im Prinzip nur um die Kommunikation mit dem Broker zu kümmern, der die Verbindung zur Gegenstelle übernimmt. Eine Möglichkeit zur zentralen Sicherheitsverwaltung inklusive. Schaffen es zwei Komponenten bei EntireX mit dem Broker zu kommunizieren, so können sie auch untereinander kommunizieren. Nicht wie CORBA oder DCOM, wo der Kommunikationsaufbau mehr oder weniger den einzelnen Rechnern untereinander überlassen bleibt und für Security- oder auch Namensdienste weitere mehr oder weniger zentrale, aber externe, Zusatzdienste genutzt werden müssen.

Es tut sich aber wieder einmal ein Silberstreif am Horizont auf, denn selten waren sich Softwareproduzenten aller Herren Länder so einig, wohin in Zukunft der Trend, insbesondere im Bereich der Internet-Applikationen, gehen soll: WebServices basierend auf XML und SOAP sollen die Zukunft der verteilten Kommunikation retten. XML als Dokumenten- und Datenformat sowie SOAP (Simple Objekt Access Protokoll) als Protokoll zum Datenaustausch scheinen auch vielversprechend zu sein. Die echte Unabhängigkeit von Programmiersprache und Plattform ohne wenn und aber liegen auf der Hand, Firewalls scheinen kein Hindernis mehr.SOAP ist ein auf XML basierendes Protokoll, das aus drei Teilen besteht: einem „Envelope“ (Umschlag), der beschreibt was in der Nachricht ist und wie sie zu verarbeiten ist, einem Satz von Regeln, wie Applikations-spezifische Datentypen beschrieben werden können und Konventionen, die RPCs und deren Antworten abbilden [w3c]. Es setzt dabei zum Datentransport auf die Get- und Put-Befehle des HTTP-Protokolls, was bezüglich Firewalls absolut unproblematisch ist.

Es gibt auch schon genügend Global Player, die sich um die Implementierung von SOAP-Lösungen kümmern, die voraussichtlich völlig interoperabel sind. Microsofts .NET-Offensive setzt ebenso im Zentrum auf die SOAP-Technologie wie beispielsweise Suns One oder IBMs WebSphere. Auch die Software AG, die sich ja als „The XML Company“ bezeichnet, arbeitet auf diesem Gebiet an vorderster Front mit. Die Zukunft wird zeigen, ob SOAP tatsächlich die Antwort auf alle offenen Fragen der Middleware-Technik ist, oder ob sich nicht früher oder spätere auch hier Einschränkungen bezüglich der Praxis-Tauglichkeit erweisen werden.

Page 117: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

116

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

b) PraxisphaseDie Praxisphase hat zunächst einmal Spaß gemacht und wie ich denke ihren Zweck erfüllt. Zwar war meine Tätigkeit recht kompliziert und Neuland gerade auch für das ESM-Team, ich selbst hatte oft mit der Grundlage „Natural“ zu kämpfen und meine Arbeit ging in eine etwas andere Richtung, als ich mir das ursptünglich vorgestellt hatte. Außerdem konnte ich in dem halben Jahr nicht ganz so produktiv arbeiten, wie ich selbst mir das vorgestellt hatte.Aber gerade diese Herausforderung, dass ich mit für mich unbekannten Technologien und Welten konfrontiert war (vor meiner Praxisphase kannte ich „Mainframe“, „OS/390“ und „EntireX“ gerade mal vom Namen, von „Natural“ hatte ich noch nie im Leben gehört und unter „PDA“ verstand ich so etwas wie meinen kleinen Palm IIIe), hat in dieser Zeit meinen Horizont enorm erweitert. Zwar weiß ich noch nicht, ob ich auf die neu kennengelernten Technologien auch in meiner beruflichen Praxis nach dem Studium aufbauen kann, denn zumindest mein Herz gehört eher einer systemnahen Programmierung unter C und C++, aber Schaden werden mir die Erfahrungen sicherlich nicht. Es war auch keinesfalls verlorene Zeit und ich glaube (und hoffe), ich konnte mich im Endeffekt auch nützlich in das Projekt einbringen. Alles in allem denke ich, war die Wahl des Projektes für mich, verglichen mit einigen anderen meiner Kommilitonen, ein Glücksfall. Zur Zeit habe ich bei der Software AG zumindest noch einen bis 31.7.2002 laufenden Werksstudenten-Vertrag und ich werde sicherlich in dieser Zeit noch weiter zur Funktionalität des Projekts beitragen können.

Das bisherige Ergebnis des ESM GUI Framework kann sich – was sicherlich nur zu einem sehr geringen Anteil mein Verdienst ist – sehen lassen und wohl auch meine Beiträge dazu, besonders die Implementierungen von Hilfe- und Security-Funktionen und bestimmt auch der ESMBrowser.Letzterer lässt jedoch noch die Implementierung von drei wesentlichen Funktionen vermissen: Zum einen, was eine Kleinigkeit sein dürfte, ist es derzeit nicht möglich, sich dem RPC-Server gegenüber mit einer anderen Identität auszuweisen, als dem Broker gegenüber, zum zweiten, was komplex werden dürfte, fehlt noch die Möglichkeit, Datenobjekte zu browsen, deren Zeilenanzahl nicht von vornherein fest steht oder deren Zeilen länger als 253 Zeichen sind.Außerdem werden Fehlermeldungen vom Control selbst behandelt und einfach in Standard-Messageboxes ausgegeben. Die Fehlerbehandlung insgesamt kann als unstrukturiert bezeichnet werden. Hier fehlt einfach noch die Weitergabe von Fehlern als ActiveX-Events nach außen.

Natural selbst weist zur GUI-Entwicklung unter Windows einige überzeugende Fähigkeiten auf, die vor allem ein RAD möglich machen, hat aber auch (noch) deutliche Einschränkungen gegenüber anderen Sprachen auf diesem Sektor, wie zum Beispiel Visual Basic oder C++. Außerdem ist die Sprache rein prozedural aufgebaut, was in großen Projekten Modellierung und Wartung außerordentlich erschwert.

Page 118: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

117

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Wäre es meine persönliche Entscheidung, so würde ich solche umfangreichen und komplexen GUI-Frontends aus diesem Grund nicht unter Natural entwickeln, wenn auch auf der Serverseite auf jeden Fall viel für Natural spricht und es auch für kleinere Applikationen mit vielen Dialogen und weniger Hintergrundfunktionalität hervoragend geeignet ist.Mein persönlicher Favorit unter Windows ist aber noch immer Visual C++, auch Visual Basic ist eine starke Alternative, die ich persönlich aber einfach nicht mag.Aber natürlich bestimmen in so einem Fall auch Marketing-Aspekte bei der Entscheidung immer mit, man kann schlecht nach außen für Natural Werbung machen, wenn man intern selbst vieles auf anderen Plattformen entwickelt. Und mit der Entwicklung unseres Projekts waren und sind wir auch in eine – wenn auch kleine – Triebfeder für die Weiterentwicklung der GUI-Fähigkeiten von Natural.

Da ich zu den ersten Studenten gehöre, die an der FH nach diesem Muster Praxisphase und Bachelorarbeit durchführen, möchte ich auch hierzu noch meine Meinung verfassen.Auf jeden Fall haben sich sowohl Praxisphase als auch Bachelorarbeit für mich gelohnt, letztere gab mir die Möglichkeit, tiefe Einblicke in Middleware-Konzepte zu nehmen.Allerdings fühlte sich mein Jahrgang doch oftmals wie eine Gruppe von Alphatestern für noch nicht ausgereifte oder noch nicht ganz durchdachte Verfahren. So zum Beispiel, dass erst kurz vor deren Beginn Organisations- und Durchführungsform der Bachelorarbeit feststanden und Anforderungen an das Praxissemester in dessen Verlauf anders definiert wurden (Stichwort Vertragsform und Wochenstundenzahl).Außerdem fände ich es besser, wenn Bachelorarbeit und Praxisphase stärker gebündelt und in einem einzigen Semester durchgeführt würden, unter eventueller Hinzunahme der Semesterferien. Ein Semester, in dem dann auch die Studienordnung keine Vorlesungen vorsieht. Ich denke dabei an eine ähnliche Form, wie die bisherigen Diplomarbeiten. Das hätte zum einen den Vorteil, dass die wirklich stark störenden Interferenzen mit den Vorlesungen vermieden würden. Man hat als Student einfach nicht die Möglichkeit, seine Vorlesungen wirklich blockweise auf eine bestimmte Anzahl von Tagen zu legen.Zum anderen könnte man sich gleich ein Projekt aussuchen, bei dem der Bezug zu einer Abschlussarbeit von vorneherein feststeht und nicht, wie bei uns, teilweise mühsam gesucht werden muss. Diejenigen Studenten, die ihre Tätigkeit in der Firma mit Abschluss der Praxisphase auch gleich beendet haben, dürften in Bezug auf Informationsbeschaffung einen noch schwereren Stand gehabt haben

Auf jeden Fall bin ich der Meinung, der Praxisteil sollte weiterhin außerhalb der Hochschule stattfinden; dies erlaubt das Kennenlernen realistischer Arbeitsbedingungen während des Studiums und man kann dadurch Kontakte zu den Firmen knüpfen. Diskussionen darüber, ob das Praxissemester nicht vielleicht ganz an der Hochschule, wenn auch in extern motivierten Projekten stattfinden soll (wie es gerüchteweise eine zeitlang hieß), hielte ich jedenfalls für verkehrt.

Page 119: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

118

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Page 120: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

119

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Literatur-Verzeichnis

Bücher:[rock-evans] Rosemary Rock-Evans „DCOM Explained“, Digital Press 1998[rosenberger] Jeremy Rosenberger „CORBA in 14 Tagen“, SAMS 1998[sceppa] David Sceppa „ADO Programmierung“, Microsoft Press 2000

Online-Quellen:(Viele der Online-Quellen sind - soweit es sich um statische Dokumente handelt - auf der Anhang-CD in HTML-, PDF- oder PPT-Format gespeichert, da Internetquellen bekanntermaßen flüchtig sind)

[webop] http://www.webopedia.comWebodpedia - „The only online dictionary and search engine you need for computer and Internet technology”

[foldoc] http://wombat.doc.ic.ac.uk/foldoc/FOLDOC - Free On-Line Dictionary Of Computing

[omg] http://www.omg.orgOMG - Objekt Managment Group Homepage

[corba] http://www.corba.orgCORBA Homepage

[osf] http://www.opengroup.org/ The Open Group Homepage

[msdnlib] http://msdn.microsoft.comMSDN (Mircosoft Developer Network) Library

[technet] http://technet.microsoft.comMicrosoft Technet

[w3c] http://www.w3.orgW3C - The World Wide Web Consortium Homepage

[geihs] http://www.vsb.cs.uni-frankfurt.de/lehre/vorlesung/MiddlewareProf. Dr. Kurt Geihs (Professur Verteilte Systeme und Betriebssysteme, Fachbereich Biologie und Informatik, Johann-Wolfgang Goethe Universität Frankfurt): Vorlesungsunterlagen „Middleware“

[mwbook] http://www.syssoft.uni-trier.de/systemsoftware/Download/Seminare/Middleware/Prof. Dr. J. Nehmer (AG Systemsoftware, Universität Kaiserslautern) und Prof. Dr. P. Sturm (AG Systemsoftware und Verteilte System, Universität Triert), Seminar: „Middleware: Betriebssysteme der Zukunft?“, 1998

[muelle] http://wwwipd.ira.uka.de/~muelle/dynbuild/Jutta Mülle (Institut für Programmstrukturen und Datenorganisation (IPD), Universität Karlsruhe): Website „Dynamische Gebäude“.

[spruth] http://tipc023.informatik.uni-leipzig.de/os390/book/Prof. Dr.-Ing. Wilhelm G. Spruth (Arbeitsbereich Technische Informatik an der Eberhard-Karls-Universität Tübingen + Universität Leipzig), “OS/390 Internet Services”

[svsmw] http://wwwmath.uni-muenster.de/u/versys/courses/WiSe0102/SemVS/Prof.Dr. Guido Wirtz (Gruppe Versys am Fachbereich Mathematik und Informatik der Westfälischen Wilhelms-Universität Münster) sowie verschiedene Referenten:Seminar „Verteilte Systeme und Middleware“, Vortragsunterlagen

Page 121: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

120

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

[gossmer] http://www.informatik.uni-stuttgart.de/ipvr/as/lehre/seminar/docss00/message-broker.pptMarkus Gossmer (Abteilung Anwendersoftware, Fakultät Informatik, Universität Stuttgart), Seminar „Enterprise Application Integration - Message Broker“

[schill] http://www.competence-site.de/eaisysteme.nsf/C937534DE4B6BC14C1256A14005E5D60/ $File/middleware.pdfProf. Dr. Alexander Schill (Lehrstuhl Rechnernetze, Technische Universität Dresden), „Middleware im Vergleich“

[buahöf] http://swt.cs.tu-berlin.de/lehre/seminar/ws00/folien/com.pdf Joseph Bauer und Edzard Höfig: Vortrag „DCOM, OLE, ActiveX“ im Seminar „Softwaretechnik“ (Wilfried Koch, Margot Bittner, Prof. Dr. Stefan Jähnichen; Institut für Softwaretechnik und Technische Informatik, Fakultät Elektotechnik und Informatik an der Technischen Universität Berlin).

[gbis] http://wwwdbis.informatik.uni-kl.de/courses/GBIS/SS2001/Vorlesungsunterlagen/ Kapitel.09.pdf Vorlesungsinhalt “Grundlagen Betrieblicher Informationssystem, SS 2001” (AG Datenbanken und Informationssysteme, FB Informatik, Universität Kaiserslautern) Kapitel 9. Author ???

[schuldt] http://www-dbs.inf.ethz.ch/~oho/SS_01/Dr. Heiko Schuldt (Institute of Information Systems, Eidgenössische Technische Hochschule Zürich), Vorlesungsunterlagen “Objektverwaltung höherer Ordnung (OHO), SS 2001”.

[najjar] http://www.devsolutions.com/Conference/ComPlusSecurity.pptJoseph N. Najjar III: „COM+ and DCOM security“, Konferenz-Vortrag

[platt] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmag00/html/comtips.aspDavid S. Platt: „COM+ and Windows 2000: Ten Tips and Tricks for Maximizing COM+ Performance“

[w2ksspi] http://www.microsoft.com/windows2000/docs/sspi2000.docMicrosoft: Windows 2000 Server SSPI White Papers

Handbücher und Informationsunterlagen:(Einige davon sind auf der Anhang-CD in HTML-, PDF- oder PPT-Format gespeichert, da sie nicht alle öffentlich zugänglich sind. Eventuelle Copyrights der Handbücher sind zu beachten!)

[msdnlib] Microsoft Developer Network Libray auf CD bzw. im Internet, Oktober 2001[exxwin] EntireX Version 6.1.1 Online Documentation, Software AG 2001[exxdcx] EntireX DCOM under Linux Version 6.1.1 – Installation and Operation, Software AG 2001[exxwp] EntireX White Paper (Final Draft, Stand 10.3.2002), Software AG 2002

Sonstiges: Das Corba-Logo auf Seite 25 ist eingetragenes Warenzeichen der OMG

Page 122: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

121

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Glossar4GL „ Fourth Generation Language“, ein Typ von Programmiersprachen, der der

menschlichen Sprache näher ist als 3GL (C, C++, Java, ...), 2GL (Assembler) und 1GL (Maschinensprache), siehe auch Kapitel 7.1.1

ACI Advanced Communication Interface (des EntireX Brokers, siehe Kapitel 6.2ADO ActiveX Data Objects, DBCP-Technologie von MicrosoftAPI Application Programming InterfaceATL Active Template Library, (Template-)Klassenbibliothek von MicrosoftB2B „Business-to-Business“, Informationsaustausch zwischen UnternehmenDBCP Database Connectivity Product, „Datenbank-Middleware“, siehe 3.2.1DBMS Database Managment System, Datenbank-SoftwareDCE Distributed Computing Environment, ein Standard der OSFDES Data Encryption Standard, Secret-Key Verschlüsselungs-AlgorithmusDTPM Distributed Transaction Processing Middleware, siehe 3.2.4EBCDIC Extended Binary-Coded Decimal Interchange Code, Zeichendarstellungs-Standard auf

IBM Mainframe- und Midrange-Systemen (analog ASCII auf PC)EDI Electronic Data Interchange, ein Standard zum Datenaustausch im B2B-BereichEJB Enterprise Java BeansERX Kurzform für EntireXESM Entire System Managment, Software-Entwicklungsteam innerhalb der Software AGGUI Graphical User Interface, Grafische Benutzer-OberflächeIDL Interface Definition LanguageIEEE Institute of Electrical and Electronics Engineers,

u.a. Standardisierungs-GremiumIIOP Internet Inter-ORB Protokoll, siehe Kapitel 5JDBC Java Database Connectivity, Standard DBMS-Zugriff unter Java, ähnlich ODBCLegacy „Erbstück“. Legacy-Applikationen sind alte Applikationen, die in Unternehmen noch

zum Einsatz kommen, deren Coding aber nicht mehr auf dem Stand der Technik istMDI Multiple Document Interface, ein Standard für Fenster-Hierarchien in GUIsMFC Microsoft Foundation Classes, C++ Klassenbibliothek von MicrosoftNOM Natural Output Monitor, ein Produkt der Software AGNOP Entire Operations, ein Produkt der Software AGOMG Object Managment Group OO objektorientiertORB Object Request BrokerOSF Open Software Foundation, heute Teil der „The Open Group“RAD Rapid Application Development, schnelle ApplikationsentwicklungRDA Remote Data Access, Zugriff auf entfernte DatenbankenRDBMS Relational Database Managment System, Relationale DatenbankRDO Remote Data Objects, DBCP-Technologie von MicrosoftRPC Remote Procedure CallSAG Kurzform für „Software AG“SNMP Simple Network Managment ProtocolSOAP Simple Object Access Protocol, siehe Kapitel 8SQL Structured Query Language, Sprach-Syntax für Zugriff auf DBMSsSTL C++ Standard Template LibararyTBI Total Business Integration, bezeichnet den Versuch, alle Geschäftsprozesse

eines Unternehmens, sowohl interne als auch externe, auf einheitliche EDV -Systeme abzubilden.

XML Extensible Markup Language

Page 123: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

122

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

AnhangAls Anhang liegt den beiden Fassungen dieser Arbeit, die für den Referenten und Korreferenten bestimmt sind, eine Anhangs-CD bei. Diese enthält einige der im Literatur-Verzeichnis angegebenen Quellen sowie Quellcodes zu Kapitel 7.

Da die Quellcodes sowie möglicherweise auch einige Teile der Quellen dem Copyright der Software AG unterliegen, sind diese anderen Personen nicht zugänglich zu machen.

Inhalt der CDa) Diese Arbeit in elektronischer Form

Format: PDF Version 1.4 - Adobe Acrobat Reader 5 oder neuer erforderlichOrder: \Arbeit eBook\

b) Benutzte Internet-Quellen aus dem Literatur-Verzeichnis(PDF-, HTML oder Powerpoint PPT-Format)Ordner: \Literatur-Quellen\benutzte Quellen\

c) Nicht berücksichtigte Internet-Quellen (dies sind solche, die ich beim Material-Sammeln gefunden, aufgrund des nicht wirklich passenden Inhalts aber beim Verfassen dieser Arbeit nicht berücksichtigt habe)Format: PDF-, HTML oder Powerpoint PPT-FormatOrdner: \Literatur-Quellen\nicht eingegangene Quellen\

d) Quellcodes zu Kapitel 7: ESM Browser ControlFormat: Workspace für Visual C++ 6.0 Enterprise-Edition US-EnglischOrdner: \Quellcode\VisualC6\ESM_COM\

Anmerkung: MS-Visual C++ / ATL - Quellcode sowie compilierte Version (Unicode Release). Der Quellcode lässt sich ohne EntireX RPC-SDK für C nicht kompilieren und die compilierte Version ist nur gebrauchsfähig im Zusammenspiel mit ESM GUI Framework und EntireX Version 5.3.1 und neuer

Page 124: Kommunikation über Middleware am Beispiel RPC - ttlv.de · Natural und über die EntireX Broker SDK für C am Beispiel des ActiveX Browser Controls vorstelle

123

Bachelor-Arbeit Marco Freudenberger Kommunikation über Middleware am Beispiel RPC

Ehrenwörtliche Versicherung

Hiermit versichere ich, dass ich die vorliegende Bachelor-Arbeitselbstständig und ausschließlich unter Verwendung der angegebenenQuellen angefertigt habe.

Modautal-Ernsthofen, den 19.April 2002

(Marco Freudenberger)