Probleme und Lösungen der Plattform

Werbung
Probleme und Lösungen der Plattform - unabhängigen Entwicklung
am Beispiel einer Software für Identity - Management
Als Vorlesung gehalten an der TU Dresden am 13.4.2007
Im Rahmen der Ringvorlesung
„Softwareentwicklung in der industriellen Praxis“
Lehrstuhl Softwaretechnologie
Frau Dr. Birgit Demuth
Autoren:
Dipl.-Ing Ingo Rohner
Absolvent 1985 an der TU Dresden, Studienrichtung Informationsverarbeitung.
Dipl.-Inf. (FH) Jörg Rosenkranz
Absolvent 1998 an der HTW in Dresden, Studienrichtung Informatik
Die Firma Völcker Informatik AG (VI) hat ihren Sitz in Berlin. Die Autoren arbeiten in
der Niederlassung Dresden als Softwareentwickler und sind hauptsächlich mit dem
Produkt ActiveEntry beschäftigt. Alle Angaben im Vortrag beziehen sich auf dieses
Produkt.
Prämissen:
a) Die Firma und das Entwicklerteam sind relativ klein, das Produkt ist relativ groß
b) die Kunden haben Freiheiten hinsichtlich
- des eingesetzten Betriebssystems
- der verwendeten Datenbank
- der verwendeten Anzeigetechnologie (Fat-Client / Browser)
- der Anpassung der Software auf ihre speziellen Gegebenheiten
Um diesen Widerspruch aufzulösen, definieren wir das Prinzip Highlander:
"Es kann nur einen (Code) geben"
Inhalt
1) Die Firma................................................................................................................ 3
2) heutiges Arbeitsgebiet von VI................................................................................. 6
2.1 Compliance ....................................................................................................... 6
2.2) Was ist Identity - Management ........................................................................ 7
2.3) Provisioning ..................................................................................................... 8
2.4 Betriebsdatenabbildung .................................................................................... 9
3. Lösungsansätze für IdM, Provisioning und ComplianceCheck ............................. 10
3.1 Lösungsansätze der Marktführer .................................................................... 10
3.2 Lösungsansatz von VI..................................................................................... 11
3.2.1 Vorgehensweise von VI im Projekt ........................................................... 14
4) Plattform- unabhängige Implementierung............................................................. 15
4.1 die Voraussetzungen bei VI ............................................................................ 15
4.2 die Kundenforderungen................................................................................... 16
4.3 die Lösungswege ............................................................................................ 17
5) Konkrete Implementierung der Ebenen ............................................................... 17
5.1 Die Businesslogik / Objekt-Ebene ................................................................... 17
5.2 ) Datenbank-Ebene ......................................................................................... 18
5.2.1. Generierung und Single Source .............................................................. 19
5.2.2. liebevolle Handarbeit ............................................................................... 22
5.2.3. SQL-Formatter......................................................................................... 23
5.3. Frontend – Ebene .......................................................................................... 25
1) Die Firma
Mit einem kleinen Rückblick in die Geschichte wollen wir zeigen, wie sich die Firma
und das Produkt entwickelt haben und wie wir zu unseren heutigen Themen im
Identity - Management kamen, ja eigentlich zwangsläufig kommen mußten.
In den Jahren 1992 / 1993 haben die späteren Gründer bei der Krone
Netzwerkservice GmbH zusammengearbeitet.
1994 wurde die Firma gegründet, erst als GbR, später als GmbH. Seit 1999 ist
Völcker Informatik AG eine Aktiengesellschaft.
Zur Gründung der Firma 1994 war der Stand der Technik auf dem Arbeitsplatz
Windows 3.11, im Serverbereich Novell Netware in den Versionen 2.x, 3.11, 3.12 und
die Herausforderung hieß, 200 PCs in einem Netz zum Laufen zu bringen. 200 PCs –
eine Herausforderung? Da lächeln Sie inzwischen drüber, mit den damaligen Mittel
war das jedoch nicht trivial zu realisieren.
Insbesondere ging es in der Anfangszeit von VI um den Aufgabenbereich
Unattended Setup, das heißt um die Fragen:
- Wie bekomme ich Stückzahlen von PCs an die Arbeitsplätze?
- Wie bekommen die PCs ihr Betriebssystem?
- Wie bekommen die PCs bzw. die Anwender ihre Applikationen?
Insbesondere der letzte Punkt führte uns zum Thema der automatischen
Softwareinstallation, d.h. wie bekommt jeder PC genau die Software und die Treiber,
die ihm zugedacht sind. Bei Windows 3.11 wurde dies realisiert über liebevolles
Patchen der Dateien Win.Ini und System.Ini. Es wurden Skripte gebaut, um die INIDateien zu modifizieren, um dann die Netze auszurollen.
Im Jahr 1996 haben wir unser erstes Netz auf Basis von NT 3.51 bei den Berliner
Verkehrsbetrieben gebaut. Damit erreichten wir erstmal die Größenordnung von
3000 Benutzern. NT 3.51 war die Software der Server, teilweise auch der Clients,
meistens hatten wir jedoch Windows 95 Clients. Dort wurde erstmalig ein Verfahren
angewendet, die Software anhand von Gruppenmitgliedschaften der Nutzer zu
verteilen. Wir hatten ein eigenes Verfahren für Softwareverteilung entwickelt. Das
Verfahren beruht auf einem Delta-Abbild und ist eigentlich eine relativ triviale Sache,
das machen heutzutage viele. Die Idee war ursprünglich auch nicht ganz von uns.
Grob umrissen funktioniert das Verfahren wie folgt: Wir haben am Anfang einen PC,
der jungfräulich mit dem Betriebssystem aufgesetzt ist. Von diesem PC merken wir
uns alle Eigenschaften, alle Dateien, Registry-Einträge, Ini-File-Einträge,
Desktopsymbole und Menüsymbole. Anschließend installieren wir die Applikation
oder den Treiber auf dem PC und konfigurieren alle Einstellungen so, wie sie
gewünscht werden. Bei Office z.B. betrifft diese Konfiguration die Menüs, die
Vorlagenverzeichnisse oder die Rechtschreibkontrolle. Von der so entstandenen PCKonfiguration merken wir uns wiederum alle Eigenschaften. Aus den gemerkten
Zuständen wird ein Delta gebildet, welches wir ein Profil nennen. Völcker Informatik
AG hat in diesem Zusammenhang ein Werkzeug entwickelt, welches dieses Profil in
eine Maschine schreiben und es auch spurlos wieder löschen kann. Damit hatten wir
einen Mechanismus für eine sehr schnelle Softwareinstallation. Die Deltabildung läuft
im Allgemeinen um die 90 Sekunden für eine kompletten PC. Bei der eigentlichen
Softwareinstallation wird die meiste Zeit dafür benötigt, die Profile durch das Netz zu
transportieren, weswegen wir inzwischen an dieser Stelle einen asynchron
arbeitenden Cache verwenden.
Für die Zuordnung der Software haben wir nicht die Maschinen sondern die NTKonten verwendet, die Software also den Nutzern zugeordnet. Der Nutzer ist Mitglied
in einer Gruppe, welche als Applikationsgruppe gekennzeichnet ist. Unser Werkzeug
schaut nach, welcher Nutzer welchen Gruppen angehört und demzufolge werden die
zugehörigen Applikationen installiert oder deinstalliert. Im Projekt bei den Berliner
Verkehrsbetrieben haben wir innerhalb von 3 Wochen die 3000 PCs einmal komplett
ausgerollt. Dazu kamen ein paar Roadies, welche die Kisten an die Plätze gebracht,
ausgepackt, aufgestellt und Kabel angesteckt haben, die MAC-ID per Telefon
durchgesagt haben, Knöpfchen gedrückt haben und dann fuhr der PC hoch. Das war
für beide Seiten ein sehr erfolgreiches Projekt, welches uns den Weg geebnet hat für
viele weitere Entwicklungen.
Im den Jahren 1997/1998 haben wir dann das erste NT 4 Projekt realisiert bei der
Schering AG. Bei diesem Kunden handelte es sich bereits um 10000 Nutzer. In
diesem Projekt haben wir zum ersten Mal das Prinzip der Vererbung über
Betriebsdaten angewendet. Der Kundenwunsch war, daß ein Mitarbeiter bzw. sein
NT4-Konto über seine Mitgliedschaft in Abteilungen, Kostenstellen oder Standorten
Applikationen und Gruppen erben soll. Das klingt erst mal ganz einfach – ist es
letztendlich auch, wenn man ein paar unbedingt notwendige Randbedingungen
einhält.
Wir haben damals auch das erste Mal eine komplette Vollsynchronisation eines
Zielsystems implementiert. Es wurden die kompletten Informationen zu den NT4Domänen vollständig in unsere Datenbank eingelesen, d.h. alle Informationen zu den
Konten, Gruppen und Mitgliedschaften. In der Datenbank wurden die Zuweisungen
der Nutzer vorgenommen und die Ergebnisse, die aufgrund von
Strukturveränderungen oder auch Direktzuweisungen entstanden sind dann wieder
in die Umgebung publiziert.
Im Jahr 1999 haben wir das Konzept der Betriebsdatenabbildung auf Wunsch eines
weiteren Kunden weiter ausgebaut. Dr. Eckhardt Knauer war damals EDV-Leiter bei
der AOK in Berlin. Er sagte uns: „Ich als EDV-Mensch bin immer der Letzte in der
Firma, der von irgendwelchen Einstellungen oder Entlassungen erfährt. Und ich bin
auch der Letzte in der Firma, der erfährt, daß ein PC irgendwo abgebaut und
woanders wieder angeschlossen wurde oder daß ein Monitor irgendwo umgesetzt
worden ist. Ich weiß eigentlich fast nichts. Das Einzige, was ich weiß, ist, da steht ein
Schreibtisch, für den eine Arbeitsaufgabe definiert ist“.
Also haben wir den Schreibtisch in unserer Datenbank modelliert. Auf dem
Schreibtisch stellen wir einen PC auf und schließen einen Drucker an. So ist das
Prinzip der Arbeitsplätze bei uns entstanden. Das hat uns dann in späteren Projekten
des Öfteren gerettet.
Im Jahr 2001 folgte die Integration von ActiveDirectory-Systemen, auch wieder
komplett per Vollsynchronisation. Zu der Zeit hatten wir erstmals das Konzept der
Person eingeführt, ein ähnliches Abstraktum wie den Arbeitsplatz. Anfänglich hatten
wir nur ein einziges Zielsystem angeschlossen, das war entweder NT 4 mit einer
oder mehreren Domänen bzw. Active Directory. Es war von einigen unserer Kunden
gewünscht, daß diese einen Überblick bekommen, wenn eine Person 2 Konten
besitzt. 99% aller Nutzer haben in einem Zielsystem genau ein Konto. Aber es gibt
ein paar wenige, die haben noch ein Extrakonto für administrative Aufgaben. Diese
Abbildung konnten wir vorher noch nicht leisten. Da galt für uns (wie heute immer
noch für viele Anbieter): Eine Person = ein Konto.
Kurz danach kamen weitere Zielsysteme in unser Produkt, so z.B. Lotus Notes und
Novell NDS, damit war die Zusammenführung diverser Konten in verschiedenen
Systemen auf Personen dringend geboten.
Im Jahr 2003 begannen wir ein Projekt in der Landeshauptstadt München mit 160000
Nutzern im Netz. Bei diesen Nutzer handelt es sich um alle Schüler von der 1. bis zur
13. Klasse, alle Berufsschüler und sämtliches Verwaltungspersonal im
Pädagogikbereich der Stadt München. Alle diese Nutzer bekamen ein Konto, ein
Postfach, ein Home-Verzeichnis und Ablageverzeichnisse. Die Verwendung
bestimmter Betriebssysteme war zu der Zeit in München ein Politikum, das dazu
führte, daß ausschließlich NICHT- Microsoft-Produkte zu verwenden waren.
Wenn wir uns im Gegensatz dazu die bisherige Geschichte von Völcker Informatik
AG dazu ansehen:
– Völcker Informatik AG war „deutlich blau gefärbt“, alles war Microsoft-geprägt
– Linux – man weiß wie man es schreibt, man hat es schon mal gehört, schon mal
gesehen – aber dafür programmieren?
– Oracle – ja, das soll wohl auch eine Datenbank sein. Wir haben bis dahin mit
Microsoft SQL-Server gearbeitet, alle Versionen von der 6.5 an
Wir nutzten die gebotene Chance und reimplementierten unsere gesamte Software.
2001 hatte Microsoft .NET vorgestellt, aus unserer Sicht das bessere JAVA. Miguel d
Icasa sah das genauso und begründete das Mono-Projekt, eine Plattformunabhängige Laufzeitumgebung für .NET. Damit hatten wir eine Basis, in der
gewohnten Microsoft-Umgebung zu entwickeln und die Software gegen Linux laufen
zu lassen. Aus diesem Projekt wurde auch das heute vollständige umgesetzte
Konzept der Plattform-Unabhängigkeit geboren.
Im Jahr 2003 haben wir angefangen SAP als ein Zielsystem zu integrieren. Bei SAP
synchronisieren wir nicht die gesamte Datenbank noch einmal in unsere Datenbank,
sondern beschränken uns auf die Informationen zu Konten, Mitgliedschaften und
Gruppen (dort Profile und Rollen genannt), wobei letztere nur gelesen werden.
2005 haben wir es dann erstmals geschafft, funktionsidentische Frontends sowohl
auf dem PC als EXE-Datei als auch im Browser laufen zu lassen, wobei in beiden
Fällen das selbe Compilat verwendet wird. Das war notwendig, da immer mehr
Kunden Intranet-Lösungen zu unserem Produkt haben wollten, insbesondere was
den Bereich der Selbstbedienung der Anwender betrifft.
Die Firma Völcker Informatik AG hat zum heutigen Tag 55 Mitarbeiter, davon
arbeiten 12 in Dresden. Dresden ist der Standort der Firma in dem komplett die
Bereiche Produktentwicklung, Qualitätssicherung, Dokumentation und Support
abgewickelt werden.
2) heutiges Arbeitsgebiet von VI
2.1 Compliance
Was ist eigentlich Compliance?
Leo.org übersetzt das mit
- in Übereinstimmung mit einer Bedingung
- in Erfüllung einer Bedingung
Wozu benötigen wir Compliance?
Schauen wir ein paar Jahre zurück, auf das Platzen der großen Internetblase. Kann
sich noch jemand an den Enron-Skandal erinnern? Dieses Energie-Unternehmen in
den Vereinigten Staaten hat Spekulations- und Scheingeschäfte innerhalb der Firma
gemacht. Zum Schluß implodierte das gesamte Spekulationsgebilde mit einem
Riesenknall und einigen Milliarden Dollar Verlusten. Als Reaktion darauf wurde in
den USA ein Gesetz verabschiedet, der „Sarbance-Oxley-Act“ (SOX). Dieses
verpflichtet Unternehmen, Regeln der innerbetrieblichen Sauberkeit zu definieren,
einzuhalten und zu überwachen. Solche Regeln sind z.B. daß jemand, der Einkäufe
über 1000 $ auslösen darf, nicht gleichzeitig auch zeichnungsberechtigt für die
dazugehörigen Überweisungen ist.
Wenn eine solche Rechtekonstellation zusammentrifft, dann ist der Versuchung Tür
und Tor geöffnet. Das sind Risiken, die in der Unternehmensbilanz benannt und
bewertet werden müssen. Die Einhaltung dieser Regeln muß nicht nur auf
allgemeiner organisatorischer Ebene, sondern ausdrücklich auch auf der Ebene der
EDV-Zugriffsrechte sichergestellt werden.
Und was geht uns das in Deutschland an? Die Beantwortung der Frage ist relativ
einfach: Jedes Unternehmen, das auch an amerikanischen Börsen gehandelt wird,
ist verpflichtet eine Bilanz zu liefern, in der auch die Einhaltung solcher Regeln
gesichert ist. Das ist Bestandteil des Wirtschaftsprüfertestats.
Es gibt aber auch bei uns gesetzliche Regelungen, die eine Regeldefinition und –
Überwachung fordern. In Deutschland haben wir z.B. das Energiewirtschaftsgesetz.
Das Energiewirtschaftsgesetz sagt unter anderem sinngemäß aus, daß, wenn eine
Firma Energieerzeuger ist, ein eigenes Endkundengeschäft betreibt und auch
Endkundengeschäft für Wiederverkäufer organisiert, niemand von diesen 3
Bereichen dem anderen in die Karten schauen darf. Ansonsten könnte ich ja als
Endkundenbetreuer eines Energieerzeugers mal eben die Kundenliste der YelloKunden nehmen, alle abtelefonieren und versuchen sie zurückzugewinnen. Da muß
also eine Wand im Unternehmen existieren, welche auch auf EDV-Ebene
repräsentiert wird. Das heißt, daß Leute, die in dem einen Bereich arbeiten nicht auf
die Ordner und Applikationen der Leute aus einem anderen Bereich zugreifen
können und umgekehrt.
Ein ähnliches Gesetz gibt es auch in Deutschland im Bereich Aktien- oder
Bankenrecht. Jemand, der im Kundenauftrag mit Aktien handelt, darf sich in seinen
Rechten, Befugnissen und Informationen nicht überschneiden mit jemandem, der
Firmenfusionen, Firmenverkäufe oder Aufspaltungen im Auftrag der Bank bearbeitet.
Im anderen Fall wäre die Gefahr eines Insider-Geschäfts gegeben. Dem Gesetz
muß derart Genüge getan werden, daß eine Trennung auch im EDV-Bereich
existiert.
Das Thema Compliance befaßt also immer mit Regeldefinitionen der Art
„Es darf nicht sein, daß jemand... “
Z.B. „Es darf nicht sein, daß jemand Zugang zu der Gruppe A und zu der Gruppe B
und zu dem Ordner C hat und sowohl die Applikation D als auch die Applikation E
verwenden darf.“
Weiterhin gefordert ist beim Thema Compliance eine dauerhafte und lückenlose
Aufzeichnung aller Rechtezuweisungen, aller Rechteabweisungen und in dem Fall,
daß eine Regelverletzung aufgedeckt wird, auch eine zeitnahe Benachrichtigung
desjenigen, der für die Überwachung dieser Regel zuständig ist, erfolgt.
„Es darf nicht sein, daß jemand...“ Wer ist dieser „jemand“? Im Sinne der Gesetze
ist damit immer eine Person gemeint. Die Rechtsprechung kennt keine Konten,
verantwortlich sind immer Personen.
Eine Person hat jedoch unter Umständen mehrere Konten in den unterschiedlichsten
Zielsystemen. Und für diese Person müssen die Regelverletzungen aufgedeckt bzw.
gleich vermieden werden.
Denken Sie jetzt mal an die EDV-Landschaften, die Sie bisher kennengelernt haben.
Haben Sie da irgendwo schon einmal eine Person als abstraktes Objekt gesehen?
Es werden immer nur Konten verwaltet.
2.2) Identity - Management
Es existiert Uneinigkeit darüber, was eine Identität ist, manch einer meint die Person,
andere meinen damit Konten. Im Sinne von Compliance sind aber immer beide im
Zusammenhang zu betrachten.
Das Ziel von Identity – Management ist es, zu jeder Zeit die Information über jede
Identität und ihre Berechtigung zur Verfügung haben, manipulieren und auswerten zu
können. Es nützt nicht, eine Überwachung von 2 Konten zu machen, es geht um die
Person – der Bankangestellte, der nicht gleichzeitig zwei sich ausschließende Rechte
haben darf, egal mit welchen Konten er sie erreicht.
Rechte sind z.B. Access-Control-Lists im ActiceDirectory oder Transaktionen in SAP.
Solche Rechte werden im Normalfall an Gruppen gebunden. Es gibt eine einzige
Stelle, wo es sinnvoll ist, ein Recht an ein einzelnes Konto zu binden, und das ist das
Recht auf dem Home-Verzeichnis eines Nutzers.
Gruppen als Träger der Rechteinformationen gibt es heute in jedem Konten
verwaltenden System (Betriebssysteme, SAP, Notes, auch Mail-Verteilerlisten sind
„nur“ Gruppen )
Für die Überprüfung von Compliance reicht es also im Normalfall aus, die
Gruppenmitgliedschaften zu überwachen, sofern die Rechte der Gruppen ordentlich
dokumentiert sind.
Zusammenfassung:
Identity - Management ist das Verwalten von Informationen über Person, ihre Konten
und deren Gruppenmitgliedschaften, das Aufzeichnen von Veränderungen und das
Anbieten von Auswerte-Möglichkeiten.
2.3) Provisioning
Das letzte Schlagwort in der Sammlung lautet Provisioning – frei übersetzt die
„Versorgung“. Das meint die Versorgung einer Person mit Konten in einem
bestimmten Zielsystem und die Versorgung eines Kontos mit
Gruppenmitgliedschaften. Im erweiterten Sinne bedeutet das auch die Versorgung
einer Person mit materiellen Gütern wie z.B. einem PC oder Telefon oder allem
Sonstigen, was die Person für ihre Tätigkeit benötigt.
Die Zielstellung, welche hinter dem Schlagwort Provisioning steht, lautet: Betritt
jemand ein Unternehmen, so soll er innerhalb kürzester Zeit arbeitsfähig gemacht
werden, auch EDV-technisch, d.h. er muß ein Konto bekommen z.B. im Active
Directory, er muß ein Postfach erhalten, muß in bestimmte Rechtegruppen
aufgenommen werden, muß ein Portfolio an Applikationen zugeteilt bekommen und
einen PC auf den Schreibtisch bekommen, der ein passendes Betriebssystem und
eine korrekte Netzanbindung hat.
Wer etwas vertraut ist mit der Materie weiß, es gibt Unternehmen, in denen dauert
es wirklich vom Eintritt des Mitarbeiters bis zu dem Zeitpunkt, an dem er EDV-mäßig
arbeitsfähig ist, 2-4 Wochen. Es kann sich solange hinziehen, weil viel Papierkram
von vielen Leuten ausgefüllt und unterschrieben werden muß bis sich dann jemand
hinsetzt und wirklich das Konto anlegt. Das Gegenstück dazu ist, jemand verläßt das
Unternehmen. Da mögen aber bitte innerhalb weniger Minuten sämtliche Konten
nicht mehr verwertbar sein – egal ob sie nun gelöscht oder gesperrt werden, oder nur
aus allen Gruppen entfernt werden. Hauptsache, man kann mit den Konten nicht
mehr arbeiten. In der Praxis dauert es allerdings oftmals mehrere Jahre, bis auch
wirklich das letzte Konto gesperrt oder gelöscht ist.
Gesamt-Zielstellung Identity - Management, Provisioning und Compliance
Eine Person soll genau über die Konten und Berechtigungen verfügen, die für ihre
Tätigkeit notwendig sind, genau für den Zeitraum in dem das erforderlich ist.
Sämtliche Arbeitsschritte, die Änderungen an diesen Daten vornehmen, sind zu
dokumentieren. Das Berechtigungsportfolio darf keine der definierten Regeln
verletzen bzw. sind diese Regelverletzungen aufzuzeichnen und kurzfristig den
Verantwortlichen zu melden.
Wie gelangt man nun eigentlich zur Mitgliedschaft in einer Gruppe, sei es nun
Applikations- oder Rechtegruppe? Wir haben 3 mögliche Herangehensweisen:
- Der erste Weg ist der Klassiker: Ich nehme das Management-Werkzeug des
Betriebssystems nehme meinen Account, füge ihn in die Gruppe ein und
speichere ihn. So hat keiner einen Überblick oder eine Benachrichtigung und
somit weiß auch keiner, wer dies wann getan hat.
- Die bessere Wahl ist ein Ablauf von Bestellung, Genehmigung und
Zuweisung. Eigentlich wird hier lediglich das Verfahren abgebildet, welches in
-
den meisten Unternehmen papiermäßig abläuft und am Ende mit den
technischen Mitteln der Direktzuweisung (s.o.) realisiert wird.
Die 3. Variante ist die Erbschaft aus Strukturmitgliedschaften bzw. aus Rollen.
Egal, welches der beiden letztgenannten Verfahren wir benutzen, wir haben es an
diesen Stellen jetzt immer mit Betriebsdatenabbildungen zu tun, da die Erbschaft aus
einer Strukturzugehörigkeit erfolgt bzw. der Besteller und der Genehmiger in einer
betrieblichen Korrelation zueinander stehen. Oftmals ist z.B. der Genehmiger der
Kostenstellenverantwortliche, da dieser später auch die zugehörige Rechnung
bekommt.
Bei der Deutschen Telekom Immobilien GmbH haben wir es so implementiert, daß
jeder Kostenstellenverantwortliche am Monatsende per E-Mail ein PDF zugestellt
bekommt mit dem Titel „Ihre EDV-Kosten für diesen Monat für ihre Mitarbeiter“.
Aufgeführt sind dort alle Kosten für PC-Abschreibung oder Leasingraten,
Applikationsnutzung oder Speicherverbrauch auf den Servern. All diese
Informationen sind letztlich in der Datenbank vorhanden und müssen nur noch per
Report strukturiert werden. Die EDV-Kostenstellen werden in der Kostenrechnung
als Verrechnungskostenstelle umgelegt, d.h. die EDV-Abteilung ist an jedem
Monatsende als interner Firmendienstleister kostenmäßig auf +/- Null gestellt.
Wir haben also immer eine gewisse Betriebsdatenabbildung durchzuführen. Wie
diese aussieht, soll unser letzter Punkt sein bevor wir uns der konkreten
Implementierung zuwenden.
2.4 Betriebsdatenabbildung
Bei der Betriebsdatenabbildung gibt es mehrere Ansätze. Ich habe mit Herrn
Professor Koch von der HTW herzliche Streitgespräche durchgeführt. Prof. Koch ist
einer der X-500 Gurus und ebenso ein Motor der Unix-Gemeinde.
X-500, ist vereinfacht gesagt, ein Modell zur hierarchischen Strukturierung von
Organisationsdaten als Container und der Zuordnung von Konten in diese Container.
Das ist das Modell mit dem viele Vertriebsleute Erfolg haben, weil es genauso
aussieht, wie sich mancher Vorstand seine Firma vorstellt. Ganz oben ist der Chef,
darunter bauen wir ein paar Container an, welche die Hauptabteilungen darstellen.
Darunter werden erneut Container aufgebaut, die dann Unterabteilungen verkörpern.
Schließlich folgen die Kleinstabteilungen. Es ist also ein richtig schönes
hierarchisches System, in dem ich auch etwas durchvererben kann.
Es gibt allerdings ein paar Probleme z.B. das Thema Standorte. Die IP-Konfiguration
der Rechner ist standortabhängig. Gut, lösen wir das Problem, indem wir auf der
ersten Ebene unserer Hierarchie Container für die Standorte einfügen und darunter
spannen sich dann die Abteilungen auf. Das ist immer noch optimal aus der Sicht
eines Vorstandsvorsitzenden. Dann gibt es aber noch die Kostenstellen. Nun wird es
langsam unübersichtlich, da man sie nicht mehr in eine einzelne Hierarchie
hineinbekommt und außerdem im X-500 jedes Konto nur in genau einem Container
Mitglied sein kann.
Vor ca. 6 Jahren hatten wir die dankbare Aufgabe bei der Wirtschaftsprüfungsfirma
KPMG eine Analyse zur Modellierung der Verteilerlisten zu erstellen. KPMG ist ein
Unternehmen, welches andere Unternehmen berät wie diese ihre Betriebsabläufe
aufzubauen und wie sie sich zu strukturieren haben. Im E-Mail - System gab es eine
Menge definierter Verteilerlisten und KPMG wollte einen Automatismus haben, mit
dem jemand aufgrund seiner Zugehörigkeit zu einem Standort, zu einer Abteilung
usw. automatisch Mitglied in einer Verteilerliste wird und die entsprechenden
Informationen, die an diese Verteilerliste gesendet werden, auch erhält.
Die 3 Klassiker in der Betriebsstrukturierung hatten wir sofort identifiziert: Abteilung,
Kostenstelle und Standort – alles kein Problem. Die Kostenstellen ergaben sich aus
Sicht der Controller.
Die Mitgliedschaft im Beratungsprojekt X oder Y ist die nächste Ebene.
Dann kamen noch die Fachgebiete hinzu z.B. Beratung in Land- und Forstwirtschaft,
dazu die Interessengebiete „Ja, ich interessiere mich auch für die
Nahrungsgüterwirtschaft“.
Weiterhin gibt es die Partnerschaften. KPMG ist keinesfalls ein homogenes
Unternehmen, sondern viel mehr eine Vereinigung mehrerer Sozietäten mit
gemischten Eigentümerschaften.
Und dann gibt es noch Spezialisierungsrichtungen: Der eine Mitarbeiter ist
verantwortlich für Prüfung und Testierung, der andere ist für die Betriebsorganisation
zuständig und der Dritte für die Finanzplanung.
Das sind also insgesamt 8 Dimensionen, in denen KPMG strukturiert ist.
Wir können davon ausgehen, daß jede Firma eine n-dimensionale Abbildung
benötigt, wobei n beliebig groß sein kann. Wir haben also eine n-dimensionale
Matrix-Sicht. Jede dieser Sichten ist bei uns letztendlich auch implementiert als ein
Baum, jedoch gegenüber X-500 mit einigen entscheidenden Unterschieden:
- Jeder Nutzer kann Mitglied in beliebig vielen Containern auch innerhalb eines
einzigen Baumes sein
- Mitglied sind die Personen, nicht die Konten
- An jeden Container kann man Rechte aus allen Zielsystemen zuweisen,
weiterhin auch Konstrukte für die Zuweisung für z.B. PCs
3. Lösungsansätze für IdM, Provisioning und ComplianceCheck
3.1 Lösungsansätze der Marktführer
MetaDirectory - Projekte
In den letzten Jahren gab es den Hype der Meta-Directory-Projekte. Die Anbieter am
Markt hatten inzwischen alle erkannt, daß eine n-dimensionale Matrix und eine X-500
Abbildung nicht so recht zueinander passen. Also definierten sie ein neues Directory,
legten dieses über das vorhandene und nannten das Ganze ein Meta-Directory.
Wenn man die Dimensionen vergleicht, kommt man schnell zu dem Schluß: „Das
kann nicht funktionieren.“ Die Meta-Directory-Projekte sind auch alle hinsichtlich
einer sauberen Betriebsdaten-Abbildung gescheitert.
Identity Management – Systeme (IdM)
Die meisten Anbieter von IdM führen mit Kunstgriffen die Person als Objekt ein,
legen jedoch nur die Referenzen zu den verwalteten Konten ab. Es erfolgt also keine
komplette Abbildung des Zielsystems (Bsp. Nur Ablage des DistinguishedName).
Dabei treten jedoch einige Probleme auf:
- Wird ein Objekt umbenannt oder geändert, stimmt die Referenz nicht mehr,
das System ist inkonsistent.
- Die Zuordnung der Eigenschaften als auch Zuordnung von Personen zu
Konten erfolgt über Mapping – Regeln z.B. zwischen Accountname oder
Email-Addresse zu Eigenschaften der Person wie Vorname und/oder
Nachname
Das klappt im besten Fall für 98 % aller Objekte, meist jedoch nur im Bereich
zwischen 60 und 80 % aller Objekte. Aber selbst 2 % Restmenge bedeuten
das Scheitern des Projektes, weil damit
a) automatisches Management über die Meta-Ebene nicht mehr zu
definiert richtigen Ergebnissen führt.
b) schon ein einziger Verstoß gegen Compliance - Regeln zur
Verweigerung eines Testats führen kann.
- Sollen Objekte betrachtet oder geändert werden, ist ein Zugriff auf das
Zielsystem notwendig, es muß also am Standort der Management – Software
verfügbar sein.
- Sollen Listen von Objekten gezogen werden, so benötigt man viel Zeit. Wir
haben Anwendungsfälle, bei denen wir die Mitglieder in einem Container
(2500 Konten), als eine Liste im Frontend produzieren müssen. Als
Reaktionszeit eines Frontends werden nur Zeiträume bis 3 Sekunden
akzeptiert. Mit Direktzugriffen auf die Zielsysteme schafft man das nicht
annähernd.
Es gibt also auf diesem Gebiet einen Glaubenskrieg – machen wir ein Store-ByReference (was u.a. in den Meta-Directory-Projekten verwendet wird) oder mache ich
ein Store-By-Value (unser Weg) d.h. alle Daten liegen komplett in der Datenbank.
Warum haben wir uns für die Datenbank entschieden? Zum einen ist das das einzige
wirklich transaktionssichere System. Für diesen Zweck sind relationale Datenbanken
entwickelt worden. Und es ist auch die einzige Technologie, die gut geeignet ist für
Massendatenverarbeitung.
3.2 Lösungsansatz von VI
3-Ebenen Architektur
Letztendlich gesehen, haben wir in unserem Produkt eine klassische 3-EbenenStruktur, bestehend aus einer Datenbank, darüber die Objektschicht und einer
Präsentationsschicht. Auch die automatische Verarbeitung auf den Servern
funktioniert wie eine Präsentationsschicht, da auch sie immer durch die Objektschicht
hindurch geht.
ObjectLayer
ObjectLayer
Datenbank
Nutzdaten
Metadaten
Die Datenbank haben wir logisch in zwei Bereiche eingeteilt. Zum einen haben wir
die Nutzdaten, welche die konkreten Informationen über Personen, Betriebsdaten,
Konten, Mitgliedschaften, Gruppen beinhalten (pay-load). Zum anderen gibt es die
Metadaten, welche die gesamte Dialogsteuerung, Queues für asynchrone
Verarbeitung sowie die komplette Systemkonfiguration umfassen.
Das Nutzdaten- Modell enthält Tabellen für:
- Die Person und ihre 1:n Abbildung zu Konten
- Beliebige Betriebsdaten-Strukturen mit beliebigen Mitgliedschaften als
Fremdschlüssel oder auch als m:n-Abbildung, um die n-dimesionale Matrix
des Unternehmens darstellen zu können.
- Die vollständige Abbildung der zu verwaltenden Zielsysteme.
Über der Datenbank liegt eine Objektschicht. In der Objektschicht ist eigentlich vom
Objekt selbst oder von Klassendefinition her nichts programmiert. Die „leere Hülle“
der Objekte wird zur Laufzeit aus dem datenbankschema erzeugt. Die
Funktionsweise der Klassen ergibt sich erst im Zusammenspiel mit den Meta-daten
aus der Datenbank.
Wir haben je Tabelle eine Objektklasse. Davon abgeleitet gibt es je nach Bedarf
weitere Teilklassen. Je Spalte ist ein Property definiert. Zur Verfügung steht ein Satz
von Datenbank-orientierten Methoden (Load, Save, GetValue, PutValue) und Events
(Insert, Update, Delete).
Wir stellen Ausdrucksmittel für die Quernavigation (Objectwalker) zur Verfügung, mit
denen sich auf der Ebene C# Fremdschlüsselbeziehungen verfolgen lassen.
Es gibt die sogenannten Customizer in der Objektebene. Diese enthalten nicht
änderbare Nebenwirkungen der Objekte. Ein Beispiel dafür ist das Wechselspiel der
Flag UserCanNotChangePassword UseMustChangePasswordAtNextLogon im
Objekte ADSAccount.
Über die Metadaten der Datenbank können weitere konfigurierbare Nebenwirkungen
geladen werden, die dem Kunden offen gelassen wurden. Beispiel dafür sind
Bildungsregeln für Postfächer.
Über Serverkomponenten, die auch gegen die Objektschicht arbeiten, erfolgt die
vollständige bidirektionale Synchronisation mit den Zielsystemen.
Das Management über Frontends erfolgt immer durch die Objektschicht hindurch. Als
Ergebnis gibt es eine Veränderung von Nutzdaten. Parallel dazu werden auch
Metadaten verändert, vorzugsweise in Queues für asynchrone Verarbeitungen. Von
den Queues holen sich Server die Informationen ab und verarbeiten diese.
Gleichzeitig befinden sich Server aber auch in der Rolle, daß sie Informationen und
Aktionen (wie ein normales Frontend) wieder einstellen können.
In den einschlägigen Studien zum Thema Identity Management und Provisioning
(z.B. Burton und Gartner) tauchen immer wieder zwei Begriffe auf, über die sich die
Gelehrten allzu gern streiten: Local Agent und Remote Agent. Ein Agent ist in dem
Sinne ein Stück Software, welches Manipulationen an Konten im Zielsystem
vornehmen kann.
Der lokale Agent: Ich mache etwas über eine Remote-Konsole auf einem Server und
lasse dort alles ausführen.
Der Remote Agent: Ich sitze an meinem Arbeitsplatz und habe einen Durchgriff
durchs Netz und mache meine Änderungen aus der Entfernung.
Nach diesen Definitionen ist unser Produkt etwas, was man konsequenterweise als
Distributed Agent bezeichnen muß.
Betrachten wir zum besseren Verständnis den Vorgang „Anlegen eines Kontos in der
ADS“.
Im Frontend hat das Konto seine Eigenschaften bekommen und soll nun in das
Zielsystem publiziert werden. Die erste Aktion hierfür ist das Anlegen des Kontos
selbst. Manch einer glaubt, das wäre schon alles gewesen, doch die eigentliche
Arbeit beginnt jetzt erst.
Nach dem Anlegen auf dem Domain-Controller folgt ein weiterer Bearbeitungsschritt,
denn der Nutzer benötigt ein Home-Verzeichnis. Dazu muß ich einen geeigneten
Home-Server aus den Betriebsdaten auswählen, im Normalfall wird das
standortabhängig sein. Auf dem Homeserver muß ich ein Verzeichnis anlegen,
dieses sharen und Rechte für den Nutzer vergeben. Des Weiteren benötigt der
Nutzer ein Postfach, welches ich sinnvollerweise auf dem Exchange-Server anlege.
Aber sowohl bei der Rechtevergabe auf dem Home-Server als auch beim Anlegen
des Postfaches auf dem Exchange-Server muß ich warten bis die ADS eigene
Replikationen mir das Konto auf dem aktuellen Server zur Verfügung stellt. Dann
muß das Konto in Rechtegruppen und Verteilerlisten aufgenommen werden, was
sinnvollerweise wieder auf dem Domain-Controller passiert.
Wir bevorzugen diese Vorgehensweise aufgrund der Installierbarkeit, der
Lastverteilung und der Sicherheit der Daten.
Wenn ich einen Dienst auf einer Maschine installiere, dessen Aktionsgebiet auf die
Maschine selber beschränkt ist, bekomme ich Rechtesituation und Betriebsstabilität
viel einfacher konfiguriert, als wenn ich Aktionen ausübe, bei denen man durchs Netz
durchgreifen muß.
Dazu müßte ich einem Konto Rechte auf entfernte Ressourcen erteilen. Sobald sich
aber an Kontensituationen oder Netztopologie irgend etwas verändert, ist solch eine
Zuordnung von Rechten immer problembehaftet. Deswegen liegt unsere
Konzentration auf lokaler Ausführung. Jeder Server holt sich aus der Queue in der
Datenbank die Aufgaben ab, die durch ihn zu bearbeiten sind und meldet sein
Verarbeitungsergebnis zurück. Darauf basierend besitzen wir einen SchaltMechanismus für Prozeßabläufe, durch die im Anschluß der möglichen Folgeschritt
freigeschalten wird.
3.2.1 Vorgehensweise von VI im Projekt
Die schwierigste Phase in IdM-Projekten ist die die Inbetriebnahme und hierbei
wiederum das Thema Datenkonsolidierung. Im Laufe der Jahre hat sich bei uns ein
Standard-Vorgehen etabliert.
Die Daten zu den Betriebsstrukturen werden durch Importe oder durch manuelles
Anlegen erzeugt.
Die Personen werden aus einem HR-System importiert, das klappt zumindest für alle
die, die auf der Lohnliste stehen. Jetzt fehlen noch externe Mitarbeiter von
Dienstleistern bzw. Leiharbeiter. Weitere Personendaten oder auch weitere
Eigenschaften von Personen werden durch Import aus Telefonbuch-Applikationen,
Telefonanlagen-Speichern oder später direkt aus Konten gewonnen.
Danach werden alle relevanten Zielsysteme mit Konten, Gruppen und
Mitgliedschaften eingelesen. Auf Basis dieser Daten machen wir eine erste
Zuordnung der Personen zu den Konten. Diese Zuordnung erfolgt durch einmaliges
Anwenden von Mapping – Regeln in den Fällen, bei denen die Regel ein
eineindeutiges Ziel ermittelt. Mit dieser Methode erreicht man ca. 60-80 %
Datenqualität.
Die so erzeugten Daten gehen als Korrekturlisten an die Abteilungen, da auf dieser
Ebene die Personen durch direkten Kontakt bekannt sind und die Informationen oft
wesentlich aktueller vorhanden sind. Den Abteilungsleitern wird ein Frontend im
Intranet zur Verfügung gestellt, mit dem sie ihren Änderungen vornehmen können.
Bis hierher kommen wir auf über 95 % Datenqualität.
Alle Konten, die sich bis zu diesem Stand nicht zuordnen lassen, werden gesperrt.
Wir gehen aus Erfahrung davon aus, daß sich der Inhaber des Kontos in der EDVAbteilung melden wird, sofern er noch Bedarf hat.
Die ausgelesenen Gruppen-Zuordnungen der Konten werden soweit möglich
umgesetzt auf Erbschaften über Betriebsdaten, sofern die Beziehung zwischen z.B.
einer Abteilung und einer Gruppenmitgliedschaft eindeutig ist und der Kunde dies
wünscht.
Ein anderer oder manchmal auch zusätzlicher Weg ist die Umsetzung der
Gruppenzuordnungen auf Bestellungen im IT-Shop. Die Zuordnungen werden so
aufbereitet, als ob sie im Intranet bestellt, genehmigt und zugeordnet wären. Das gibt
dem Kunden die Möglichkeit, solche Zuordnungen einfach abbestellen zu können.
Die Zuordnung der Konten zu Personen kann ebenfalls wie eine ITShop-Bestellung
aufbereitet werden, so daß z.B. ein Abteilungsleiter für seinen Mitarbeiter ein Konto
wieder abbestellen kann, wenn er dies nicht mehr benötigt.
4) Plattform - unabhängige Implementierung
4.1 Die Voraussetzungen bei VI
Die Wurzeln von Völcker Informatik liegen ganz eindeutig im Microsoft-Umfeld
Alles was bisher beschrieben wurde, hatten wir über die Jahre schon Stück für Stück
in C++ und COM - Technologie (für die Zugriffs- und Objektebene) bzw. in Visual
Basic für die Frontends implementiert. Als Datenbank diente MSSQL in den
Versionen 6.5, 7 und auch 2000.
Alle Mitarbeiter haben mit Microsoft DevStudio 5 und 6 gearbeitet, VI-Editor und
Arbeit ohne einen Schritttest-Debugger hat niemand mehr akzeptiert.
Die Niederlassung Dresden setzt sich nach Aufgaben heute wie folgt zusammen
(Teilzeitverträge und Aufgabenteilungen sind anteilig umgerechnet auf ganze Stellen)
Objektschicht
Zielsystem –Abgleich
Standard-Frontends (Fat + Web)
QS
Standard-Prozesse
Kundenspezifische Frontends
Dokumentation
Entwicklung primäre Datenbank
Umsetzung Oracle
Support
1
1
2
1,5
0,75
1
1
1
0,3
1,5
Das bedeutete, je nach Zählweise ca. 7 Leute für alle Entwicklungen
Für alle Software-Ebenen mußte eine Entscheidung fallen für ein System unter dem
primär entwickelt wurde. Alle anderen Plattformen müssen dann per Anpassen /
„Abschreiben“ nachgezogen werden. Bei der Entwicklung auf der jeweiligen
Primärplattform müssen die Einschränkungen durch die anderen Plattformen immer
schon berücksichtigt werden. Alles was gebaut wird, muß Unit-Tests erhalten, die
identisch auch in der Sekundär - Implementierung ablaufen.
4.2 Die Kundenforderungen
Die Kundenwünsche beinhalten Plattformunabhängigkeit hinsichtlich
- Datenbank
- Zugrunde liegendes Betriebssystem, Programmiersprache und
Laufzeitumgebung
- Frontend-Technologie als Exe bzw. als Browser-Frontend
wobei der Webserver und der Browser selbst auch wieder Plattformunabhängig sein sollen.
Insgesamt ergibt das die nachfolgend skizzierte Vielfalt an Möglichkeiten
4.3 Die Lösungswege
Das Ergebnis soll hier schon einmal vorweggenommen werden.
Aus unserer Sicht hat man genau 3 Lösungsmöglichkeiten, um eine Software
plattformunabhängig zu entwickeln.
Nr. 1 die schöne heile Welt:
Wir haben identischen Schnittstellen auf allen Plattformen. Dazu entwickelt man
einen Quelltext, compiliert diesen und läßt das Ergebnis auf alle Plattformen laufen.
Nr. 2 die ähnliche Welt:
Die Zielumgebungen sind sich zumindest weitgehend ähnlich, haben eine
ausreichend großen Durchschnittsmenge, so daß sich eine Entwicklung auf einer
Meta-Ebene lohnt. Das bedeutet, daß man auf einer abstrahierten Ebene entwickelt
und dann entweder zur Laufzeit oder zur Generierungszeit aus dieser Meta-Ebene
ein Programm erzeugt, das auf den jeweiligen Plattformen läuft.
Nr. 3 die Unterwelt:
Die Zielumgebungen sind so unterschiedlich, daß getrennte Implementierungen
notwendig sind. Üblicherweise wird für ein Primärsystem entwickelt und nach
erfolgten Tests der Code anschließend durch Abschreiben in eine oder mehrere
Sekundärimplementierungen übertragen.
In Reinform trifft man diese Möglichkeiten in der Realität fast nie an. Meistens treten
Mischformen auf.
5) Konkrete Implementierung der Ebenen
5.1 Die Businesslogik / Objekt-Ebene
Für die Implementierung einer plattformunabhängigen Objekt - Ebene standen im
Jahr 2002 zwei relevante Systeme zur Auswahl:
Die zuerst untersuchte und damals auch bekanntere Grundlage war Java. Es war
damals schon weit verbreitet und hatte vor allem serverseitig eine große Akzeptanz
erreicht. Die Fat - Clients waren jedoch recht langsam und instabil. Für die
Zukunftssicherheit der Entscheidung kam erschwerend hinzu, daß Java kein offener
Standard ist, sondern unter Hoheit der Firma SUN steht.
Als technisches Problem stellte sich die Einbindung von nativem Code heraus,
welcher jedoch bei der Ansteuerung z.B. einer ADS oder eines Notes-API benötigt
wird.
Die Alternative hieß .NET Framework mit C# als Entwicklungssprache.
Das war für uns aufgrund unserer Vergangenheit eine vertraute
Entwicklungsumgebung mit der auch native Windows-Frontends möglich waren.
.NET war eingereicht als ECMA-Standard und eine Portierung auf andere
Betriebssysteme war mit dem quelloffenen Mono im Entstehen. Mono war zwar
anfangs noch nicht ausgereift, Probleme konnten von uns aufgrund der
Quelloffenheit gefixt und an die Mono-Community eingereicht werden.
Die Einbindung von bestehendem Code war für eine Übergangszeit bzw. für die
direkte Betriebssystemansteuerung möglich.
Letztendlich trafen wir also unsere Entscheidung zugunsten .NET.
Eine totale Plattformunabhängigkeit läßt sich nicht erreichen, es gibt immer
Fallstricke zu beachten. Einige Beispiele dafür sollen nachfolgend kurz benannt
werden.
-
-
-
Pfade im Dateisystem
Linux ist in diesem Bereich Case Sensitiv, Windows ist Case Insensitiv. Beide
Betriebssysteme haben andere Trennzeichen und andere
Verzeichnisstrukturen (Laufwerksbuchstaben)
Fehlende Features
Linux kennt keine Registry und keine COM-Interfaces
Unterstützung für Oberflächenbibliotheken
Es gibt erhebliche Unterschiede zwischen WinForms und GTK#
externen Bibliotheken
In den Anfangszeiten gab es für MONO keine vollständige VB.NETUmsetzung
Verwendung von nicht portablen externen Bibliotheken
Zugekaufte Controls oder Bibliotheken enthalten oftmals native
Betriebssystem-Aufrufe, das ist z.B. bei fast alle Reporting-Werkzeugen der
Fall
Nutzung von Tools, die nur auf einem der Systeme zur Verfügung stehen (z.B.
Robocopy vs. Rsync)
Die Grundregel lautet hier: Soweit wie möglich abstakt implementieren und z.B.
Path.Combine statt String.concat verwenden. Wenn es wirklich massive
Unterschiede gibt, greift Methode 3: Man verwende einen Case-Block, der nach
Betriebssystemen differenziert. Zu diesem Zweck kann man ein zentrales Property
unserer Klassenbibliothek zur Unterscheidung abfragen.
5.2 ) Datenbank-Ebene
Was ist das Schöne an Standards? Daß es so viele davon gibt!
Es gibt einen ANSI-SQL-Standard. Man kann sich daran orientieren und es ist als
Lehrbeispiel auch gut zu verstehen. Daneben gibt es die Implementierung von
Microsoft mit dem Namen Transact-SQL, meist abgekürzt mit T-SQL.
Weiterhin gibt es eine Implementierung von Oracle, die sich PL/SQL nennt.
Die nachfolgenden Aussagen sind nicht wissenschaftlich, sondern eher im
Gefühlsbereich angesiedelt. Es gibt Überschneidungen und Differenzmengen
zwischen MSSQL, Oracle und dem ANSI-Standard.
ANSI-SQL ist von Haus aus, was Abläufe und prozentuale Elemente betrifft, etwas
schwach auf der Brust – Da ist eigentlich gar nichts definiert.
T-SQL
PL/SQL
ANSI-SQL
Unser Ziel war immer offen zu bleiben für die spätere Integration weiterer
Datenbanksysteme. Deshalb wurde vor Grundsatzentscheidungen auch immer die
Machbarkeit gegen PostgreSQL abgetestet. DB2 haben wir außen vor gelassen, da
es bei unseren Kunden so gut wie nicht vorkommt und MySQL mußten wir
ignorieren, da es mit Triggern und SPs noch nicht so weit war.
5.2.1. Generierung und Single Source
Die Datenbank ist der Kern unseres Produktes, die Stelle, wo alle Informationen
zusammenlaufen. In der Codestatistik im Anhang kann man erkennen, wie sich
dieser Sachverhalt auch auf die Code-Menge auswirkt. Das konnten wir natürlich
nicht alles zweimal machen.
Deswegen ist es nötig zu differenzieren. Soweit wie möglich nutzen wir MetaEntwicklung aus einer einzigen Quelle. Das Datenbankschema wird mit einem
schönen, alten Werkzeug gepflegt, das inzwischen schon 10 Jahre alt ist und ERWin
heißt. Wir nehmen unsere Entity-Relationship-Modelle um das Schema zu definieren
und daraus einen Report zu erstellen. Weiterhin haben wir ein kleines
Generierungstool und generieren uns aus dem Report des Modells das eigentliche
Schema.
Die Generierung erzeugt das Schema mit allen Tabellen, Indizes, allen Anweisungen
für referentielle Integrität (teilweise als Trigger, teilweise als Constraint).
Im nachfolgenden Beispiel sehen wir die generierten Quelltexte für die
Tabellendefinition für Betriebssystem-Informationen. Die beiden Texte sehen sich
noch recht ähnlich, haben aber schon ein paar Unterschiede, die rot gekennzeichnet
wurden.
Bsp.: Create Table
Create Table OS (
Ident_OS
varchar(32) NOT NULL,
UID_Licence char(38) NULL,
Name
varchar(64) NULL,
Version
varchar(64) NULL,
IsServerOS bit
default 0 NULL ,
IsClientOS bit
default 0 NULL ,
XDateInserted datetime NULL,
XDateUpdated
datetime NULL,
XUserInserted varchar(64) NULL,
XUserUpdated
varchar(64) NULL,
XTouched
char(1) NULL
Primary Key (Ident_OS)
)
go
Create Index XIF1126OS on OS
(
UID_Licence
)
go
Create Table OS (
Ident_OS
Varchar2(32 ) NOT NULL,
UID_Licence Varchar2(38 ) NULL,
Name
Varchar2(64 )
NULL,
Version
Varchar2(64 )
NULL,
IsServerOS Number(1,0 ) default 0 ,
IsClientOS Number(1,0 ) default 0 ,
XDateInserted Date NULL ,
XDateUpdated
Date NULL ,
XUserInserted Varchar2(64 ) NULL,
XUserUpdated
Varchar2(64 ) NULL,
XTouched
Varchar2(1 ) NULL
, Primary Key (Ident_OS)
)
go
Create Index XIF1126OS on OS
(
UID_Licence
)
go
Der Name von Tabellen darf bei Oracle aus historischen Gründen nur 30 Zeichen
betragen, Microsoft hingegen erlaubt bis zu 260 Zeichen. Will man beide Systeme
verwenden, muß man praktisch alles auf die kleine Variante reduzieren – also 30
Zeichen.
Die Gültigkeit von Namen ist bei Oracle prinzipiell schemaweit. Bei Microsoft muß
Indexname nur unikal sein im Zusammenhang mit dem Tabellennamen.
Die Wertarten sind ein Thema für sich. Varchar ist Standard für alle variablen
Zeichenketten. Oracle besitzt außerdem ein Varchar2. Oracle kennt zwar auch ein
varchar, das ist aber kaum in Verwendung. Varchar2 wurde wahrscheinlich deshalb
so genannt, weil es ein bißchen anders ist. Microsoft trennt strikt: eine leere
Zeichenkette (’’) ist etwas anderes als ein Null-Wert. Oracle sagt, es ist dasselbe.
Das kann einem ganz böse auf die Füße fallen, wenn man für beide Plattformen
etwas entwickelt.
Microsoft kennt für logische Informationen die Wertart Bit. Sie kann die Werte 0,1 und
null annehmen und benimmt sich ansonsten wie andere numerische Werte. Oracle
hingegen kennt einen richtigen boolean mit true und false. Damit wir aber wieder
kompatibel in der ganzen darüber liegenden Umgebung sind, haben wir bei Oracle
logische Werte generiert als Numeric (1,0) und interpretieren das auf der
Objektebene als logischen Wert mit 0 und 1. Nach außen aus der Objektschicht
kommt es als boolean mit true und false wieder an.
Ein ganz böses Thema ist der ANSI-Join. Diese Notation kann Oracle überhaupt erst
seit Version 9. Leider ist die Implementierung so instabil, da man bei Verwendung
der ANSI-Notation Fehler in der Zugriffsschicht provozieren kann, wenn mehr als 5
(Version 9) oder 7 Tabellen (Version 10) beteiligt sind.
Es gab im Jahr 2003 eine Vorstellungskonferenz für Yukon, was dann der Microsoft
SQL-Server 2005 wurde. Steve Ballmer ist ja bekannt für seine oftmals humorigen
Auftritte. Er hatte sich auf die Bühne gestellt und gesagt: „Microsoft is a Database –
Company.“ Kichern, Lachen und Stöhnen im Saal. Aber er ließ sich nicht davon
beirren und sagte den Spruch noch einmal. Seit ich den ANSI-Join von Oracle kenne,
glaube ich Mr. Ballmer.
Weitere Unterschiede, die in schon in der Generierung berücksichtigt werden
müssen, sollen nachfolgend nur kurz benannt werden:
Standard - Funktionen haben zum Teil unterschiedliche Name und
Parametrierungen.
Substring <-> substr
left <-> substring(x,1)
dateadd, datediiff <-> keine direkte Entsprechung
Diese Funktionen haben wir in Oracle alle nachimplementiert, um sie in der gleichen
Notation wie in MSSQL nutzen zu können.
DDL-Anweisungen sind bei MSSQL innerhalb einer Transaktionen möglich, bei
Oracle beenden sie die Transaktion.
Bei MSSQL arbeiten wir aus historischen Gründen Case - Insensitiv, da das in
Windows (Konten, Filename) auch so ist. Oracle kennt keine case-insensitiven
Daten. Bei Vergleichen muß man also darauf Rücksicht nehmen.
Bsp.:
MSSQL:
Oracle:
Lastname = @Lastname
upper(Lastname) = upper(v_Lastname)
Besonders dramatisch ist das bei Fremdschlüssel - Beziehungen. Bisher war es
uninteressant ob ein Wert in der Childrelation groß oder klein geschrieben war, jetzt
haben wir auch in MSSQL dafür gesorgt, daß beide den gleichen Case haben.
Der 2. Teil der Generierung, umfaßt die referentielle Integrität, was man als Trigger
oder als Constraint bauen kann. Wir haben in manchen Fällen das eine, in manchen
Fällen das andere gemacht. Nachfolgend sehen wir einen generierten Trigger,
einmal die Microsoft-Implementierung und einmal die Oracle-Implementierung. Blau
markiert sind die Bereiche, welche noch gleich sind, denn es sind einfach zu viele
Sachen, die unterschiedlich sind. Es kommt aber aus derselben Source, aus
demselben Schema - Entwurf.
exec vidroptrigger 'vi_2LicencePurchase'
go
create trigger vi_2LicencePurchase on LicencePurchase
for Update
as
begin
declare @numrows int,
@errno int,
@errmsg varchar(255)
if 0 = (select count(*) from inserted) + (select count(*) from
deleted) return
if (select count(*) from deleted, inserted
where deleted.UID_LicencePurchase =
inserted.UID_LicencePurchase
) <> (select count(*) from inserted)
begin
select @errno = 30002,
@errmsg = '#LDS#Änderung des
Primärschlüssels in Tabelle {0} ist nicht
zulässig|LicencePurchase'
goto error
end
end
return
error:
create or replace trigger vi_8LicencePurchase before update
on LicencePurchase
for each row
declare
numrows int;
errmsg varchar2(255);
begin
select count(*) into numrows from dual
where ( :old.UID_LicencePurchase =
:new.UID_LicencePurchase or
(:old.UID_LicencePurchase is null and
:new.UID_LicencePurchase is null));
if numrows = 0 then
errmsg := '#LDS#Änderung des Primärschlüssels in
Tabelle {0} ist nicht zulässig|LicencePurchase';
goto error;
end if;
return;
Und dann gibt es noch das Thema:
5.2.2. liebevolle Handarbeit
Stellen Sie sich folgenden Fall vor: Eine Person wird Mitglied in einer Abteilung. Es
könnte sein, daß sich die Rechtesituation dieser Person ändert, indem die Konten
der Person eine Gruppenmitgliedschaft oder irgendwelche Software erben.
Demzufolge ist für die Zuweisung der Person zur Abteilung ein Trigger nötig, der
einen asynchronen Berechnungsauftrag einstellt. Die Verarbeitung muß asynchron
sein, da jede Antwortzeit des Systems über 3 Sekunden vom Anwender nicht
akzeptiert wird.
Wenn Sie sich mit einem Menschen unterhalten und dieser sie über 3 Sekunden lang
starr ohne jede Regung ansieht, dann werden sie unsicher. Man wird skeptisch.
Versteht er mich jetzt noch oder muß ich es noch mal sagen oder wie? Genauso
gehen wir auch mit dem Computer um. Bei jeder Reaktionszeit unseres Frontends
über 3 wird der Anwender unsicher.
Die Trigger werden von Hand geschrieben, da wir bisher keinen gescheiten Weg zur
Meta-Programmierung gefunden haben. Die Primärimplementierung ist MSSQL.
Nachfolgend ein Beispiel für manuell doppelt implementierte SQL-Texte:
create procedure viDropProcedure
(@name varchar(64))
create or replace procedure viDropProcedure
(in_name IN VARCHAR2 DEFAULT NULL)
as
begin
declare @cmd varchar(255)
declare @owner varchar(255)
as
DECLARE viDropProcedureSchritt SCROLL CURSOR for
select rtrim(ROUTINE_SCHEMA)
from information_schema.routines
where ROUTINE_NAME = @name
and ROUTINE_type = 'procedure'
for read only
OPEN viDropProcedureSchritt
FETCH FIRST FROM viDropProcedureSchritt into @owner
WHILE (@@fetch_status <> -1)
BEGIN
select @cmd = 'drop procedure ' + @owner + '.' + @name
exec (@cmd)
FETCH NEXT FROM viDropProcedureSchritt INTO @owner
END
close viDropProcedureSchritt
deallocate viDropProcedureSchritt
end
go
cursor schritt_VIDROPPROCEDURE is
SELECT object_name FROM user_objects
WHERE upper(object_name) = upper(in_name )
and upper(object_name) not like 'VIDROP%'
and upper(object_type) = upper('procedure');
v_object_name varchar2(255);
cmd varchar2(255);
BEGIN
open schritt_VIDROPPROCEDURE;
loop
fetch schritt_VIDROPPROCEDURE into v_object_name;
exit when schritt_VIDROPPROCEDURE%notfound;
cmd := 'drop procedure ' || v_object_name;
EXEC_sql (VIDROPPROCEDURE.cmd);
END LOOP;
END VIDROPPROCEDURE;
go
Es gibt von der Grundstruktur noch ein paar Ähnlichkeiten, aber es läuft soweit
auseinander, daß es nicht mehr automatisch umsetzbar ist. Wir haben uns allerdings
die Arbeit des Abschreibens an einer Stelle ein bißchen erleichtert.
Wir haben ein Word-Makro gebaut welches ein paar bedingte Ersetzungen enthält.
Der MSSQL-Text wird in das Word-Dokument gepackt, das Makro läuft und wir
haben die Rohübersetzung für Oracle.
Das mag jetzt etwas laienhaft anmuten, hat aber einen sehr praktischen Hintergrund.
Wir haben einige Tools ausprobiert, die versprachen, eine SQL-Notation in eine
andere umzusetzen. Keines von denen hat Code produziert, der verwendbar
gewesen wäre. Entweder gab es Fehler beim Parsen oder der erzeugte Zielcode hat
das 10-fache Volumen des primären Codes oder der Zielcode war einfach nur
syntaktisch oder inhaltlich falsch.
Die größte Erfolgsquote hatten wir letztendlich bei Verwendung des Word-Makros.
Die Nacharbeit hält sich in Grenzen und die Struktur der beiden Texte ist immer noch
so ähnlich, daß man Änderungen, die sich ja immer im Laufe einer Weiterentwicklung
ergeben, in der Sekundär - Implementierung schnell nachziehen kann.
5.2.3. SQL-Formatter
Zur Verwendung in den Softwareschichten oberhalb der Datenbank gibt es eine
Klasse, die wir SQL-Formatter genannt haben.
In diesen Softwareschichten werden die Queries nicht von Hand ausformuliert,
sondern der Formatter erzeugt die Einzelteile, die sich unter den eingesetzten
Datenbanksystemen unterscheiden. Dies lohnt auch schon bei einfachen StringVergleichen, da der Formatter auch die Maskierung übernimmt.
Beispiel:
"Lastname = 'Meier'"
Mit Formatter:
Connection.SqlFormatter.Comparison("Lastname", "Meier", ValType.String)
using System;
using System.Collections;
using VI.Base;
using VI.DB;
using VI.DB.Implementation;
using VI.DB.Oracle;
public class MyClass
{
public static void Main()
{
ISqlFormatter mssql = new MicrosoftSqlFormatter();
ISqlFormatter oracle = new OracleSqlFormatter();
// Beispiel für ein Statement
WL("Plain", "select * from Person where Lastname = 'Meier'");
// Formatiert für MS SQL
WL("1. MS SQL", "select * from Person where " +
mssql.Comparison("Lastname", "Meier", ValType.String));
// Und Oracle
WL("1. Oracle", "select * from Person where " +
oracle.Comparison("Lastname", "Meier", ValType.String));
// Mit Hochkommas
WL("2. MS SQL", "select * from Person where " +
mssql.Comparison("Lastname", "O'Donnell", ValType.String));
WL("2. Oracle", "select * from Person where " +
oracle.Comparison("Lastname", "O'Donnell", ValType.String));
// Unicode
WL("3. MS SQL", "select * from Person where " +
mssql.Comparison("Lastname", "\u0425\u0440\u0443\u0449\u0451\u0432",
ValType.String));
WL("3. Oracle", "select * from Person where " +
oracle.Comparison("Lastname", "\u0425\u0440\u0443\u0449\u0451\u0432",
ValType.String));
// Aufruf einer Stored Procedure
WL("4. MS SQL", mssql.StoredProcedure(
"TestProc",
mssql.FormatValue("Test", ValType.String, true),
mssql.FormatValue(42, ValType.Int, true)));
WL("4. Oracle", oracle.StoredProcedure(
"TestProc",
oracle.FormatValue("Test", ValType.String, true),
oracle.FormatValue(42, ValType.Int, true)));
}
public static void WL(string prefix, string mssql, string oracle)
{
Console.WriteLine("{0}:", prefix);
Console.WriteLine("MS SQL:\t" + mssql);
Console.WriteLine("Oracle:\t" + oracle);
Console.WriteLine();
}
}
Da der Formatter nur Teile von Statements formatiert, kann man komplexe
Statements nach Systemen getrennt in einer Resource-Datei hinterlegen und nur
Vergleiche gegen dynamische Werte per Formatter einfügen.
5.3. Frontend – Ebene
Das Frontend soll sowohl als Fat-Client laufen als auch als Thin-Client im Web. Wir
haben insgesamt über 500 Tabellen im Datenmodell, zu jeder Tabelle muß es
Formulare geben, mit denen die Daten bearbeitbar werden. Dazu kommt noch eine
Menge an Zuordnungs- und Übersichtsformularen. Diese Formulare in zwei
verschiedenen Systemen zu bauen, hätte unsere Kapazitäten gesprengt. Unser Ziel
war demzufolge ein Compilat für alle zu erhalten.
Wir haben diese Zielstellung so erreicht, indem wir Layout und Funktionen strikt
getrennt haben.
Ein Frontend besteht immer aus 2 Bestandteilen, der Darstellung und dem dahinter
liegenden Code. Die Darstellung ist z.B. die Definition eines Buttons, der Code der
dazugehörige Click-Eventhandler. Die Darstellung wird durch eine bei uns
entwickelte Engine aus einer in XML hinterlegten Beschreibung gerendert. Der Code
liegt als DLL bei und spricht die jeweiligen Frontend-Controls über Schnittstellen an.
Für jedes Control gibt es eine Fat- und eine Web-Client-Implementierung.
Der Fat-Client basiert auf Windows-Forms, d.h. wir haben die bestmögliche
Integration in die Windows-Umgebung. Er läuft derzeit nicht unter Mono, da nicht
portable Fremdcontrols verwendet wurden.
Der Web-Client besitzt ein eigenes Control-Set, welches dieselben Interfaces wie der
Fat-Client implementiert. Die Kommunikation mit dem Server erfolgt über Javascript.
Das ermöglicht eine Aktualisierung der Control-Inhalte ohne eine kompletten
Roundtrip für die angezeigte Seite. Einen ersten Prototyp dieser Lösung hatten wir
2001 gebaut. Heute ist diese Art der Kommunikation allgemein als “Ajax“ bekannt.
Damit ist das Problem der Nutzer-Interaktion gelöst. Wenn ein Wert geändert wird
(z.B. der Nachname einer Person) so ändert sich direkt ein anderer davon
abhängiger Wert (z.B. die EMail-Adresse). Diese Änderung soll dem Nutzer immer
sofort angezeigt werden.
Die Navigation ist in der Datenbank hinterlegt und wird durch die jeweilige Engine
interpretiert. Für den jeweiligen Kunden an seine Bedürfnisse anpaßbar.
Zum Schluß noch einen kurzen Blick auf die Statistik. Der gesamte Quelltext von
ActiveEntry ohne Dokumentation und ohne kundenspezifische Anpassungen umfaßt
162 MB. Die einzelnen Bestandteile wurden klassifiziert nach den 3 Bereichen
- allgemein gültig
- Meta-Programmierung
- Doppelimplementierung
Die beste Nachnutzung haben wir auf der Objektebene, da handelt es sich nur um
ein paar Prozent, die doppelt implementiert werden mußten und deswegen keiner
weiteren Beachtung benötigen. Viele Quellen sind hier allgemein gültig, zumal die
Objektebene auch vom Gesamtvolumen her das Größte ist. Im Frontend ist uns das
nicht ganz so gut gelungen. Wir haben 7 MB Quelltext im Frontendbereich als
Doppelimplementierung, das sind vor allem die Controls für Fat-Client und die
Controls für Thin-Client.
Softwareebene
Doppelt
implementiert
Allgemeingültig
Auf MetaEbene
Gesamtergebnis
DBLayer
11.280.750
9.352.411
5.663.247
26.296.408
Object
4.601
74.243.447
Frontend
7.782.746
20.984.713
74.248.048
20.469.139
49.236.598
Tools
1.115.490
1.115.490
Unit
17.362
Gesamt: Summe
19.085.459
von Byte
11.522.995
11.540.357
117.219.056
26.132.386
162.436.901
Lines of Code ist die Meßgröße, mit der üblicherweise hantiert wird. Insgesamt
haben wir inzwischen 3,4 Millionen Zeilen erstellt. Mit Dokumentation und
kundenspezifischen Projekten, die wir im Laufe der Jahre gebaut haben, sind es
noch einmal so viel, also insgesamt fast 7 Millionen Quelltextzeilen.
Softwareebene
Doppelt
implementiert
Allgemeingültig
Auf MetaEbene
Gesamtergebnis
DBLayer
320.673
215.765
171.775
708.213
Object
171
1.215.790
Frontend
247.561
593.827
1.215.961
462.788
1.304.176
Tools
34.110
34.110
Unit
516
Gesamt: Summe
568.921
von Lines
209.805
210.321
2.269.297
634.563
3.472.781
Am spannendsten scheint jedoch die Zusammenstellung nach Prozenten zu sein.
Die Datenbankschicht hat 16 % Anteil am Gesamtprodukt. In diesem Bereich haben
wir aufgrund der SQL-Unterschiede die schlechteste Quote der Allgemeingültigkeit
erreicht, aber immerhin mit Meta-Ebene und Allgemeingültigkeit trotz der großen
Differenzen zwischen den SQL-Dialekten nur 42 % doppelt entwickelt.
Bei den Frontends haben wir mit 80 % Allgemeingültigkeit eine passable Quote
erreicht. Spezielle Buildtools, welche im Daily-Build-Prozess gebraucht werden,
haben wir vollständig allgemeingültig und bei den Unit-Tests sind es auch nahezu
100%
Softwareebene
Doppelt
implementiert
Allgemeingültig
Auf MetaEbene
Anteil am
Gesamtprodukt
DBLayer
42,9%
35,6%
21,5%
16,2%
Object
0,0%
100,0%
Frontend
15,8%
42,6%
Tools
45,7%
41,6%
30,3%
100,0%
0,7%
7,1%
Unit
0,2%
99,8%
Gesamtprodukt
11,7%
72,2%
16,1%
100,0%
Herunterladen