Entwurf und Implementierung eines verteilten Systems ... - copton.net
Entwurf und Implementierung eines verteilten Systems ... - copton.net
Entwurf und Implementierung eines verteilten Systems ... - copton.net
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
·<br />
<strong>Entwurf</strong> <strong>und</strong> <strong>Implementierung</strong> <strong>eines</strong> <strong>verteilten</strong><br />
<strong>Systems</strong> mit Benutzerschnittstelle zur<br />
Erstellung, Verteilung <strong>und</strong> Verwaltung von<br />
Simulationen in der Kanalcodierung<br />
Diplomarbeit<br />
von<br />
Stephanie Wist<br />
· T E L E C O M M U N<br />
I C A T<br />
I O N S<br />
A P P L<br />
T H E O R Y<br />
I E D<br />
I N F O R M A T<br />
I O N<br />
Abteilung Telekommunikationstechnik<br />
<strong>und</strong> Angewandte Informationstheorie<br />
Universität Ulm<br />
Mai 2006<br />
D/2005/ST/1
Abteilung Telekommunikationstechnik<br />
<strong>und</strong> Angewandte Informationstheorie<br />
Universität Ulm<br />
DIPLOMARBEIT<br />
<strong>Entwurf</strong> <strong>und</strong> <strong>Implementierung</strong> <strong>eines</strong> <strong>verteilten</strong> <strong>Systems</strong> mit<br />
Benutzerschnittstelle zur Erstellung, Verteilung <strong>und</strong><br />
Verwaltung von Simulationen in der Kanalcodierung<br />
Erläuterungen:<br />
Um in der Kanalcodierung theoretische Ergebnisse zu verifizieren, werden Simulationen<br />
für die Berechnung der Restbit- <strong>und</strong> -blockfehlerraten verwendet. Dabei werden entweder<br />
graphische Simulationstools wie „ML Designer“ verwendet oder es werden komplette<br />
Simulationsumgebungen in einer Programmiersprache wie C/C++ oder „Matlab“ erstellt.<br />
Beide Möglichkeiten haben ihre Vor- <strong>und</strong> Nachteile.<br />
Bestehende Simulationstools sind meist recht umfangreich <strong>und</strong> dementsprechend unübersichtlich.<br />
Die Einarbeitung nimmt daher oftmals viel Zeit in Anspruch. Desweiteren<br />
handelt es sich bei diesen Tools häufig um kommerzielle Software, wodurch hohe<br />
Lizenzkosten anfallen.<br />
Auf der anderen Seite sind vom Anwender selbst geschriebene Simulationsumgebungen<br />
zwar frei, haben aber den Nachteil, dass von anderen Benutzern sehr viel Progammierkenntnis<br />
verlangt wird, um Modifikationen vornehmen zu können. Die komfortable<br />
graphische Benutzeroberfläche kommerzieller Tools entfällt in diesem Fall.<br />
Im Rahmen dieser Diplomarbeit soll daher ein verteiltes System zur Erstellung, Verteilung<br />
<strong>und</strong> Verwaltungen von Simulationen in der Kanalcodierung entworfen <strong>und</strong> implementiert<br />
werden. Dies sollte unter Verwendung <strong>eines</strong> Simulationsframeworks stattfinden,<br />
welches Gegenstand einer weiteren Diplomarbeit ist. Das System sollte mehrbenutzerfähig<br />
<strong>und</strong> in einem heterogenen Rechner<strong>net</strong>z einsetzbar sein, sowie eine Schnittstelle zur<br />
Verwaltung bereits laufender Simulationen bieten. Die Erstellung der an der Simulation<br />
beteiligten Komponenten <strong>und</strong> der Simulation selbst sollte einfach <strong>und</strong> ohne tiefer<br />
gehende Kenntnis der dahinter liegenden Mechanismen möglich sein.<br />
Abgabetermin: 17. Mai 2006<br />
Bearbeiter:<br />
Betreuung:<br />
Stephanie Wist<br />
Prof. Dr.-Ing. M. Bossert<br />
Prof. Dr.-Ing. F. J. Hauck<br />
Dipl.-Ing. A. Hof<br />
Dipl.-Inform. S. Schober<br />
Katalognr.:<br />
D/2005/ST/1
Erklärung<br />
Ich versichere, dass ich die vorliegende Diplomarbeit selbständig <strong>und</strong> ohne unzulässige<br />
fremde Hilfe angefertigt habe.<br />
Ulm, den 16. Mai 2006<br />
Stephanie Wist
Danksagung<br />
Mein besonderer Dank an dieser Stelle gilt meinen Eltern, die mich während des Studiums<br />
nicht nur finanziell unterstützt haben, sondern mir auch in schwierigen Situationen<br />
immer beigestanden sind. Auch möchte ich allen Mitwirkenden der Universität Ulm<br />
danken, die diese Arbeit ermöglicht <strong>und</strong> zu ihrem Gelingen beigetragen haben. Dies<br />
sind speziell die Gutachter Prof. Dr.-Ing. Martin Bossert <strong>und</strong> Prof. Dr.-Ing. Franz J.<br />
Hauck, sowie meine Betreuer Dipl.-Ing. Axel Hof <strong>und</strong> Dipl.-Inform. Steffen Schober.<br />
Auch danke ich allen Korrekturlesern für ihre Mühen. Dies gilt besonders für meinen<br />
Vater, sowie für Markus Schaber <strong>und</strong> Markus Wörle, die nicht müde wurden, die<br />
Diplomarbeit immer <strong>und</strong> immer wieder nach Fehlern zu durchsuchen.<br />
Für den <strong>Entwurf</strong> <strong>und</strong> die <strong>Implementierung</strong> des <strong>verteilten</strong> <strong>Systems</strong> wurde sehr viel freie<br />
Software eingesetzt. Deshalb an dieser Stelle auch einen Dank an alle Entwickler <strong>und</strong><br />
Maintainer von freier Software, ohne deren Arbeit die Ergebnisse dieser Diplomarbeit<br />
in ihrer jetzigen Form nicht möglich gewesen wären.<br />
Abschließend möchte ich mich noch besonders bei Markus Wörle bedanken, der mich<br />
immer wieder aufgebaut hat, wenn ich nicht mehr weiter wusste.
Inhaltsverzeichnis<br />
Inhaltsverzeichnis<br />
IX<br />
1 Einführung 1<br />
1.1 Aufteilung <strong>und</strong> Gliederung . . . . . . . . . . . . . . . . . . . . . . . . . . 2<br />
1.2 Anforderungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2<br />
1.3 Der Anwender . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />
2 Gr<strong>und</strong>lagen 5<br />
2.1 Simulationsprogramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5<br />
2.2 ICE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />
2.2.1 Funktionsweise . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />
2.2.2 Dienste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />
2.3 XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10<br />
2.3.1 XML-Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10<br />
2.3.2 XSLT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />
2.4 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />
2.4.1 Reflection-API . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />
2.4.2 JDOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />
2.4.3 Saxon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />
3 Systementwurf 13<br />
3.1 Module <strong>und</strong> Simulationen . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />
3.1.1 Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />
3.1.2 Datentyp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />
3.1.3 Simulationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />
3.1.4 Simulationsauftrag . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />
3.2 Konzeption des <strong>verteilten</strong> <strong>Systems</strong> . . . . . . . . . . . . . . . . . . . . . 17<br />
3.2.1 Auswahl der Middleware . . . . . . . . . . . . . . . . . . . . . . . 17<br />
3.2.2 Systemaufbau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18<br />
3.2.3 Codeverteilung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20<br />
3.2.4 Benutzer- <strong>und</strong> Rechteverwaltung . . . . . . . . . . . . . . . . . . 20<br />
3.2.5 Sicherheit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />
3.2.6 Kommunikation zwischen Komponenten . . . . . . . . . . . . . . 26<br />
3.2.7 Systemgröße . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />
3.3 Simulationsablauf im <strong>verteilten</strong> System . . . . . . . . . . . . . . . . . . . 29<br />
3.3.1 Entgegennahme <strong>und</strong> Verwaltung von Simulationsaufträgen . . . 29<br />
3.3.2 Erstellen von Sicherungspunkten . . . . . . . . . . . . . . . . . . 30<br />
IX
INHALTSVERZEICHNIS<br />
3.3.3 Verteilen von Simulationen . . . . . . . . . . . . . . . . . . . . . 31<br />
3.3.4 Ausführen von Simulationen . . . . . . . . . . . . . . . . . . . . . 31<br />
3.3.5 Ende einer Simulation . . . . . . . . . . . . . . . . . . . . . . . . 32<br />
3.3.6 Informationen über laufende Simulationen . . . . . . . . . . . . . 32<br />
3.4 Überblick über die Dienste im <strong>verteilten</strong> System . . . . . . . . . . . . . 33<br />
3.4.1 Umsetzung der Dienste . . . . . . . . . . . . . . . . . . . . . . . 33<br />
3.4.2 Anwenderprogramme . . . . . . . . . . . . . . . . . . . . . . . . . 34<br />
4 <strong>Implementierung</strong> 35<br />
4.1 Wahl der Programmier- <strong>und</strong> Beschreibungssprachen . . . . . . . . . . . 35<br />
4.1.1 Java versus C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />
4.1.2 Beschreibungssprache . . . . . . . . . . . . . . . . . . . . . . . . 36<br />
4.2 Module <strong>und</strong> Simulationen . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />
4.2.1 Erzeugen von Modulen . . . . . . . . . . . . . . . . . . . . . . . . 37<br />
4.2.2 Erzeugen von Simulationen . . . . . . . . . . . . . . . . . . . . . 40<br />
4.2.3 Erstellen von Simulationsaufträgen . . . . . . . . . . . . . . . . . 40<br />
4.3 Das verteilte System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />
4.3.1 Hinzufügen <strong>und</strong> Entfernen von Knoten . . . . . . . . . . . . . . . 43<br />
4.3.2 Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />
4.3.3 Benutzerverwaltung . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />
4.3.4 Codeverteilung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />
4.3.5 Dienste im <strong>verteilten</strong> System . . . . . . . . . . . . . . . . . . . . 47<br />
4.4 Benutzeranwendungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49<br />
4.4.1 Paketgenerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49<br />
4.4.2 Ergebnisexportierer . . . . . . . . . . . . . . . . . . . . . . . . . 49<br />
4.4.3 Modulsuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50<br />
4.4.4 Die grafische Oberfläche . . . . . . . . . . . . . . . . . . . . . . . 51<br />
5 Zusammenfassung <strong>und</strong> Ausblick 55<br />
5.1 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55<br />
5.2 Erfüllung der Anforderungen . . . . . . . . . . . . . . . . . . . . . . . . 56<br />
5.3 Lizenzbestimmungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56<br />
5.4 Probleme mit ICE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57<br />
5.5 Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58<br />
A Kommandozeilen-Tools 61<br />
A.1 Simulationsverwaltung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />
A.2 Benutzerverwaltung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />
A.3 Paketgenerierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62<br />
A.4 Modulsuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />
A.5 Ergebnisse exportieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />
X
INHALTSVERZEICHNIS<br />
B Installation <strong>und</strong> Wartung 65<br />
B.1 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />
B.1.1 Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />
B.1.2 zentrale Komponente . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />
B.1.3 Simulationsknoten . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />
B.1.4 Codeverteilung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66<br />
B.2 Wartung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66<br />
B.2.1 Simulationsknoten hinzufügen . . . . . . . . . . . . . . . . . . . . 66<br />
B.2.2 Simulationsknoten entfernen . . . . . . . . . . . . . . . . . . . . 66<br />
B.2.3 Neue Codeverteilung hinzufügen . . . . . . . . . . . . . . . . . . 67<br />
C Schnittstellen 69<br />
C.1 Schnittstellen im <strong>verteilten</strong> System . . . . . . . . . . . . . . . . . . . . . 70<br />
C.2 Schnittstellen der GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74<br />
D Software 75<br />
D.1 verwendete Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75<br />
D.2 Inhalt der beigefügten CD . . . . . . . . . . . . . . . . . . . . . . . . . . 75<br />
Index 77<br />
Literaturverzeichnis 79<br />
XI
1 Einführung<br />
Die Telekommunikation spielt in der modernen Gesellschaft eine zentrale Rolle. Egal<br />
ob bei Steuerchips in Autos, Schiffen oder Flugzeugen, bei Signalprozessoren in Mobiltelefonen<br />
oder bei Controllern von Bussystemen in Computern oder Industrieanlagen:<br />
überall werden Informationen ausgetauscht <strong>und</strong> verarbeitet. Dabei steigen die Anforderungen<br />
an Geschwindigkeit <strong>und</strong> Robustheit unter immer kritischeren Bedingungen<br />
kontinuierlich an.<br />
Forscher auf dem Gebiet der Informationstheorie sorgen seit Jahrzehnten immer wieder<br />
für Lösungen, die den wachsenden Ansprüchen gerecht werden. Einer der zentralen<br />
Schauplätze auf diesem Gebiet ist dabei die Kanalcodierung. Sie beschäftigt sich mit<br />
der Frage, wie man den Informationsaustausch durch kontrolliertes Hinzufügen von möglichst<br />
wenig Red<strong>und</strong>anz robust gegen Übertragungsfehler machen kann.<br />
Die Komplexität der Systeme, die sich bei der Erforschung geeig<strong>net</strong>er Algorithmen<br />
ergeben, ist ohne Hilfsmittel allerdings kaum in den Griff zu bekommen. So sind z.B.<br />
nichtlineare Optimierungsprobleme keine Seltenheit. Deshalb ist die Simulation ein gern<br />
verwendetes Hilfsmittel. Dabei berech<strong>net</strong> ein Computer möglichst exakt, wie sich das<br />
System bei einem echten Einsatz verhalten würde.<br />
Es existiert also ein Markt für Simulationsprogramme <strong>und</strong> er wird reichlich bedient.<br />
Doch keine der Lösungen schöpft die Möglichkeiten, die sich durch verteiltes Rechnen<br />
ergeben, ausreichend aus. Und das, obwohl in den meisten Forschungseinrichtungen viele<br />
Computer vorhanden sind. Deshalb bleibt es dem Anwender überlassen, die Probleme<br />
zu lösen, die sich beim Einsatz in einem Netzwerk ergeben: Es gibt keine automatisierte<br />
Verteilung, keine Ausfallsicherheit <strong>und</strong> keine zentrale Verwaltung für Ressourcen,<br />
Simulationen <strong>und</strong> Benutzer.<br />
Diese Arbeit behandelt den <strong>Entwurf</strong> <strong>und</strong> die <strong>Implementierung</strong> von Lethe 2 , einer Lösung<br />
dieser Probleme. Lethe ist zum einen ein verteiltes System mit einem zentralen<br />
Anwenderprogramm für die Erzeugung <strong>und</strong> Verwaltung von Simulationen. Neben der<br />
automatisierten Verteilung ermöglicht Lethe es, Simulationen im laufenden Betrieb auf<br />
andere Computer zu verlagern. Damit ist eine flexible Nutzung der zur Verfügung stehenden<br />
Ressourcen möglich. Außerdem erstellt Lethe in regelmäßigen Abständen Sicherungspunkte<br />
von Simulationen, die jederzeit auf einem beliebigen Computer fortgesetzt<br />
werden können. Lethe kümmert sich damit um die transparente Behandlung von Systemausfällen.<br />
Alle automatisierten Vorgänge können auch manuell gesteuert werden.<br />
1 Die vorliegende Diplomarbeit wurde im Verb<strong>und</strong> mit der Diplomarbeit von Alexander Bernauer erstellt.<br />
Dabei ist diese Einleitung in Gemeinschaftsarbeit erstellt worden <strong>und</strong> wird in beiden Arbeiten<br />
verwendet.<br />
2 Der Name Lethe stammt aus der griechischen Mythologie. Er bezeich<strong>net</strong> dort den Fluß des Vergessens<br />
im Reich von Hades, dem Gott der Unterwelt [21].<br />
1
1 Einführung<br />
Dabei sind Zugriffe auf das verteilte System durch ein Rechtesystem für Benutzer geschützt.<br />
Zum anderen ist Lethe ein Framework für die Simulationen. Dazu gehören zwei Dinge:<br />
eine Programmierschnittstelle <strong>und</strong> eine Laufzeitumgebung. Das wesentliche Kriterium<br />
für die Gestalt dieses Frameworks ist die Unterstützung der oben beschriebenen<br />
Besonderheiten von Lethe. Ermöglicht wird das vor allem durch eine Spezialisierung<br />
auf Anwendungen in der Kanalcodierung. Ein anderes wichtiges Kriterium ist es, die<br />
Wiederverwendbarkeit von <strong>Implementierung</strong>en zu maximieren. Dazu existiert ein Modulkonzept<br />
mit einem Konfigurationssystem.<br />
Lethe stellt an das Netzwerk, in dem es eingesetzt wird, fast keine Anforderungen. Es<br />
benötigt lediglich POSIX kompatible Systeme, wobei die einzelnen Systeme im Netzwerk<br />
verschieden sein dürfen. Außerdem steht Lethe unter der GNU General Public Licence<br />
[19] der Free Software Fo<strong>und</strong>ation [17].<br />
1.1 Aufteilung <strong>und</strong> Gliederung<br />
Das Lethe Projekt ist zu umfangreich, um in einer einizgen Diplomarbeit ausreichend<br />
behandelt werden zu können. Aus diesem Gr<strong>und</strong> wird das Thema in zwei Diplomarbeiten<br />
behandelt. Die vorliegende Arbeit deckt die Themen um das verteilte System <strong>und</strong> das<br />
Anwenderprogramm ab, während sich die Arbeit von Alexander Bernauer sich um das<br />
Framework kümmert. Die Schnittpunkte zwischen diesen beiden Teilen werden jeweils<br />
aus der entsprechenden Perspektive in beiden Arbeiten behandelt.<br />
Zum besseren Verständnis dieser Diplomarbeit ist Abschnitt 2.1 aus der Diplomarbeit<br />
von Alexander Bernauer entnommen. Zusätzlich ist er mit einem klärenden Vermerk<br />
über seinen Autor gekennzeich<strong>net</strong>. Diese Einführung stammt von beiden Autoren<br />
gemeinsam.<br />
Beide Arbeiten besitzen den selben Aufbau: Das Kapitel „Gr<strong>und</strong>lagen“ erklärt, welche<br />
alternativen Lösungen existieren <strong>und</strong> warum diese den Anforderungen nicht gerecht<br />
werden. Außerdem liefert dieses Kapitel kurze Einführungen in die für die Arbeit relevanten<br />
Themengebiete <strong>und</strong> verweist dabei ggf. auf weiterführende Literatur.<br />
Der <strong>Entwurf</strong> in Kapitel 3 diskutiert, wie die Anforderungen umgesetzt <strong>und</strong> die dabei<br />
entstehenden Probleme gelöst werden. Das nachfolgende Kapitel über die <strong>Implementierung</strong><br />
beschäftigt sich damit, wie die Lösungen des <strong>Entwurf</strong>s tatsächlich umgesetzt<br />
werden.<br />
Trotz der Aufteilung in zwei Diplomarbeiten werden nicht alle Fragen geklärt, die sich<br />
bei der Diskussion um Lethe ergeben. Kapitel 5 bietet einen Überlick über die Arbeit,<br />
listet die offenen Fragen auf <strong>und</strong> erlaubt einen Ausblick auf eventuelle Folgearbeiten.<br />
1.2 Anforderungen<br />
Die folgenden Anforderungen werden an Lethe allgemein <strong>und</strong> speziell an das verteilte<br />
System <strong>und</strong> die Anwenderprogramme gestellt:<br />
• leichte Benutzbarkeit. Dazu zählt sowohl die Anbindung an das verteilte System,<br />
als auch die Erweiterbarkeit des <strong>verteilten</strong> <strong>Systems</strong> um zusätzlich benötigte Kom-<br />
2
1.3 Der Anwender<br />
ponenten. Desweiteren soll das Hinzufügen <strong>und</strong> Entfernen von Knoten aus dem<br />
<strong>verteilten</strong> System möglichst einfach durchzuführen sein.<br />
• Mehrbenutzersystem. Lethe soll mehreren Benutzern gleichzeitig den Zugriff auf<br />
das verteilte System erlauben. Ausserdem sollen unterschiedliche Benutzergruppen<br />
mit verschiedenen Rechten <strong>und</strong> Prioritäten bezüglich der Simulationsdurchführung<br />
unterstützt werden.<br />
• automatische Ressourcenzuteilung. Verfügbare Ressourcen sollen automatisch <strong>und</strong><br />
möglichst gerecht an die Simulationen verteilt werden. Dabei sind die unterschiedlichen<br />
Prioritäten der Benutzer zu beachten.<br />
• Ausfallsicherheit. Das verteilte System soll möglichst robust gegen Knotenausfälle<br />
sein <strong>und</strong> auf einen Ausfall angemessen reagieren.<br />
• Zugriff auf laufende Simulationen. Dem Benutzer soll es erlaubt sein, während der<br />
Ausführung auf seine Simulationen zuzugreifen. Dazu zählt im Besonderen: Anhalten<br />
<strong>und</strong> Fortfahren von Simulationen, Abbrechen von Simulationen <strong>und</strong> Umziehen<br />
von Simulationen auf andere Rechner.<br />
• Ausgewogenheit. Die Anwenderprogramme für den Zugriff auf das verteilte System<br />
sollen einerseites dem erfahrenen Benutzer einen schnellen Zugriff erlauben, andererseits<br />
sollen sie dem unerfahrenen Benutzer den Einstieg erleichtern. Dazu zählt<br />
insbesondere eine möglichst intuitive Bedienbarkeit der Programme.<br />
• einfache Erstellung von Simulationen. Ein Modul soll einfach benutzbar sein <strong>und</strong><br />
den Benutzer nicht zwingen, sich vor dem Gebrauch mit der <strong>Implementierung</strong><br />
des Moduls auseinanderzusetzen. Im Idealfall sollen sich Simulationen vollständig<br />
ohne Programmierkenntnisse erstellen lassen <strong>und</strong> Programmierkenntnisse nur für<br />
die Erstellung <strong>und</strong> Programmierung eigener Module erfordern.<br />
Das Lethe soll in der Abteilung TAIT 1 der Universität Ulm eingesetzt werden <strong>und</strong><br />
dort zu einfacheren <strong>und</strong> schnelleren Simulationen von Algorithmen zur Kanalcodierung<br />
dienen. Um die vorhandene Rechenerstruktur möglichst gut nutzen zu können, soll Lethe<br />
plattformunabhängig sein.<br />
1.3 Der Anwender<br />
Da es im Kontext von Lethe drei getrennte Rollen von Anwendern gibt, verwenden die<br />
folgenden Kapitel die hier aufgelisteten Termini.<br />
Entwickler Anwender, der einen neuen Algorithmus simulieren will <strong>und</strong> ihn deshalb<br />
unter Verwendung der Programmierschnittstelle von Lethe implementiert.<br />
Benutzer Anwender, der auf eine gegebene Menge von Algorithmen zurückgreift <strong>und</strong><br />
daraus eine Simulation erstellt, die Lethe ausführen soll.<br />
1 Telekommunikationstechnik <strong>und</strong> Angewandte Informationstheorie<br />
3
1 Einführung<br />
Administrator Anwender, der das System betreut. Er verwaltet die Benutzer <strong>und</strong> ihre<br />
Rechte. Er fügt neue Knoten in das verteilte System hinzu <strong>und</strong> entfernt alte.<br />
4
2 Gr<strong>und</strong>lagen<br />
In diesem Kapitel soll dargestellt werden, welche Möglichkeiten für Simulationen in der<br />
Kanalcodierung bereits existieren. Anschließend werden die Technologien erläutert, die<br />
für das Verständnis der weiteren Arbeit notwendig sind.<br />
Dazu wird im ersten Abschnitt zuerst auf bereits exisitierende Simulationsprogramme<br />
eingegangen. Dieser Abschnitt ist komplett aus der Diplomarbeit von Alexander<br />
Bernauer [7] übernommen worden <strong>und</strong> dient dem besseren Verständnis für die Anforderungen,<br />
die an das verteilte System gestellt sind.<br />
Im zweiten Abschnitt wird auf die Inter<strong>net</strong> Communications Engine (ICE) eingegangen,<br />
die für den <strong>Entwurf</strong> <strong>und</strong> die <strong>Implementierung</strong> des <strong>verteilten</strong> <strong>Systems</strong> in der<br />
Diplomarbeit verwendet wird. Nach einem kurzen Überblick über das Framework werden<br />
die einzelnen Dienste beschrieben, die ICE unterstützt.<br />
Der dritte Abschnitt beschäftigt sich mit der Extensible Markup Language (XML), das<br />
ein inzwischen weit verbreiteter Standard für Beschreibungssprachen ist. In Verbindung<br />
mit XML wird die Grammatikbeschreibung XML-Schema sowie die Extensible Stylesheet<br />
Language Transformation (XSLT) beschrieben.<br />
Abschließend wird im vierten Abschnitt ein kurzer Überblick über die in der <strong>Implementierung</strong><br />
verwendete Programmiersprache Java, sowie auf die für die Diplomarbeit<br />
wichtigen Bibliotheken gegeben.<br />
2.1 Simulationsprogramme<br />
dieser Abschnitt stammt vollständig aus der Diplomarbeit von Alexander Bernauer<br />
Ein weitverbreitetes <strong>und</strong> sehr beliebtes Simulationsprogramm ist Matlab [29]. Dabei<br />
ist es im eigentlichen Sinn kein Simulationsprogramm, sondern eine allgemeine Plattform<br />
für numerische Berechnungen. Gründe für die Beliebtheit <strong>und</strong> die weite Verbreitung sind<br />
sicherlich die mächtige Matlab Programmiersprache <strong>und</strong> die sehr umfangreichen Bibliotheken.<br />
Damit ist es möglich, einfach <strong>und</strong> in kurzer Entwicklungszeit komplexe Berechnungen<br />
durchzuführen. Mit etwas Programmieraufwand lassen sich diese Berechnungen<br />
schließlich zu einer Simulation verknüpfen.<br />
Ein großes Problem, das sich dem Einsatz von Matlab in den Weg stellt, ist der<br />
hohe Preis für eine Lizenz. Je nach Lizenztyp kostet das Basispaket bis zu 1900 US<br />
Dollar. Dazu kommen weitere Kosten für Zusatzpakete, die zwischen $ 400 <strong>und</strong> $ 5000<br />
liegen (Stand 10. April 2006). Für den, der sich diese Ausgaben sparen möchte, besteht<br />
die Möglichkeit, auf eine freie Alternative wie Scilab [46] oder mit eingeschränktem<br />
Funktionsumfang auch GNU Octave [37] zurückzugreifen.<br />
Die Unterstützung für verteiltes <strong>und</strong> paralleles Rechnen muss bei Matlab mit Hilfe<br />
von Zusatzpaketen nachgerüstet werden. Die meisten dieser Pakete verwenden eine<br />
5
2 Gr<strong>und</strong>lagen<br />
<strong>Implementierung</strong> des “Message Passing Interface” (MPI [35]) oder die “Parallel Virtual<br />
Machine” (PVM [41]). Beides bedeutet, dass der Entwickler die Algorithmen zur<br />
Verteilung von Hand implementieren muss. Letzteres zwingt sogar zum Einsatz einer<br />
homogenen Hardwarelandschaft. Diesen Nachteil bringen auch die Pakete mit, die eine<br />
transparente Verteilung bieten, da sie einen Cluster wie z.B. Beowulf [5] voraussetzen.<br />
Scilab unterstützt die PVM von Haus aus. Für GNU Octave existiert ein MPI basierter<br />
Klon namens Parallel Octave. Beide bringen jeweils die oben genannten Nachteile mit<br />
sich.<br />
Matlab <strong>und</strong> seine Alternativen bringen keine Unterstützung zum Migrieren von Simulationen<br />
oder zum Erstellen von Sicherungspunkten mit. Auch die Verteilung der<br />
Rechenkapazitäten im Netzwerk <strong>und</strong> die Durchsetzung von Interessen verschiedener Benutzergruppen<br />
muss mit Mitteln der jeweiligen Systeme von Hand gemacht werden. Da<br />
so etwas von einer Plattform für numerische Berechnungen auch nicht erwartet wird, ist<br />
das nicht verw<strong>und</strong>erlich. Dennoch ist der Einsatz dieser Programme in einem Netzwerk<br />
deshalb unkomfortabel <strong>und</strong> fehlerträchtig.<br />
Wer dem oben erwähnten Programmieraufwand zur Erstellung einer Simulation entgehen<br />
möchte, greift zu einem auf Simulationen spezialisierten Programm, wie z.B.<br />
GoldSim [18]. Über eine graphische Benutzeroberfläche kann der Anwender dort seine<br />
Simulation zusammenstellen <strong>und</strong> die einzelnen Komponenten konfigurieren. Dabei<br />
kann er auf eine umfangreiche Menge von fertigen Kompontenten zurück greifen, so<br />
dass er keine Programmierkenntnisse braucht. Am Ende der Simulation kann er sich<br />
die Ergebnisse graphisch anzeigen lassen <strong>und</strong> mit Hilfe von mitgelieferten Werkzeugen<br />
analysieren. Das ist alles sehr komfortabel. Inwiefern ein Anwender selbst neue Kompontenten<br />
entwickeln kann, ist allerdings unklar. Die oben zitierte Inter<strong>net</strong>seite schweigt<br />
sich darüber aus. Die Lizenz für eine kommerzielle Nutzung von GoldSim kostet $ 3950<br />
für das Basispaket. Für akademische Zwecke existiert eine kostenlose Version mit einem<br />
etwas eingeschränkten Funktionsumfang. Für Zusatzpakete kommen allerdings auf jeden<br />
Fall Kosten zwischen $ 1000 <strong>und</strong> $ 9000 hinzu (Stand 10. April 2006).<br />
Bekannte Alternativen zu GoldSim sind z.B. MLDesigner [33], das “CoCentric <strong>Systems</strong><br />
Studio” [13] <strong>und</strong> das freie Ptolemy [39]. Obwohl die drei Programme jeweils einen<br />
etwas anderen Einsatzzweck haben, ergeben sich für den Kanalcodierer dieselben Probleme.<br />
So ist k<strong>eines</strong> der Programme auf den Einsatz in der Kanalcodierung spezialisiert.<br />
Das bedeutet, dass der Kanalcodierer eine geeig<strong>net</strong>e Abbildung s<strong>eines</strong> Problems auf<br />
das Modell des Simulationsprogrammes finden muss. Das kann mitunter sehr aufwendig<br />
<strong>und</strong> frustrierend sein. Dazu kommt, dass k<strong>eines</strong> der Programme die in der Einführung<br />
aufgelisteten Probleme beim Einsatz in Netzwerken löst. Der Anwender muss selbständig<br />
verteilen <strong>und</strong> die einzelnen Simulationen verwalten. Simulationen migrieren oder<br />
Sicherungspunkte erstellen ist überhaupt nicht möglich.<br />
2.2 ICE<br />
Die Inter<strong>net</strong> Communications Engine (ICE) ist eine objektorientierte Middleware des<br />
Softwareunternehmens ZeroC [23], das es sich zur Aufgabe gemacht hat, ein Framework<br />
zu entwickeln, welches ebenso mächtig wie CORBA <strong>und</strong> dabei aber schlank <strong>und</strong> einfach<br />
6
2.2 ICE<br />
zu bedienen ist. Dazu ermöglicht ICE eine orts- <strong>und</strong> plattformtransparente Kommunikation<br />
zwischen Objekten auf verschiedenen Rechnern.<br />
Außerdem unterstützt ICE eine breite Auswahl an Sprachen: Neben Java <strong>und</strong><br />
C++ auch C#, Python, VisualBasic <strong>und</strong> PHP. Weitere Sprachen können bei kommerziellem<br />
Bedarf hinzukommen. ICE ist auch für viele Plattformen, darunter Windows<br />
(98SE/ME/2000/XP), Linux (i386, x86_64), Solaris 9 (SPARC), HP-UX 11.11<br />
(PA_RISC) sowie MacOS X (10.3 <strong>und</strong> 10.4, PPC), verfügbar. Da nicht jede Sprachumsetzung<br />
von allen Plattformen unterstützt wird, können einzelne Sprachen unter<br />
bestimmten Umständen nicht verwendet werden. Dies betrifft jedoch nicht die in der<br />
<strong>Implementierung</strong> von Lethe verwendeten Sprachen Java <strong>und</strong> C++.<br />
Im Folgenden wird auf die Funktionsweise von ICE eingegangen. Anschließend werden<br />
die Dienste erläutert, die bei der Installation von ICE mitgeliefert werden. Die Beschreibung<br />
weiterer bekannter Middleware-Systeme ist in Abschnitt 3.2.1 ausgelagert. Dies<br />
geschah, um unnötige Wiederholungen zu vermeiden. Der interessierte Leser kann in<br />
den Referenzen auf das jeweilige System zusätzliche Informationen finden.<br />
2.2.1 Funktionsweise<br />
In diesem Abschnitt wird erklärt, wie ICE die Kommunikation zwischen einem Client<br />
<strong>und</strong> Server ermöglicht. Dabei sei der Server ein entferntes Objekt, das Dienste anbietet,<br />
auf die das Client-Objekt zugreifen möchte.<br />
Kommunikation<br />
Die Kommunikation zwischen Client <strong>und</strong> Server findet über sogenannte Proxy-Objekte<br />
statt. Dazu muss der Client einen lokalen Proxy des Servers besitzen auf den er zugreifen<br />
will. Im Abschnitt Auffinden von Objekten wird beschrieben, wie der Client zu<br />
einem Proxy gelangt. Möchte der Client eine Methode auf dem Server aufrufen, benutzt<br />
er dazu das Proxy-Objekt, das den Aufruf entgegennimmt <strong>und</strong> entsprechend der<br />
ICE-Spezifikation [31, Seite 881 ff.] transformiert, um anschliessend einen entfernten<br />
Methodenaufruf auf den Server auszuführen.<br />
Die Transformation der Methodenaufrufe <strong>und</strong> speziell der Methodenparameter in ein<br />
spezifiziertes Format erlaubt ICE eine Abstraktion von der tatsächlich verwendeten<br />
Plattform <strong>und</strong> ermöglicht die Unterstützung der zu Beginn dieses Abschnitts aufgezählten<br />
Systeme.<br />
Schnittstellendefinition<br />
Slice ist die Schnittstellen-Beschreibungssprache von ICE. Mit ihr können neben Schnittstellen<br />
auch eigene Klassen <strong>und</strong> Datenstrukturen definiert werden, die dann für die verteilte<br />
Kommunikation oder zum Persistieren von Daten (vgl. Freeze) verwendet werden<br />
können.<br />
Um Sprachen wie VisualBasic zu unterstützen, die nicht zwischen Gross- <strong>und</strong> Kleinschreibung<br />
in Bezeichnernamen unterscheiden, differenziert auch Slice nicht zwischen ihnen.<br />
Allerdings muss eine einmal gewählte Schreibweise beibehalten werden. Außerdem<br />
7
2 Gr<strong>und</strong>lagen<br />
wird der Namensraum für eigene Strukturen <strong>und</strong> Parameter durch die von ICE reservierten<br />
Wortteile (ice, ptr, prx, helper) <strong>und</strong> dem Verbot des Unterstrichs eingeschränkt.<br />
Diese Einschränkungen werden benötigt, um Namenskollisionen zwischen generierten<br />
Hilfsklassen <strong>und</strong> Benutzercode zu verhindern.<br />
Die Slice-Definitionen können mit speziellen Parsern, wie zum Beispiel slice2java oder<br />
slice2cpp, in sprachspezifischen Code transformiert werden. Desweiteren können in der<br />
Slice-Definition sprach- <strong>und</strong> ausführungsspezifische Details angegeben werden. Dazu<br />
zählt zum Beispiel, ob eine Sequenz in ein Array oder eine Liste in Java übersetzt werden<br />
soll, oder ein Methodenaufruf asynchron stattfindet. Diese Informationen werden<br />
von den entsprechenden Parsern ausgewertet <strong>und</strong> umgesetzt.<br />
Auffinden von Objekten<br />
ICE verwendet einen Registry genannten Namensdienst, um Objekte im <strong>verteilten</strong> System<br />
zu finden. Dazu müssen sich neue Objekte, die einen Dienst anbieten möchten, bei<br />
dem Namensdienst anmelden. Wird dieser anschließend von einem Client nach einem<br />
bei ihm angemeldeten Objekt gefragt, kann er einen Proxy auf das gesuchte Objekt<br />
zurückgeben. Dieser Proxy enthält die Adresse des entfernten Objekts <strong>und</strong> wird vom<br />
Client für Zugriffe auf das Objekt benutzt, solange dieses existiert <strong>und</strong> erreichbar ist.<br />
Um den Lesefluss zu erleichtern, ist in den folgenden Kapiteln ausschließlich von einem<br />
Namensdienst im <strong>verteilten</strong> System die Rede. Gemeint ist damit immer die Registry von<br />
ICE.<br />
Neben der Verwendung der Registry besteht bei ICE auch die Möglichkeit, entfernte<br />
Objekte anhand ihres Namens <strong>und</strong> ihrer Adresse (IP-Adresse <strong>und</strong> Portnummer) zu<br />
erreichen. Für ein größeres, verteiltes System birgt diese Vorgehensweise jedoch den<br />
Nachteil, dass Objekte nicht transparent auf andere Rechner verlagert werden können.<br />
Hierauf wird an dieser Stelle nicht näher eingegangen, weitere Informationen finden sich<br />
in [31].<br />
Synchrone <strong>und</strong> asynchrone Kommunikation<br />
ICE erlaubt sowohl synchrone als auch asynchrone Methodenaufrufe. Während bei einem<br />
synchronen Methodenaufruf der Client blockiert ist, bis er eine Antwort vom Server<br />
erhält, wird die Programmausführung nach einem asynchronen Aufruf normal fortgesetzt<br />
<strong>und</strong> eine spezielle Callback-Methode gerufen, wenn die Antwort vom Server verfügbar<br />
ist.<br />
Desweiteren bietet ICE auch eine serverseitige asynchrone Verarbeitung von Methodenaufrufen<br />
an: Diese erlaubt es dem Server, eine Anfrage zu einem späteren Zeitpunkt<br />
zu bearbeiten <strong>und</strong> eine entsprechende Antwort zu senden. Dafür stellt die ICE-<br />
Umgebung dem Server für jeden Aufruf ein sogenanntes Caller-Objekt zur Verfügung,<br />
das die Anfrage kapselt <strong>und</strong> erst nach entsprechendem Methodenaufruf den Rückgabewert<br />
an den Client sendet.<br />
Ob ein Methodenaufruf asynchron stattfindet oder auf Serverseite asynchron bearbeitet<br />
werden soll, muss in der entsprechenden Schnittstellendefinition angegeben werden<br />
(vgl. Schnittstellendefinition).<br />
8
2.2 ICE<br />
Fehlertoleranz<br />
ICE erlaubt die Replikation <strong>eines</strong> Dienstes über mehrere Knoten hinweg, so dass bei einem<br />
Knotenausfall auf einen Replikanten zugegriffen werden kann. Dieser Zugriff erfolgt<br />
für den Entwickler transparent durch die ICE-Umgebung.<br />
2.2.2 Dienste<br />
Neben der eigentlichen Funktionalität werden auch verschiedene Dienste für die Kommunikation<br />
von ICE-Objekten angeboten. Auf die für die Diplomarbeit wichtigsten<br />
Dienste wird im Folgenden kurz eingegangen. Eine umfassendere Erklärung für jeden<br />
Dienst findet sich in [31].<br />
IceGrid Der Einsatz von IceGrid erlaubt eine einfache Konfiguration <strong>und</strong> Verwaltung<br />
von <strong>verteilten</strong> Systemen. Ihr Aufbau <strong>und</strong> die am System beteiligten Knoten können<br />
an einer zentralen Stelle angegeben <strong>und</strong> konfiguriert werden. Anschließend lassen<br />
sich die Dienste auf den einzelnen Knoten zentral starten, beenden <strong>und</strong> aktualisieren.<br />
Ebenso können Änderungen am System im laufenden Betrieb eingespielt<br />
werden.<br />
Zusätzlich werden Load-Balancing-Informationen über die einzelnen Knoten zur<br />
Verfügung gestellt, so dass eine Auswahl der verwendeten Dienste anhand ihrer<br />
Auslastung möglich ist.<br />
Freeze Freeze erlaubt es, auf einfache Art <strong>und</strong> Weise zuvor in Slice definierte Strukturen<br />
dauerhaft abzuspeichern. Dazu werden zwei verschiedene Möglichkeiten angeboten:<br />
FreezeMap erzeugt eine assoziative Liste, die den Zugriff auf festgelegte<br />
Strukturen über Schlüssel-Bezeichner erlauben. Die andere Möglichkeit ist die<br />
Benutzung des Evictors: Er erlaubt das automatische Sichern <strong>und</strong> Starten von<br />
Diensten. Da er in der weiteren Diplomarbeit nicht verwendet wird, sei für weitere<br />
Informationen auf [31] verwiesen.<br />
IcePatch Um Programmcode oder Daten zu synchronisieren, bietet ICE mit IcePatch<br />
einen einfach zu benutzenden Dienst an. Er erlaubt eine checksummenbasierte,<br />
inkrementelle Synchronisation von Verzeichnissen.<br />
IceStorm IceStorm ist ein einfach zu bedienender Publisher-Subscriber-Dienst, mit dessen<br />
Hilfe sich Sender <strong>und</strong> Empfänger entkoppeln lassen. Beliebig viele Empfänger<br />
können sich bei IceStorm für ein spezielles Thema registrieren. Möchte eine Sender<br />
zu diesem Thema Informationen verteilen, sendet er sie an den IceStorm-Dienst,<br />
der wiederum die Zustellung an die entsprechenden Empfänger vornimmt.<br />
IceSSL Genaugenommen ist IceSSL kein Dienst sondern ein Plugin von ICE. Es erlaubt<br />
die Verwendung des Secure Sockets Layer (SSL) [3] als Übertragungsprotokoll, um<br />
die Kommunikation abzusichern. Die Authentifizierung erfolgt dabei auf Basis von<br />
signierten Zertifikaten. Die Verwendung von IceSSL lässt sich zu einem bestehenden<br />
System sehr einfach hinzukonfigurieren, da es transparent für die Dienste<br />
abläuft.<br />
9
2 Gr<strong>und</strong>lagen<br />
Desweiteren gibt es noch (Stand: Mai 2006 ) IceBox <strong>und</strong> Glacier. IceBox dient im <strong>verteilten</strong><br />
System als Applikationsserver <strong>und</strong> erlaubt es, die benötigten Dienste selbständig<br />
aus Bibliotheken oder Java-Klassen bei Bedarf nachzuladen. Da er für den <strong>Entwurf</strong><br />
<strong>und</strong> die <strong>Implementierung</strong> des <strong>verteilten</strong> <strong>Systems</strong> von Lethe nicht benötigt wird, wird an<br />
dieser Stelle nicht weiter auf ihn eingegangen.<br />
Glacier ist eine einfach zu konfigurierende Firewall <strong>und</strong> zugleich Router für ICE-<br />
Objekte. Sie kann Clientanfragen authentifizieren <strong>und</strong> filtern, außerdem kann sie auch<br />
zusammen mit einer herkömmlichen Firewall sinnvoll eingesetzt werden, damit nicht für<br />
jeden Dienst ein Port freigeschaltet werden muss.<br />
2.3 XML<br />
Die Extensible Markup Language (XML) [11] ist ein mittlerweile sehr weit verbreiteter<br />
Standard des World Wide Web Consortiums (W3C) [48] für die Beschreibung <strong>und</strong><br />
Strukturierung von Daten. XML ist eine Metasprache, mit deren Hilfe man anwendungsspezifische<br />
Sprachen erstellen kann, jedoch spezifiziert sie weder die Grammatik noch<br />
die Sprachelemente. Dies geschieht erst mit Hilfe einer sogenannten Schemabeschreibung<br />
(vgl. Abschnitt 2.3.1).<br />
Die Daten werden durch Paare sich öffnender <strong>und</strong> schließender spitzer Klammern<br />
(Tags) strukturiert, wodurch XML-Dateien menschenlesbar sind. Desweiteren gibt es<br />
durch die weite Verbreitung von XML mittlerweile sehr gute XML-Editoren, die Benutzern<br />
bei der Erstellung von XML-Dateien zu Hand gehen.<br />
Eine XML-Datei heisst wohlgeformt, wenn sie den Regeln für XML entspricht. Dies<br />
bedeutet speziell, dass für jeden öffnenden Tag ein schließender Tag auf derselben hierarchischen<br />
Ebene existiert. Desweiteren nennt man eine XML-Datei gültig oder valide,<br />
wenn sie das für die Anwendung spezifizierte Schema einhält.<br />
2.3.1 XML-Schema<br />
Da eine reine XML-Beschreibung der Daten noch keine feste Grammatik besitzt, wird<br />
eine Möglichkeit benötigt, die Struktur der Daten zu beschreiben. Dies ermöglicht eine<br />
leichtere Verarbeitung der Daten durch verschiedene Applikationen, da sich die Programme<br />
darauf verlassen können, dass eine valide XML-Datei ihrer Grammatik genügt.<br />
Die Spezifikation der Grammatik kann dabei mit Hilfe von XML-Schema erfolgen,<br />
einer Sprache, die wiederum selbst in XML beschrieben ist. Weitere Informationen dazu<br />
finden sich in [16, 47, 8]. XML-Schema erlaubt – im Gegensatz zu ihrer Vorgängersprache,<br />
der in XML integrierten Document Type Definition – eine sehr feingranulare<br />
Beschreibung der Struktur, sowie eine Beschränkungsmöglichkeit der Element- <strong>und</strong><br />
Attributinhalte auf spezielle Typen, wie z.B. eine Datumsangabe oder einen Bytewert.<br />
Damit erlaubt XML-Schema bereits bei der Validierung der XML-Datei eine Überprüfung<br />
auf die Korrektheit der Daten.<br />
10
2.4 Java<br />
2.3.2 XSLT<br />
Mit Hilfe einer Extensible Stylesheet Language Transformation (XSLT) [26] können die<br />
Daten einer XML-Datei in ein anderes, in der Transformationsdatei direkt beschriebenes<br />
Format umgewandelt werden.<br />
Eine Transformation besteht dabei aus der wiederholten Anwendung einzelner Transformationsvorschriften.<br />
Diese Transformationsvorschriften, Templates genannt, werden<br />
dann auf die angegebenen Elemente angewandt <strong>und</strong> das Ergebnis der Transformationsvorschriften<br />
ausgegeben.<br />
Momentan ist XSLT 1.0 (Stand: Mai 2006 ) der offizielle Standard. XSLT 2.0 liegt<br />
derzeit nur als Candidate Recommendation des W3Cs vor. Jedoch existieren bereits<br />
einige XSLT-Prozessoren, die XSLT 2.0 unterstützen. Da die neue Version deutliche Erleichterungen<br />
bei der Definition von Transformationsvorschriften im Vergleich zu XSLT<br />
1.0 besitzt, wird für Lethe die neue Version benutzt.<br />
Im Zusammenhang mit XSLT müssen auch XPath [6] <strong>und</strong> XQuery [9] erwähnt werden,<br />
die beide von XSLT 2.0 unterstützt werden. XPath ist eine Anfragesprache, die die<br />
Adressierung von Elementen <strong>und</strong> Attributen anhand der hierarchischen Struktur in einer<br />
XML-Datei erlaubt. Dazu stehen Angaben wie child für die Kinder <strong>eines</strong> Elements oder<br />
parent für den Vater <strong>eines</strong> Elements zur Verfügung. Alternativ lassen sich Elemente<br />
auch durch relative oder absolute Pfade adressieren.<br />
XQuery ist eine turingvollständige Programmiersprache, die im Verb<strong>und</strong> mit XPath<br />
einfache Abfragen von Werten in XML-Dateien erlaubt. Diese lassen innerhalb der Sprache<br />
sortieren, vergleichen <strong>und</strong> bearbeiten. Desweiteren erlaubt XQuery Variablen <strong>und</strong><br />
benutzerdefinierte Funktionen.<br />
Zusammen stellen XPath <strong>und</strong> XQuery ein mächtiges Werkzeug für XSLT dar, um<br />
Transformationsvorschriften zu beschreiben.<br />
2.4 Java<br />
Obwohl Java mittlerweile weit verbreitet ist, soll an dieser Stelle ein kurzer Überblick<br />
gegeben werden. Speziell die in der <strong>Implementierung</strong> verwendete Reflection-API <strong>und</strong><br />
die JDOM - <strong>und</strong> Saxon-Bibliothek werden in den nächsten Abschnitten erläutert.<br />
Java wurde 1995 offiziell von Sun Microsystems vorgestellt. Momentan liegt die Sprache<br />
in Version 1.5 vor, für die <strong>Implementierung</strong> der Diplomarbeit wird jedoch aufgr<strong>und</strong><br />
der größeren Verbreitung noch die Vorgängerversion 1.4.2 verwendet.<br />
Sie wurde mit dem Ziel entworfen, eine einfache, plattformunabhängige <strong>und</strong> objektorientierte<br />
Sprache zu sein. Durch fehlende Pointerarithmetik, Einfachvererbung <strong>und</strong><br />
einen im System integrierten GarbageCollector zur Speicherbereinigung versucht sie<br />
Tücken, die bei der Programmierung mit C++ auftreten können, zu vermeiden.<br />
Die Plattformunabhängigkeit von Java-Programmen wird durch die Verwendung einer<br />
plattformspezifischen Virtual Machine (VM) erreicht. Dazu wird der Quellcode vom<br />
Übersetzer in Bytecode umgewandelt, der von der VM interpretiert wird. Dadurch wird<br />
die Ausführung von Java-Programmen zwar langsamer als bei gleichwertigen, kompilierten<br />
C++-Programmen, jedoch wird dieser Geschwindigkeitsvorteil von C++ durch<br />
11
2 Gr<strong>und</strong>lagen<br />
Just-In-Time-Übersetzer [27] <strong>und</strong> die sogenannte HotSpot-Technologie, die während der<br />
Laufzeit Teile der Programme in Maschinencode übersetzt, weitestgehend kompensiert.<br />
2.4.1 Reflection-API<br />
Java-Programme enthalten eine beachtliche Menge an Laufzeifzeitinformationen, die<br />
dazu benutzt werden, den Zugriff auf Objekte zu verifizieren <strong>und</strong> aufzulösen [45]. Auf<br />
diese Laufzeitinformationen kann auch mit Hilfe der Reflection-API [45, Seite 645 ff.] aus<br />
dem Programm heraus zugegriffen werden. Damit lassen sich sämtliche Informationen<br />
über ein Objekt auslesen: Sein Name, sein Typ, welche Methodenaufrufe es erlaubt<br />
<strong>und</strong> welche Felder das Objekt besitzt. Desweiteren kann beliebig auf die Felder <strong>und</strong><br />
Methoden zugegriffen werden.<br />
Außerdem ermöglicht es die Handhabung von Objekten, deren Typ zur Programmier<strong>und</strong><br />
Übersetzungszeit noch nicht feststeht. Im Zusammenhang mit Lethe ist das bei<br />
der Erstellung von Simulationsaufträgen wichtig, da erst zur Laufzeit bekannt ist, aus<br />
welchen Modulen die Simulation besteht <strong>und</strong> wie deren Parameter aussehen.<br />
2.4.2 JDOM<br />
JDOM [22] ist eine einfach zu verwendende API zum Erstellen <strong>und</strong> Parsen von XML-<br />
Dokumenten. Dazu stellt es eine einfach zu verwendente Abbildung von XML-Elementen<br />
in Java-Klassen zur Verfügung. Dies erlaubt eine einfache Traversierung der Baumstruktur<br />
von XML. Weiterführende Dokumentationen zu JDOM finden sich in [22, 30].<br />
2.4.3 Saxon<br />
Um mit Hilfe von XSLT XML-Dateien zu transformieren, wird ein entsprechendes<br />
Prozessor-Programm benötigt. Saxon [44] ist ein solcher Prozessor, der sich als Open-<br />
Source Bibliothek in Java verwenden lässt. In der aktuellen Version 8.6.1 unterstützt<br />
Saxon neben XSLT 2.0, XQuery 1.0 auch die Empfehlungen des W3Cs für XPath 2.0<br />
(November 2005).<br />
12
3 Systementwurf<br />
Dieses Kapitel beschreibt <strong>Entwurf</strong> <strong>und</strong> Design des <strong>verteilten</strong> Simulationssystems <strong>und</strong><br />
der beteiligten Komponenten. Ziel des <strong>Entwurf</strong>s ist ein einfaches verteiltes System, in<br />
dem verschiedene Benutzer ihre Simulationen durchführen können. Das Kapitel ist in<br />
drei große Abschnitte untergliedert: den Gr<strong>und</strong>lagen von Simulationen, ihre Integration<br />
im <strong>verteilten</strong> System <strong>und</strong> dem Zusammenspiel der einzelnen Komponenten.<br />
Der erste Abschnitt führt das Modulkonzept ein, beschreibt den Aufbau von Simulationen<br />
generell <strong>und</strong> wie diese formal beschrieben werden müssen, damit sie plattformunabhängig<br />
ausgeführt werden können.<br />
Der zweite Abschnitt befasst sich mit dem gr<strong>und</strong>legenden Aufbau des <strong>verteilten</strong> <strong>Systems</strong><br />
im allgemeinen <strong>und</strong> speziell mit Fragen zur Codeverteilung im <strong>verteilten</strong> System<br />
<strong>und</strong> der Benutzer- <strong>und</strong> Rechteverwaltung, sowie Fragen zur Sicherheit, die sich durch die<br />
Verteilung der Simulationen ergeben. Der Abschnitt schließt mit einem Überblick über<br />
die Kommunikation im <strong>verteilten</strong> System sowie Überlegungen zur Anzahl von Benutzern<br />
<strong>und</strong> Simulationsknoten.<br />
Der dritte Abschnitt beschreibt Details bei der Ausführung von Simulationen. Er<br />
klärt, wie Simulationsaufträge in das verteilte System eingespeist werden <strong>und</strong> wie diese<br />
auf die verfügbaren Simulationsknoten verteilt <strong>und</strong> ausgeführt werden. Desweiteren<br />
beschäftigt sich der Abschnitt mit dem Ende von Simulationen, <strong>und</strong> was mit den Simulationsergebnissen<br />
im <strong>verteilten</strong> System passiert.<br />
Abschließend bietet der vierten Abschnitt einen Überblick über die Dienste, die im<br />
<strong>verteilten</strong> System aktiv sein müssen. Desweiteren stellt er die Anwenderprogramme vor,<br />
mit denen auf das verteilte System zugegriffen werden kann.<br />
3.1 Module <strong>und</strong> Simulationen<br />
Simulationen in der Kanalcodierung basieren typischerweise auf den Komponenten [10]<br />
Quelle, Encodierer, Kanal, Decodierer <strong>und</strong> Senke, die folgendermaßen (vgl. auch Abbildung<br />
3.1) zusammenarbeiten: die Quelle erzeugt Zufallszahlen, die ein Encodierer<br />
mit genügend Red<strong>und</strong>anz versieht, um sie möglichst sicher über den Kanal zu übertragen,<br />
wobei durch Störungen auf dem Kanal die übertragenen Daten verändert werden<br />
können. Anschließend versucht der Decodierer, die ursprünglichen Daten wieder zu rekonstruieren.<br />
Die Senke vergleicht, die rekonstruierten mit den gesendeten Daten.<br />
Diese Komponenten werden in verschiedenen Ausprägungen für viele Simulationen<br />
benötigt. Dazu können noch weitere Komponenten wie zum Beispiel ein Interleaver <strong>und</strong><br />
ein entsprechender Deinterleaver zum Schutz vor Bündelfehlern hinzukommen.<br />
Um die Entwicklungszeit für Simulationen zu verkürzen, bietet es sich deshalb an, die<br />
<strong>Implementierung</strong> der einzelnen Komponenten zu kapseln. Die Kapselung einer Komponente<br />
wird im folgenden als Modul bezeich<strong>net</strong>. Eine Simulation lässt sich dann als<br />
13
3 Systementwurf<br />
Quelle Encodierer Kanal Decodierer Senke<br />
Abbildung 3.1: Gebräuchlicher Aufbau von Simulationen aus einzelnen Komponenten bzw.<br />
Modulen.<br />
Verknüpfung mehrerer Module definieren. Dies soll im folgenden Abschnitt näher untersucht<br />
werden <strong>und</strong> zu einem Modulkonzept führen, das es ermöglicht, aus einzelnen<br />
Modulen eine Simulation zu erstellen.<br />
3.1.1 Module<br />
Ein Modul lässt sich als schwarzer Kasten ansehen, der einen oder mehrere Algorithmen<br />
in sich vereinigt. Die Anzahl der Ein- <strong>und</strong> Ausgänge <strong>eines</strong> Moduls hängt von seiner<br />
Funktionsweise ab <strong>und</strong> kann stark variieren. Eine Simulation lässt sich dann als Verknüpfung<br />
einzelner Module erstellen. Dabei müssen nur die Module neu programmiert<br />
werden, die im <strong>verteilten</strong> System noch nicht vorhanden sind. Ansonsten kann auf bereits<br />
existente Module zugegriffen werden.<br />
Damit ein Modul in vielen Simulationen wiederverwendet werden kann, empfiehlt es<br />
sich, die Module möglichst allgemein zu implementieren <strong>und</strong> mit Hilfe von Konfigurationsparametern<br />
zu spezialisieren.<br />
Die Wiederverwendung von Modulen durch verschiedene Benutzer führt aber zu Konflikten<br />
mit der Anforderung an die einfache Erstellung von Simulationen (vgl. die Anforderungen<br />
in 1.2). Deshalb wird eine Beschreibung des Moduls benötigt, mit deren Hilfe<br />
ein Benutzer feststellen kann, wie <strong>und</strong> in welcher Weise sich Module verknüpfen lassen.<br />
Außerdem muss die Beschreibung die für das entsprechende Modul benötigten Konfigurationsparameter<br />
enthalten. Diese sollten mit sinnvollen Standardwerten vorbelegt sein,<br />
um einem unbedarften Benutzer die Verwendung des Moduls zu erleichtern.<br />
Dafür werden von der Beschreibung folgende Typen bereitgestellt:<br />
• einfache Typen, speziell string, int, long, byte, float <strong>und</strong> boolean<br />
• Enumerationen, die einen Wert aus einer Menge von Zeichenketten annehmen<br />
können<br />
• komplexe Typen, wie Arrays, Tabellen <strong>und</strong> Dictionaries sowie Klassen, die<br />
wiederum alle Typen ausser sich selbst enthalten können.<br />
Neue Datentypen können entweder innerhalb <strong>eines</strong> Moduls oder modulübergreifend<br />
(siehe dazu Abschnitt 3.1.2) definiert werden.<br />
Außerdem muss die Beschreibung die Art <strong>und</strong> Anzahl der Ein- <strong>und</strong> Ausgänge enthalten.<br />
Die Art beschreibt dabei, welcher <strong>und</strong> wie viele Datentypen von dem Modulcode<br />
gelesen beziehungsweise geschrieben werden. Dies ermöglicht eine Aussage darüber, ob<br />
14
3.1 Module <strong>und</strong> Simulationen<br />
zwei Module miteinander verknüpft werden können. Dies ist genau dann möglich, wenn<br />
sie einen Ein- bzw. Ausgang mit demselben Datentyp besitzen.<br />
Um ein Modul in Lethe zu verwenden, werden außer der Beschreibung noch andere<br />
Dateien benötigt: Die modulspezifische <strong>Implementierung</strong> der Schnittstelle [7, Abschnitt<br />
4.4.2] <strong>und</strong> der Ein- <strong>und</strong> Ausgabekanäle, sowie eine Slice-Definition der im Modul verwendeten<br />
Parameter. Die Slice-Definitionen werden benötigt, um sprachunabhängig auf<br />
die Parameter zugreifen zu können <strong>und</strong> sie transparent mit Hilfe von ICE im <strong>verteilten</strong><br />
System zu versenden. Zusätzlich gibt es ein zweites Beschreibungsformat für Module,<br />
das es dem Benutzer erlaubt, die Standardwerte der Konfigurationsparameter einfach<br />
zu ändern. Eine Diskussion über die <strong>Implementierung</strong> von Modulen findet sich in [7,<br />
Abschnitt 4.4.2].<br />
3.1.2 Datentyp<br />
Die Definition eigener Typen innerhalb von Modulen ist in manchen Fällen unvorteilhaft:<br />
Zum einen muss ein Typ in jedem Modul definiert werden, in dem er benötigt<br />
wird, zum anderen können nur Module miteinander verküpft werden, die einen Einbzw.<br />
Ausgabekanal mit demselben Datentyp besitzen. Dies ist jedoch nur möglich,<br />
wenn der entsprechende Datentyp ausserhalb der Module definiert wird, da er sonst<br />
modulspezifisch ist. Deshalb wird ein Beschreibungsformat für Datentypen benötigt,<br />
das von den Modulen eingeb<strong>und</strong>en werden kann. Um die Verwendung für den Benutzer<br />
möglichst einfach zu halten ist es stark an das Beschreibungsformat der Module angelehnt.<br />
Wie bei den Modulen muss der Datentyp vor einer Verwendung zuerst in weitere<br />
Formate konvertiert werden. Dazu gehören: eine <strong>Implementierung</strong>sdatei Typname.h, eine<br />
Slice-Definitionsdatei gen_Typname.ice, sowie verschiedene Ausprägungen mit einer<br />
speziellen Schemabeschreibung.<br />
3.1.3 Simulationen<br />
Eine Simulation besteht aus der Verknüpfung verschiedener Module nach einem bestimmten<br />
Schema. Dabei können Module ausschließlich über Ein- oder Ausgabekanäle<br />
mit demselben Datentyp verb<strong>und</strong>en werden.<br />
Im Gespräch mit den Betreuern wurde deutlich, dass in der Kanalcodierung häufig<br />
eine Simulation mit verschiedenen Parametern durchgeführt wird. Dies geschieht zum<br />
Beispiel, um die Auswirkung unterschiedlich stark gestörter Kanäle auf den Dekodiererfolg<br />
<strong>eines</strong> Algorithmus zu testen. Dieser Sachverhalt wird von Lethe durch das R<strong>und</strong>en-Konzept<br />
unterstützt, das die mehrfache Durchführung einer Simulation erlaubt.<br />
Dazu müssen die Einstellungsparameter der Module in zwei Gruppen geteilt werden:<br />
Konfigurationsparameter, die für alle R<strong>und</strong>en identisch sind, <strong>und</strong> Einstellungsparameter,<br />
die sich in jeder R<strong>und</strong>e ändern können. Eine Generatormatrix (vgl. [10, Seite 21<br />
ff.]) ist ein gutes Beispiel für einen Konfigurationsparameter <strong>eines</strong> Encodierer-Moduls.<br />
Diese Generatormatrix wird dann in allen R<strong>und</strong>en zum Kodieren der Daten verwendet.<br />
Die Rauschleistung des Kanals ist hingegen ein Einstellungsparameter, der sich in<br />
den einzelnen R<strong>und</strong>en häufig unterscheidet. Prinzipiell kann man sagen, dass Einstellungsparameter<br />
die Werte sind, in denen sich die einzelnen Ausführungen unterscheiden<br />
15
3 Systementwurf<br />
<strong>und</strong> anhand deren Auswirkung der Benutzer die Ausführungen miteinander vergleichen<br />
möchte.<br />
Da die einzelnen R<strong>und</strong>en einer Simulation unabhängig voneinander sind, versucht das<br />
verteilte System, diese parallel auszuführen, wenn genügend Ressourcen zur Verfügung<br />
stehen. Dadurch kann eine Simulation, die beispielsweise aus sieben R<strong>und</strong>en besteht,<br />
theoretisch sieben mal schneller durchgeführt werden als wenn die einzelnen R<strong>und</strong>en<br />
hintereinander ausgeführt werden.<br />
Für spezielle Simulationen kann es nötig sein, dass die Kanäle zwischen den Modulen<br />
mit Daten initialisiert sind. Aus diesem Gr<strong>und</strong> kann eine R<strong>und</strong>e in mehrere Phasen<br />
unterteilt werden, die z.B. zur Initialisierung <strong>und</strong> Ausführung verwendet werden können.<br />
Die Anzahl der Phasen pro R<strong>und</strong>e, sowie die aktiven Ein- <strong>und</strong> Ausgänge der Module<br />
müssen ebenfalls in der Simulationsbeschreibung angegeben werden.<br />
Zusätzlich muss für jedes Modul angegeben werden, wo sich der Modulcode im <strong>verteilten</strong><br />
System befindet. Dies ist wichtig, da der Code für die Simulationsausführung<br />
benötigt sind.<br />
3.1.4 Simulationsauftrag<br />
Ein Simulationsauftrag beinhaltet alle notwendigen Informationen, um eine Simulation<br />
im <strong>verteilten</strong> System auszuführen. Dies umfasst:<br />
• Den der Simulation zugr<strong>und</strong>e liegenden Hypergraph (vgl. [7, Abschnitt 3.1.2]),<br />
der durch die Vernüpfung der einzelnen Module entsteht. Dieser beinhaltet eine<br />
Beschreibung der verwendeten Module, wie sie konfiguriert <strong>und</strong> miteinander<br />
verknüpft sind. Der Graph ist während der gesamten Simulationsdauer konstant.<br />
• Eine Menge von Einstellungen für die einzelnen Module.<br />
• Eine Liste der Codeverteilungsdienste (vgl. 3.2.3), die den benötigten Code zum<br />
Erstellen der Simulation vorhalten.<br />
Zusätzlich benötigt ein Simulationsauftrag Metainformationen für seine Verwaltung<br />
im <strong>verteilten</strong> System.<br />
Eine wichtige Information ist die des Besitzers. Der Besitzer <strong>eines</strong> Simulationsauftrages<br />
ist immer der Benutzer, der sie gestartet hat. Er reguliert den Zugriff auf die<br />
Simulation.<br />
Desweiteren benötigt ein Simulationsauftrag eine eindeutige Kennung im <strong>verteilten</strong><br />
System. Diese Kennung erlaubt einen einfachen Zugriff auf die Simulationen, wie er zum<br />
Beispiel für das Abbrechen oder Umziehen von Simulationen benötigt wird.<br />
Um dem Benutzer die Wiedererkennung <strong>eines</strong> Simulationsauftrags zu erleichtern, besitzt<br />
er zusätzlich einen vom Benutzer gesetzten Namen <strong>und</strong> eine möglichst aussagekräftige<br />
Beschreibung. Diese Informationen werden vom <strong>verteilten</strong> System nicht benötigt,<br />
jedoch unterstützen sie den Benutzer, wenn er mehrere aktive Simulationen hat.<br />
16
3.2 Konzeption des <strong>verteilten</strong> <strong>Systems</strong><br />
3.2 Konzeption des <strong>verteilten</strong> <strong>Systems</strong><br />
Ziel dieser Diplomarbeit ist es, Simulationen nicht nur auf Einzelplatzrechnern ausführen,<br />
sondern auch auf mehrere Rechner verteilen zu können. Dies erlaubt zum einen eine<br />
bessere Ausnutzung vorhandener Rechenressourcen, da die Rechner zu jedem Zeitpunkt<br />
möglichst gut ausgelastet werden können. Zum anderen kann es für die Ausführung einer<br />
Simulation einen enormen Geschwindigkeitsvorteil bedeuten, da Teile der Simulation auf<br />
verschiedenen Rechnern parallel ausgeführt werden können.<br />
Dazu wird im folgenden ein verteiltes System entworfen, in dem die in Abschnitt<br />
3.1.4 beschriebenen Simulationsaufträge ausgeführt werden können. Die Problematik,<br />
neue Knoten in das System hinzuzufügen <strong>und</strong> andere daraus zu entfernen, wird durch<br />
ICE gelöst <strong>und</strong> deshalb im Systementwurf nicht weiter behandelt. Sie wird in Abschnitt<br />
4.3.1 angesprochen.<br />
3.2.1 Auswahl der Middleware<br />
Die Verwendung einer Middleware erleichtert eine plattformunabhängige Entwicklung<br />
des <strong>verteilten</strong> <strong>Systems</strong> ungemein, da diese von der tatsächlichen Rechnerplattform abstrahiert,<br />
<strong>und</strong> eine allgemeine Umgebung anbietet, während sie sich für die tatsächliche<br />
Umsetzung in die jeweilige Systemarchitektur kümmert.<br />
Derzeit gibt es mehrere Standards, die für ein objektorientiertes, verteiltes System in<br />
Frage kommen:<br />
• CORBA[14], das von der Object Management Group (OMG) [38] spezifiziert wurde<br />
<strong>und</strong> seither regelmäßig erweitert <strong>und</strong> verbessert wurde<br />
• SOAP[28], das sich speziell für Web-Anwendungen durchgesetzt hat<br />
• RMI [20] für verteilte Java-Objekte<br />
• sowie das von Microsoft entworfene .NET [32]-Framework, das sich in den letzten<br />
Jahren großer Beliebtheit bei der Entwicklung verteilter Anwendungen auf<br />
Windows-Plattformen erfreut.<br />
Das .NET -Framework von Microsoft wurde für die Diplomarbeit nicht weiter in<br />
Betracht gezogen, da im Gegensatz zu den anderen hier beschriebenen Middleware-<br />
Systemen die <strong>Implementierung</strong> von Microsoft ausschließlich Windows-Plattformen unterstützt.<br />
Zwar existiert mit Mono[34] mittlerweile auch eine zu .NET kompatible Umsetzung<br />
des Frameworks für Linux-Systeme, jedoch ergibt die Nutzung von .NET im<br />
Rahmen dieser Arbeit keinen Vorteil gegenüber z.B. CORBA.<br />
Für ein verteiltes System, das ausschließlich in Java programmiert ist, bietet sich<br />
die Verwendung von RMI an. Dies ist bei Lethe jedoch nicht der Fall. Zwar ist es<br />
möglich, RMI in Verbindung mit CORBA zu benutzen. Allerdings ist es fraglich, ob<br />
die Verwendung von zwei verschiedenen Middleware-Systemen sinnvoll ist, wenn Java<br />
auch von CORBA- <strong>Implementierung</strong>en direkt unterstützt wird. Denn zumindest die<br />
Schnittstellen, auf die auch mittels CORBA zugegriffen werden soll, müssen sowohl für<br />
RMI als auch für CORBA definiert sein.<br />
17
3 Systementwurf<br />
SOAP wäre eine weitere Möglichkeit gewesen. Jedoch bietet SOAP für Lethe keinerlei<br />
erkennbare Vorteile, sondern besitzt nur den Nachteil <strong>eines</strong> im Vergleich zu ICE <strong>und</strong><br />
CORBA aufgeblähten <strong>und</strong> langsamen Protokolls. Dies gilt insbesondere, da Lethe keine<br />
webbasierte Anwendung ist, ansonsten wäre die Wahl der Middleware vermutlich auf<br />
SOAP gefallen.<br />
Obwohl sich CORBA sicherlich auch sehr gut für die Kommunikation im <strong>verteilten</strong><br />
System eig<strong>net</strong>, haben Alexander Bernauer <strong>und</strong> ich uns gegen CORBA <strong>und</strong> für die unbekanntere<br />
Middleware ICE entschieden. Diese lässt sich leicht bedienen <strong>und</strong> beinhaltet<br />
darüber hinaus zusätzliche Dienste, die den <strong>Entwurf</strong> <strong>und</strong> die <strong>Implementierung</strong> des <strong>verteilten</strong><br />
<strong>Systems</strong> erleichtern. Speziell zählen dazu der IceGrid-Dienst, das IceSSL-Plugin,<br />
das eine sichere Kommunikation zwischen den Diensten ermöglicht, <strong>und</strong> der IcePatch-<br />
Dienst, der eine einfache <strong>und</strong> schnelle Synchronisierung von Verzeichnissen ermöglicht.<br />
Desweiteren erlaubt ICE sowohl den asynchronen Aufruf, als auch die asynchrone serverseitige<br />
Verarbeitung von Funktionen. CORBA sieht zwar beide auch in der aktuellen<br />
Spezifikation [14] vor, umgesetzt ist es jedoch erst in wenigen <strong>Implementierung</strong>en.<br />
Ein weiterer Vorteil von ICE ist sein kompakter Aufbau. Es wurde von einem kleinen<br />
Entwicklerteam entworfen, implementiert <strong>und</strong> unter der GPL frei verfügbar gemacht.<br />
Im Gegensatz zu CORBA, das von der OMG [38] spezifiziert <strong>und</strong> anschließend von verschiedenen<br />
Firmen implementiert wurde. Diese <strong>Implementierung</strong>en waren früher nicht<br />
frei verfügbar <strong>und</strong> mussten teuer erworben werden. Mittlerweile gibt es jedoch auch freie<br />
<strong>Implementierung</strong>en, wie z.B. [1, 40].<br />
3.2.2 Systemaufbau<br />
Prinzipiell gibt es für die Konzeption <strong>eines</strong> <strong>verteilten</strong> <strong>Systems</strong> zwei Möglichkeiten: Das<br />
System basiert entweder auf einem Client-Server Modell <strong>und</strong> enthält einen zentralen<br />
Koordinator, oder es ist autonom <strong>und</strong> alle Knoten sind gleichberechtigt (siehe dazu<br />
Abbildung 3.2). Beide Systeme haben ihre Stärken <strong>und</strong> Schwächen:<br />
Während ein Ausfall des zentralen Koordinators zu einem Totalausfall des gesamten<br />
<strong>Systems</strong> führen kann, kann ein Ausfall im autonomen System transparent kompensiert<br />
werden. Allerdings ist der Verwaltungs- <strong>und</strong> Programmieraufwand für ein solches System<br />
ungleich höher: Um den Ausfall <strong>eines</strong> Knotens kompensieren zu können, muss dieser<br />
fehlerhafte Knoten von allen korrekten Knoten im System zuverlässig erkannt werden.<br />
Außerdem muss dafür gesorgt werden, daß die Simulationsaufträge rechtzeitig red<strong>und</strong>ant<br />
im System repliziert werden, um den Verlust von Aufträgen durch ausgefallenen Knoten<br />
zu vermeiden. Bei der Verwaltung durch einen zentralen Koordinator lassen sich diese<br />
Probleme größtenteils vermeiden.<br />
ICE unterstützt zwar beide Modelle, setzt jedoch einen speziell ausgezeich<strong>net</strong>en zentralen<br />
Knoten voraus, auf dem ein Namensdienst (vgl. Abschnitt 2.2.1) läuft. Dieser<br />
Namensdienst lässt sich nicht replizieren, obwohl sein Ausfall die Benutzbarkeit des<br />
<strong>Systems</strong> stark beeinträchtigen: Die ICE-<strong>Implementierung</strong> erlaubt zwar weiterhin den<br />
Zugriff auf bereits bekannte verteilte Objekte, jedoch können neue Objekte ohne den<br />
Nmanesdiensr nicht mehr gef<strong>und</strong>en werden. Dieser Nachteil von ICE – zusammen mit<br />
dem höheren Aufwand für ein autonomes System – wiegt meiner Meinung nach schwerer,<br />
18
3.2 Konzeption des <strong>verteilten</strong> <strong>Systems</strong><br />
a)<br />
Zugangspunkt<br />
b)<br />
Zugangspunkt<br />
zentraler Koordinator<br />
Zugangspunkt<br />
Zugangspunkt<br />
Abbildung 3.2: a) verteiltes System mit zentralem Koordinator. Der Zugriff auf das System<br />
erfolgt immer über den Koordinator. b) autonomes System mit gleichberechtigten<br />
Knoten <strong>und</strong> mehreren Zugangspunkten in das verteilte System.<br />
als die Nachteile <strong>eines</strong> zentralen Koordinators <strong>und</strong> ist ausschlaggebend für die Entscheidung<br />
für das Client-Server-Modell.<br />
Ein Nachteil des Client-Server Modells ist, dass der zentrale Koordinator zum Engpass<br />
werden kann <strong>und</strong> die Ausführung im <strong>verteilten</strong> System dadurch verzögert wird.<br />
Aufgr<strong>und</strong> der geringen Kommunikation zwischen den Knoten sollte dieser Fall <strong>verteilten</strong><br />
System von Lethe jedoch nicht eintreten, denn eine nachrichtenbasierte Kommunikation<br />
zwischen den Simulationsknoten <strong>und</strong> dem zentralen Koordinator findet nur statt, um<br />
einen Simulationsauftrag zu starten oder sein Ende bekannt zu geben.<br />
Der <strong>Entwurf</strong> wurde daraufhin optimiert, möglichst wenige Nachrichten zu benötigen.<br />
Das Starten einer Simulation erfordert zum Beispiel maximal drei Nachrichten: eine<br />
Nachricht zum Erstellen <strong>eines</strong> Simulationsobjekts (siehe dazu: [7, Abschnitt 3.2.2]), eine<br />
zweite Nachricht, um das Simulationsobjekt zu initialisieren <strong>und</strong> eine letzte Nachricht,<br />
um die Simulation zu starten. Aufgr<strong>und</strong> der Struktur der Simulationsaufträge (vgl. 3.1.4)<br />
ist die Aufgliederung in diese drei Nachrichten sinnvoll, da sie eine effiziente Wiederverwendung<br />
der Simulationsobjekte erlaubt: Für die Simulation einer weiteren R<strong>und</strong>e<br />
kann das einmal erstelle Simulationsobjekt mit Angabe der R<strong>und</strong>ennummer neu gestartet<br />
werden (vgl. [7, Abschnitt 3.2.2]), die Nachrichten zum Erstellen <strong>und</strong> Initialisieren<br />
des Simulationsobjekts entfallen.<br />
Zusätzliche Kommunikation findet bei verwaltungsbedingten Zugriffen auf die Simulationen<br />
statt. Dazu zählen das Anhalten <strong>und</strong> Fortführen von Simulationen, das Abbrechen<br />
<strong>und</strong> das Erstellen von Sicherungspunkten. Da diese nur ein oder zwei Nachrichten<br />
benötigen, <strong>und</strong> eher die Ausnahme als die Regel darstellen, sollten sie vernachlässigbar<br />
sein.<br />
Problematisch hingegen könnte der Rechenaufwand innerhalb des zentralen Koordinators<br />
sein. Immerhin muss er die Anfragen der Benutzer bearbeiten, Simulationsaufträge<br />
verwalten <strong>und</strong> Statusnachrichten der Simulationsknoten entgegennehmen. Sollte sich<br />
19
3 Systementwurf<br />
herausstellen, das diese Aufgaben den zentralen Koordinator spürbar verlangsamen, so<br />
besteht in ICE die Möglichkeit, dem zentralen Koordinator mehrere Threads zur Verfügung<br />
zu stellen. Speziell auf einer Mehrprozessor-Maschine sollte dies zu einer deutlichen<br />
Beschleunigung führen.<br />
3.2.3 Codeverteilung<br />
Wird auf einem Knoten eine Simulation neu gestartet, so muss sie dort aus den Code-<br />
Dateien neu erstellt werden (siehe [7, Abschnitt 3.2.2]). Dies setzt voraus, dass die<br />
Modulimplementierungen auf den jeweiligen Knoten verfügbar sind, was aber dem <strong>Entwurf</strong>sziel<br />
der leichten Wartbarkeit von Lethe widerspricht. Änderungen an den <strong>Implementierung</strong>en<br />
einzelner Module würden dann ein Update der entsprechenden <strong>Implementierung</strong><br />
auf allen Knoten erfordern.<br />
Dieses Problem lässt sich durch eine zentrale Codeverteilung umgehen. Sie muss Zugriff<br />
auf die Beschreibung <strong>und</strong> <strong>Implementierung</strong> aller verwendbaren Module haben, <strong>und</strong><br />
diese bei Bedarf zur Verfügung stellen. Die Verteilung der Dateien kann idealerweise<br />
über den IcePatch-Dienst von ICE erfolgen. Da IcePatch immer komplette Verzeichnisse<br />
überträgt, muss allerdings für jede Simulation ein eigenes Verzeichnis mit den<br />
benötigten Dateien angelegt werden.<br />
Um die Codeverteilung zu nutzen, müssen vor dem Starten <strong>eines</strong> Simulationsauftrags<br />
alle von der Simulation benötigten Module <strong>und</strong> Typen bei dem Codeverteilungsdienst<br />
unter der Simulations-ID eingetragen werden. Anschließend kann der Generator von<br />
diesem Dienst alle Ressourcen zu dieser ID anfordern. Dazu erhält er von der Codeverteilung<br />
einen lokalen Proxy auf einen IcePatch-Server zugeteilt, über den er die zuvor<br />
angemeldeten Ressourcen synchronisieren kann. Dabei tritt jedoch das Problem auf,<br />
dass der Codeverteilungsdienst nicht wissen kann, wann ein Client seine Synchronisierung<br />
beendet hat <strong>und</strong> er den entsprechenden IcePatch-Server stoppen kann. Dies kann<br />
durch einen speziellen Aufruf des Clients bei der Codeverteilung gelöst werden, so dass<br />
diese den IcePatch-Server anhalten kann. Ebenso muss eine Simulation ihr Ende der<br />
Codeverteilung bekannt geben, damit diese die von der Simulation benötigten Ressourcen<br />
wieder freigeben kann. Geschieht dies nicht, sammeln sich immer mehr unbenutzte<br />
Verzeichnisse an, welche dann manuell gelöscht werden müssen.<br />
Um nicht allen Benutzern des <strong>verteilten</strong> <strong>Systems</strong> die eigenen Module zur Verfügung<br />
zu stellen (z.B. bei industriellen Entwicklungen oder zum Testen von unausgereiftem<br />
Modulcode), besteht die Möglichkeit, verschiedene Dienste zur Codeverteilung zu verwenden<br />
<strong>und</strong> sogar private Dienste zu starten, die alle Module enthalten, die der Benutzer<br />
nicht weitergeben möchte. Dabei muss sichergestellt sein, dass die eigenen Dienste zur<br />
Codeverteilung aktiv sind, während der Simulationsauftrag im <strong>verteilten</strong> System bearbeitet<br />
wird, da bei jeder neuen Erzeugung <strong>eines</strong> Simulationsobjekts auf den Dienst<br />
zugegriffen werden muss.<br />
3.2.4 Benutzer- <strong>und</strong> Rechteverwaltung<br />
Die gemeinsame Nutzung des <strong>Systems</strong> durch mehrere, nicht gleichberechtigte Benutzer<br />
erfordert sowohl eine Benutzerverwaltung als auch ein entsprechendes Rechtesystem,<br />
20
3.2 Konzeption des <strong>verteilten</strong> <strong>Systems</strong><br />
g = Obergruppe von g<br />
g = Benutzer<br />
Aktion für Benutzer/<br />
Gruppe g verboten?<br />
ja<br />
nein<br />
Aktion verboten<br />
Aktion für Benutzer/<br />
Gruppe g erlaubt?<br />
ja nein<br />
Aktion erlaubt<br />
Existiert eine<br />
Obergruppe von g?<br />
ja nein<br />
Aktion verboten<br />
Abbildung 3.3: Schema zur Überprüfung, ob ein Benutzer oder eine Gruppe das Recht zur<br />
Ausführung einer bestimmten Aktion hat.<br />
welches den gemeinsames Zugriff auf die Simulationen in geeig<strong>net</strong>er Weise einschränkt.<br />
Dafür bieten sich mehrere Möglichkeiten: Die Rechte können mit Hilfe von Access Control<br />
Lists [49] durchgesetzt werden, wobei für jede Simulation Zugriffsrechte für verschiedene<br />
Benutzer gespeichert werden können. Soll nun eine Aktion auf eine Simulation<br />
ausgeführt werden, so kann in ihrer Zugriffsliste überprüft werden, ob die Aktion<br />
zulässig ist. Dieses Verfahren hat den Nachteil, das für jede Simulation eine solche Liste<br />
von erlaubten Aktionen geführt <strong>und</strong> gesichert werden muss.<br />
Da anzunehmen ist, dass typischerweise mehr Simulationen ausgeführt werden als<br />
Benutzer vorhanden sind <strong>und</strong> die Zugriffsrechte auf eine Simulation lediglich von dem<br />
Benutzer <strong>und</strong> der Simulation abhängen, ist eine Verwaltung in Form einer Role Based<br />
Access Control (RBAC) [15] sinnvoller. Dabei sind die Zugriffsrechte nicht Bestandteil<br />
der Simulationen selbst, sondern Eigenschaften der Benutzer. Bei RBAC gehört jeder<br />
Benutzer genau einer Gruppe an, welche selbst wieder Mitglied genau einer anderen<br />
Gruppe sein kann. Dadurch ergibt sich eine baumähnliche Struktur mit Gruppen als<br />
innere Knoten <strong>und</strong> den Benutzern als Blätter. Genaugenommen ist diese Struktur ein<br />
Wald, da es mehrere unabhängige Bäume geben kann. Jedem Benutzer <strong>und</strong> jeder Gruppe<br />
können beliebig viele Aktionen erlaubt oder verboten werden. Diese Rechte werden<br />
jeweils auf alle Mitglieder einer Gruppe vererbt, so dass sich, wie in Abbildung 3.3<br />
gezeigt, leicht bestimmen lässt, ob die Rechte für einen speziellen Benutzer vorhanden<br />
sind oder nicht.<br />
Die ersten beiden Entscheidungen (Benutzer oder Gruppe darf nicht bzw. darf die Aktion<br />
durchführen) sind intuitiv verständlich. Ihre Reihenfolge stellt sicher, dass zuerst<br />
die Verbote geprüft werden <strong>und</strong> erst dann die erlaubten Rechte. Die dritte Entschei-<br />
21
3 Systementwurf<br />
any<br />
Gast<br />
Student<br />
Mitarbeiter<br />
G1<br />
St1<br />
St2<br />
Professor<br />
Assistent<br />
P A1 A2<br />
Abbildung 3.4: Exemplarischer Aufbau einer Gruppenhierarchie, bestehend aus den Gruppen<br />
Gast, Student, Mitarbeiter, Professor <strong>und</strong> Assistent, mit einem gemeinsamen<br />
Ursprung. Tatsächliche Benutzer sind G1 (Gast), St1 <strong>und</strong> St2 (Student), P<br />
(Professor) <strong>und</strong> A1 <strong>und</strong> A2 (Assistent). Hat die Gruppe Mitarbeiter das Recht,<br />
Simulationen von Studenten anzuhalten, so könnte A1 eine Simulation von St2<br />
anhalten.<br />
dung anhand der Gruppenzugehörigkeit erlaubt die dynamische Vererbung von Rechten,<br />
so dass sich eine Änderung an den Rechten einer Gruppe sofort auf ihre Mitglieder<br />
auswirkt. Außerdem löst sie das Dilemma, wenn innerhalb der Gruppenhierarchie sich<br />
widersprechende Rechte definiert sind. In diesem Fall hat das Recht Vorrang, das sich<br />
am nächsten auf dem Weg vom Blatt zur Wurzel befindet.<br />
Dieses Vorgehen erlaubt eine einfache <strong>und</strong> intuitive Rechteverwaltung, da Gruppen<br />
für bestimmte Aktionen vordefiniert werden können <strong>und</strong> bei den einzelnen Benutzern<br />
nur noch davon abweichende Rechte explizit angegeben werden müssen. Im universitären<br />
Bereich böte sich beispielsweise folgende Gruppeneinteilung an: Die Gruppe Gast, deren<br />
Mitglieder Simulationen starten <strong>und</strong> abbrechen dürfen; eine Gruppe der Studenten, die<br />
zusätzlich Simulationen anhalten oder fortführen können; die Mitarbeiter, die zudem<br />
in der Lage sind, Simulationen umzuziehen <strong>und</strong> weiter in Assistenten <strong>und</strong> Professoren<br />
unterteilt sind. Dieser Aufbau ist in Abbildung 3.4 exemplarisch dargestellt.<br />
Diese Vorgehensweise verhindert einen unbefugten Zugriff. Da es aber möglich sein<br />
soll, unter Umständen auch auf fremde Simulationen zuzugreifen, müssen die Rechte <strong>und</strong><br />
Aktionen erweitert werden. Eine solche Situation tritt zum Beispiel ein, wenn ein Mitarbeiter<br />
eine dringende Simulation durchführen will, alle Ressourcen jedoch von Studenten<br />
belegt sind. In diesem Fall soll es möglich sein, das der Mitarbeiter die Simulationen<br />
der Studenten anhalten kann, um seine Simulation durchzuführen. Andersherum sollen<br />
Studenten jedoch keinen Zugriff auf die Simulation des Mitarbeiters erhalten. Deshalb<br />
wird eine Erweiterung der Aktionen <strong>und</strong> Rechte benötigt, um die Information auf welche<br />
Benutzergruppe ein Recht angewandt werden darf. Sind Benutzer <strong>und</strong> Besitzer der<br />
22
3.2 Konzeption des <strong>verteilten</strong> <strong>Systems</strong><br />
Simulation identisch, so wird das ursprüngliche Verfahren beibehalten, ansonsten wird<br />
das Verfahren, wie in Abbildung 3.5 dargestellt, erweitert.<br />
Zu beachten ist die Änderung zu Beginn der Überprüfung: Sie bedeutet, das sich<br />
Zugriffsrechte sowohl aus Benutzer- als auch Besitzersicht vererben. Solange keine explizites<br />
Verbot oder eine explizite Erlaubnis vorliegen, wird in die Gruppenhierarchie<br />
des Besitzers einer Simulation aufgestiegen, um zu prüfen, ob Rechte auf diese Gruppe<br />
vorliegen.<br />
Somit müsste der Mitarbeiter aus dem letzten Beispiel das Recht besitzen, zusätzlich<br />
Simulationen von Benutzern aus der Gruppe der Studenten anhalten zu dürfen. Dies<br />
ist auch dann möglich, wenn die Gruppe der Studenten weiter unterteilt wurde in Studentengruppen<br />
für einzelne Abteilungen, sofern dem Mitarbeiter nicht der Zugriff auf<br />
einzelne Abteilungsgruppen explizit verboten wurde.<br />
Bisher wurde das Rechtesystem immer im Zusammenhang mit Simulationen betrachtet.<br />
Das ist sicher auch der wichtigste Anwendungsbereich für die Rechteüberprüfung,<br />
allerdings ist sie nicht darauf beschränkt. So wird das Rechtesystem auch zur Zugriffsbeschränkung<br />
auf die Benutzerverwaltung selbst verwendet. Dies verhindert ein unbefugtes<br />
Anlegen, Ändern <strong>und</strong> Löschen von Benutzern <strong>und</strong> Gruppen. Desweiteren können<br />
die bereits definierten Aktionen einfach erweitert werden, um eine Rechteverwaltung für<br />
zukünftige Aufgaben des <strong>verteilten</strong> <strong>Systems</strong> zu erlauben.<br />
Für eine einfachere Benutzung können die Aktionen in Kategorien eingeteilt werden.<br />
Damit ist es möglich, Benutzern <strong>und</strong> Gruppen den Zugriff sowohl auf einzelne Aktionen<br />
als auch auf komplette Kategorien zu erlauben oder zu verbieten. Dabei entspricht eine<br />
Kategorie der Menge aller in ihr definierten Aktionen.<br />
3.2.5 Sicherheit<br />
Das Thema Sicherheit im <strong>verteilten</strong> System muss unter verschiedenen Aspekten betrachtet<br />
werden: Zum einen unter der Ausfallsicherheit, zum anderen darunter, wie sichergestellt<br />
werden kann, dass keine unerlaubten Zugrifffe im <strong>verteilten</strong> System durchgeführt<br />
werden können.<br />
Die Ausfallsicherheit von Simulationsknoten wird dadurch gewährleistet, dass die auf<br />
ihnen ausgeführten Simulationen von dem zentralen Koordinator gesichert werden. Fällt<br />
ein Simulationsknoten aus, kann der Koordinator die entsprechende Simulation auf einem<br />
anderen Knoten neu starten. Der zentrale Koordinator darf die Simulationsaufträge<br />
jedoch nicht ausschließlich im Speicher halten, sondern muss sie auch gegen einen eigenen<br />
Ausfall sichern, indem er sie zum Beispiel in einer Datenbank persistiert. Außerdem<br />
muss er auch seinen internen Zustand sichern, um einen Ausfall kompensieren zu können.<br />
Die Zugriffskontrolle auf das verteilte System ist wesentlich schwieriger zu gewährleisten,<br />
da durch die Verwendung von ICE die Dienste im <strong>verteilten</strong> System theoretisch<br />
jedem zugänglich sind, der die entsprechenden Schnittstellen kennt. Problematisch wird<br />
dies bezüglich den Simulationen. Wenn jeder direkt auf die Simulationsobjekte zugreifen<br />
<strong>und</strong> diese manipulieren kann, ist es schwierig, ein vernünftiges Rechte- <strong>und</strong> Verwaltungssystem<br />
durchzusetzen. Jedes Simulationsobjekt muss dann selbst dafür sorgen,<br />
dass keine unbefugten Zugriffe ausgeführt werden können. Da sich die Simulationsob-<br />
23
3 Systementwurf<br />
g' = Obergruppe von g'<br />
g' = Gruppe des Besitzers<br />
g = Benutzer<br />
g = Obergruppe von g<br />
Aktion für Benutzer/Gruppe g<br />
auf Gruppe g' explizit verboten?<br />
ja<br />
nein<br />
Aktion verboten<br />
Aktion für Benutzer/Gruppe g<br />
auf Gruppe g' explizit erlaubt?<br />
ja<br />
nein<br />
Aktion erlaubt<br />
Existiert eine<br />
Obergruppe von g?<br />
ja nein<br />
Existiert eine<br />
Obergruppe von g'?<br />
ja<br />
nein<br />
Aktion verboten<br />
Abbildung 3.5: Schema zur Überprüfung, ob ein Benutzer oder eine Gruppe das Recht zur Ausführung<br />
einer bestimmten Aktion hat, wenn er nicht Eigentümer des Objektes<br />
ist, auf das die Aktion ausgeführt werden soll.<br />
24
3.2 Konzeption des <strong>verteilten</strong> <strong>Systems</strong><br />
Zone 1<br />
nur Serverzertifikate<br />
Zone 2<br />
Client- <strong>und</strong> Serverzertifikate<br />
Benutzer1<br />
zentraler<br />
Koordinator<br />
Benutzer2<br />
Simulationsknoten<br />
Abbildung 3.6: Aufteilung des <strong>verteilten</strong> <strong>Systems</strong> in zwei Zonen mit unterschiedlicher Authentifizierung.<br />
Die Pfeile geben die Richtung der Authentifizierung bei einem Verbindungsaufbau<br />
an.<br />
jekte ausschließlich auf die Simulation konzentrieren sollen, muss dieser Zugriff generell<br />
verhindert werden.<br />
ICE bietet dafür unter anderem eine leicht konfigurierbare <strong>und</strong> für die Simulationsobjekte<br />
transparente Router- <strong>und</strong> Firewall-Lösung names Glacier an. Sie erlaubt es, eigene<br />
Filterprogramme zu schreiben <strong>und</strong> mit Hilfe von Session-IDs den Zugriff auf bestimmte<br />
Dienste zu verweigern. Allerdings muss der Zugriff über den Router in der Konfiguration<br />
auf Benutzerseite angegeben werden <strong>und</strong> wäre damit leicht zu umgehen.<br />
Um das zu verhindern, müssen sich sämtliche Simulationsknoten in einem privaten,<br />
von den Benutzern nicht erreichbaren Netz befinden. In diesem Fall würde Glacier zwischen<br />
den Benutzern <strong>und</strong> dem privaten Netz vermitteln <strong>und</strong> unbefugte Zugriffe abfangen.<br />
Da dieser Ansatz ein eigenes Sub<strong>net</strong>z für die Simulationsknoten benötigt, wurde er<br />
wieder verworfen.<br />
Stattdessen wird mit Hilfe von IceSSL, einem weiteren Plugin von ICE, das verteilte<br />
System in zwei Zonen aufgeteilt: In der einen Zone befinden sich die Benutzer, in der<br />
anderen Zone die Simulationsknoten. Dazwischen gibt es Dienste wie den zentralen<br />
Koordinator, die aus beiden Zonen erreicht werden können, wie Abbildung 3.6 zeigt.<br />
Die Trennung der beiden Zonen erfolgt mit Hilfe von SSL <strong>und</strong> digitalen Zertifikaten:<br />
In der Zone 1 müssen sich lediglich die Server mit gültigen Zertifikaten gegenüber den<br />
Clients authentifizieren. Zone 2 hingegen erfordert zusätzlich gültige Client-Zertifikate,<br />
ansonsten kann die SSL-Verbindung nicht aufgebaut werden.<br />
Die generelle Verwendung von Server-Zertifikaten bei allen Diensten im <strong>verteilten</strong><br />
System verhindert auch eine andere Sicherheitslücke: Die Fälschung <strong>eines</strong> Dienstes. So<br />
könnte ein Angreifer den Authentifizierungsdienst fälschen, um an die Zugangsdaten<br />
der Benutzer von Lethe zu gelangen. Dies ist in einem SSL-geschützten Netzwerk nicht<br />
mehr ohne weiteres möglich, da das benötigte Zertifikat fehlt. Um diese Angriffsart zu<br />
verhindern, ist es notwendig, die Zertifikate möglichst gut zu schützen.<br />
Eine Rechteverwaltung verhindert das Ausführen von unberechtigten Aktionen. Damit<br />
ein Benutzer nicht unter fremdem Namen Aktionen ausführen kann, ist es wichtig,<br />
25
3 Systementwurf<br />
das sich jeder, der auf das verteilte System zugreifen möchte, sich zuvor dem System<br />
gegenüber authentifiziert hat. Bei erfolgreicher Authentifikation erhält der Benutzer eine<br />
Session-ID zugewiesen, die ihn fortan im Zusammenhang mit seinem Benutzernamen im<br />
<strong>verteilten</strong> System ausweist <strong>und</strong> jederzeit von den einzelnen Komponenten überprüft werden<br />
kann. Da die Session-ID nur innerhalb des <strong>verteilten</strong> <strong>Systems</strong> verwendet wird <strong>und</strong><br />
hier die Kommunikation geschützt ist, ist ein Diebstahl dieser ID durch einen Angreifer<br />
höchst unwahrscheinlich. Dazu müsste er zuerst einen eigenen Dienst mit entsprechendem<br />
Serverzertifikat in das verteilte System einbringen, den der Benutzer diesen Dienst<br />
auch in Anspruch nimmt, damit der Angreifer an die Session-ID gelangt.<br />
3.2.6 Kommunikation zwischen Komponenten<br />
Die Verknüpfung der einzelnen Komponenten ergibt ein System, wie in Abbildung 3.7<br />
zu sehen ist, mit folgenden Kommunikationspartnern:<br />
• Die Benutzer kommunizieren mit dem zentralen Koordinator für den Zugriff auf<br />
das verteilte System, <strong>und</strong> der Codeverwaltung, um die für eine Simulation benötigten<br />
Module anzumelden. Zuallererst müssen sie sich jedoch bei dem Authentifizierungsdienst<br />
am System anmelden.<br />
• Der zentrale Koordinator kommuniziert mit den Simulationsknoten, um neue Simulationen<br />
zu starten oder laufende Simulationen anzuhalten, abzubrechen oder<br />
umzuziehen. Desweiteren prüft er bei der Rechteverwaltung, ob die Ausführung<br />
einer Benutzeraktion erlaubt ist.<br />
• Die Simulationsknoten konnektieren sich zu der Codeverteilung, wenn sie eine neue<br />
Simulation erstellen möchten. Sie teilen dem zentralen Koordinator Fehler in der<br />
Simulation oder das Ende der Simulation mit.<br />
3.2.7 Systemgröße<br />
Eine wichtige Frage bezüglich <strong>eines</strong> <strong>verteilten</strong> <strong>Systems</strong> ist die nach seiner Größe. Dabei<br />
muss unterschieden werden zwischen der Anzahl der Benutzer, die zeitgleich auf das<br />
verteilte System zugreifen können <strong>und</strong> der Zahl an Knoten im <strong>verteilten</strong> System, die<br />
ohne empfindliche Geschwindigkeitseinbußen verwaltet werden können.<br />
Wie man in Abbildung 3.7 sieht, wird der Hauptteil der Kommunikation über den<br />
zentralen Koordinator durchgeführt. Besonders bei den Aufrufen wie dem Starten von<br />
Simulationen auf Simulationsknoten, das bis zu mehreren Minuten dauern kann, ist es<br />
deshalb wichtig, dass die Ausführung des zentralen Koordinators nicht blockiert wird.<br />
Aus diesem Gr<strong>und</strong> werden sowohl die Anfrage des Benutzers, als auch die Methodenaufrufe<br />
zu den Simulationsobjekten im zentralen Koordinator asynchron ausgeführt.<br />
Dadurch kann der Koordinator weitere Benutzeranfragen entgegennehmen, während er<br />
z.B. auf die Erstellung <strong>eines</strong> Simulationsobjekts wartet.<br />
Die Zahl der Benutzer, die gleichzeitig das verteilte System benutzen können, hängt<br />
damit stark von dem Durchsatz im zentralen Koordinator ab. Für eine Benutzergröße<br />
von 50 bis 70 Personen, wie sie in der Abteilung, in der Lethe eingesetzt werden soll,<br />
26
3.2 Konzeption des <strong>verteilten</strong> <strong>Systems</strong><br />
Benutzer1<br />
Benutzer2<br />
Codeverteilung1<br />
Authentifizierung<br />
zentraler<br />
Koordinator<br />
Rechteverwaltung<br />
Codeverteilung2<br />
Simulationsknoten<br />
Abbildung 3.7: Kommunikation im <strong>verteilten</strong> System zwischen den einzelnen Komponenten:<br />
Benutzer, Simulationsknoten, zentraler Koordinator, Codeverteilung, Authentifizierung<br />
<strong>und</strong> Rechteverwaltung.<br />
zu finden ist, sollten diese Überlegungen keine Auswirkung auf die Benutzbarkeit haben.<br />
Denn neben dem tatsächlichen Durchsatz des zentralen Koordinators stellt sich<br />
auch die Frage nach dem typischen Benutzer: Da die Simulationen von Algorithmen zur<br />
Kanalcodierung sehr zeitintensive Simulationen sind (vgl. dazu Abschnitt 3.3.1), wird<br />
die Interaktion <strong>eines</strong> Benutzers mit dem <strong>verteilten</strong> System entsprechend sparsam ausfallen,<br />
so dass Lethe eine weit höhere Benutzerzahl erlaubt, als der reine Durchsatz im<br />
Koordinator vermuten lässt.<br />
Die tatsächliche Obergrenze für die Benutzerzahl lässt sich jedoch nur in einem Feldversuch<br />
feststellen. Sollte sich diese Obergrenze als zu niedrig erweisen, besteht die<br />
Möglichkeit, dem zentralen Koordinator mehrere Ausführungseinheiten durch das ICE-<br />
Framework zur Verfügung zu stellen.<br />
Die Anzahl der Simulationsknoten im <strong>verteilten</strong> System wird durch ihre Verwaltung<br />
im Koordinator begrenzt. ICE erlaubt theoretisch beliebig viele Knoten, jedoch spielt<br />
die Anzahl der Simulationsknoten bei der Verteilung von Simulationen (siehe dazu Abschnitt<br />
3.3.3) eine wichtige Rolle. Die im zentralen Koordinator verwendeten Algorithmen<br />
haben eine Komplexität von maximal O(N log N). Dies kommt hauptsächlich durch<br />
die Sortierung der Simulationsknoten nach ihrer momentanen Auslastung zustande. Für<br />
eine realistische Anzahl von 50 bis 100 Knoten im <strong>verteilten</strong> System sollte die Sortierung<br />
die Ausführung nicht behindern. Es gibt sicher eine Schwelle, bei deren Überschreiten<br />
die Verwendung <strong>eines</strong> autonomen <strong>Systems</strong> zeitsparender ist. Dies wurde jedoch im Rahmen<br />
der Diplomarbeit nicht nachgewiesen <strong>und</strong> stellt damit lediglich eine Vermutung<br />
dar.<br />
27
3 Systementwurf<br />
Simulation starten<br />
Benutzer:<br />
zentrale Komponente:<br />
Rechteverwaltung:<br />
Generator:<br />
Simulationsobjekt:<br />
.starte Simulation<br />
a / 1) .überprüfe Rechte<br />
a / 1) .Aktion erlaubt<br />
.erzeuge Simulation<br />
b / 1) .erzeuge Objekt<br />
.Simulation erzeugt od. Fehler<br />
b / 1) .Objekt erzeugt<br />
.Simulation angenommen / Fehler<br />
Abbildung 3.8: Benötigte Kommunikation, um einen Simulationsauftrag in das verteilte System<br />
einzuspeisen.<br />
Der zentrale Koordinator muss jedoch nicht nur Benutzeranfragen bearbeiten, sondern<br />
auch Statusmeldungen von den Simulationsobjekten entgegen nehmen. Deshalb<br />
ist nicht nur die Anzahl der Benutzer, die gleichzeitig auf den Koordinator zugreifen<br />
wollen, entscheidend für den Durchsatz, sondern auch die Zahl der Simulationsobjekte.<br />
Die Simulationsobjekte kontaktieren den zentralen Koordinator, wenn die Durchführung<br />
ihrer Simulation beendet ist. Dies kann durch einen Laufzeitfehler im verwendeten Modulcode<br />
passieren oder durch das Ende der Simulation. Eine solche Nachricht löst beim<br />
Koordinator meist weitere Nachrichten aus, da der Benutzer bei einem Fehler möglichst<br />
sofort darüber informiert werden soll. Außerdem muss der Status des entsprechenden<br />
Simulationsauftrages angepasst werden. Dennoch ist im praktischen Einsatz die Zahl<br />
dieser Nachrichten gering, da sie immer das Ende einer Simulation kennzeichnen.<br />
Die Schnittstellen im zentralen Koordinator sind auf eine minimale Anzahl an Nachrichten<br />
optimiert. Deutlich wird das an folgenden drei Beispielen: dem Hinzufügen einer<br />
neuen Simulation in das verteilte System, dem Abbrechen einer Simulation <strong>und</strong> dem<br />
Umziehen einer Simulation auf einen anderen Simulationsknoten.<br />
Abbildung 3.8 zeigt die benötigte Kommunikation, um einen neuen Simulationsauftrag<br />
in das verteilte System einzubringen: Der Benutzer übergibt den Simulationsauftrag<br />
an den zentralen Koordinator. Nach erfolgreicher Überprüfung, ob der Benutzer<br />
überhaupt Simulationen starten darf, lässt der Koordinator die Simulation auf einem<br />
beliebigen Simulationsknoten erzeugen. Dies hat einen einfachen Gr<strong>und</strong>: Tritt beim Bauen<br />
der Simulation ein Fehler auf, so kann der zentrale Koordinator den Benutzer sofort<br />
darüber informieren. Konnte die Simulation hingegen erfolgreich erzeugt werden, so bestätigt<br />
der Koordinator die Annahme des Simulationsauftrags gegenüber dem Benutzer<br />
<strong>und</strong> kann ihn in die Warteschlange der auszuführenden Simulationen einreihen.<br />
Abbildung 3.9 zeigt, wie eine Simulation im <strong>verteilten</strong> System abgebrochen werden<br />
kann. Nachdem der zentrale Koordinator den Auftrag dazu vom Benutzer erhalten hat<br />
28
Simulation abbrechen<br />
3.3 Simulationsablauf im <strong>verteilten</strong> System<br />
Benutzer:<br />
zentrale Komponente:<br />
Rechteverwaltung:<br />
Simulationsobjekt:<br />
.Simulation abbrechen<br />
1) .überprüfe Rechte<br />
1) .Aktion erlaubt<br />
.Simulation abgebrochen<br />
.Simulation abbrechen<br />
Abbildung 3.9: Kommunikation, um eine laufende Simulation abzubrechen.<br />
<strong>und</strong> dieser die entsprechenden Rechte zu einem Abbruch der Simulation besitzt, beendet<br />
der Koordinator mit einer Nachricht das entsprechende Simulationsobjekt, sofern die<br />
Simulation aktiv ist. Ist die Simulation zu diesem Zeitpunkt pausiert, entfällt diese<br />
Nachricht, <strong>und</strong> der Simulationsauftrag wird direkt aus der Warteschlange gelöscht. Es<br />
werden also entweder vier – dem Benutzer fehlen die entsprechenden Rechte oder die<br />
Simulation ist pausiert – oder fünf Nachrichten benötigt.<br />
Mehr Nachrichten sind nötig, um eine Simulation umzuziehen, wie in Abbildung 3.10<br />
gezeigt wird. Ist die Simulation aktiv, so muss zuerst ein Sicherungspunkt von der Simulation<br />
erzeugt <strong>und</strong> das Simulationsobjekt vom zentralen Koordinator beendet werden.<br />
Anschließend wird auf dem neuen Simulationsknoten ein neues Simulationsobjekt erzeugt,<br />
das gestartet <strong>und</strong> mit dem entsprechenden Sicherungspunkt für die Simulation<br />
initialisiert wird.<br />
3.3 Simulationsablauf im <strong>verteilten</strong> System<br />
Dieser Abschnitt soll klären, wie die Simulationen im <strong>verteilten</strong> System tatsächlich ausgeführt<br />
werden. Dazu zählt auch, wie Benutzer mit dem <strong>verteilten</strong> System interagieren<br />
können, um zum Beispiel Informationen zu ihren laufenden Simulationen zu erhalten.<br />
3.3.1 Entgegennahme <strong>und</strong> Verwaltung von Simulationsaufträgen<br />
Zur Entgegennahme von Simulationsaufträgen wird eine spezifizierte Schnittstelle im<br />
<strong>verteilten</strong> System benötigt. Um den Anforderungen an Lethe gerecht zu werden, muss<br />
diese Schnittstelle Methoden für folgende Aktionen bereitstellen:<br />
• Starten <strong>und</strong> Abbrechen von Simulationen<br />
• Anhalten <strong>und</strong> Fortführen von Simulationen<br />
• Verlagern von Simulationen auf andere Simulationsknoten<br />
29
3 Systementwurf<br />
Simulation umziehen<br />
Benutzer:<br />
zentrale Komponente:<br />
Rechteverwaltung: Simulationsobjekt1:<br />
Generator: Simulationsobjekt2:<br />
.Simulation umziehen<br />
a / 1) .überprüfe Rechte<br />
.Simulation umgezogen<br />
a / 1) .Aktion erlaubt<br />
.Simulation anhalten<br />
.Sicherungspunkt für Simulation<br />
.Simulation beenden<br />
.Simulationsobjekt erzeugen<br />
.Simulationsobjekt erzeugt<br />
.Simulation mit Sicherungspunkt starten<br />
.Simulation gestartet<br />
b / 1) .erzeuge Objekt<br />
><br />
b / 1) .Objekt erzeugt<br />
Abbildung 3.10: Notwendige Nachrichten, um eine Simulation von einem Knoten zum nächsten<br />
umzuziehen. Dazu muss die Simulation auf einem Knoten abgebrochen, <strong>und</strong><br />
auf dem nächsten neu gestartet werden.<br />
Bei der Annahme von Simulationsaufträgen müssen diese gleich gesichert werden.<br />
Diese Vorgehensweise verhindert, dass Aufträge durch den Ausfall <strong>eines</strong> Knotens im<br />
<strong>verteilten</strong> System verloren gehen können, da ein Auftrag alle Informationen beinhaltet<br />
um eine Simulation zu starten.<br />
3.3.2 Erstellen von Sicherungspunkten<br />
Simulationen in der Kanalcodierung arbeiten oft mit sehr großen Datenmengen, um<br />
statistische Fehler zu minimieren. Dies führt meist zu langen Rechenzeiten von mehreren<br />
Tagen bis hin zu einigen Wochen. Deshalb ist es sinnvoll, in regelmäßigen Intervallen<br />
Sicherungspunkte der Simulationen anzulegen <strong>und</strong> gemeinsam mit dem dazugehörenden<br />
Simulationsauftrag zu speichern. Dabei muss ein Sicherungspunkt alle Informationen<br />
enthalten, um die Simulation später an dieser Stelle fortsetzen zu können. Fällt dann<br />
ein Simulationsknoten aus, auf dem eine Simulation läuft, kann diese auf einem anderen<br />
Simulationsknoten von ihrem letzten Sicherungspunkt aus fortgesetzt werden. Das setzt<br />
voraus, dass sich Sicherungspunkte von den Simulationen erstellen lassen können, wie<br />
in [7, Absschnitt 3.1.9] diskutiert wird.<br />
Sicherungspunkte können sowohl von den Benutzern veranlasst werden, als auch vom<br />
zentralen Koordinator in regelmäßigen Abständen angefordert <strong>und</strong> abgespeichert werden.<br />
Dies hat den Vorteil, dass sich die Abstände, in denen Sicherungspunkte angelegt<br />
werden, an einer zentralen Stelle konfigurieren lassen. Standardmäßig fordert der zentrale<br />
Koordinator nach jeder St<strong>und</strong>e einen neuen Sicherungspunkt an, wenn der vorherige<br />
Sicherungspunkt veraltet ist.<br />
30
3.3 Simulationsablauf im <strong>verteilten</strong> System<br />
Eine weitere Möglichkeit wäre gewesen, dass die Simulationsobjekte selbst dem zentralen<br />
Koordinator mitteilen, wann sie bei der Simulationsausführung an einer Stelle<br />
angelangt sind, an denen sich ein Sicherungspunkt effizient, also mit möglichst geringem<br />
Datenvolumen, erstellen lässt. Dies hat jedoch den Nachteil, dass die Erstellung<br />
von Sicherungspunkten abhängig von der Simulation ist: Es kann Simulationen geben,<br />
die alle fünf Minuten in die Lage kommen, einen Sicherungspunkt zu erzeugen, <strong>und</strong><br />
Simulationen, die nie in diesen Zustand gelangen. Deshalb kann bei diesem Verfahren<br />
nicht sichergestellt werden, dass Sicherungspunkte überhaupt in regelmäßigen Abständen<br />
erzeugt werden, im Gegensatz zu der Vorgabe durch den zentralen Koordinator, der<br />
regelmäßig Sicherungspunkte erzwingt.<br />
3.3.3 Verteilen von Simulationen<br />
Typischerweise sollen im Normalfall mehr Simulationsaufträge ausgeführt werden, als<br />
Ressourcen im <strong>verteilten</strong> System vorhanden sind. Aus diesem Gr<strong>und</strong> wird ein Kalkül<br />
benötigt, das die Ressoucenzuteilung auf die Aufträge optimiert. Dabei muss das Kalkül<br />
mehreren Anforderungen gerecht werden: Einerseits soll es möglich sein, Simulationen<br />
mit Prioritäten zu versehen. Dabei sollen höherpriorisierte Simulationen bevorzugt ausgeführt<br />
werden. Andererseits ist jedoch zu beachten, das niederpriorisierte Simulationen<br />
nicht ausgehungert werden, d.h. wegen immer neuen höher priorisierten Simulationen<br />
nie zur Ausführung kommen. Das ist am einfachsten zu erreichen, wenn auch das Alter<br />
der Simulation im Kalkül berücksichtigt wird. Eine mögliche, in Lethe verwendete<br />
Formel ist:<br />
points = prio · age + α · finishedRo<strong>und</strong>s + β · pausedRo<strong>und</strong>s (3.1)<br />
Dabei werden die Simulationen mit den höchsten Punktestand bei der Ressourcenzuteilung<br />
bevorzugt. Außerdem können Gruppen <strong>und</strong> Benutzern eine Priorität zugewiesen<br />
werden, die über prio direkt in den Punktestand einfließt. Das Alter der Simulation wird<br />
durch age berücksichtigt. Damit soll verhindert werden, das Simulationen im <strong>verteilten</strong><br />
System aushungern können. finishedRo<strong>und</strong>s sind zusätzliche Punkte für bereits beendete<br />
R<strong>und</strong>en (vgl. 3.1.3) einer Simulation, gewichtet mit einem Faktor α; pausedRo<strong>und</strong>s<br />
sind zusätzliche, mit β gewichtete Punkte für vom Benutzer explizit angehaltene R<strong>und</strong>en<br />
(vgl. Schnittstellenbeschreibung in Abschnitt 3.3.1) einer Simulation. Der Einfluß<br />
von finishedRo<strong>und</strong>s <strong>und</strong> pausedRo<strong>und</strong>s erlaubt die bevorzugte Ausführung von fast vollständig<br />
durchgeführten Simulationsaufträgen <strong>und</strong> belohnt Benutzer, die eigene Simulationsr<strong>und</strong>en<br />
explizit angehalten haben <strong>und</strong> deren Simulationsauftrag dadurch weniger<br />
Ressourcen belegen kann.<br />
3.3.4 Ausführen von Simulationen<br />
Um eine Simulation auszuführen, muss auf dem entsprechenden Simulationsknoten ein<br />
dazugehörendes Simulationsobjekt für die Simulation vorhanden sein. Ansonsten muss<br />
ein solches neu erzeugt werden. Diese Aufgabe übernimmt ein Generator, der aus den<br />
entsprechenden Modulcodes ein Simulationsobjekt erzeugt, das mit dem Simulationsauftrag<br />
initialisiert wird. Das Simulationsobjekt kann entweder mit einer neuen Simulation<br />
31
3 Systementwurf<br />
beginnen, oder eine ältere Simulation weiterführen. Da die Ausführung von Simulationen<br />
Thema der Diplomarbeit von Alexander Bernauer ist [7], soll an dieser Stelle nicht<br />
näher darauf eingegangen werden.<br />
3.3.5 Ende einer Simulation<br />
Ist eine Simulation beendet, möchte der Benutzer üblicherweise auf die Ergebnisse der<br />
Simulation zugreifen. Hierfür muss eine entsprechende Abfragemöglichkeit im <strong>verteilten</strong><br />
System vorhanden sein.<br />
Ein schwieriger Konflikt ergibt sich allerdings bei der Frage, zu welchem Zeitpunkt<br />
Simulationsaufträge <strong>und</strong> ihre Ergebnisse im <strong>verteilten</strong> System gelöscht werden. Eine<br />
dauerhafte Speicherung der Ergebnisse ist nur dann sinnvoll, wenn die Ergebnisse über<br />
einen längeren Zeitraum <strong>und</strong> für mehrere Benutzer interessant sein können. Löscht man<br />
die Ergebnisse jedoch gleich nach Abruf durch den Besitzer, können andere Nutzer<br />
überhaupt nicht mehr auf diese zugreifen. Für Lethe wurde ein Kompromiss gef<strong>und</strong>en:<br />
Ergebnisse werden zusammen mit den Simulationsaufträgen gesichert, bis sie von einem<br />
dazu berechtigten Benutzer gelöscht werden.<br />
3.3.6 Informationen über laufende Simulationen<br />
Um den Benutzer über den Fortschritt seiner Simulationen zu informieren, wird eine<br />
weitere Schnittstelle benötigt. Sie muss entsprechende Informationen über eine Simulation<br />
bereitstellen, um dem Benutzer einen Überblick über ihren Status zu ermöglichen.<br />
Dazu zählen speziell folgende Punkte:<br />
• Ausführungszeit. Die Zeit, die die Simulation schon lief. Dabei wird unterschieden<br />
zwischen: realer Ausführungszeit, d.h. die Zeit, die die Simulation auf einem<br />
Simulationsknoten ausgeführt wurde, absoluter Ausführungszeit <strong>und</strong> verbrauchte<br />
Rechenzeit. Die absolute Ausführungszeit ist größer oder gleich der realen Ausführungszeit,<br />
<strong>und</strong> gibt die Zeitspanne an, in der die Simulation bereits im <strong>verteilten</strong><br />
System ist. An der Differenz zwischen absoluter <strong>und</strong> realer Ausführungszeit kann<br />
der Benutzer erkennen, wie ausgelastet das verteilte System ist <strong>und</strong> notfalls seine<br />
Simulation pausieren.<br />
• Fortschritt der Simulation. Um einen aussagekräftigen Wert für den Fortschritt<br />
einer Simulation zu erhalten, muss mindestens ein in der Simulation verwendetes<br />
Modul eine Aussage über den Fortschritt machen können. Ist dies der Fall, so<br />
kann der Benutzer daran ablesen, wie weit die Ausführung seiner Simulation bereits<br />
ist. Dieser Fortschritt erlaubt jedoch nur eine bedingte Abschätzung über die<br />
verbleibenden Simulationsdauer, da im Normalfall keine Aussage darüber gemacht<br />
werden kann, wie lange <strong>und</strong> in welcher Reihenfolge die Simulationen ausgeführt<br />
werden (vgl. 3.3.3).<br />
• Status der Simulation. Da im Normalfall mehr Simulationen ausgeführt werden<br />
sollen, als Ressourcen auf den Simulationsknoten zur Verfügung stehen, ist es für<br />
den Benutzer interessant zu wissen, wie es um seine Simulation steht. Der Status<br />
32
3.4 Überblick über die Dienste im <strong>verteilten</strong> System<br />
der Simulation zeigt an, ob eine Simulation gerade auf einem Simulationsknoten<br />
ausgeführt wird, ob sie in der Warteschlange auf eine Zuteilung wartet, ob ein<br />
Fehler aufgetreten ist oder ob sie bereits vollständig ausgeführt wurde.<br />
Um den Kommunikationsaufwand im <strong>verteilten</strong> System zu verringern, werden Statusänderungen<br />
über IceStorm direkt dem Benutzer mitgeteilt, so dass eine regelmäßige<br />
Statusabfrage durch den Benutzer entfallen kann.<br />
• Fehlermeldung. Ist bei der Ausführung der Simulation ein Fehler aufgetreten, so<br />
muss der Benutzer darüber informiert werden, damit dieser entsprechend auf den<br />
Fehler reagieren kann, indem er z.B. die fehlerhafte Simulation abbricht, ausbessert<br />
<strong>und</strong> als neue Simulation startet.<br />
3.4 Überblick über die Dienste im <strong>verteilten</strong> System<br />
Dieser Abschnitt fasst die in den letzten Abschnitten entworfenen Dienste zusammen<br />
<strong>und</strong> beschreibt kurz, wie sie umgesetzt werden können. Im nächsten Kapitel wird dann<br />
ausführlicher auf die Umsetzung der einzelnen Dienste eingegangen. Abschließend werden<br />
die für den Betrieb von Lethe benötigten Anwenderprogramme aufgelistet.<br />
3.4.1 Umsetzung der Dienste<br />
Die in Abschnitt 3.2 entworfenen Dienste können – wie in Abbildung 4.2 gezeigt – in<br />
einzelne Komponenten umgesetzt werden.<br />
• Der Manager übernimmt die Rolle des zentralen Koordinators <strong>und</strong> damit auch<br />
die Verwaltung <strong>und</strong> Verteilung von Simulationsaufträgen. Um den Verlust von<br />
Simulationsaufträgen zu verhindern, werden die Aufträge mit Hilfe von Freeze,<br />
dem Persistierungsdienst von ICE, in einer Datenbank gesichert.<br />
• Die Benutzerverwaltung vereinigt die Benutzerauthentifikation <strong>und</strong> die Rechtevewaltung.<br />
Sie werden als zwei getrennte, aber auf dem gleichen Knoten laufende<br />
Dienste implementiert, die auf eine gemeinsame Benutzerliste zugreifen.<br />
• Die Codeverteilung wird vom Codeverteilungsdienst vorgenommen. Die Modulbeschreibungen<br />
werden über den Synchronisierungsdienst IcePatch den Simulationsknoten<br />
zur Verfügung gestellt.<br />
• Der Generator erstellt auf den Simulationsknoten aus einem Simulationsauftrag<br />
ein Simulationsobjekt.<br />
• Das Simulationsobjekt führt die Simulation auf den Simulationsknoten aus. Dazu<br />
stellt es die Schnittstelle in Abbildung C.2 aus dem Anhang bereit, um Zugriffe<br />
auf die Simulation zu ermöglichen. Die sich daraus ergebenden Probleme werden<br />
– wie auch der Generator – in [7] diskutiert.<br />
33
3 Systementwurf<br />
3.4.2 Anwenderprogramme<br />
Eine wichtige Anforderung an Lethe ist, dass die Benutzeranwendungen flexibel genug<br />
sind, um sich den Bedürfnissen der Benutzer anpassen zu können. Deshalb werden die<br />
Anwenderprogramme in kleine, unabhängige Kommandozeilenprogramme gekapselt:<br />
• Den Paketgenerator, der aus einer Modul- oder Typbeschreibung das entsprechende<br />
Paketformat generiert.<br />
• Die Simulationsverwaltung, die dem Benutzer Zugriff auf das verteilte System ermöglicht,<br />
indem er mit ihrer Hilfe Simulationsaufträge starten, abbrechen, pausieren<br />
<strong>und</strong> umziehen kann. Desweiteren zeigt sie ihm den Status der aktuell ausgeführten<br />
Simulationen an.<br />
• Den Ergebnisexportierer, der die Simulationsergebnisse in ein XML-Format umwandelt,<br />
so dass sie leichter von anderen Programmen weiterverwendet werden<br />
können.<br />
• Die Benutzerverwaltung, die dem Administrator erlaubt, Benutzer <strong>und</strong> Gruppen<br />
neu anzulegen, zu bearbeiten oder zu löschen, ohne dass er in direkten Kontakt<br />
mit der XML-Beschreibung kommt.<br />
• Die Modulsuche, die es dem Benutzer erlaubt, fertige Module <strong>und</strong> Typen im <strong>verteilten</strong><br />
System zu finden <strong>und</strong> für eigene Simulationen zu benutzen.<br />
Zusätzlich zu den Kommandozeilenprogrammen werden die wesentlichen Aufgaben<br />
zum Erstellen <strong>und</strong> Ausführen von Simulationen über eine intuitiv zu bedienende graphische<br />
Oberfläche (GUI) angeboten. Desweiteren soll sie dem Entwickler bei der Erstellung<br />
von neuen Modulen zu Hand gehen.<br />
34
4 <strong>Implementierung</strong><br />
In den folgenden Abschnitten werden wichtige <strong>und</strong> interessante Aspekte aus der <strong>Implementierung</strong><br />
des <strong>verteilten</strong> <strong>Systems</strong> herausgegriffen <strong>und</strong> näher beleuchtet. Dabei wird<br />
speziell auf Fälle eingegangen, in denen der <strong>Entwurf</strong> unterschiedliche <strong>Implementierung</strong>en<br />
zugelassen hätte oder sich unerwartete Probleme durch die Verwendung von ICE<br />
ergeben haben.<br />
Der erste Abschnitt befasst sich mit der Auswahl der geeig<strong>net</strong>sten Programmier- <strong>und</strong><br />
Beschreibungssprache. Der zweite Abschnitt beschäftigt sich mit der Realisierung <strong>und</strong><br />
der Umsetzung von Modulbeschreibungen <strong>und</strong> Simulationsaufträgen in Objekte.<br />
Der dritte Abschnitt behandelt die Umsetzung <strong>und</strong> <strong>Implementierung</strong> der in Abschnitt<br />
3.2 skizzierten Dienste. Dazu wird zuerst ein Überblick über die entstandenen Klassen<br />
gegeben <strong>und</strong> anschließend ihre <strong>Implementierung</strong> näher beschrieben. Dabei wird auch<br />
auf die Probleme eingegangen, die sich bei der Umsetzung ergaben. Desweiteren wird<br />
kurz beschrieben, wie neue Knoten in das verteilte System eingefügt <strong>und</strong> alte Knoten<br />
aus dem System entfernt werden.<br />
Im vierten Abschnitt werden die Anwenderprogramme erklärt, die es dem Benutzer<br />
ermöglichen, seine Simulationen in Lethe auszuführen. Abschließend wird noch auf die<br />
grafische Oberfläche eingegangen.<br />
4.1 Wahl der Programmier- <strong>und</strong> Beschreibungssprachen<br />
Für die Umsetzung des Systementwurfs wird sowohl eine Programmiersprache für die<br />
<strong>Implementierung</strong> der einzelnen Dienste benötigt, als auch eine Beschreibungssprache,<br />
mit der Module <strong>und</strong> Simulationen beschrieben werden können. Im Folgenden wird versucht,<br />
die optimale Sprache für die jeweilige Aufgabe zu finden.<br />
4.1.1 Java versus C++<br />
Ein ausschlaggebendes Kriterium für in Frage kommende Programmiersprache ist, dass<br />
ICE sie vollständig unterstützen muss. Dies trifft momentan (Stand: April 2006 ) ausschließlich<br />
auf Java <strong>und</strong> C++ zu.<br />
Ich habe mich für Java entschieden, weil die Sprache gegenüber C++ speziell bei<br />
der <strong>Implementierung</strong> der Benutzerprogramme viele Vorteile bietet: Java ermöglicht eine<br />
plattformunabhängige Programmierung einer grafischen Benutzeroberfläche <strong>und</strong> eine für<br />
den Benutzer leicht durchzuführende Installation, da der von Java erzeugte Bytecode<br />
durch die Verwendung einer Virtual Machine (VM) plattformunabhängig ist. Eine VM<br />
für Java befindet sich inzwischen bereits auf vielen Rechnern oder lässt sich zumindest<br />
einfach nachinstallieren.<br />
35
4 <strong>Implementierung</strong><br />
Desweiteren erlaubt die Verwendung der Reflection-API von Java einen einfachen<br />
Zugriff auf dynamische, zur Entwicklungszeit unbekannte Strukturen, wie sie zum Beispiel<br />
bei den Konfigurationsparametern von Modulen entstehen. Ein dazu vergleichbares<br />
Konzept ist mir bei C++ nicht bekannt, so dass die Verwendung von C++ an dieser<br />
Stelle entweder die Umsetzung des <strong>Entwurf</strong>s stark eingeschränkt oder die Entwicklung<br />
<strong>eines</strong> entsprechend mächtigen Parsers benötigt hätte. Java erlaubt es, ähnlich wie C++<br />
mit dynamischen Bibliotheken, Klassen während der Ausführung anhand ihres Namens<br />
nachzuladen. Dies ermöglicht die Bereitstellung einer einfachen <strong>und</strong> intuitiven Erweiterungsschnittstelle.<br />
Durch immer bessere Übersetzungsprogramme <strong>und</strong> einem Just-in-Time-Konzept<br />
[27], das den Bytecode während der Ausführung in Maschinencode übersetzt, haben<br />
C++-Programme auch ihren Geschwindigkeitsvorteil gegenüber entsprechenden Java-<br />
Programmen mittlerweile größtenteils eingebüßt.<br />
4.1.2 Beschreibungssprache<br />
Bei der Wahl der Beschreibungssprache war wichtig, dass sowohl die Sprache als auch<br />
das Format möglichst einfach <strong>und</strong> strukturiert ist. Es soll möglich sein, die Modul- <strong>und</strong><br />
Simulationsbeschreibungen ohne spezielle Vorkenntnisse, langer Einarbeitungszeit oder<br />
speziell dafür benötigten Programmen zu erstellen beziehungsweise zu ändern.<br />
Dazu bieten sich mehrere Möglichkeiten an: Zum einen kann ein eigenes Beschreibungsformat<br />
entworfen werden, das speziell auf die Bedürfnisse von Lethe zugeschnitten<br />
ist. Dies hat jedoch neben dem zusätzlichen Aufwand, einen Parser dafür zu entwickeln,<br />
den Nachteil, das sich Benutzer <strong>und</strong> Entwickler erst in das Format einarbeiten müssen,<br />
bevor sie es benutzen können. Diese Schwierigkeit lässt sich durch die Verwendung von<br />
Schlüssel-/Werte-Listen – wie zum Beispiel den .ini-Dateien unter Windows – umgehen.<br />
Jedoch können diese bei größeren, hierarchisch strukturierten Daten sehr unübersichtlich<br />
werden.<br />
Schlussendlich fiel meine Wahl auf XML, das eine einfache Darstellung hierarchisch gegliederter<br />
Daten erlaubt. Seine Struktur aus öffnenden <strong>und</strong> schließenden Tags, zwischen<br />
denen die entsprechenden Daten stehen, ist zum einen leicht erlernbar <strong>und</strong> zum anderen<br />
lassen sich die Daten mit Hilfe von Schemabeschreibungen einfach validieren. Die Verwendung<br />
von Schemabeschreibungen, die den Aufbau <strong>und</strong> die Struktur einer XML-Datei<br />
beschreiben, erleichtern sowohl dem Benutzer das Erstellen der XML-Dateien, als auch<br />
der Anwendung die Verarbeitung der Daten, da mit ihrer Hilfe die formale Korrektheit<br />
der XML-Dateien geprüft werden kann. Da XML ein weit verbreiteter Standard ist,<br />
existieren für die meisten Plattformen bereits spezielle Editoren, die das Erstellen <strong>und</strong><br />
Konfigurieren von XML-Dateien erleichtern <strong>und</strong> die Dateien anschließend validieren.<br />
Die Validierung von XML-Dateien verlangsamt zwar das Parsen von XML-Dateien<br />
merklich, jedoch wird dies dadurch ausgeglichen, das die Anwendung die Daten nicht<br />
mehr selbst überprüfen muss. Desweiteren findet bei Lethe der Einsatz von XML-<br />
Dateien ausschließlich auf Benutzerseite statt, so dass sich eine längere Einlesezeit nicht<br />
negativ auf die Ausführung des Gesamtsystems auswirkt.<br />
36
4.2 Module <strong>und</strong> Simulationen<br />
Ausgangsbeschreibung<br />
modul.xml<br />
modul.xml<br />
spezielle Modulbeschreibung<br />
modul.xsd<br />
Schema für<br />
spezielle Modulbeschreibung<br />
modul.h gen_adapter.xml gen_modul.ice<br />
Modulcode Code für Ein- <strong>und</strong> Ausgänge Slice-Definition<br />
Abbildung 4.1: Aus der Modulbeschreibung werden verschiedene Dateien in unterschiedlichen<br />
Formaten erzeugt.<br />
Außerdem existieren für XML freie Parser in Java, die einfach in eigene Programme<br />
eingeb<strong>und</strong>en werden können. Damit entfällt die Entwicklung <strong>eines</strong> speziell für Lethe<br />
ausgerichteten Parsers.<br />
Für die Transformation der XML-Dateien in die benötigten Formate bietet es sich an,<br />
das speziell für solche Aufgaben entwickelte XSLT zu verwenden. XSLT erlaubt es, das<br />
Ausgabeformat direkt in die Transformationsbeschreibung einzufügen. An den Stellen,<br />
die von XML-Daten abhängen, lassen sich mit Hilfe von XPath <strong>und</strong> XQuery die benötigten<br />
Daten aus der XML-Datei extrahieren <strong>und</strong> entsprechend aufbereitet einfügen.<br />
Dies erlaubt eine kompaktere <strong>und</strong> übersichtlichere Beschreibung einer Transformation<br />
als sie zum Beispiel mit Java möglich wäre.<br />
4.2 Module <strong>und</strong> Simulationen<br />
Im Folgenden wird dargelegt, wie Module <strong>und</strong> Simulationen aus ihrer Beschreibung erstellt<br />
werden <strong>und</strong> welche speziellen Probleme hierbei zu berücksichtigen sind. Anschließend<br />
wird beschrieben, wie aus einer Simulationsbeschreibung ein Simulationsauftrag<br />
erstellt wird, der im <strong>verteilten</strong> System ausgeführt werden kann.<br />
4.2.1 Erzeugen von Modulen<br />
Ein Modul im <strong>verteilten</strong> System besteht aus mehreren Dateien mit unterschiedlichen<br />
Formaten. Abbildung 4.1 zeigt die für ein Modul benötigten Datein. Diese werden mit<br />
Hilfe von XSLT aus der Modulbeschreibung erzeugt. Dabei gibt es für jedes Format eine<br />
eigene Transformationsdatei. XSLT 2.0 unterstützt zwar die Ausgabe in verschiedene<br />
Formate, jedoch ist die Verwendung von separaten Dateien bei Lethe übersichtlicher.<br />
37
4 <strong>Implementierung</strong><br />
Die hier beschriebenen Transformationen gelten in gleicher Weise für die Erzeugung<br />
von modulübergreifenden Datentypen. Allerdings wird für diese keine Benutzerimplementierung<br />
benötigt, da sie keine Ein- <strong>und</strong> Ausgabekanäle besitzt.<br />
Spezielle Modulbeschreibung<br />
Für die spezielle Modulbeschreibung wird die ursprüngliche XML-Beschreibung lediglich<br />
umgeformt. Zweck der speziellen Modulbeschreibung ist es, dem Benutzer die Verwendung<br />
<strong>eines</strong> Moduls zu erleichtern: Daten, die er ändern kann, sollen sich zwischen einem<br />
Paar sich öffnender <strong>und</strong> schließender Tags befinden; Daten, die er nicht verändern darf,<br />
als Attribute in den entsprechenden, sich öffnenden Tags. Ändern darf der Benutzer<br />
die Werte der Konfigurations- <strong>und</strong> Einstellungsparameter, fest sind die Parametertypen<br />
<strong>und</strong> die Ein- <strong>und</strong> Ausgabekanäle <strong>eines</strong> Moduls.<br />
Die entsprechende Transformationsdatei liest die Modulbeschreibung ein <strong>und</strong> wandelt<br />
die Daten um, indem sie die Beschreibung der Parameter <strong>und</strong> Kanäle entsprechend<br />
umstellt.<br />
Neben dieser Transformation muss eine weitere Transformation der ursprünglichen<br />
Modulbeschreibung in eine speziell an die Modulbeschreibung angepassten XML-<br />
Schema-Beschreibung durchgeführt werden. Diese wird benötigt, da der Aufbau einer<br />
speziellen Modulbeschreibung von dem Aufbau der Modulbeschreibung abweicht. Die<br />
Schemabeschreibung muss sicherstellen, dass in der neuen Modulbeschreibung alle benötigten<br />
Parameter <strong>und</strong> Kanäle vorhanden sind, dass die Attribute nicht verändert wurden<br />
<strong>und</strong> die Parameterwerte sich in definierten Schranken befinden. Diese Beschreibung lässt<br />
sich ebenfalls aus der allgemeinen Modulbeschreibung erstellen, da sie ausser dem Aufbau<br />
des Moduls keine weiteren Informationen benötigt. Dabei werden der Reihe nach die<br />
einzelnen Parameter <strong>eines</strong> Moduls durchgegangen <strong>und</strong> eine entsprechende Beschreibung<br />
erzeugt.<br />
Slice-Definition<br />
Neben der speziellen Modulbeschreibung wird auch die Slice-Definition mittels XSLT<br />
erzeugt. Dabei muss die Modulbeschreibung in eine ICE-Struktur gebracht werden. Um<br />
Namenskonflikte mit anderen Modulen zu vermeiden, wird jedem Modul ein Namensraum<br />
in der Form Extensions.Modules..Lethe zugewiesen. In diesem<br />
Namensraum werden Strukturen für die Parameter, die Ergebnisse <strong>und</strong> den Zustand des<br />
Moduls entsprechend ihrer Definition in der Modulbeschreibung erzeugt. Dabei werden<br />
die Typen folgendermaßen auf ICE-Strukturen abgebildet:<br />
• Die einfachen Typen string, int, long, byte, float <strong>und</strong> double haben eine<br />
gleichnamige Entsprechung in ICE. Der Typ boolean wird in bool umbenannt.<br />
• Enumerationen werden in eine entsprechende enum-Struktur abgebildet, die in Slice<br />
folgendermaßen aussieht: enum {string1, string2, ... , stringN}<br />
• Klassen werden in eine eigene Struktur abgebildet, die mit den Klassenfeldern<br />
gefüllt wird: struct { ; ; ... ;<br />
}<br />
38
4.2 Module <strong>und</strong> Simulationen<br />
• Listen werden auf Sequenzen abgebildet, die in den entsprechenden Strukturen<br />
verwendet werden. Dies entspricht sequence < > <br />
• Tabellen dienen dem Komfort der Benutzer <strong>und</strong> werden in eine Sequenz von<br />
Sequenzen abgebildet. Damit dies transparent stattfinden kann, wird für die<br />
innere Sequenz das dem Benutzer verbotene 1 Präfix icegen benutzt. Damit<br />
sieht die Umsetzung einer Tabelle wie folgt aus: sequence < <br />
> icegenarray; sequence < icegenarray ><br />
<br />
• Assoziative Listen werden auf den Typ dictionary abgebildet. Um die Benutzung<br />
einer assoziativen Liste in der Modulbeschreibung möglichst einfach zu halten,<br />
sind die Schlüssel auf Werte des Typs string beschränkt. Dies stellt allerdings<br />
keine allzu große Einschränkung für die Entwickler von Modulen dar, da es im<br />
Normalfall möglich ist, beliebige Typen durch eine Zeichenkette zu repräsentieren.<br />
Die Abbildung von assoziativen Listen erfolgt folgendermaßen: dictionary<br />
< , > <br />
Bei diesen einfachen Regeln zur Umsetzung der Typen treten jedoch Probleme im<br />
Zusammenhang mit Slice auf: So können in Slice Strukturen nur verwendet werden,<br />
wenn sie vor ihrer Verwendung bereits definiert sind. Eine Vorwärtsdefinition wie sie<br />
zum Beispiel in C möglich ist, wird von Slice nicht unterstützt. Dies ist speziell für<br />
Klassen, Listen, Tabellen <strong>und</strong> assoziativen Listen ein Problem, die nicht ausschließlich<br />
aus einfachen Typen bestehen. Deshalb müssen für die Erstellung der Slice-Definitionen<br />
die verwendeten Typen nach ihrem Auftreten sortiert werden. Dazu werden zwei Mengen<br />
verwendet: Die Menge U enthält alle noch zu definierenden Typen, die Menge V bereits<br />
definierte Typen. Zu Beginn der Sortierung enthält V ausschließlich die einfachen Typen,<br />
wie string oder int. Anschließend wird U nach folgendem Algorithmus durchsucht, bis<br />
|U| = 0 oder kein entsprechender Typ mehr gef<strong>und</strong>en wurde:<br />
1. Finde einen Typ t ∈ U, so dass t entweder eine Enumeration ist oder ausschließlich<br />
von Typen aus V abhängt.<br />
2. Definiere t nach obigen Regeln.<br />
3. Entferne t aus U <strong>und</strong> füge t in V ein.<br />
Gilt |U| = 0 so konnte eine Ordnung auf den verwendeten Typen gef<strong>und</strong>en werden,<br />
die sicherstellt, dass kein Typ definiert wird, bevor nicht alle von ihm verwendeten<br />
Typen definiert wurden. Andernfalls gibt es Typen, die entweder auf unbekannten Typen<br />
basieren oder eine zirkuläre Abhängigkeit besitzen. In diesem Fall kann keine Slice-<br />
Definition erzeugt werden.<br />
Eine weitere Schwierigkeit ergibt sich daraus, dass leere Strukturen nicht erlaubt sind.<br />
Das wird zu einem Problem, wenn zum Beispiel ein Modul keine Ergebnisse erzeugt oder<br />
keine Konfigurationsparameter benötigt. Die dafür benötigte Struktur muss trotzdem<br />
1 icegen ist für den Benutzer wegen des Präfix ice verboten.<br />
39
4 <strong>Implementierung</strong><br />
erzeugt werden, um die Programmierschnittstelle für den Modulcode einheitlich zu gestalten.<br />
In diesem Fall wird der Struktur eine Boolsche Variable namens icegenDUMMY<br />
als Platzhalter hinzugefügt. Durch das Präfix ice, das für benutzerdefinierte Bezeichner<br />
verboten 2 ist, kann diese Variable nicht mit benutzerdefinierten Typen kollidieren.<br />
Modulcode<br />
Damit ein Modul sinnvoll verwendet werden kann, muss der Entwickler die Simulations-<br />
API aus [7, Abschnitt 3.1.10] implementieren. Dazu stellt ihm Lethe ein Gr<strong>und</strong>gerüst<br />
bestehend aus den Methodenrümpfen <strong>und</strong> den Modulparametern bereit. Desweiteren<br />
werden aus den Ein- <strong>und</strong> Ausgängen <strong>eines</strong> Moduls Hilfsfunktionen zum Schreiben <strong>und</strong><br />
Lesen für die Modulimplementierung erzeugt.<br />
4.2.2 Erzeugen von Simulationen<br />
Eine Simulationsbeschreibung enthält alle Informationen, um aus ihr einen Simulationsauftrag<br />
erstellen zu können. Trotzdem wird für jede Simulationsbeschreibung eine spezielle<br />
Schemabeschreibung erstellt. Dieses Vorgehen erleichtert es dem Benutzer, selbst<br />
eine Simulationsbeschreibung zu erzeugen. Damit aus der Simulationsbeschreibung nämlich<br />
ein Auftrag generiert werden kann, muss für jeden verwendeten Modulparameter<br />
Zusatzinformationen wie Typ, Klassenname oder Standardwert angegeben werden. Diese<br />
Zusatzinformationen können jedoch auch bei der Transformation automatisch aus<br />
den entsprechenden Modulbeschreibungen ausgelesen <strong>und</strong> in die Schemabeschreibung<br />
aufgenommen werden. Der Parser fügt dann beim Validieren der Simulation selbständig<br />
die Zusatzinformationen aus der Schemabeschreibung ein, wenn sie nicht vorhanden<br />
sind. Da die benötigten Zusatzinformationen von den verwendeten Modulen abhängen,<br />
benötigt normalerweise jede Simulation eine eigene Schemabeschreibung. Bei der<br />
Simulationsbeschreibung selbst muss lediglich der Verweis auf die zu verwendende Schemabeschreibung<br />
geändert werden, da sonst weiterhin die allgemeine Beschreibung für<br />
Simulationen verwendet wird.<br />
4.2.3 Erstellen von Simulationsaufträgen<br />
Simulationsaufträge werden aus Simulationsbeschreibungen erstellt, indem die einzelnen<br />
Daten geparst <strong>und</strong> dem Simulationsobjekt zugewiesen werden. Im einfachsten Fall<br />
geschieht dies wie bei den Feldern name <strong>und</strong> description über eine gleichnamige Entsprechung<br />
in der Simulationsbeschreibung. Das Feld owner wird auf den aktuellen Benutzernamen<br />
gesetzt, der Wert des Feldes jobId muss hingegen von der zentralen Komponente<br />
im <strong>verteilten</strong> System abgefragt werden, da sie im gesamten System eindeutig<br />
sein muss.<br />
Komplizierter ist die Erstellung des Hypergraphen <strong>und</strong> der Einstellungsparameter<br />
für die einzelnen R<strong>und</strong>en. Ein Knoten im Graphen entspricht einer Modulinstanz <strong>und</strong><br />
besitzt einen eindeutigen Namen. Eine mögliche Anwendung dafür wäre zum Beispiel<br />
2 Die Benutzung ist tatsächlich nicht erlaubt, kann aber durch die Übersetzung der Definitionsdatei<br />
mit - -ice umgangen werden.<br />
40
4.2 Module <strong>und</strong> Simulationen<br />
die Verwendung von zwei Quellen: Quelle1 <strong>und</strong> Quelle2, die beide Instanzen des Moduls<br />
Quelle sind.<br />
Ein Graph besteht also aus einer Menge von Knoten <strong>und</strong> einer Menge von Verbindungskanten.<br />
Um die Verbindungskanten korrekt zuordnen zu können, benötigt er außerdem<br />
eine Liste mit Ein- <strong>und</strong> Ausgängen der einzelnen Knoten. Da sich die Verbindungen<br />
während der Ausführung in den Phasen ändern können, benötigt er auch noch die jeweils<br />
aktiven Ein- <strong>und</strong> Ausgänge pro Phase. Damit das Simulationsobjekt später entscheiden<br />
kann, wann eine Phase beendet ist, benötigt es auch noch eine Liste von Knoten, die<br />
Ergebnisse produzieren oder selbst aktiv entscheiden können, wann eine Phase beendet<br />
ist. Desweiteren kann für jede Phase angegeben werden, ob ein Eingang zu Beginn der<br />
Phase auf den im Kanal vorhandenen Daten weiterarbeiten möchte oder nicht.<br />
Desweiteren muss für jeden Knoten im Graphen dessen Konfigurationsparameter instantiiert<br />
werden. Daraus ergibt sich das Problem, wie die in den einzelnen Modulen<br />
verwendeten Parameter ausgelesen <strong>und</strong> im <strong>verteilten</strong> System versendet werden können.<br />
Um die Parameter über das ICE-Framework verschicken zu können, bedarf es einiger<br />
Kniffe. Zuerst muss ein Verfahren gef<strong>und</strong>en werden, das es sowohl Java- als auch C++-<br />
Programmen erlaubt, plattformunabhängig die Parameter zu lesen <strong>und</strong> zu schreiben.<br />
Hierzu bietet es sich an, die Parameter in Slice, der Schnittstellenbeschreibungssprache<br />
von ICE, als Konfigurationsobjekt zu definieren. Diese Definition kann anschließend in<br />
Java- oder C++-Klassen umgewandelt werden, so dass sowohl die Anwenderprogramme<br />
als auch die Simulationsobjekte auf die Konfigurationsparameter zugreifen können.<br />
Diese Parameter können jedoch nicht direkt als Konfigurationsobjekt im <strong>verteilten</strong><br />
System verschickt werden. Andernfalls müsste die zentrale Komponente über dieses<br />
spezielle Objekt in Form einer speziellen Slice-Definition für den gesamten Simulationsauftrag<br />
Bescheid wissen. Dies ist jedoch nicht mit vertretbarem Aufwand möglich, da<br />
sonst für jeden Simulationsauftrag neue Slice-Definitionen an den zentralen Koordinator<br />
geschickt werden müssen, aus denen dieser dann Java-Klassen erzeugen <strong>und</strong> während<br />
der Laufzeit nachladen kann.<br />
Eine weitere Möglichkeit wäre die Verwendung von Klassen statt Strukturen für die<br />
Konfiguration. Für Klassen erlaubt Slice eine Vererbung, so dass alle Konfigurationsobjekte<br />
von einer gemeinsamen Oberklasse abgeleitet sein können. In diesem Fall kann<br />
die zentrale Komponente problemlos die verschiedenen Simulationsaufträge annehmen.<br />
Möchte die zentrale Komponente jedoch den Simulationsauftrag sichern, tritt sogenanntes<br />
Slicing [31, Seite 121 – 124] auf. Dies bedeutet, dass nicht das komplette Konfigurationsobjekt<br />
gespeichert wird, sondern lediglich die Felder, die der zentralen Komponente<br />
aus der Oberklasse für Konfigurationsobjekte bekannt sind.<br />
Deshalb wird eine Möglichkeit benötigt, das Konfigurationsobjekt an den zentralen<br />
Koordinator zu senden, <strong>und</strong> zwar derart, dass es einerseits nicht verstümmelt wird <strong>und</strong><br />
andererseits ohne Aufwand empfangen werden kann. Die Lösung für dieses Problem liegt<br />
in der Verwendung von sogenannten Strömen, die die Daten des Konfigurationsobjekts<br />
enthalten. ICE erlaubt, ICE-Objekte in Byteströme umzuwandeln <strong>und</strong> sie aus diesen<br />
wieder zu rekonstruieren. Aus dem Konfigurationsobjekt wird also ein Bytestrom in<br />
Form <strong>eines</strong> byte-Arrays erzeugt, der problemlos versandt <strong>und</strong> von der zentralen Komponente<br />
gesichert werden kann. Simulationsobjekte wiederum können auf die Parame-<br />
41
4 <strong>Implementierung</strong><br />
ter sehr einfach zugreifen, indem sie den Bytestrom wieder in ein Konfigurationsobjekt<br />
überführen.<br />
Es stellt sich nun die Frage, wie dieser Bytestrom erzeugt <strong>und</strong> initialisiert werden kann.<br />
Eine Möglichkeit wäre es, die Parameter durchzugehen <strong>und</strong> mit Hilfe der Serialisierungs-<br />
API von ICE Feld für Feld in den Bytestrom zu schreiben. Dies kann auch durch XSLT<br />
geschehen, das durch eine Transformation die Parameterwerte in einen der Spezifikation<br />
in [31, Abschnitt 33.2] entsprechenden Strom umwandelt. Besonders die zweite Vorgehensweise<br />
ist jedoch sehr von der ICE-internen Serialisierungsvorschrift abhängig, <strong>und</strong><br />
muss bei Änderungen in der Spezifikation entsprechend angepasst werden.<br />
Deswegen erzeugt Lethe einen der Konfiguration entsprechenden Objektgraphen, den<br />
es dann als ganzes von ICE serialisieren lässt. Eine elegante Möglichkeit, um aus den<br />
Konfigurationsdateien die entsprechenden Objektstrukturen aufzubauen, wäre sicher die<br />
direkte Erzeugung <strong>eines</strong> generierenden Javacodes via XSLT. Da diese Idee jedoch im<br />
Laufe der <strong>Implementierung</strong> zu spät aufkam, verwendet Lethe die Java Reflection-API<br />
zum Aufbau der Datenstruktur. Dazu müssen die Slice-Definitionen zuerst mit Hilfe<br />
von slice2java in Java-Code umgewandelt werden. Die somit in der Java-VM verfügbaren<br />
Klassen werden nun mittels der Reflection-API instantiiert, <strong>und</strong> die entsprechenden<br />
Attribute <strong>und</strong> Referenzen gesetzt. Der Fall, dass ein Knoten keine Konfigurationsparameter<br />
besitzt, kann durch die Verwendung des Platzhalter-Feldes (vgl. Abschnitt 4.2.1)<br />
nicht eintreten, <strong>und</strong> muss deshalb nicht berücksichtigt werden. Die Umsetzung erfolgt<br />
dabei ähnlich wie bei der Abbildung von XML-Beschreibung zu Slice-Definition:<br />
• Die einfachen Typen (string, int, long, byte, float, double, bool) werden<br />
direkt in ihre Entsprechung in Java umgesetzt <strong>und</strong> mit dem angegebenen Wert<br />
belegt.<br />
• Für Enumerationen (enum) werden durch den Aufruf von slice2java spezielle Hilfsklassen<br />
erzeugt, die dynamisch nachgeladen, instantiiert <strong>und</strong> mit dem angegebenen<br />
Wert belegt werden.<br />
• Ebenso werden für Klassen (struct) eigene Hilfsklassen angelegt. Diese werden,<br />
wie bei den Enumerationen, nachgeladen <strong>und</strong> instantiiert. Anschließend werden<br />
nach den selben Regeln die einzelnen Felder der Klassen erzeugt.<br />
• Listen <strong>und</strong> Tabellen werden als ein- bzw. zweidimensionale Listen des entsprechenden<br />
Typs angelegt. Die Größe der Listen hängt dabei von der jeweiligen Anzahl<br />
der Elemente ab. Anschließend werden die einzelnen Elemente erzeugt <strong>und</strong> entsprechend<br />
ihrer Definition in der Simulationsbeschreibung belegt.<br />
• Assoziative Listen werden als HashMap angelegt <strong>und</strong> anschließend wie bei den<br />
Listen mit entsprechenden Schlüssel-/Wertepaaren gefüllt.<br />
Die Einstellungsparameter werden wie die Konfigurationsparameter eingelesen <strong>und</strong> gespeichert.<br />
Dabei wird die Anzahl der R<strong>und</strong>en implizit mit den Einstellungsparametern<br />
gesichert: Für jeden Knoten stehen genauso viele Byteströme mit Einstellungsparametern<br />
zur Verfügung, wie es R<strong>und</strong>en gibt.<br />
42
4.3 Das verteilte System<br />
4.3 Das verteilte System<br />
Im Folgenden wird zuerst auf die Problematik eingegangen, wie Knoten in das verteilte<br />
System eingefügt bzw. daraus entfernt werden können. Anschließend befasst sich dieser<br />
Abschnitt mit der Umsetzung der in Abschnitt 3.4 entworfenen Dienste. Abschließend<br />
werden Überlegungen zu der Ausführung der einzelnen Dienste gemacht. Dies betrifft<br />
speziell die Frage, welche Dienste auf welchen Knoten ausgeführt werden.<br />
4.3.1 Hinzufügen <strong>und</strong> Entfernen von Knoten<br />
Das Hinzufügen <strong>und</strong> Entfernen von Knoten im <strong>verteilten</strong> System läuft für Lethe vollkommen<br />
transparent ab, da es mit Hilfe von IceGrid gelöst wird. IceGrid benötigt eine<br />
Konfiguration des <strong>Systems</strong> in einem XML-Format, das angibt, welche Knoten im <strong>verteilten</strong><br />
System vorhanden sind, <strong>und</strong> was für Dienste auf ihnen ausgeführt werden. Mit<br />
dieser Information erlaubt IceGrid, Dienste zu starten, zu beenden <strong>und</strong> ihren Status<br />
abzufragen.<br />
Um einen neuen Simulationsknoten im System hinzuzufügen, muss auf diesem Knoten<br />
ein icegridnode gestartet werden <strong>und</strong> die Konfigurationsdatei des <strong>verteilten</strong> <strong>Systems</strong><br />
um den entsprechenden Knoten erweitert werden. Anschließend müssen die Änderungen<br />
dem <strong>verteilten</strong> System mitgeteilt werden. Dies geschieht am einfachsten durch den Aufruf<br />
von icegridadmin -e ’application update lethe.xml’. Dabei ist zu beachten,<br />
dass die Namen der einzelnen Knoten im <strong>verteilten</strong> System eindeutig sein müssen. Eine<br />
Möglichkeit, das zu gewährleisten, ist, die Knoten fortlaufend durchzunumerieren, oder<br />
ihnen den Namen des Rechners zu geben, auf dem sie ausgeführt werden.<br />
Um einen Knoten aus dem <strong>verteilten</strong> System zu entfernen, kann einfach der Rechner<br />
vom Netz genommen werden oder die icegridnode auf dem entsprechenden Rechner<br />
beendet werden. Im ersten Fall wird der Knoten wieder dem Netz zugeführt sobald<br />
eine icegridnode darauf gestartet wird. Soll der Knoten jedoch dauerhaft aus dem<br />
<strong>verteilten</strong> System entfernt werden, so muss er aus der Konfigurationsdatei gelöscht, <strong>und</strong><br />
die Änderung im <strong>verteilten</strong> System mit Hilfe von icegridadmin -e ’application<br />
update lethe.xml’ propagiert werden.<br />
4.3.2 Manager<br />
Der Manager dient als Ansprechpartner für Benutzer <strong>und</strong> Vermittler von Systemressourcen.<br />
Die Simulationsobjekte melden ihm, wenn sich am Status ihrer Ausführung<br />
etwas ändert. Dies kann durch einen Laufzeitfehler im Simulationsprogramm geschehen<br />
oder durch das Ende der Simulation. Da der Zugriffsschutz im <strong>verteilten</strong> System<br />
durch die Einführung von Sicherheitszonen (vgl. siehe auch: 3.2.5) gewährleistet wird,<br />
sind die Schnittstellen des zentralen Koordinators in zwei voneinander getrennte Teile<br />
aufgeteilt, wie man am Klassendiagramm in Abbildung C.1 im Anhang sieht: die Benutzerschnittstelle,<br />
auf die aus Zone 1 zugegriffen werden kann, <strong>und</strong> die Schnittstelle<br />
für Simulationsobjekte, die aus Zone 2 auf den zentralen Koordinator zugreifen. Die<br />
explizite Trennung der Schnittstellen ist notwendig, da ICE sonst keine Unterscheidung<br />
bezüglich des Zugriffs machen kann.<br />
43
4 <strong>Implementierung</strong><br />
Verwalten von Simulationen<br />
Die Simulationsaufträge im <strong>verteilten</strong> System werden mit Hilfe von eindeutigen IDs<br />
(Simulations-ID) verwaltet. Soll ein neuer Auftrag gestartet werden, bekommt er vom<br />
zentralen Koordinator eine eindeutige ID zugeteilt. Diese setzt sich aus dem Benutzernamen<br />
<strong>und</strong> einer für jeden Benutzer durchlaufenden Nummer zusammen. Ebenso werden<br />
auch die R<strong>und</strong>en der einzelnen Simulationen mit einer eindeutigen ID versehen: Sie leitet<br />
sich aus der Simulations-ID <strong>und</strong> der R<strong>und</strong>ennummer ab. Diese ID wird zum Ansprechen<br />
<strong>und</strong> Sichern der einzelnen R<strong>und</strong>en benötigt.<br />
Um die Simulationsaufträge bei einem Ausfall zu schützen, sichert die zentrale Komponente<br />
diese nach dem Empfang unter seiner ID in einer FreezeMap. Desweiteren speichert<br />
er für jede Simulationsr<strong>und</strong>e ab, ob sie bereits einen Sicherungspunkt hat. Ist dies<br />
der Fall, wird der Sicherungspunkt mitgespeichert. Da für den zentralen Koordinator<br />
keine Möglichkeit besteht, Simulationsobjekte im <strong>verteilten</strong> System gezielt zu finden,<br />
speichert er für jede aktive R<strong>und</strong>e das Zugriffsobjekt auf das Simulationsobjekt.<br />
Verteilen von Simulationen<br />
Damit eine möglichst gerechte Ausführung der Simulationen stattfindet, wird für die<br />
Zuteilung ein Zeitscheibenverfahren verwendet. Das bedeutet, dass Simulationen nach<br />
Ablauf <strong>eines</strong> konfigurierbaren Intervalls angehalten werden, um anderen Simulationen<br />
Ressourcen zur Verfügung zu stellen. Dieses Verhalten hat einen weiteren Vorteil, da<br />
von der Simulation automatisch ein Sicherungspunkt erzeugt wird, bevor sie angehalten<br />
wird. Dadurch ist bei einem Knotenausfall die Rechenzeit von maximal einer Zeitscheibe<br />
verloren. Der Verteilungsalgorithmus von Simulationen läuft wie folgt ab:<br />
1. Bestimme die Menge S aller aktiven Simulationen, deren Zeitscheibe abgelaufen<br />
ist.<br />
2. Erzeuge für jede Simulation s ∈ S einen Sicherungspunkt <strong>und</strong> pausiere s.<br />
3. Erstelle eine nach ihrer Systemauslastung sortierte Liste L von verfügbaren Simulationsknoten.<br />
Kann ein Simulationsknoten mehrere Simulationen gleichzeitig<br />
ausführen, wird er entsprechend oft in die Liste aufgenommen.<br />
4. Sortiere die auf ihre Ausführung wartenden Simulationen nach ihrem Punktestand<br />
(vgl. Funktion 3.1) <strong>und</strong> weise ihnen der Reihe nach Simulationsknoten aus L zu.<br />
Dabei soll einer Simulation bevorzugt ein Knoten zugewiesen werden, auf dem<br />
bereits ein entsprechendes Simulationsobjekt vorhanden ist.<br />
5. Ist einer Simulation s ein Simulationsknoten k zugewiesen worden, muss geprüft<br />
werden, ob ein für s passendes Simulationsobjekt auf k bereits vorhanden ist.<br />
Ansonsten muss es neu erzeugt werden. Anschließend wird die Simulation s auf<br />
dem Simulationsobjekt ausgeführt.<br />
Die Reihenfolge, in der Simulationen ausgeführt werden, ist von ihrer Sortierung abhängig.<br />
In Lethe wird das Verfahren nach Sainte-Laguë [43] verwendet, das sich in den<br />
44
4.3 Das verteilte System<br />
Untersuchungen von [4] als das exakteste proportionale Zuteilungsverfahren erwiesen<br />
hat. Dabei werden die Simulationsknoten aus L den einzelnen Simulationen verhältnismäßig<br />
zu deren Punktezahl im Vergleich zu den anderen zugeteilt. Diese Zuweisung ist<br />
konfigurierbar, andere Algorithmen lassen sich verwenden, wenn sie das Interface aus<br />
Abbildung C.6 im Anhang implementieren. Dabei sind jobs Simulationsaufträge, die<br />
auf ihre Ausführung warten, <strong>und</strong> seats ist die Anzahl der zur Verfügung stehenden Simulationsknoten.<br />
Der Rückgabewert ist eine sortierte Liste der Simulations-IDs, wobei<br />
eine ID mehrfach enthalten sein kann.<br />
Umziehen von Simulationen<br />
Die Möglichkeit zur Laufzeit Simulationen auf andere Knoten umziehen zu können, ist<br />
eine wichtige Anforderung an das verteilte System, die auch vom Manager unterstützt<br />
werden muss. Prinzipiell lässt sich eine aktive Simulation sehr einfach umziehen: Man<br />
erstellt einen Sicherungspunkt der Simulation, erzeugt auf dem neuen Simulationsknoten<br />
ein entsprechendes Simulationsobjekt <strong>und</strong> startet dieses mit den Daten aus dem<br />
Sicherungspunkt.<br />
Probleme ergeben sich jedoch in der Ausführung: Zum einen müssen dem Benutzer<br />
sowohl der Rechnername bekannt sein, auf dem seine Simulation gerade ausgeführt wird,<br />
als auch der Rechnername, auf den er die Simulation übertragen möchte. Zum anderen<br />
ist es unwahrscheinlich, dass auf dem Zielknoten noch Kapazitäten frei sind, wenn sich<br />
zu dem Zeitpunkt, an dem eine Simulation umgezogen werden soll, bereits sehr viele<br />
Simulationsaufträge im System befinden. Dennoch soll die Simulation auf dem Knoten<br />
weiterlaufen. Aus diesem Gr<strong>und</strong> ignoriert der Manager beim Umziehen einer Simulation<br />
die angegebene, maximale Kapazität des Zielknotens. So kann es passieren, dass auf<br />
einem Simulationsknoten mehr Simulationen ausgeführt werden als angegeben. Dies ist<br />
jedoch ein temporärer Zustand, der zum einen nur durch das Umziehen von Simulationen<br />
auftreten kann, <strong>und</strong> zum anderen nach dem Ablauf der aktuellen Zeitscheibe vom<br />
Manager automatisch behoben wird.<br />
Es werden jedoch – wenn auch nur für eine beschränkte Zeit – andere Simulationen<br />
in ihrer Ausführung benachteiligt. Deshalb sollten nur ausgewählte Benutzergruppen<br />
in der Lage sein, Simulationen umzuziehen. Durch die automatische Erstellung von Sicherungspunkten<br />
ist außerdem der Informationsverlust bei einem Knotenausfall sehr<br />
gering, so dass es sich selbst bei geplanten Knotenausfällen, wie sie zum Beispiel durch<br />
Stromabschaltungen auftreten können, nicht mehr lohnen kann, eine Simulation aktiv<br />
umzuziehen. Eine Alternative zum Umziehen ist auch das manuelle Erstellen von Sicherungspunkten,<br />
die jedem Benutzer zur Verfügung steht, der Simulationen im <strong>verteilten</strong><br />
System starten darf.<br />
Bei dem Umziehen von Simulationen muss dem Benutzer bewusst sein, dass diese<br />
transparent für die Knotenverteilung abläuft. Dadurch kann es passieren, das der<br />
Manager die Simulation im nächsten Zeitschlitz wieder auf dem ursprünglichen Knoten<br />
startet. Aus diesem Gr<strong>und</strong> ist es sicher sinvoll, Simulationen Knotengruppen zuweisen zu<br />
können, denen sie ausschließlich zugeteilt werden. Desweiteren wäre es praktisch, Simulationen<br />
in logische Gruppen eingeteilen zu können, die dann z.B. gemeinsam umgezogen<br />
werden können. Vorstellbar ist z.B. eine Gruppe aller Simulationen <strong>eines</strong> Benutzers oder<br />
45
4 <strong>Implementierung</strong><br />
einer Benutzergruppe, sowie eine Gruppe aller auf einem Knoten laufenden Simulationen.<br />
Diese Punkte konnten jedoch wegen Zeitmangels nicht mehr implementiert werden.<br />
4.3.3 Benutzerverwaltung<br />
Die Benutzerverwaltung kümmert sich um die Authentifizierung, die Rechteverwaltung<br />
<strong>und</strong> das Hinzufügen <strong>und</strong> Löschen von Benutzern <strong>und</strong> Gruppen. Dabei sind die Informationen<br />
bezüglich der Benutzer <strong>und</strong> Gruppen in den entsprechenden Klassen gekapselt.<br />
Die Rechteverwaltung implementiert die in Abschnitt 3.2.4 beschriebenen Algorithmen,<br />
weshalb an dieser Stelle nicht mehr näher darauf eingegangen wird. Die Benutzerauthentifizierung<br />
erfolgt bei Lethe mit Hilfe einer Benutzername/Passwort-Liste, da sie<br />
durch den Administrator einfach zu handhaben ist. Desweiteren lassen sie sich auch<br />
von dem Authentifizierungsprogramm einfach verwenden. Diese Listen haben jedoch<br />
einen großen Nachteil: Fallen sie den falschen Personen in die Hände, können sie sich<br />
unter falschem Namen am System anmelden. Lethe umgeht dieses Problem, indem es<br />
die Passwörter nicht im Klartext, sondern nur ihren MD5-Hashwert [42] speichert. Um<br />
sicherzustellen, das das Passwort bei der Anmeldung mit dem gespeicherten Hashwert<br />
übereinstimmt, wird das Benutzerpasswort im Klartext zum Authentifizierungsdienst<br />
gesendet. Dieses Vorgehen ist insofern unproblematisch, da die Verbindung mittels SSL<br />
geschützt ist (vgl. Abschnitt 3.2.5). Andernfalls wäre es bedenklich, die Passwörter im<br />
Klartext im <strong>verteilten</strong> System zu versenden, da sie potentiell von Anderen mitgelesen<br />
werden können.<br />
4.3.4 Codeverteilung<br />
Die Codeverteilung selbst ist ein sehr einfach gehaltener Dienst, der über ein Erweiterungssystem<br />
auf unterschiedlich gespeicherte Daten zugreifen kann. Die Funktionsweise<br />
des Erweiterungssystems wird im nächsten Abschnitt beschrieben. Die Synchronisierung<br />
findet dabei, wie im <strong>Entwurf</strong> in Abschnitt 3.2.3 beschrieben, mit Hilfe von Ice-<br />
Patch statt. ICE beinhaltet ein Kommandozeilenprogramm, das einen IcePatch-Server<br />
implementiert, auf den die Clients zugreifen können.<br />
Bei der <strong>Implementierung</strong> der Codeverteilung ergeben sich jedoch Probleme, wenn der<br />
Dienst mehrere IcePatch-Server starten muss. Dies ist der Fall, wenn Simulationsknoten<br />
zur gleichen Zeit die Daten von verschiedenen Simulationsaufträgen anfordern. Damit<br />
die Simulationsknoten auf den Server zugreifen können, muss die Codeverteilung den<br />
Knoten mitteilen, unter welchem Namen <strong>und</strong> auf welchem Port die Server erreicht werden<br />
können. Da die Server mit Hilfe <strong>eines</strong> eigenständigen Kommandozeilenprogramms<br />
gestartet wurden, benötigt jeder Server einen eigenen Port.<br />
Im Normalfall wird das dadurch gelöst, indem das Betriebssystem dem Server einen<br />
zufälligen Port zuweist. Diese einfache Lösung kommt aber für Lethe nicht in betracht,<br />
da die Codeverteilung wissen muss, an welchem Port ein Server aktiv ist. Daher ist es<br />
erforderlich, dass die Portnummer nicht vom Betriebssystem, sondern von der Codeverteilung<br />
zugewiesen wird. Allerdings benötigt dieses Vorgehen eine komplizierte Konfiguration,<br />
da die Codeverteilung Kenntnis davon haben muss, aus welchem Intervall sie<br />
46
4.3 Das verteilte System<br />
Portnummern vergeben darf. Dabei stellt sich jedoch die Frage nach der Größe dieses<br />
Intervalls: Ist es zu klein gewählt, können keine neuen Server mehr gestartet werden.<br />
Letztendlich habe ich mich für eine eigene <strong>Implementierung</strong> des IcePatch-Servers in<br />
Java entschieden, da es bei ICE nur eine <strong>Implementierung</strong> in C++ gibt. Dadurch können<br />
die IcePatch-Server als normale Dienste durch die Codeverteilung gestartet werden <strong>und</strong><br />
über den selben Port angesprochen werden, auf dem auch die Codeverteilung läuft. Diesen<br />
Port kann die Codeverteilung beim Starten <strong>eines</strong> neuen IcePatch-Servers abfragen<br />
<strong>und</strong> entsprechend an die Simulationsknoten weitergeben.<br />
Erstellen neuer Zugriffsverfahren<br />
Momentan unterstützt die Codeverteilung bei Lethe den Zugriff auf Subversion-<br />
Repositories (SVN-Repositories) [12] <strong>und</strong> auf das lokale Dateisystem. Um weitere Zugriffsarten<br />
wie zum Beispiel HTTP oder FTP zu ermöglichen, müssen folgende Punkte<br />
beachtet werden:<br />
1. Für das neue Verfahren muss eine Java-Klasse geschrieben werden, die die<br />
SourceController-Schnittstelle (C.5 im Anhang) implementiert. Diese Schnittstelle<br />
besteht aus einer Methode, um die benötigten Dateien in ein Verzeichnis zu<br />
kopieren.<br />
2. Es wird eine Slice-Definition für die Beschreibung der neuen Zugriffsart benötigt.<br />
Bei SVN ist dies die sogenannte Revisionsnummer, die URL zum Repository sowie<br />
der Pfad im Repository zu den entsprechenden Verzeichnissen. Im lokalen Dateisystem<br />
ist dies lediglich der entsprechende Pfad zu den Verzeichnissen. Bei HTTP<br />
wäre es die Adresse. Diese Definition muss von der leeren Klasse SourceDesc<br />
abgeleitet sein, damit sie über die bestehenden Methoden im <strong>verteilten</strong> System<br />
versandt werden kann.<br />
3. Damit der Benutzer auch die neue Zugriffsart benutzen kann, muss eine entsprechende<br />
Definition in der Simulationsbeschreibung erstellt werden.<br />
4. Schlussendlich muss der Paketgenerator oder vielmehr die Klasse<br />
xml.JobSpecification so erweitert werden, dass sie aus der XML-Beschreibung<br />
das entsprechene ICE-Objekt erstellen <strong>und</strong> belegen kann.<br />
4.3.5 Dienste im <strong>verteilten</strong> System<br />
Abschließend ist zu klären, welche Dienste auf welchen Knoten ausgeführt werden. Dazu<br />
lassen sich die Knoten im System in vier Gruppen aufteilen:<br />
1. Die zentrale Komponente im <strong>verteilten</strong> System: Auf ihm läuft der Namensdienst<br />
von ICE, der Manager, die Benutzerverwaltung <strong>und</strong> der Logging-Dienst Breeze 3 .<br />
Außerdem wird auf ihm der standardmäßig benutzte Dienst zur Codeverteilung<br />
ausgeführt.<br />
3 Breeze ist ein zentraler Logging-Dienst im <strong>verteilten</strong> System. Er wurde von Alexander Bernauer in<br />
[7] entworfen <strong>und</strong> deshalb hier nicht weiter diskutiert.<br />
47
4 <strong>Implementierung</strong><br />
Benutzer<br />
Client<br />
privater Rechner<br />
zentrale Komponente<br />
Manager<br />
Breeze<br />
Simulationsobjekt<br />
Namensdienst<br />
Codeverteilung<br />
Benutzerverwaltung<br />
Simulationsknoten<br />
Generator<br />
Codeverteilung<br />
Abbildung 4.2: Dienste im <strong>verteilten</strong> System, gruppiert nach den Knoten, auf denen sie ausgeführt<br />
werden.<br />
2. Die Gruppe der Simulationsknoten: Auf ihnen läuft ein Generator, der bei Bedarf<br />
Simulationsobjekte für diesen Knoten erzeugt.<br />
3. Knoten, auf denen private Codeverteilungsdienste laufen, die von den einzelnen<br />
Benutzern gestartet wurden.<br />
4. Die Benutzerknoten, die auf das verteilte System zugreifen.<br />
Diese Gruppeneinteilung, wie sie auch in Abbildung 4.2 gezeigt wird, ist fliessend. So<br />
lassen sich alle Gruppen zu Testzwecken auch auf einem einzigen Knoten ausführen, <strong>und</strong><br />
private Codeverteilungsdienste werden in der Praxis vermutlich auch auf Benutzerknoten<br />
oder Simulationsknoten laufen, statt einen eigenen Knoten zu verwenden.<br />
Auf der zentralen Komponente müsste im Gr<strong>und</strong>e lediglich der Namensdienst laufen,<br />
da er eine feste Adresse benötigt, an der er von den anderen Objekten gef<strong>und</strong>en<br />
werden kann. Verwaltungstechnisch ist es jedoch einfacher, auch den Manager, die Benutzerverwaltung,<br />
den standardmäßig verwendeten Codeverteiltungsdienst <strong>und</strong> Breeze<br />
auf demselben Rechner auszuführen. Damit besitzt das verteilte System lediglich einen<br />
Single-Point-of-Failure, bei dessen Ausfall nicht mehr auf das System zugegriffen werden<br />
kann. Andernfalls würden auch die Knoten, auf denen der Manager oder die Benutzerverwaltung<br />
laufen, zu Problemknoten, da ICE eine Replikation des Managers zur Zeit<br />
noch nicht unterstützt. Eine Replikation der Benutzerverwaltung wäre möglich, ist aber<br />
momentan nicht vorgesehen, um den Aufwand bei Änderungen an den Benutzern oder<br />
Gruppen möglichst gering zu halten.<br />
Bei dem Manager <strong>und</strong> der Benutzerverwaltung ergibt sich zusätzlich ein gravierender<br />
Geschwindigkeitsvorteil, wenn die Dienste auf demselben Knoten ausgeführt werden, auf<br />
dem auch der Namensdienst läuft: Für die Verteilung der Simulationen auf Simulationsknoten<br />
werden viele Informationen über das verteilte System benötigt, wie die Anzahl<br />
der verfügbaren Knoten <strong>und</strong> deren Last. Da der Manager <strong>und</strong> der Namensdienst auf<br />
demselben Rechner ausgeführt werden, müssen diese Anfragen nicht über das Netzwerk<br />
48
4.4 Benutzeranwendungen<br />
gestellt werden, sondern werden von ICE lokal weitergeleitet. Ähnlich ist es mit der<br />
Benutzerverwaltung: Da die meisten Anfragen bezüglich Benutzerrechten vom Manager<br />
ausgehen, ist es sinnvoll, beide Dienste auf derselben Maschine zu betreiben.<br />
4.4 Benutzeranwendungen<br />
Im Folgenden wird näher auf die <strong>Implementierung</strong> einiger in Abschnitt 3.4.2 beschriebenen<br />
Anwenderprogramme – im speziellen dem Paketgenerator, dem Ergebnisexportierer<br />
<strong>und</strong> der Modulsuche – eingegangen. Die Simulationsverwaltung <strong>und</strong> die Benutzerverwaltung<br />
werden nicht näher erklärt, da sie hauptsächlich eine Benutzerschnittstelle zum<br />
<strong>verteilten</strong> System anbieten <strong>und</strong> ihr Gegenpart im System die hauptsächliche Arbeit übernimmt.<br />
Um einen Simulationsauftrag zu starten, bedient sich die Simulationsverwaltung<br />
dem in Abschnitt 3.3.1 beschriebenen Verfahren.<br />
Abschließend werden die Erweiterungsmöglichkeiten der grafische Benutzerschnittstelle<br />
(GUI) beschrieben. Eine ausführlichere Beschreibung der einzelnen Elemente der GUI<br />
würde jedoch den Rahmen der Diplomarbeit sprengen, so dass lediglich die Gr<strong>und</strong>funktionen<br />
<strong>und</strong> die Erweiterungsmöglichkeiten dargestellt werden.<br />
4.4.1 Paketgenerator<br />
Der Paketgenerator erstellt, wie oben beschrieben, aus Modul- oder Typbeschreibungen<br />
die entsprechenden Modul- bzw. Typpakete. Dazu verwendet er Saxon (vgl. 2.4.3),<br />
um die entsprechenden Dateien über einzelne XSLT-Transformationen zu erzeugen. Um<br />
den Modulnamen auszulesen, muss der Paketgenerator zuerst die Beschreibung mit dem<br />
XML-Parser JDOM (siehe: 2.4.2) einlesen, um den Modulnamen auszulesen. Saxon<br />
ermöglicht es, auf die bereits im Speicher liegende Beschreibung verschiedene Transformationen<br />
in Folge anzuwenden, so dass die Beschreibungsdatei nicht jedesmal neu<br />
eingelesen werden muss. Die einzelnen Dateinamen werden, wie im Paketformat spezifiziert,<br />
anhand des Modulnamens erzeugt, wobei bereits bestehende Dateien überschrieben<br />
werden. Davon ausgenommen ist die Modulimplementierung: Existiert bereits eine<br />
<strong>Implementierung</strong>sdatei, wird diese zuerst umbenannt <strong>und</strong> dadurch nicht überschrieben.<br />
Dieses Vorgehen hat den Vorteil, dass kein Code durch die Generierung der <strong>Implementierung</strong>sdatei<br />
verloren gehen kann. Hat der Entwickler Teile des Moduls schon programmiert,<br />
kann er den Programmcode in die neu erzeugte Datei kopieren. Angedacht war<br />
auch eine inkrementelle Transformation für die Modulimplementierung, die ausschließlich<br />
die notwendigen Teile in der Datei ändert. Dies hätte jedoch einen Parser für die<br />
Modulimplementierung vorausgesetzt, <strong>und</strong> den Rahmen dieser Diplomarbeit gesprengt.<br />
4.4.2 Ergebnisexportierer<br />
Ist eine Simulation beendet, können die Ergebnisse entweder automatisch oder vom Benutzer<br />
selbst abgeholt (vgl. Abschnitt 3.3.5) <strong>und</strong> in einer lokalen Datenbank gesichert<br />
werden. Die Ergebnisse liegen dort allerdings in Form mehrerer Byteströme vor, die das<br />
selbe Format haben, wie auch die Parameter in einem Simulationsauftrag (vgl. Abschnitt<br />
4.2.3). Um diese Parameter in ein menschenlesbares Format zu überführen, bedarf es<br />
49
4 <strong>Implementierung</strong><br />
des Ergebnisexportierers, der aus den Ergebnissen eine XML-Beschreibung erzeugt. Die<br />
Konvertierung erfolgt dabei umgekehrt zu der Parametererzeugung im Simulationsauftrag:<br />
Zuerst werden aus dem Simulationsauftrag die beteiligten Modulknoten bestimmt.<br />
Anschließend wird für jeden Modulknoten überprüft, ob ein Ergebnis vorhanden ist. Ist<br />
dies der Fall, wird mit Hilfe einer modulspezifischen Slice-Hilfsklasse der Bytestrom in<br />
ein Objekt transformiert. Anschließend werden durch die Reflection-API die einzelnen<br />
Felder im Ergebnis-Objekt durchgegangen <strong>und</strong> in entsprechende XML-Elemente umgewandelt.<br />
Zusätzlich zu den Ergebnissen werden auch noch die Konfigurations- <strong>und</strong> Einstellungsparameter<br />
nach dem gleichen Schema in die XML-Beschreibung aufgenommen.<br />
Dies erlaubt es dem Benutzer, die Simulationsergebnisse in Abhängigkeit der Parameter<br />
darzustellen. Ein Beispiel dafür wäre das Auftragen der Ergebnisse in Abhängigkeit der<br />
Rauschleistung des Kanals.<br />
Ursprünglich war geplant, die Ergebnisse direkt in ein Format abzuspeichern, in dem<br />
die einzelnen Werte durch Kommata getrennt sind (CSV ). Durch die Verwendung beliebiger<br />
Ergebnistypen stellte sich dieses Vorhaben jedoch als beinahe unmöglich heraus, da<br />
Anzahl <strong>und</strong> Größe der Felder von den Ergebnistypen abhängig sind. Die Beschreibung<br />
der Ergebnisse in XML stellt einen Kompromiss dar, da es mit Hilfe von XSLT oder kleinen<br />
Programmen ohne großen Aufwand möglich ist, ausgewählte Teile der Ergebnisse<br />
in CSV oder ein beliebiges anderes Format zu konvertieren.<br />
4.4.3 Modulsuche<br />
Die Modulsuche wird benötigt, um Benutzern den Zugriff auf Module <strong>und</strong> Typen im<br />
<strong>verteilten</strong> System zu erleichtern. Sie fragt dafür eine Menge von Codeverteilungsdiensten<br />
nach den angebotenen Modulen <strong>und</strong> Typen an, <strong>und</strong> präsentiert diese Liste dem Benutzer.<br />
Dieser kann daraus auswählen, welche Module <strong>und</strong> Typen er für seine Simulation<br />
verwenden möchte <strong>und</strong> ihre Beschreibung auf seinen lokalen Rechner herunterladen<br />
lassen. Die Synchronisierung erfolgt dabei ähnlich zu der Synchronisierung bei den Simulationsknoten<br />
(vgl. 3.2.3), jedoch wird nicht anhand einer Simulations-ID, sondern<br />
direkt nach den Modulnamen synchronisiert.<br />
Dabei trat in der <strong>Implementierung</strong> ein ärgerliches Problem auf: Damit eine Modulbeschreibung<br />
validiert werden kann, benötigt sie die Angabe, wo sich die dazugehörige<br />
Schemabeschreibung findet. Zunächst wurde das Problem dadurch gelöst, dass bei der<br />
Modulerstellung der absolute Pfad zu der Schemabeschreibung angegeben wurde. Dies<br />
hatte jedoch den großen Nachteil, dass der Pfad meist nur auf dem Rechner des Modulentwicklers<br />
gültig ist. Möchte ein anderer Benutzer dieses Modul verwenden, so stimmt<br />
höchstwahrscheinlich der Pfad nicht mehr <strong>und</strong> das Modul kann nicht benutzt werden,<br />
wenn der Benutzer die Pfade nicht manuell ändert. Als Lösung boten sich relative Pfade<br />
an: Eine relative Adressierung erlaubt das Finden der Schemabeschreibung ausgehend<br />
von dem Ort, an dem die Modulbeschreibung liegt. Dieses Vorgehen setzt nur voraus,<br />
dass die hierarchische Dateistruktur beim Entwickler <strong>und</strong> dem Benutzer gleich ist, d.h.<br />
dass in beiden Fällen die Schemabeschreibung mit der gleichen relativen Pfadangabe<br />
gef<strong>und</strong>en werden kann. Dies ist jedoch insofern unbefriedigend, weil für die Transformationen<br />
verschiedene relative Pfadangaben zu den einzelnen Beschreibungen benötigt<br />
werden <strong>und</strong> man den Überblick bei der Konfiguration leicht verlieren kann. Aus die-<br />
50
4.4 Benutzeranwendungen<br />
sem Gr<strong>und</strong> werden letztendlich doch wieder absolute Pfade verwendet. Jedoch passt die<br />
Modulsuche die Pfade nach der Synchronisierung automatisch an die lokale Umgebung<br />
an.<br />
4.4.4 Die grafische Oberfläche<br />
Die grafische Oberfläche (GUI) dient der leichteren Bedienbarkeit von Lethe. Sie kapselt<br />
die Zugriffsmöglichkeiten auf das verteilte System <strong>und</strong> präsentiert sie angemessen<br />
aufbereitet dem Benutzer. Momentan unterstützt die GUI das Erstellen, Starten <strong>und</strong><br />
die Verwaltung von Simulationen. Außerdem unterstützt sie den Entwickler bei der Erstellung<br />
von Modul- <strong>und</strong> Typbeschreibungen. Dem Benutzer geht sie bei der Erstellung<br />
von Simulationsaufträgen zur Hand.<br />
Damit die GUI leicht erweiterbar ist, stellt sie ein Framework zur Verfügung, um beliebige<br />
Funktionen einbinden zu können. Tatsächlich sind bis auf die Authentifizierung alle<br />
unterstützten Benutzeranwendungen als Erweiterung realisiert. Die GUI selbst stellt das<br />
Basisfenster bereit mit einer Buttonleiste, die einen Wechsel der verschiedenen Funktionen<br />
erlaubt. Außerdem stellt sie die Schnittstellen aus Abbildung C.7 im Anhang für<br />
die Verwendung der Buttonleiste, des Hauptfensters <strong>und</strong> einer Konfigurationsdatei bereit.<br />
Auch gibt es für Erweiterungsprogramme die Möglichkeit, sich für Menüeinträge zu<br />
registrieren, so dass sie bei einer entsprechenden Benutzerauswahl aufgerufen werden.<br />
Eine Erweiterung muss unterhalb des Verzeichnisses plugins im Dateisystem abgelegt<br />
sein oder in den Klassenpfad von Java aufgenommen werden. Ansonsten kann die<br />
GUI nicht auf die Erweiterung zugreifen. In die GUI kann es entweder über den Menüpunkt<br />
others → plugins → add oder manuell durch Bearbeiten der Einstellungsdatei<br />
properties.xml hinzugefügt werden.<br />
In Abbildung 4.3 <strong>und</strong> 4.4 werden die Fenster zur Simulationsverwaltung <strong>und</strong> die<br />
Simulationserstellung gezeigt. Beide sind über das Erweiterungs-Framework in die GUI<br />
eingeb<strong>und</strong>en. Gut zu sehen ist die erweiterungsspezifische Buttonleiste links oben. Über<br />
die Buttons rechts oben lassen sich weitere Erweiterungen auswählen.<br />
51
4 <strong>Implementierung</strong><br />
Abbildung 4.3: Screenshot von der Simulationsverwaltung in der GUI. Momentan sind 2 Simulationsaufträge<br />
mit jeweils fünf R<strong>und</strong>en aktiv.<br />
52
4.4 Benutzeranwendungen<br />
Abbildung 4.4: Screenshot von der Simulationserstellung in der GUI. Gezeigt wird die Standardbelegung<br />
für die Einstellungsparameter der R<strong>und</strong>en einer Simulation.<br />
53
5 Zusammenfassung <strong>und</strong> Ausblick<br />
Dieses Kapitel erlaubt einen Überblick über die gesamte Diplomarbeit. Dazu wird sie<br />
im ersten Abschnitt kurz zusammengefasst.<br />
Anschließend wird diskutiert, ob <strong>und</strong> wie die in Abschnitt 1.2 gestellten Anforderungen<br />
tatsächlich erfüllt wurden. Der nächste Abschnitt beschäftigt sich mit der Frage<br />
nach den Lizenzbedingungen, unter der das verteilte System <strong>und</strong> die Anwenderprogramme<br />
stehen. Diese ist insbesondere bei einer kommerziellen Weiterentwicklung von Lethe<br />
zu berücksichtigen.<br />
Im vierten Abschnitt wird diskutiert, ob die Entscheidung für ICE <strong>und</strong> gegen CORBA<br />
in Abschnitt 3.2.1 gerechtfertigt war.<br />
Abgeschlossen wird das Kapitel mit dem fünften Abschnitt, der Ideen präsentiert, die<br />
während des <strong>Entwurf</strong>s <strong>und</strong> der Entwicklung des <strong>verteilten</strong> <strong>Systems</strong> aufgekommen sind.<br />
Diese Ideen konnten wegen Zeitmangels nicht umgesetzt werden, stellen aber interessante<br />
<strong>und</strong> nützliche Aspekte für zukünftige Weiterentwicklungen von Lethe dar.<br />
5.1 Zusammenfassung<br />
Ziel dieser Diplomarbeit war der <strong>Entwurf</strong> <strong>und</strong> die Entwicklung <strong>eines</strong> <strong>verteilten</strong> Simulationssystems,<br />
um das in der Diplomarbeit von Alexander Bernauer erstellte Framework<br />
auf <strong>verteilten</strong> Rechnern automatisiert auszuführen <strong>und</strong> anzusteuern.<br />
Entstanden ist ein Simulationssystem mit einem Mehrbenutzersystem, einer automatisierten<br />
Codeverteilung <strong>und</strong> einem Sicherungskonzept, das Knotenausfälle ausreichend<br />
kompensiert. Das verteilte System erlaubt eine automatisierte Ressourcenzuteilung<br />
<strong>und</strong> damit eine optimale Auslastung vorhandener Rechenkapazitäten. Desweiteren<br />
kann durch die Aufteilung von Simulationen in unabhängige R<strong>und</strong>en die Rechendauer<br />
für eine Simulation spürbar gesenkt werden, indem die einzelnen R<strong>und</strong>en parallel<br />
ausgeführt werden.<br />
Neben dem <strong>verteilten</strong> System wurde auch ein Modulkonzept verwirklicht, das eine<br />
einfache Wiederverwendung von Modulen im <strong>verteilten</strong> System ermöglicht. Dazu wurde<br />
eine Sprache entworfen, die die einzelnen Bestandteile <strong>eines</strong> Moduls beschreibt. Mehrere<br />
Module lassen sich dann zu einer Simulation verknüpfen, die mit weiteren Informationen<br />
versehen, im <strong>verteilten</strong> System ausgeführt werden kann. Damit Module beliebige<br />
Parameter für ihre Konfiguration <strong>und</strong> ihren internen Zustand verwenden können, musste<br />
eine Lösung gef<strong>und</strong>en werden, um zur Laufzeit Objekte aus den Modulbeschreibungen<br />
zu erstellen.<br />
Außerdem wurden verschiedene Anwenderprogramme erstellt, um dem Benutzer den<br />
Zugriff auf das verteilte System <strong>und</strong> auf seine laufenden Simulationen zu erleichtern. Desweiteren<br />
unterstützen diese ihn bei der Erstellung von Modulen <strong>und</strong> Simulationen. Um<br />
55
5 Zusammenfassung <strong>und</strong> Ausblick<br />
die Verwendung von Lethe möglichst einfach zu gestalten, wurde neben den konsolenbasierten<br />
Anwenderprogrammen auch eine grafische Oberfläche entworfen <strong>und</strong> entwickelt,<br />
die eine möglichst intuitive Benutzung der angebotenen Möglichkeiten erlaubt.<br />
5.2 Erfüllung der Anforderungen<br />
Die Anforderung an eine einfache Bedienbarkeit des <strong>verteilten</strong> <strong>Systems</strong> ist durch die<br />
Verwendung von ICE <strong>und</strong> dem IceGrid-Dienst erfüllt (vgl. Abschnitt 4.3.1).<br />
Ein Mehrbenutzerbertrieb wird durch die Rechte- <strong>und</strong> Benutzerverwaltung unterstützt<br />
<strong>und</strong> gewährleistet (siehe auch: Abschnitt 3.2.4, 3.2.5 <strong>und</strong> 4.3.3).<br />
Die Ausfallsicherheit des <strong>verteilten</strong> Simulationssystems wird durch die Erstellung von<br />
Sicherungspunkten (siehe Abschnitt 3.3.1) gewährleistet, solange nicht der zentrale Knoten<br />
im <strong>verteilten</strong> System ausfällt. Dieser Ausfall ist im <strong>Entwurf</strong> <strong>und</strong> der <strong>Implementierung</strong><br />
des zentralen Koordinators ausreichend berücksichtigt, so dass das Wiederanlaufen des<br />
zentralen Knotens <strong>und</strong> somit des Simulationsbetriebs ohne Verluste möglich ist.<br />
Die geforderte automatische Ressourcenzuteilung findet im Manager (vgl. Abschnitt<br />
4.3.2) gemäß den derzeitigen Erkenntnissen statt. Sollte es sich in der Praxis ergeben,<br />
das eine andere Zuteilung besser geeig<strong>net</strong> ist, lässt sie sich sehr einfach austauschen<br />
(siehe dazu Abschnitt 4.3.2).<br />
Module <strong>und</strong> Simulationen lassen sich über die GUI einfach <strong>und</strong> ohne XML-Kenntnisse<br />
erstellen. Desweiteren können die meisten Anwenderprogramme wahlweise über die GUI<br />
bedient oder über die Kommandozeile ausgeführt werden (vgl. Abschnitt 4.4).<br />
Damit sind die in Abschnitt 1.2 spezifizierten Anforderungen im <strong>verteilten</strong> System<br />
<strong>und</strong> den Anwenderprogrammen erfüllt <strong>und</strong> umgesetzt. Die <strong>Implementierung</strong> in Java<br />
bietet zusätzlich eine leicht verwendbare, plattformunabhängige Umsetzung des Systementwurfs.<br />
5.3 Lizenzbestimmungen<br />
Das verteilte System <strong>und</strong> die Benutzeranwendungen basieren auf bereits bestehende<br />
Produkte. Diese müssen bei der Frage nach den Lizenzbestimmungen für Lethe berücksichtigt<br />
werden. Diese Produkte sind:<br />
ICE Das verteilte Simulationssystem basiert auf ICE, das unter der GNU General Public<br />
Licence (GPL) [19] veröffentlicht ist. Damit stehen alle Programme <strong>und</strong> Anwendungen,<br />
die auf das verteilte System zugreifen oder anderen darüber Dienste zur<br />
Verfügung stellen, automatisch ebenfalls unter der GPL. Auf Nachfrage werden<br />
von der Firma ZeroC [23] jedoch auch kommerzielle Lizenzen vergeben.<br />
JDOM Verschiedene Anwenderprogramme greifen auf JDOM zu, das unter der freizügigen<br />
Lizenz der Apache-Fo<strong>und</strong>ation [2] steht. Sie erlaubt die Weitergabe von<br />
Binärpaketen ohne den Quelltext zur Verfügung zu stellen.<br />
Saxon Das zur XSLT-Transformation verwendete Saxon ist unter der Mozilla Public<br />
License [36] veröffentlicht, die ebenfalls eine uneingeschränkte Weitergabe von<br />
proprietärem Code erlaubt.<br />
56
5.4 Probleme mit ICE<br />
Die Verwendung von JDOM <strong>und</strong> Saxon stellt damit keine Einschränkung für eine<br />
kommerzielle Nutzung des <strong>verteilten</strong> <strong>Systems</strong> <strong>und</strong> der Benutzeranwendungen von Lethe<br />
dar. Ist dies gewünscht, müssen allerdings von ZeroC kommerzielle Lizenzen für<br />
ICE angefordert werden. Ansonsten steht Lethe – mit Ausnahme von JDOM <strong>und</strong> Saxon<br />
– unter der GPL. Dies bedeutet insbesondere, das bei Änderungen an Lethe <strong>und</strong><br />
anschließender Weitergabe auch der geänderte Quellcode zur Verfügung gestellt werden<br />
muss.<br />
Ein weiteres lizenzrechtliches Problem kann sich bei der Entwicklung eigener Module<br />
ergeben, wenn Bibliotheken eingeb<strong>und</strong>en werden. Dies wird aber in [7, Abschnitt 5.3]<br />
diskutiert, so dass hier nicht näher darauf eingegangen werden muss.<br />
5.4 Probleme mit ICE<br />
Die Verwendung von ICE als Middleware hat einige Probleme nach sich gezogen, die<br />
zu Beginn der Arbeit noch nicht abzusehen waren. Die Schwierigkeiten ergaben sich<br />
speziell im Umgang mit der Beschreibungssprache Slice :<br />
• Um Sprachen wie VisualBasic zu unterstützen, die zwischen Groß- <strong>und</strong> Kleinschreibung<br />
nicht unterscheideen, macht auch Slice solche Differenzierungen nicht.<br />
Eine einmal getroffene Schreibweise muss allerdings eingehalten werden, d.h. es<br />
ist verboten, eine Struktur namens Foo zu definieren <strong>und</strong> sie dann als FOO zu<br />
benutzen.<br />
• ICE reserviert sich einen verhältnismäßig großen Bereich im Namensraum für<br />
Bezeichner. Sie dürfen nicht mit ice beginnen, oder mit helper, holder, prx oder<br />
ptr enden. Diese Einschränkung gilt nach obigem Punkt auch für alle denkbaren<br />
Schreibweisen, wie zum Beispiel Ice oder ICE. Desweiteren dürfen die Bezeichnernamen<br />
keinen Unterstrich enthalten. Diese Regeln müssen deshalb bei Lethe auch<br />
von den Modulentwicklern bei der Wahl von Bezeichnern strikt beachtet werden.<br />
• Slice unterstützt Vorwärtsdeklarationen ausschließlich für Klassen <strong>und</strong> Schnittstellen.<br />
Dies führt dazu, dass Strukturen sich nicht selbst enthalten dürfen. Auch<br />
dürfen sie keine Strukturen enthalten, die wiederum sie enthalten.<br />
• Um Definitionen aus anderen Dateien zu unterstützen, benutzt Slice das Include-<br />
Konzept mit Hilfe des Präprozessors von C. Damit sind zyklische Abhängigkeiten<br />
von einzelnen Dateien verboten, da sie der Präprozessor nicht auflösen kann.<br />
Weitere Schwierigkeiten traten mit der Konfiguration von IceSSL <strong>und</strong> der Bereitstellung<br />
von IcePatch-Servern auf. Diese Probleme, sowie die Schwierigkeiten mit Slice,<br />
konnten alle gelöst oder umgangen werden. Jedoch sind sie sehr ärgerlich, speziell was<br />
die Benennung von Variablen betrifft.<br />
Dennoch ist ICE eine gute Wahl für ein in sich abgeschlossenes System wie Lethe: ICE<br />
lässt sich problemlos auf verschiedenen Plattformen installieren <strong>und</strong> unterstützt Java,<br />
C++ <strong>und</strong> Python. Letztere werden in der <strong>Implementierung</strong> von Alexander Bernauer<br />
verwendet. Demgegenüber ließ sich für CORBA keine freie <strong>Implementierung</strong> finden, die<br />
57
5 Zusammenfassung <strong>und</strong> Ausblick<br />
alle drei Sprachen unterstützt. Außerdem sollte man die Dienste <strong>und</strong> Plugins, die ICE<br />
anbietet, nicht unterschätzen, da sie die Entwicklungszeit von neuen Anwendungen stark<br />
verkürzen können. Lethe verwendet selbst viele der angebotenen Dienste: Einerseits um<br />
die Wartung des <strong>Systems</strong> zu erleichtern; andererseits, um Dienste wie die Codeverteilung<br />
einfach <strong>und</strong> plattformunabhängig anbieten zu können. Ohne diese Dienste hätte die<br />
Entwicklung von Lethe sicher mehr Zeit in Anspruch genommen.<br />
5.5 Ausblick<br />
Aufgr<strong>und</strong> der Größe der Aufgabe <strong>und</strong> der beschränkten Zeit konnten nicht alle Ideen<br />
umgesetzt werden. Im Folgenden wird deshalb auf mögliche Erweiterungen eingegangen.<br />
Außerdem muss bewusst sein, dass die im Rahmen der Diplomarbeit erstellten Programme<br />
lediglich den Charakter von Prototypen haben. Sie wurden während der <strong>Implementierung</strong><br />
fortlaufend getestet, speziell zugeschnittene Testabläufe fehlen jedoch.<br />
Auch muss die GUI noch mit aussagekräftigeren Fehlermeldungen versehen werden,<br />
um den Benutzer bei Problemen mit der Erstellung von Simulationen zu unterstützen.<br />
1. Erweiterungen für das verteilte System:<br />
• Ein autonomes System mit gleichberechtigten Knoten würde sowohl die Wartbarkeit<br />
als auch die maximale Größe des <strong>verteilten</strong> <strong>Systems</strong> erhöhen. Allerdings<br />
muss geprüft werden, ob es den zusätzlichen Programmieraufwand<br />
tatsächlich lohnt.<br />
• Neue Zugriffsmöglichkeiten für die Codeverteilung. Dabei stellt sich die Frage,<br />
ob ein Zugriff auf Web- oder FTP-Server benötigt wird.<br />
• Eine Einführung von Simulationsgruppen, um Aktionen auf mehrere Simulationen<br />
gleichzeitig ausführen zu können.<br />
• Es muss geprüft werden, ob das Umziehen von Simulationen durch die automatische<br />
<strong>und</strong> regelmäßige Erstellung von Sicherungspunkten noch benötigt<br />
wird. Ist dies der Fall, wäre es von Vorteil, Simulationen Knotengruppen zuzuweisen,<br />
auf denen sie ausschließlich ausgeführt werden, um ein erneutes<br />
Ausführen der Simulationen auf den Ursprungsknoten zu verhindern (vgl.<br />
letzter Absatz von Abschnitt 4.3.2).<br />
2. Erweiterungen auf Benutzerseite:<br />
• Anzeigen von Resultaten <strong>und</strong> Statistiken in der Anwendung selbst. Dies kann<br />
zum Beispiel mit Hilfe der Open Source API JFreeChart von JFree [24] geschehen.<br />
• Eine erleichterte Zusammenstellung von Simulationen durch einen graphischen<br />
Editor in der Anwendung. Dazu bietet sich die JUNG API [25] an, die<br />
bereits über verschiedene Werkzeuge zur Darstellung von Graphen verfügt.<br />
Sie unterstützt auch das für den Simulationsgraphen benötigte Konzept des<br />
Hypergraphen. Zur Darstellung sollte er aber in einen gewöhnlichen Graphen<br />
mit Hilfsknoten umgewandelt werden.<br />
58
5.5 Ausblick<br />
• Eine automatische Überprüfung der durch den Benutzer eingegebenen Parameter<br />
bei der Erstellung von Simulationen. Diese muss mit möglichst aussagekräftigen<br />
Fehlermeldungen verb<strong>und</strong>en sein, wenn sich die vorgenommene<br />
Eingabe mit der Spezifikation der Parameter in der Modulbeschreibung widerspricht.<br />
• Mit Hilfe von ICE-E ist es möglich, ICE auf Smartphones <strong>und</strong> PDAs zu installieren.<br />
Das ermöglicht es, verschiedene Benutzerprogramme zum Zugriff<br />
auf das verteilte System auf mobile Endgeräte zu portieren. Denkbar ist damit<br />
zum Beispiel eine mobile Lösung, um den Status von Simulationen zu<br />
überwachen.<br />
3. Messungen: Interessante Messungen im <strong>verteilten</strong> System kamen leider zu spät<br />
auf, um sie mit der angemessenen Sorgfalt durchzuführen. Interessante Messungen<br />
speziell im Zusammenhang mit der Diplomarbeit von Alexander Bernauer sind<br />
folgende:<br />
• Simulation starten: Wieviel Zeit vergeht, bis eine Simulation tatsächlich gestartet<br />
ist? Dazu gehört vor allem die benötigte Zeit, um ein neues Simulationsobjekt<br />
zu erstellen <strong>und</strong> zu initialisieren. Diese Dauer sollte im Bereich<br />
von wenigen Minuten liegen <strong>und</strong> spielt eine wichtige Rolle bei der Wahl der<br />
Zeitscheibengröße (vgl. Abschnitt 4.3.2). Die Standardgröße der Zeitscheibe<br />
beträgt 1h <strong>und</strong> sollte damit ausreichend groß gewählt sein, dass die Erstellungszeit<br />
des Simulationsobjekts nicht die Ausführung dominiert.<br />
• Simulationen verteilen: Hier stellt sich die Frage, wieviel Zeit der Verteilungsalgorithmus<br />
(vgl. Abschnitt 4.3.2) benötigt, um den Simulationen Knoten zur<br />
Ausführung zuzuteilen. Diese Dauer beschränkt das verteilte System sowohl<br />
in der Anzahl der Simulationsknoten als auch in der Benutzerzahl, da während<br />
dieses Zeitraums keine Simulationen ausgeführt werden. Für den Einsatzzweck<br />
von Lethe in einer einzelnen Abteilung sollten diese Überlegungen<br />
jedoch unerheblich sein, da ein Großteil der benötigten Zeit für die Bewertung<br />
<strong>und</strong> Sortierung von Simulationsaufträgen aufgewendet wird <strong>und</strong> nicht<br />
zu erwarten ist, dass im <strong>verteilten</strong> System massenhaft Simulationsaufträge<br />
zur selben Zeit ausgeführt werden sollen.<br />
59
Anhang A<br />
Kommandozeilen-Tools<br />
A.1 Simulationsverwaltung<br />
Die Simulationsverwaltung startet neue Simulationsaufträge <strong>und</strong> ermöglicht dem Benutzer<br />
Zugriff auf bereits gestartete Simulationen.<br />
Kommando: simulationManagement [-u ] [-p ] [-l | -s<br />
| [-a | -p | -r | -g] | -m ]<br />
-l Listet die Simulationen des Benutzers auf.<br />
-s Startet den in beschriebenen Simulationsauftrag.<br />
-a Bricht den Simulationsauftrag oder die R<strong>und</strong>e, die in angegeben<br />
ist, ab.<br />
-p Pausiert den Simulationsauftrag oder die R<strong>und</strong>e, die in angegeben<br />
ist.<br />
-r Fügt einen pausierten Simulationsauftrag oder eine pausierte R<strong>und</strong>e mit<br />
der ID wieder in die automatische Verteilung ein.<br />
-m Verschiebt die Simulation mit der ID auf den Simulationsknoten<br />
.<br />
-g Holt die Ergebnisse der Simulation mit der ID aus dem <strong>verteilten</strong><br />
System <strong>und</strong> speichert sie lokal ab.<br />
-u Der zur Authentifizierung am System verwendete Benutzernamen. Wird<br />
kein Benutzernamen angegeben, verwendet simulationManagement den in der<br />
Konfigurationsdatei unter config.Authentication.user gespeicherten Benutzer.<br />
-p Das zur Authentifizierung am System verwendete Passwort. Wird kein<br />
Passwort angegeben, verwendet simulationManagement das in der Konfigurationsdatei<br />
unter config.Authentication.passwd gespeicherte Passwort.<br />
A.2 Benutzerverwaltung<br />
Die Benutzerverwaltung erlaubt dem Administrator das einfache Anlegen <strong>und</strong> Löschen<br />
von Benutzern <strong>und</strong> Gruppen. Desweiteren können bestehende Benutzer <strong>und</strong> Gruppen<br />
mit ihren Rechten angezeigt werden.<br />
61
Anhang A Kommandozeilen-Tools<br />
Kommando: userManagement [-u ] [-p ] [-lu [] |<br />
-lg [] | -lp | -au [-x priority] -g | -ag<br />
[-x ] [-g ] | -du | -dg | -su<br />
[-x ] -g | -sg [-x ] [-g
A.4 Modulsuche<br />
-i Erzeugt eine Slice-Definitionsdatei aus .<br />
-c Erzeugt Hilfsmethoden <strong>und</strong> ein Gerüst zur Modulimplementierung aus<br />
.<br />
-s Erzeugt eine neue Schema-Beschreibung aus .<br />
-d Erzeugt eine neue spezielle Modul-/Typ-Beschreibung aus .<br />
-x Kopiert zusätzlich in das erstellte Paket.<br />
-m Erzeugt die Datei , in der modulspezifische Übersetzungsanweisungen<br />
stehen können.<br />
-j Erzeugt eine neue Schema-Datei aus , wenn eine<br />
Simulationsbeschreibung ist.<br />
A.4 Modulsuche<br />
Die Modulsuche erlaubt es dem Benutzer, Moduldefinitionen im <strong>verteilten</strong> System zu<br />
finden <strong>und</strong> lokal zu nutzen.<br />
Kommando: moduleFinder [-l | -m .. | -t <br />
.. ] [-p ] <br />
-l Listet alle verfügbaren Module <strong>und</strong> Datentypen der Codeverteilung unter address<br />
auf.<br />
-m .. Synchronisiert die Modulbeschreibungen <br />
.. mit den Beschreibungen der Codeverteilung unter .<br />
-t .. Synchronisiert die Datentypbeschreibungen<br />
.. mit den Beschreibungen der Codeverteilung unter<br />
.<br />
-p Verwendet für die Anfrage an die Codeverteilung nicht den dafür vorgesehenen<br />
Standardport, sondern die Portnummer port.<br />
A.5 Ergebnisse exportieren<br />
Der Ergebnisexportierer exportiert Simulationsergebnisse aus einer speziellen Datenbank<br />
nach XML.<br />
Kommando: resultExporter [-l | -e ]<br />
-l Listet alle verfügbaren Ergebnisse auf.<br />
-e Exportiert die Ergebnisse der Simulation mit ID in<br />
die Datei .<br />
63
Anhang B<br />
Installation <strong>und</strong> Wartung<br />
B.1 Installation<br />
Die Installation der einzelnen Komponenten läuft momentan über ein make-System.<br />
Anpassungen müssen dabei im Hauptverzeichnis in der Datei config.mak vorgenommen<br />
werden.<br />
B.1.1 Client<br />
Die Anwenderprogramme lassen sich durch das im Hauptverzeichnis eingegebene Kommando<br />
make client installieren. Im Verzeichnis client/bin liegen Skripte, um die<br />
einzelnen Programme zu starten.<br />
B.1.2 zentrale Komponente<br />
Um die Dienste auf der zentralen Komponente zu installieren, muss im Hauptverzeichnis<br />
das Kommando make center ausgeführt werden. Anschliessend werden der Manager, die<br />
Benutzerverwaltung <strong>und</strong> die Codeverteilung erzeugt. Breeze ist in Python geschrieben<br />
<strong>und</strong> braucht deshalb nicht übersetzt zu werden.<br />
Um die zentrale Komponente im <strong>verteilten</strong> System zu starten, müssen folgende Dienste<br />
im Verzeichnis grid gestartet werden:<br />
• icegridregistry - -Ice.Config=registry.cfg startet den Namensdienst.<br />
• icegridadmin - -Ice.Config=center.cfg ’-e application add lethe.xml’<br />
liest die Konfigurationsdatei für das verteilte System ein <strong>und</strong> trägt die am System<br />
beteiligten Knoten in eine Liste ein.<br />
• icegridnode - -Ice.Config=center.cfg fügt den Knoten als zentrale Komponente<br />
dem <strong>verteilten</strong> System hinzu.<br />
B.1.3 Simulationsknoten<br />
Ein Simulationsknoten lässt sich durch den Aufruf von make node im Hauptverzeichnis<br />
erstellen.<br />
Anschliessend muss der Knoten in das verteilte System hinzugefügt werden. Dies<br />
geschieht durch:<br />
• icegridnode - -Ice.Config=node.cfg<br />
65
Anhang B Installation <strong>und</strong> Wartung<br />
B.1.4 Codeverteilung<br />
Die Codeverteilung wird durch den im Hauptverzeichnis ausgeführten Aufruf make<br />
sourceservice erstellt.<br />
Anschliessend muss der Knoten in das verteilte System hinzugefügt werden. Dies<br />
geschieht durch:<br />
• sourceservice/run [-p]<br />
Dabei ist die Portnummer, an der der Dienst eingehende Anfragen annimmt.<br />
Fehlt die Angabe der Portnummer, wird versucht, stattdessen Port 10.000 zu benutzen.<br />
B.2 Wartung<br />
B.2.1 Simulationsknoten hinzufügen<br />
Um einen neuen Simulationsknoten hinzuzufügen, muss die Datei grid/lethe.xml um<br />
einen neuen Simulationsknoten erweitert werden. Dies geschieht durch folgenden Eintrag:<br />
<br />
<br />
<br />
Anschliessend muss die Konfiguration im <strong>verteilten</strong> System aktualisiert werden. Dies<br />
geschieht lokal von dem Rechner, auf dem die zentrale Komponente läuft mit:<br />
• icegridadmin –Ice.Config=center.cfg ’-e application update<br />
lethe.xml’<br />
Wenn auf dem Rechner noch keine Knoteninstanz ausgeführt wird, muss zusätzlich<br />
noch mit:<br />
• icegridnode –Ice.Config=node.cfg<br />
eine Instanz gestartet werden. Anschliessend ist der Knoten im System aufgenommen.<br />
B.2.2 Simulationsknoten entfernen<br />
Um einen Knoten aus dem <strong>verteilten</strong> System zu entfernen, muss der entsprechende<br />
Eintrag für den Knoten in der Datei grid/lethe.xml gelöscht werden. Anschliessend<br />
muss diese Änderung im System propagiert werden. Dies verläuft analog zum Hinzufügen<br />
<strong>eines</strong> Simulationsknotens.<br />
66
B.2 Wartung<br />
B.2.3 Neue Codeverteilung hinzufügen<br />
Eine neue Codeverteilung wird in das verteilte System hinzugefügt, indem eine neue<br />
Knoteninstanz mit dem Befehl:<br />
• sourceservice/run [-p]<br />
gestartet wird. Um diesen Dienst zu nutzen, müssen die Adresse <strong>und</strong> der Port, falls er<br />
angegeben wurde, in die Simulationsbeschreibung mit aufgenommen werden.<br />
67
Anhang C<br />
Schnittstellen<br />
Im Folgenden sind die wichtigsten Schnittstellen im <strong>verteilten</strong> System abgebildet. Dies<br />
sind im speziellen:<br />
• Die Schnittstelle des Managers zur Annahme <strong>und</strong> Verwaltung von Simulationen,<br />
sowie seine Schnittstelle mit den Simulationsobjekten.<br />
• Die Schnittstelle des Generators zum Erzeugen von neuen Simulationsobjekten<br />
sowie die Schnittstelle des Simulationsobjekts selbst.<br />
• Die Schnittstelle der Benutzerverwaltung <strong>und</strong> -authentifikation <strong>und</strong> der Rechteverwaltung.<br />
• Die Schnittstelle für die Codeverwaltung.<br />
Außerdem ist die Schnittstelle zur Sortierung, <strong>und</strong> damit der Festlegung der Verteilungsreihenfolge,<br />
von Simulationsaufträgen angegeben, sowie die zur Erweiterung der<br />
GUI bereitgestellten Schnittstellen.<br />
69
Anhang C Schnittstellen<br />
C.1 Schnittstellen im <strong>verteilten</strong> System<br />
Klassendiagramm_3<br />
Manager<br />
><br />
Comm.Manager.PublicInterface<br />
+getNextId():String<br />
+startSimulation(job:Comm.Job.Specification):void<br />
+pauseSimulation(jobId:String):void<br />
+restartSimulation(jobId:String):void<br />
+abortSimulation(jobId:String):void<br />
+moveSimulation(jobId:String,host:String):void<br />
><br />
Comm.Manager.ProtectedInterface<br />
+onSimulationFinished(jobId:String,suffix:String,results:Comm.Simulation.Results):void<br />
+onSimulationError(jobId:String,suffix:String,error:String,abort:boolean):void<br />
Abbildung C.1: Schnittstellen des Managers. Die Aufteilung in zwei Schnittstellen erfolgte wegen<br />
dem 2-Zonen-Sichereitssystem.<br />
70
C.1 Schnittstellen im <strong>verteilten</strong> System<br />
Klassendiagramm_2<br />
Simulationsobjekt<br />
Comm.Simulation.Interface<br />
+init(job:):void<br />
+start(ro<strong>und</strong>:int):void<br />
+resume(checkpoint:Comm.Simulation.Checkpoint):void<br />
+stop():void<br />
+suspend(out checkpoint:Comm.Simulation.Checkpoint,job:):void<br />
Abbildung C.2: Schnittstelle des Simulationsobjekts. Auf diese greift ausschließlich der Manager<br />
zu.<br />
Klassendiagramm_5<br />
Generator<br />
Generator<br />
+createSimulation(job:,suffix:String,buildOnly:boolean):Comm.Simlation.InterfacePrx<br />
Abbildung C.3: Schnittstelle des Generators. Der Manager greift darauf zu, um Simulationsobjekte<br />
zu erstellen.<br />
71
Anhang C Schnittstellen<br />
Klassendiagramm_6<br />
Benutzerverwaltung<br />
><br />
Comm.AuthenticationService.PublicInterface<br />
+authenticate(user:String,password:String):String<br />
+logout(user:String):void<br />
><br />
Comm.AuthenticationService.ProtectedInterface<br />
+userExists(user:int,sessionId:String):boolean<br />
+getPriority(user:String):int<br />
+hasPermission(user:String,owner:String,permission:String):boolean<br />
+hasPermissions(user:String,owner:String,permissions:String[]):boolean<br />
><br />
Comm.AuthenticationService.UserManagement<br />
+getUser(user:String):User<br />
+getGroup(group:String):Group<br />
+getAllUsers():User[]<br />
+getAllGroups():Group[]<br />
+addUser(u:User,password:String):void<br />
+addGroup(g:Group):void<br />
+deleteUser(user:String):void<br />
+deleteGroup(group:Group):void<br />
+setUser(name:String,u:User):void<br />
+setPassword(user:String,password:String):void<br />
+setGroup(name:String,g:Group):void<br />
Abbildung C.4: Schnittstellen der Benutzer- <strong>und</strong> Rechteverwaltung. Zusätzliche Schnittstelle<br />
zur Authentifizierung der Benutzer.<br />
72
C.1 Schnittstellen im <strong>verteilten</strong> System<br />
Klassendiagramm_7<br />
Codeverteilung<br />
><br />
Comm.SourceService.PublicInterface<br />
+announce(jobId:String,files:String[],f:Filter,source:SourceDesc):void<br />
+getAvailableModules():String[]<br />
><br />
Comm.SourceService.ProtectedInterface<br />
+startSourceService(jobId:String):String<br />
+stopSourceService(jobId:String):void<br />
><br />
SourceController<br />
+getSource(source:SourceDesc,files:String[],directory:String):void<br />
+getSourceList(source:SourceDesc,directory:String):String[]<br />
Abbildung C.5: Schnittstelle zur Codeverteilung. Die eine Schnittstelle wird ausschließlich von<br />
den Benutzern genutzt, um Ressourcen für Simulationen anzumelden. Die andere<br />
dient der Synchronisierung von Modulcode im <strong>verteilten</strong> System.<br />
Klassendiagramm_4<br />
Simulationsverteilung<br />
><br />
SortingAlgorithm<br />
+sort(jobs:Collection,seats:int):List<br />
+init(manager:Manager):void<br />
Abbildung C.6: Schnittstelle, um einen eigenen Zuteilungsalgorithmus zu implementieren. Der<br />
verwendete Algorithmus muss in der Konfigurationsdatei angegeben werden.<br />
73
Anhang C Schnittstellen<br />
C.2 Schnittstellen der GUI<br />
Klassendiagramm_1<br />
GUI<br />
><br />
Pluggable<br />
+init():void<br />
+release():void<br />
+show():JPanel<br />
+hide():void<br />
><br />
Personalizable<br />
+setSettings(settings:Element):void<br />
+getSettings():Element<br />
+getDefaultSettings():Element<br />
><br />
ToolbarUsable<br />
+getShowButton():JButton<br />
+addToToolbar():List<br />
Abbildung C.7: Schnittstellen für das Erweiterungsframework der GUI. Plugins sollten zumindest<br />
die Schnittstelle Pluggable implementieren. Die anderen Schnittstellen<br />
dienen der automatischen Speicherung von internen Zuständen <strong>und</strong> der Benutzung<br />
der Buttonleiste in der GUI.<br />
74
Anhang D<br />
Software<br />
D.1 verwendete Software<br />
• Eclipse zur Entwicklung der Java-Programme<br />
• EditiX zum Erstellen von XML-Beschreibungen, XML-Schema <strong>und</strong> XSLT-<br />
Vorschriften<br />
• Poseidon zum Erstellen von UML-Diagrammen<br />
• SubEthaEdit zum Erstellen der Diplomarbeit<br />
• SVN zur Versionskontrolle<br />
• LATEX zur Textformatierung für die Diplomarbeit<br />
• GNU make als Build-System<br />
D.2 Inhalt der beigefügten CD<br />
• Diplomarbeit im LATEX-Format, sowie das daraus erstellte pdf-Dokument.<br />
• <strong>Implementierung</strong> der Diplomarbeit (client, manager, authservice, sourceservice)<br />
• Dokumentation zu ICE 3.0.1<br />
• Benötigte Programme (hauptsächlich ICE) zum Ausführen von Lethe sowohl als<br />
kompiliertes Paket als auch die Source-Dateien<br />
• Beispiele für Modul- <strong>und</strong> Datentypbeschreibungen, sowie Beispielsimulationen.<br />
75
Index<br />
.NET, 17<br />
asynchroner Methodenaufruf, 8<br />
Ausfallsicherheit, 23<br />
Authentifizierung, 46<br />
autonomes System, 18<br />
C++, 7, 35<br />
Client-Server Modell, 18<br />
Codeverteilung, 20, 46–47<br />
CORBA, 6, 17<br />
Datentyp, 15<br />
Freeze, 9<br />
Glacier, 10, 25<br />
Graph, 16, 40–42<br />
Sicherheitszonen, 25<br />
Sicherungspunkte, 30, 45<br />
Simulation, 15–16, 31–33<br />
Simulations-ID, 16, 44<br />
Simulationsauftrag, 16, 29, 40–42<br />
Slice, 7, 38–41, 47, 50, 57<br />
SOAP, 17<br />
Transformation, 11, 38–40<br />
XML, 10, 36<br />
XML-Schema, 10<br />
XPath, 11<br />
XQuery, 11<br />
XSLT, 11, 37<br />
Zugriffskontrolle, 23<br />
ICE, 6<br />
IceGrid, 9, 43<br />
IcePatch, 9, 20, 46<br />
IceSSL, 9, 25<br />
IceStorm, 33<br />
Java, 7, 11, 35<br />
JDOM, 12, 56<br />
Kommunikation, 26<br />
Kommunikationsaufwand, 19, 28<br />
Modul, 13–15, 37–40<br />
Namensdienst, 8, 18, 48<br />
Rechteverwaltung, 20–23<br />
Reflection-API, 12, 36, 42, 50<br />
RMI, 17<br />
Saxon, 12, 56<br />
Session-ID, 26<br />
77
Literaturverzeichnis<br />
[1] The ACE ORB (TAO). http://www.theaceorb.com, May 2006.<br />
[2] Apache Licence. http://apache.org/licenses/LICENSE-2.0.html, May 2006.<br />
[3] Alan O. Freier, Philip Karlton, Paul C. Kocher: The SSL Protocol —<br />
Version 3.0. Inter<strong>net</strong> Draft, Transport Layer Security Working Group, November<br />
1996.<br />
[4] Benoit, Ken<strong>net</strong>h: Which Electoral Formula Is the Most Proportional? A New<br />
Look with New Evidence. Political Analysis, 8(4), 2000.<br />
[5] Beowulf. http://www.beowulf.org/, April 2006.<br />
[6] Bergl<strong>und</strong>, Anders, Scott Boag, Donald D. Chamberlin, Mary F.<br />
Fernández, Michael Kay, Jonathan Robie <strong>und</strong> Jérôme Siméon: XML Path<br />
Language (XPath) 2.0. World Wide Web Consortium, Candidate Recommendation<br />
CR-xpath20-20051103, 2005.<br />
[7] Bernauer, Alexander: <strong>Entwurf</strong> <strong>und</strong> <strong>Implementierung</strong> <strong>eines</strong> Frameworks für Simulationen<br />
in der Kanalcodierung. Diplomarbeit, University of Ulm, April 2006.<br />
[8] Biron, Paul V. <strong>und</strong> Ashok Malhotra: XML Schema Part 2: Datatypes Second<br />
Edition. World Wide Web Consortium, Recommendation REC-xmlschema-<br />
2-20041028, 2004.<br />
[9] Boag, Scott, Donald D. Chamberlin, Mary F. Fernández, Daniela Florescu,<br />
Jonathan Robie <strong>und</strong> Jérôme Siméon: XQuery 1.0: An XML Query<br />
Language. World Wide Web Consortium, Candidate Recommendation CR-xquery-<br />
20051103, 2005.<br />
[10] Bossert, M.: Channel Coding for Telecommunications. John Wiley & Sons, New<br />
York, 1. Auflage, 1999.<br />
[11] Bray, Tim, Jean Paoli, C. Michael Sperberg-McQueen, Eve Maler <strong>und</strong><br />
François Yergeau: Extensible Markup Language (XML) 1.0 (Third Edition).<br />
World Wide Web Consortium, Recommendation REC-xml-20040204, 2004.<br />
[12] Budszuhn, Frank: Subversion. Galileo Press, 1. Auflage, 2005.<br />
[13] CoCentric System Studio. http://www.synopsys.com/, April 2006.<br />
[14] The Common Object Request Broker Architecture (CORBA/IIOP), 2004.<br />
79
LITERATURVERZEICHNIS<br />
[15] David F. Ferraiolo, D. Richard Kuhn, Ramaswamy Chandramouli: Role-<br />
Based Access Control. Artech House, April 2003.<br />
[16] Fallside, David C. <strong>und</strong> Priscilla Walmsley: XML Schema Part 0: Primer<br />
Second Edition. World Wide Web Consortium, Recommendation REC-xmlschema-<br />
0-20041028, 2004.<br />
[17] Free Software Fo<strong>und</strong>ation. http://www.fsf.org/, April 2006.<br />
[18] GoldSim. http://www.goldsim.com/, April 2006.<br />
[19] GNU General Public Licence. http://www.gnu.org/copyleft/gpl.html, April 2006.<br />
[20] Haase, Oliver: Kommunikation in <strong>verteilten</strong> Anwendungen. Oldenbourg, 2001.<br />
[21] Howatson, M.C.: Reclams Lexikon der Antike. Reclam, 2006.<br />
[22] Hunter, Jason: JDOM 1.0. Java Specification Request (JSR) 102, 2001.<br />
[23] The Inter<strong>net</strong> Communication Engine. http://www.zeroc.com/, April 2006.<br />
[24] JFree software projects. http://jfree.org/index.php, May 2006.<br />
[25] Java Universal Network/Graph Framework. http://jung.sourceforge.<strong>net</strong>, May 2006.<br />
[26] Kay, Michael: XSL Transformations (XSLT) Version 2.0. World Wide Web<br />
Consortium, Candidate Recommendation CR-xslt20-20051103, 2005.<br />
[27] Kazuaki Ishizaki, Motohiro Kawahito, Toshiaki Yasue et al.: Design,<br />
Implementation, and Evaluation of Optimizations in a Just-In-Time Compiler. In:<br />
Proceedings of the ACM 1999 conference on Java Grande. Java Grande Conference,<br />
ACM Press, June 1999.<br />
[28] Kennard Scribner, Mark C. Stiver: Soap. Markt + Technik Verlag, 2001.<br />
[29] Matlab. http://www.mathworks.com/, April 2006.<br />
[30] McLaughlin, Brett: Java and XML. O’Reilly & Associates, 1. Auflage, 2000.<br />
[31] Michi Henning, Mark Spruiell: Distributed Programming with Ice.<br />
http://www.zeroc.com/download/Ice/3.0/Ice-3.0.1.pdf, May 2006.<br />
[32] Microsoft: .NET. http://www.microsoft.com/germany/msdn/<strong>net</strong>framework,<br />
May 2006.<br />
[33] MLDesigner. http://www.mldesigner.com/, April 2006.<br />
[34] Mono Project. http://www.mono-project.com/, May 2006.<br />
[35] Message Passing Interface. http://www.mpi-forum.org/, April 2006.<br />
[36] Mozilla Public License, Version 1.0. http://www.mozilla.org/MPL/MPL-1.0.html,<br />
May 2006.<br />
80
LITERATURVERZEICHNIS<br />
[37] GNU Octave. http://www.octave.org/, April 2006.<br />
[38] The Object Management Group. http://omg.org/, May 2006.<br />
[39] Ptolemy. http://ptolemy.eecs.berkeley.edu/, April 2006.<br />
[40] Puder, Arno <strong>und</strong> Kay Römer: MICO is CORBA: A CORBA 2.2 Compliant<br />
Implementation. 2nd Auflage, 1999.<br />
[41] Parallel Virtual Machine. http://www.csm.ornl.gov/pvm/, April 2006.<br />
[42] Rivest, Ronald L.: The MD5 Message-Digest Algorithm. Inter<strong>net</strong> informational<br />
RFC 1321, April 1992.<br />
[43] Sainte-Laguë, André: Les réseaux. E. Privat, 1924.<br />
[44] Saxon, the XSLT and XQuery Processor. http://saxon.sourceforge.<strong>net</strong>/, May 2006.<br />
[45] Schildt, Herbert: Java Ent-packt. MITP-Verlag GmbH, Bonn, 1. Auflage, 2001.<br />
[46] Scilab. http://www.scilab.org/, April 2006.<br />
[47] Thompson, Henry S., David Beech, Murray Maloney <strong>und</strong> Noah Mendelsohn:<br />
XML Schema Part 1: Structures Second Edition. World Wide Web Consortium,<br />
Recommendation REC-xmlschema-1-20041028, 2004.<br />
[48] World Wide Web Consortium. http://w3c.org, May 2006.<br />
[49] William Tolone, Gail-Joon Ahn, Tanusree Pai Seng-Phil Hong: Access<br />
Control in Collaborative <strong>Systems</strong>. ACM Computing Surveys, 37(1), March 2005.<br />
81