100
Masterarbeit Evaluierung und Konfiguration eines DBMS sowie die Konzeption und Entwicklung eines Datenbank-Service auf Basis von RESTful Web Services in Scala Zur Erlangung des akademischen Grades eines Master of Science - Media Processing and Interactive Services - Fakultät Informatik Referent: Prof. Dr. Oliver Braun Korreferent: Dipl.-Mathematiker Michael Otto eingereicht von: Benjamin Lüdicke Matr.-Nr. 260156 Schwarzhäuser Str. 6b 99891 Winterstein Schmalkalden, den 13.09.2011

Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

  • Upload
    padsfhs

  • View
    193

  • Download
    8

Embed Size (px)

Citation preview

Page 1: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Masterarbeit

Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Zur Erlangung des akademischen Grades einesMaster of Science- Media Processing and Interactive Services -

Fakultät InformatikReferent: Prof. Dr. Oliver BraunKorreferent: Dipl.-Mathematiker Michael Otto

eingereicht von:Benjamin LüdickeMatr.-Nr. 260156Schwarzhäuser Str. 6b99891 Winterstein

Schmalkalden, den 13.09.2011

Page 2: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Zusammenfassung

Diese Arbeit ist Teil des Projekts ”spirit@fhs“, welches sich mit der Implementierungeines Informations- und Planungssystems für die Fakultät Informatik der Fachhoch-schule Schmalkalden beschäftigt. Ziel dieser Arbeit ist es, herauszufinden inwiefernsich eine relationale oder NoSQL Datenbank für die Datenhaltung eignet und wie diegespeicherten Daten über eine REST-Schnittstelle für andere Anwendungen zugäng-lich gemacht werden können. Dabei wird die relationale Datenbank PostgreSQL, dieGraphen-Datenbank OrientDB und die Key/Value-Datenbank Riak näher unter-sucht. Ferner wird ein Datenmodell anhand von Anforderungen, welche vom Team”sprit@fhs“ aufgestellt wurden, entwickelt und in den Datenbank-Service eingebet-tet. Der Datenbank-Service wird so konzipiert, dass Abhängigkeiten zur Datenbankvermieden werden und somit der Wechsel zu einer anderen Datenbank möglich ist.

Page 3: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Danksagung

An dieser Stelle möchte ich bei allen bedanken, die mich bei der Erstellung die-ser Master-Thesis unterstützt haben. Besonderen Dank gilt dabei Prof. Dr. OliverBraun, welcher mir die Chance gab innerhalb des Team ”spirit@fhs“ diese Arbeitanzufertigen.Einen ganz besonderen Dank gilt ebenso Dipl.-Mathematiker Michael Otto, der michbei der Einrichtung eines Servers unterstützt hat, damit auch andere Teammitgliederden Datenbank-Service nutzen können.Auch möchte ich mich bei meinen Teammitgliedern für die tolle Zusammenarbeitbedanken. Besonders zu erwähnen sind Sebastian Stallenberger, Ronny Schleicherund Florian Schuhmann, welche die Qualität des Datenmodell durch Vorschläge undkonstruktive Kritik maßgeblich verbessert haben.Abschließend möchte ich mich bei meinen Eltern Detlef und Scarlett Lüdicke be-danken, die mich während meiner Studienzeit stets unterstützt und ermutigt haben.

Page 4: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Inhaltsverzeichnis

1 Einleitung 11.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Das Projekt Spirit . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.3 Ziel der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.4 Vorgehensweise der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . 4

2 Theoretischer Hintergrund 62.1 Datenformate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.1.1 Extensible Markup Language . . . . . . . . . . . . . . . . . . 62.1.2 JavaScript Object Notation . . . . . . . . . . . . . . . . . . . 7

2.2 Web-Services mit REST . . . . . . . . . . . . . . . . . . . . . . . . . 72.3 Lift - Ein Framework für RESTful Web Services in Scala . . . . . . . 82.4 Datenbanken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.4.1 Relationale Datenbanken . . . . . . . . . . . . . . . . . . . . . 92.4.2 Die Standard Query Language . . . . . . . . . . . . . . . . . . 102.4.3 Definition und Kategorisierung von NoSQL . . . . . . . . . . . 11

3 Anforderungsspezifikation 153.1 Ausgangssituation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153.2 Anforderungen an den Datenbank-Service . . . . . . . . . . . . . . . 153.3 Anforderungen an die Datenbank . . . . . . . . . . . . . . . . . . . . 16

4 Anforderungsanalyse 174.1 Miniwelt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174.2 Interaktion zwischen Anwender und System . . . . . . . . . . . . . . 174.3 Beurteilung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

5 Evaluierung möglicher Datenbanken 225.1 OrientDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5.1.1 Datenmodell . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235.1.2 Beispielanwendung . . . . . . . . . . . . . . . . . . . . . . . . 235.1.3 CRUD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255.1.4 Backup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305.1.5 Skalierung und Replikation . . . . . . . . . . . . . . . . . . . 315.1.6 Bewertung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

5.2 Riak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325.2.1 Datenmodell . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325.2.2 CRUD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335.2.3 Backup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

Benjamin LüdickeIV

Page 5: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Inhaltsverzeichnis Fachhochschule Schmalkalden SS 2011

5.2.4 Skalierung, Replikation und Konfiguration . . . . . . . . . . . 395.2.5 Bewertung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

5.3 PostgreSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425.3.1 CRUD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425.3.2 Backup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465.3.3 Replikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475.3.4 Bewertung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

5.4 EclipseLink als Object-Relational Mapper . . . . . . . . . . . . . . . 495.5 Auswahl einer Datenbank . . . . . . . . . . . . . . . . . . . . . . . . 50

6 Festlegen des Datenmodell 516.1 Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526.2 Appointment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526.3 Location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536.4 DegreeClass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536.5 Member . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546.6 News . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546.7 NewsComment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

7 Realisierung 567.1 Grobentwurf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567.2 Feinentwurf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

7.2.1 REST-Schnittstelle des Datenbank-Service . . . . . . . . . . . 567.2.2 Einbinden des Datenmodells in den Datenbank-Service . . . . 607.2.3 Helfer-Klassen . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

8 Implementierung 638.1 Die REST-Schnittstelle und Http-Basic-Authentication . . . . . . . . 63

8.1.1 Die Klasse Boot . . . . . . . . . . . . . . . . . . . . . . . . . . 638.1.2 Die Klasse ServiceApi . . . . . . . . . . . . . . . . . . . . . . 658.1.3 Die abstrakte Klasse Invoke . . . . . . . . . . . . . . . . . . . 678.1.4 Die Klasse WithBody . . . . . . . . . . . . . . . . . . . . . . . 69

8.2 EclipseLink und PostgreSQL . . . . . . . . . . . . . . . . . . . . . . . 708.2.1 Das Datenmodell und EclipseLink . . . . . . . . . . . . . . . . 708.2.2 Anbinden von PostgreSQL an EclipseLink . . . . . . . . . . . 738.2.3 Datenbankabfragen mit EclipseLink . . . . . . . . . . . . . . . 74

9 Test 80

10 Zusammenfassung und Ausblick 82

Literaturverzeichnis 83

A Anhang 85

Eidesstattliche Erklärung 95

Benjamin LüdickeV

Page 6: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

1 EinleitungDas Internet ist in der Gegenwart eine nicht mehr wegzudenkende Informations-quelle. Mit der stetig wachsenden Menge an Daten werden neue Anforderungen andie Speichertechniken und besonders an die Datenbanken gestellt. Alle Datenban-ken müssen in der Lage sein, schnell auf angeforderte Informationen zuzugreifenund diese bereitzustellen. Dabei ist jedoch nicht jede Datenbank für jedes Anwen-dungsszenario gleich gut geeignet. Vor allem durch das Aufkommen der sogenann-ten NoSQL Datenbanken erweckt es den Anschein, als ob die klassischen relatio-nalen Datenbanken nicht in neue Konzepte der Web2.0-Entwicklung passen. DieAuswahl einer geeigneten Datenbank für ein geplantes Projekt, ist somit keine tri-viale Angelegenheit. Ferner sind jedoch nicht nur Datenbanken von der wachsendenAnzahl an Diensten im Internet betroffen. Soziale Netzwerke, Nachrichten-Portale,Streaming-Portale und Blogs werden immer enger miteinander vernetzt. Somit erge-ben sich auch neue Anforderungen an die Schnittstellen zukünftiger Webentwicklun-gen. Dienste müssen plattformübergreifend bereitgestellt werden, um eine optimaleNutzung zu gewährleisten. Auch die Fachhochschule Schmalkalden hat diesen Trenderkannt und plant mit dem Projekt ”spirit@fhs“1 eine Neuimplementierung des der-zeitigen Informations- und Planungssystems. Als Teilprojekt von ”spirit@fhs“ istdiese Master-Thesis für die Evaluierung einer geeigneten Datenbank verantwortlich.Des Weiteren muss eine Schnittstelle konzipiert werden, welche unabhängig von dergewählten Datenbank deren Dienste bereitstellt. Im folgenden Abschnitt wird aufdie Motivation und das Projekt ”spirit@fhs“ eingegangen. Danach wird das Ziel die-ser Master-Thesis erläutert und abschließend die Vorgehensweise der Bearbeitungder Arbeit dargestellt.

1.1 MotivationFür die Fakultät Informatik an der Fachhochschule Schmalkalden gibt es derzeit keineinheitliches Informations- und Planungssystem. Um Neuigkeiten und Termine zuverbreiten, werden verschiedene Distributionskanäle genutzt. Es gibt die Homepageder Fakultät sowie die einzelnen Homepages der Professoren. Des Weiteren werdenE-Mails an die betroffenen Studiengänge versendet oder Termine und Neuigkeiten ineinem Aushang veröffentlicht. Der Empfänger muss somit viel Aufwand betreiben,um über alles informiert zu sein und ist zudem für die Verwaltung der Termine selberverantwortlich. Studenten und Dozenten nutzen dafür einen Terminkalender in Formeines Buches oder einer Anwendung auf dem PC. Ein Abgleich der Termine findetmeist nicht automatisch statt. Somit werden Änderungen und Konflikte bei der Ter-minplanung nicht sofort oder erst viel später erkannt. Auch die Bereitstellung des

1http://pads.fh-schmalkalden.de/spirit.html

Benjamin Lüdicke Seite 1 von 95

Page 7: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

1. Einleitung Fachhochschule Schmalkalden SS 2011

Stundenplans für die einzelnen Studiengänge erfolgt nicht dynamisch, sondern durcheine einmalig generierte HTML-Seite. Der statische Stundenplan im HTML-Formathat mehrere Nachteile. Zum Beispiel kann aus Platzgründen nur die Abkürzung desTitels einer Vorlesung angezeigt werden. Um den vollständigen Titel einer Vorlesungzu erfahren, muss in einem Abkürzungsverzeichnis nachgeschlagen werden. Außer-dem ist nicht sofort zu erkennen, von wie vielen und welchen Dozenten die Vorlesunggehalten wird, da nur eine Zeile für den Dozenten-Namen vergeben werden kann.Folglich entstehen zusammengesetzte Namen, wenn die Vorlesung von mehreren Do-zenten gehalten wird. Findet beispielsweise eine Vorlesung mit den Dozenten Böse,Chantelau und Hettler statt, steht im Stundenplan der zusammengesetzte Name”BoeChaHett“ (siehe Listing A.1). Weitere Termine wie Gastvorträge von Externenoder Tutorien können in diesem Plan nicht angezeigt werden. Das Erstellen einespersonalisierten Stundenplans, mit einem automatischen Terminabgleich ist nichtmöglich. Ferner können die Stundenpläne und Nachrichten nur schlecht archiviertund gegebenenfalls wieder abgerufen werden. Auch das Festlegen bestimmter Filter-kriterien, um Informationen gezielt anzuzeigen ist derzeit nicht umgesetzt. Aufgrundder dargelegten Missstände ist es notwendig ein System zu entwickeln, welches dieLimitierung der bisherigen statischen Lösung aufhebt. Durch das Speichern des Stun-denplans in einer Datenbank, ist es möglich personalisierte Stundenpläne zu erstellensowie Änderungen bei der Terminplanung nachzuvollziehen. Auch das Archivierenund Filtern von Nachrichten kann durch eine Datenbank realisiert werden. Damitdie Datenbank bei Bedarf ausgetauscht oder erweitert werden kann, ist die Funk-tionalität durch eine Service-Schnittstelle zu kapseln. Ferner wird so eine plattform-und programmiersprachenunabhängige Nutzung gewährleistet.

1.2 Das Projekt SpiritDas Projekt ”spirit@fhs“ ist von Prof. Dr. Oliver Braun im Sommersemester 2010an der Fachhochschule Schmalkalden gestartet worden. Es befasst sich mit derNeuimplementierung des Informations- und Planungssystems für den FachbereichInformatik. Dabei soll der Aufwand bei der Planung und Verwaltung von Terminenminimiert werden. Umgesetzt werden dabei mehrere Teilprojekte mit unterschied-lichen Schwerpunkten. Diese Teilprojekte werden im Rahmen von Bachelor- bzw.Masterarbeiten durchgeführt und bilden unabhängige Module. So können einzelneAnwendungen ausgetauscht oder erweitert werden, ohne andere Anwendungen inihrer Funktionalität zu beeinflussen. Diese einzelnen Teilprojekte werden nun kurzvorgestellt.

Core

Das Teilprojekt ”Core“ ist ein prototypischer Generator. Dieser erstellt anhand vonvorher definierten Bedingungen gültige Stundenpläne. Eine Aussage über die Güteeines Stundenplans wird jedoch nicht getroffen.

Benjamin Lüdicke Seite 2 von 95

Page 8: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

1. Einleitung Fachhochschule Schmalkalden SS 2011

Studweb

”Studweb“ wird das neue Informationsportal für Studenten der Fakultät Informatik.Es soll Funktionen wie das Anzeigen von Nachrichten und Kommentaren sowie dasVerwalten eines Terminkalenders beinhalten.

EmployeeWeb

Das Teilprojekt ”EmployeeWeb“ wird ähnliche Funktionen wie ”Studweb“ haben.Jedoch soll es auf die Nutzung durch Mitarbeiter der Fachhochschule Schmalkaldenoptimiert werden.

PlanningWeb

Dieses Teilprojekt bietet Unterstützung bei der Planung von Stundenplänen. Ziel istes, den Aufwand bei der Planung zu minimieren indem durch eine Web-Anwendung,die für ”Core“ benötigten Daten bereitgestellt werden. Alle erfassten Daten werdenfür eine spätere Verwendung in einer separaten Datenbank abgelegt.

Mobile

Das Teilprojekt ”Mobile“ umfasst mehrere Anwendungen. Ziel ist es, für verschie-dene mobile Endgeräte einen ähnlichen Funktionsumfang wie von ”EmployeeWeb“und ”StudWeb“ bereitzustellen. Dafür werden Applikationen für die Betriebssyste-me Android, Windows 7 Phone und iOS entwickelt.

DistributedCalc

Nachdem keine Aussage über die Güte eines erstellten Stundenplans getroffen wird,soll durch diese Anwendung anhand einer Metrik, der beste Stundenplan ermitteltwerden.

Migrate

Das Teilprojekt ”Migrate“ hat als Ziel den bisherigen statischen Stundenplan zuparsen und in eine dynamische Datenstruktur zu überführen. Dieses Projekt ist eineÜbergangslösung bis das Projekt ”DistributedCalc“ funktionsfähig ist.

News

Das Teilprojekt ”News“ ist eine Informationsplattform, mit dem Nachrichten vonDozenten auf der Homepage der Fakultät veröffentlicht werden. Es bietet zusätzli-che Funktionen, wie das veröffentlichen von Nachrichten über Twitter oder die Mög-lichkeit einen RSS-Feed zu abonnieren. Dieses Teilprojekt ist schon fertiggestellt

Benjamin Lüdicke Seite 3 von 95

Page 9: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

1. Einleitung Fachhochschule Schmalkalden SS 2011

und kann als Übergangslösung oder Ergänzung für die neuen Informationsportale”Studweb“ und ”EmployeeWeb“ angesehen werden.

Data

Das Teilprojekt ”Data“ ist Bestandteil dieser Master-Thesis und wird imAbschnitt 1.3 genauer erläutert.

1.3 Ziel der ArbeitUm das Ziel dieser Master-Thesis zu erläutern, wird zunächst der Titel der Arbeitbetrachtet: ”Evaluierung und Konfiguration eines DBMS2 sowie die Konzeption undEntwicklung eines Datenbank-Service auf Basis eines RESTful Web-Service in Sca-la.“ Zu erkennen ist, dass in der Master-Thesis zwei Ziele verfolgt werden. Zum einensoll untersucht werden, was für ein DBMS sich für das Projekt ”spirit@fhs“ eignetund zum anderen soll ein Service konzipiert werden, welcher die Dienste von diesemSystem abstrahiert, um eine einheitliche Schnittstelle bereitzustellen. Ziel ist, dassdie Teilprojekte von ”spirit@fhs“ auf den Datenbank-Service zugreifen, um Infor-mationen zu speichern oder abzurufen. Durch das Kapseln der Datenbank hinterden Datenbank-Service ist es möglich die Datenbank auszutauschen, ohne dass dieSchnittstellen zu den Teilprojekten angepasst werden müssen.

1.4 Vorgehensweise der ArbeitUm ein besseres Verständnis für die Thematik zu bekommen, wird in dem Kapi-tel 2 auf Begriffe und Technologien eingegangen, welche die Grundlage für dieseArbeit bilden. Zuerst werden die zwei Datenformate JavaScript Object Notationund Extensible Markup Language erläutert die genutzt werden, um Daten vomDatenbank-Service zu empfangen oder zum Datenbank-Service zu senden. Danachwird die Übertragungstechnologie REST vorgestellt. Um einen Überblick über diebestehenden Datenbanktechnologien zu bekommen, wird des Weiteren das Konzeptder relationalen Datenbanken und die dazugehörige Abfragesprache SQL erläutert.Ferner wird der Begriff NoSQL definiert und eine Kategorisierung von NoSQL Da-tenbanken vorgenommen. In den darauf folgendem Kapitel 3 werden die Anforderun-gen an den Datenbank-Service und an die Datenbank definiert. Damit die Auswahleiner geeigneten Datenbank eingeschränkt werden kann, wird im Abschnitt 4 eineDatenanalyse durchgeführt, wobei Zusammenhänge zwischen den Daten verdeutlichtwerden. Mögliche Datenbanken werden daraufhin an den festgelegten Anforderun-gen gemessen. Ferner wird untersucht, welche Unterstützung Frameworks für dieausgewählten Datenbanken bieten und wie die REST-Schnittstelle vom Datenbank-Service umgesetzt werden kann. Im Kapitel 7 wird ein Datenmodell entworfen, wel-ches den Anforderungen an den Datenbank-Service genügt. Auf diesem Datenmo-dell beruht der Entwurf der zu implementierenden REST-Schnittstelle. Im Kapitel 8

2Datenbankmanagementsystem

Benjamin Lüdicke Seite 4 von 95

Page 10: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

1. Einleitung Fachhochschule Schmalkalden SS 2011

wird dargestellt, wie die Datenbank an den Datenbank-Service angebunden ist. Fer-ner wird anhand einer Beispiel-Anfrage gezeigt, wie diese vom Datenbank-Serviceabgearbeitet wird. Abschließend erfolgen eine Zusammenfassung über die erreichtenZiele und ein Ausblick.

Benjamin Lüdicke Seite 5 von 95

Page 11: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

2 Theoretischer HintergrundDieses Kapitel befasst sich mit den Grundlagentechnologien und Begriffen, welche fürdas Verständnis dieser Master-Thesis notwendig sind. Einleitend werden die Daten-formate JavaScript Object Notation und Extensible Markup Language beschrieben.Im Anschluss wird die Übertragungstechnologie REST erläutert, die genutzt wirdum den Datenbank-Service für andere Applikationen zugänglich zu machen. ZumSpeichern der Daten stehen verschiedene Technologien zur Verfügung. In diesemKapitel wird auf das relationale Datenmodell und die Abfragesprache SQL einge-gangen. Des Weiteren wird der Begriff NoSQL definiert und NoSQL Datenbankenkategorisiert.

2.1 DatenformateFür den Datenaustausch zwischen Datenbank-Service und anderenSpirit-Applikationen, werden die Extensible Markup Language und die JavaScriptObject Notation verwendet. Beide Datenformate sind im Internet weit verbreitetund gewährleisten ein programmiersprachen- und plattformunabhängiges Austau-schen von Informationen.

2.1.1 Extensible Markup Language

Die Extensible Markup Language (XML) ist eine Meta-Auszeichnungssprache die1998 entstand und vom W3C1 spezifiziert wurde. Entspricht die Syntax eines XML-Dokumentes dieser Spezifikation, wird es als ”wohlgeformt“ bezeichnet. Der Vorteileines ”wohlgeformten“ XML-Dokumentes ist, dass es von allen Anwendungen inter-pretiert werden kann, welche die XML-Spezifikation kennen. Ein gültiges XML-Dokument besteht aus einem oder mehreren XML-Elementen, wobei ein XML-Element durch sogenannte Tags definiert ist. Weil XML eine Meta-Auszeichnungs-sprache ist, hat es keine fest vergebene Menge an Elementen, wie es bei HTMLder Fall ist. Dadurch ermöglicht XML, den Autoren eines XML-Dokuments, sel-ber Elemente zu definieren. Dadurch wird das XML-Dokument selbstbeschreibendund für den Menschen lesbar. Ferner ermöglicht XML das Erstellen von Auszeich-nungssprachen. Die Struktur einer Auszeichnungssprache wird in einem Schema er-fasst. Ein XML-Schema kann zum Beispiel als XML-Schema-Definition (XSD) oderDocument-Type-Definition (DTD) erstellt werden. Ein Dokument welches der Struk-tur des Schemas entspricht, wird als valide bezeichnet [HM04].

1World Wide Web Consortium

Benjamin Lüdicke Seite 6 von 95

Page 12: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

2. Theoretischer Hintergrund Fachhochschule Schmalkalden SS 2011

2.1.2 JavaScript Object Notation

Die JavaScript Object Notation (JSON) ist ein weiteres Übertragungsformat, mitdem es möglich ist strukturiert Daten zwischen Anwendungen auszutauschen. Esentstand im Jahr 2005 und wird im RFC 4627 beschrieben. Anders als bei XML wer-den Strukturen nicht durch lange Tag-Namen, sondern durch eckige und geschweifteKlammern definiert [Rie09]. Die eigentlichen Daten werden durch Schlüssel/Wert-Paare dargestellt und können vom Typ String, Number, Array, Object, Booleanoder Null sein. Wie auch bei XML werden Binärdaten nicht unterstützt. Dateninnerhalb von geschweiften Klammern repräsentieren ein Objekt. Mehrere Objek-te oder Schlüssel/Wert-Paare innerhalb eckigen Klammern stellen ein Array dar.Eine genauere Beschreibung der JSON-Struktur ist auf der JSON-Homepage2 zufinden. Der Vorteil dieser knappen Strukturierung ist das Reduzieren des sogenann-ten Daten-Overheads. Infolgedessen ist JSON geeignet, um Daten mit mobilen oderschwachen Endgeräten auszutauschen.

2.2 Web-Services mit RESTDie im vorherigen Abschnitt vorgestellten Übertragungsformate werden genutzt,um Informationen zwischen dem Datenbank-Service und dessen Clients auszutau-schen. Die dafür verwendete Architektur ist REST. REST bedeutet ”Representatio-nal State Transfer“ und wurde im Jahr 2000, in der Dissertation [Fie00] von RoyThomas Fielding, als Verfahren zum Bewerten von Architekturen präsentiert. Indieser Master-Thesis wird REST verwendet, um einen Web-Service bereitzustellen.Im Gegensatz zu dem Web-Service-Stack3 gilt REST als weniger komplex [RR07, S.XV], da es möglich ist Daten ohne eine zusätzliche Transportschicht zu versenden.Eine besondere Eigenschaft von REST ist die Adressierbarkeit von Ressourcen4.Eine Ressource ist genau einem http-URI5 zugeordnet. In der Tabelle 2.1 sind diehttp-Methoden aufgelistet, welche ein Client für eine Anfrage verwenden kann. Indieser Master-Thesis werden lediglich die Methoden GET, PUT, POST und DE-LETE implementiert. Durch den Kontext der Methoden, wird dem Client das Ver-halten des jeweiligen URI verdeutlicht. Wie bei GET beschrieben, erhält der Clienteine Repräsentation als Antwort auf eine Anfrage. Dabei kann eine Repräsentationin verschiedenen Formen vorliegen. Die in dieser Arbeit verwendeten Repräsentati-onsformen sind XML und JSON, welche im Abschnitt 2.1 erläutert wurden. Fernerenthält die Antwort die üblichen http-Statuscodes. Ein weiteres Merkmal von RESTist die Zustandslosigkeit. Laut Richardson und Ruby [RR07, S. 101] existieren zweiArten von Zuständen - den Anwendungszustand und den Ressourcenzustand. Ers-terer wird im Client gespeichert und bei jeder Anfrage an den Server mitgesendet.Ein Beispiel ist die Eingabe eines Begriffs in eine Suchmaschine. Je nachdem welcher

2Homepage: http://www.json.org/3als Web Service Stack wird die Sammlung an Protokollen und Standards bezeichnet, die not-wendig sind um eine service-orientierte Architektur (SOA) aufzubauen

4eine Ressource repräsentiert eine Information auf dem Server - das können eine Methode oderDaten aus einer Datenbank sein

5RFC 3986: http://tools.ietf.org/html/rfc3986#page-16

Benjamin Lüdicke Seite 7 von 95

Page 13: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

2. Theoretischer Hintergrund Fachhochschule Schmalkalden SS 2011

GET liefert eine Repräsentation einer Ressource an den Client zurückPUT erzeugt eine Ressource auf dem ServerPOST erzeugt oder ändert eine Ressource auf dem ServerDELETE löscht eine Ressource auf dem ServerHEAD liefert nur den Header einer AntwortTRACE sendet die Anfrage so zurück, wie sie der Server empfangen hatOPTION sendet eine Liste mit Features zurück, welche von diesem URI

unterstützt werdenCONNECT wird verwendet um SSL-Tunnel zu erstellen

Tabelle 2.1: http-Methoden

Begriff eingeben wurde, liefert der Server eine andere Liste an Links. Der Ressour-cenzustand wird auf dem Server gehalten und ist für jeden Client gleich. In denmeisten Fällen ist der Ressourcenzustand eine Datenbank. Infolgedessen ist der Ser-ver, welcher eine REST-konforme Schnittstelle anbietet, nicht für die Verwaltungdes Anwendungszustandes verantwortlich.

2.3 Lift - Ein Framework für RESTful Web Servicesin Scala

Wie im Abschnitt 2.2 erwähnt, wird der Datenbank-Service über eineREST-Schnittstelle erreichbar sein. Um diese in Scala umzusetzen, gibt es verschie-dene Frameworks wie zum Beispiel Scalatra6, BlueEyes7 oder Lift8. In dieser Master-Thesis wird Lift, aufgrund einer besseren Dokumentation gegenüber den anderenFrameworks, verwendet. Das Lift-Projekt startete im Jahr 2007 und die erste stabi-le Version 1.0 wurde im Jahr 2009 veröffentlicht. Derzeitig liegt Lift in der stabilenVersion 2.3 vor. Lift ist jedoch nicht nur ein Framework mit dem ein RESTful WebService implementiert werden kann. Ferner ist es ein Web-Framework, mit dem kom-plette Webseiten und Webapplikationen entwickelt werden können. Zusätzlich kannLift für ORM9 verwendet werden. Dafür hat Lift das Mapper- und Record Frame-work integriert, wobei Mapper als primärer ORM von Record abgelöst werden soll.Weil sich Record noch in der Entwicklungsphase befindet, ist die Verwendung imProduktiveinsatz nicht zu empfehlen [CBDW].

2.4 Datenbanken”Es gibt heutzutage in den meisten Unternehmen und Organisationen keine Alterna-tive mehr zum Einsatz eines DBMS für die Informationsverarbeitung“ [KE01, S. 17].Der Verzicht eines Datenbankmanagementsystems hat weitreichende Konsequenzen

6https://github.com/scalatra/scalatra7https://github.com/jdegoes/blueeyes8http://liftweb.net/9Object-Relational Mapping

Benjamin Lüdicke Seite 8 von 95

Page 14: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

2. Theoretischer Hintergrund Fachhochschule Schmalkalden SS 2011

auf die Informationsverarbeitung. Durch die Speicherung der Daten in isolierten Da-teien auf einem Server, kann es zu Inkonsistenzen10 kommen, da Daten redundantin weiteren Dateien gespeichert sein könnten. Ferner ist es schwer eine Beziehungzwischen diesen Dateien aufzubauen und somit zusammenhängende Abfragen zuformulieren. Außerdem wird auch kein Mehrbenutzerbetrieb unterstützt, was In-konsistenzen oder Leistungseinbußen zur Folge haben kann. Aus diesem Grund wirdfür das Projekt ”spirit@fhs“ das Speichern der Daten in einem DBMS bevorzugt.In diesem Abschnitt wird das Konzept der relationalen Datenbanken sowie die Ab-fragesprache SQL erläutert. Zusätzlich wird der Begriff NoSQL definiert und einenKategorisierung von NoSQL Datenbanken vorgenommen.

2.4.1 Relationale Datenbanken

Relationale Datenbanken beruhen auf dem relationalen Modell, welches am Anfangder siebziger Jahre von E. F. Codd konzipiert wurde. Die grundlegende Daten-struktur des relationalen Datenmodells ist dabei die Relation. Die Deklaration einerRelation erfolgt über das sogenannte Relationenschema, wobei ein relationales Da-tenbankschema aus mehreren dieser Schemen besteht [Kud07, S. 73]. Ein Relationen-schema beschreibt dabei die zugrundeliegende Datenstruktur, wobei das relationaleDatenbankschema die Beziehungen zwischen den Relationen abbildet. Der Aufbaueiner Relation wird in Abbildung 2.1 dargestellt. Die Spalten einer Relation wer-den als Attribute oder Felder bezeichnet und repräsentieren die Eigenschaften einesObjekttyps. Die Zeilen heißen Tupel und stellen mehrere Objekte dar. Die Anzahlder Tupel einer Relation nennt man Grad. Die Mengeneigenschaft einer Relation

Abbildung 2.1: Eigene Darstellung einer Relation in Anlehnung an [Kud07, S. 74]

10als Konsistenz bezeichnet man die logische Widerspruchsfreiheit von Daten, wobei eine Inkon-sistenz das Gegenteil bedeutet

Benjamin Lüdicke Seite 9 von 95

Page 15: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

2. Theoretischer Hintergrund Fachhochschule Schmalkalden SS 2011

fordert die Einzigkeit der Tupel. Damit diese und eine logische Konsistenz umge-setzt werden kann, nutzt man Integritätsbedingungen. Unterschieden werden dabeidie Entitätsintegrität und die referentielle Integrität. Entitätsintegrität bedeutet,dass jedes Tupel in einer Relation nur einmal vorkommen darf. Sichergestellt wirddas durch sogenannte Primärschlüssel. Ein Schlüssel ist dabei eine Attributmenge,welche ein Tupel eindeutig identifiziert. Die kleinste Menge dieser Attributmenge,nennt man Primärschlüssel [Kud07, S. 76]. Zum Beispiel ist ein Student eindeutigan seiner Matrikelnummer zu identifizieren. Als referenzielle Integrität bezeichnetman die Konsistenzsicherung über sogenannte Fremdschlüssel. ”Ein Fremdschlüsselist eine Attributmenge, die einen Primärschlüssel einer (anderen) Relation referen-ziert“ [Kud07, S. 77]. Zu beachten ist, dass zu jeden Wert eines Fremdschlüssels, einPrimärschlüssel mit dem gleichen Wert existiert, wie es in Abbildung 2.2 dargestelltist. In der Tabelle warenkorb_artikel verweist der Fremdschlüssel artikel_id aufden Primärschlüssel id der Tabelle artikel. Laut Meinung des Autors sind die be-kanntesten Vertreter relationaler Datenbanken: Microsoft mit dem SQL Server, IBMmit DB2, MySQL, PostgreSQL und Oracle.

Abbildung 2.2: Eigene Darstellung einer N:M Beziehung zwischen Relationen

2.4.2 Die Standard Query Language

Die Standard Query Language (SQL) beruht auf der relationalen Algebra und wurde1970 von E. F. Codd vorgestellt. Derzeit liegt SQL, ISO/ANSI standardisiert, in derVersion 200811 vor. SQL heißt übersetzt Standard Abfrage-Sprache. Durch SQL istes möglich relationale Datenbanken zu steuern oder zu manipulieren. SQL lässt sichin vier Teilsprachen aufteilen, welche in Tabelle 2.2 abgebildet sind.Wie ein SQL-Ausdruck aufgebaut ist und wie mit der DML und DQL eine relationaleDatenbank manipuliert bzw. abgefragt wird, ist im Kapitel 5.3 erläutert. NebenSQL existieren noch weitere Abfragesprachen wie zum Beispiel QUEL, welche in

11SQL-Standard: http://www.iso.org/iso/catalogue_detail.htm?csnumber=45498

Benjamin Lüdicke Seite 10 von 95

Page 16: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

2. Theoretischer Hintergrund Fachhochschule Schmalkalden SS 2011

Teilsprache AnwendungData Definition Language (DDL) zum Erzeugen, Löschen und Ändern

von SchemataData Manipulation Language (DML) zum Erzeugen, Löschen und Ändern

von TabelleninhaltenData Query Language (DQL) zur Abfrage von TabelleninhaltenData Control Language (DCL) zur Vergabe von Zugriffsrechten

Tabelle 2.2: Teilsprachen von SQL laut [Kud07, S. 108]

der open-source Datenbank INGRES12 eingebettet ist.

2.4.3 Definition und Kategorisierung von NoSQL

Der Begriff NoSQL erweckt den Anschein, dass es sich hierbei um eine Ablehnungvon SQL handelt. Das ist jedoch nicht der Fall. Vielmehr ist der Begriff NoSQL eineProvokation um Aufmerksamkeit zu erregen und wird heutzutage als ”not only SQL“übersetzt [EFHB10, S. XI]. In diesem Abschnitt wird der Begriff NoSQL definiertund eine mögliche Kategorisierung von NoSQL Datenbanken vorgestellt.

Definition von NoSQL

Die NoSQL-Community möchte mit dem Begriff NoSQL eine Alternative zu denrelationalen Datenbanken und dem Transaktionsmanagement herausstellen. Dabeisollen NoSQL-Technologien besonders bei den Betriebskosten, der Skalierbarkeitund der Anwendungsentwicklung einem relationalen Datenbanksystem überlegensein. Durch die Open-Source-Community wird diesbezüglich selten auf Standardszurückgegriffen, sondern durch die verbreitete Anwendung von Programmiermodel-len De-facto-Standards erschaffen, die sich in NoSQL Datenbanksystemen wieder-finden. Ein Beispiel dazu ist das Map/Reduce Framework aus dem Projekt Hadoop,mit dem es möglich ist nebenläufige Berechnungen effizient durchzuführen. Auf derWebseite http://nosql-databases.org sind viele Vertreter der NoSQL Datenban-ken aufgelistet. Jedoch sind nicht nur neue unbekannte Datenbanksysteme verzeich-net, sondern auch schon länger existierende Objekt- oder XML-Datenbanken. Fernerexistieren Hybrid-Lösungen wie GenieDB, welche die Trennung zwischen relationa-len Datenbanksystemen und NoSQL Datenbanksystemen erschweren. Anhand vonsieben Punkten wird in dem Buch [EFHB10, S. 2] versucht eine Grenze zwischenrelationalen und NoSQL Datenbanken herzustellen.

1. das zugrundeliegende Datenmodell ist nicht relational2. die Systeme sind von Anbeginn an auf eine verteilte und horizontale Skalier-

barkeit ausgerichtet3. das NoSQL-System ist open-source4. das System ist schemafrei oder hat nur schwächere Schemarestriktionen

12Homepage INGRES: http://www.ingres.com

Benjamin Lüdicke Seite 11 von 95

Page 17: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

2. Theoretischer Hintergrund Fachhochschule Schmalkalden SS 2011

5. aufgrund der verteilten Architektur unterstützt das System eine einfache Da-tenreplikation

6. dem System liegt meist auch ein anderes Konsistenzmodell zugrunde: Even-tually Consistent und BASE, aber nicht ACID

Die aufgezählten Punkte sind nicht alle als k.o. Kriterium zu sehen. Zum Beispielgibt es durchaus NoSQL-Systeme wie SimpleDB von Amazon, welche keine open-source Projekte darstellen. Der Punkt vier, welcher Schemafreiheit fordert, wirdjedoch als grundlegende Anforderung an ein NoSQL-System angesehen. Weil sichWebanwendungen oft ändern, muss auch das Datenbankschema oft angepasst wer-den. In nichtrelationalen Datenbanken geschieht dies durch die DDL. In schemafrei-en Datenbanken wird die Verantwortung für das Schema aus der Datenbank in dieAnwendung verlagert. Dadurch sollen schnellere Anpassungen des Schemas möglichsein [EFHB10, S. 3]. Im folgenden Abschnitt wird gezeigt, in welche Kategorien sichNoSQL Datenbanken einteilen lassen.

Kategorisierung von NoSQL Datenbanken

In der Abbildung 2.3 ist zu erkennen welche Datenbanken laut [EFHB10, S. 6] eherals relationale und welche als NoSQL Datenbanken angesehen werden. Unter der Ru-brik relational/SQL world sind bekannte relationale Datenbanken aufgelistet, wobeiunter Core NoSQL keine Datenbanken stehen, sondern verschiedene Kategorien vonNoSQL Datenbanken. Damit wird nochmals deutlich, dass NoSQL kein Datenmo-dell ist, sondern eine Sammlung von alternativen zu dem relationalen Datenmodell.Die vier gezeigten NoSQL Datenbankkategorien werden jetzt kurz vorgestellt.

Key/Value-Systeme Ein Key/Value-System speichert Informationen in Schlüs-sel/Wert Paaren ab. Dabei können die Werte nicht nur einzelne Strings, sondernauch Listen oder Mengen darstellen. Key/Value Systeme lassen sich wiederum indie Varianten In-Memory und On-Disk aufteilen. In-Memory Datenbanken haltendie Informationen im Speicher und sind deshalb in der Lage schnell Ergebnisse zuliefern, ohne das langsame Festplattenzugriffe erfolgen müssen. Der Nachteil ist, dassbei einem Ausfall der Hardware die Daten im Speicher eventuell verloren gehen kön-nen und nicht wiederherzustellen sind. Bei der zweiten Variante handelt es sich umDatenbanksysteme, welche die Daten auf der Festplatte hinterlegen um Datenver-lusten vorzubeugen. Jedoch ist diese Variante technisch bedingt nicht so performantwie bei In-Memory Systemen [WM]. Ein Beispiel für ein On-Disk System ist dieDatenbank Riak, welche im Kapitel 5.2 vorgestellt wird.

Wide Column Systeme Die relationalen Datenbanken wie zum Beispiel Postgre-SQL werden als zeilenorientiert bezeichnet, da das Speichern von Informationenzeilenweise durchgeführt wird. Bei einer spaltenorientierten Datenbank ist es jedochso, dass die Informationen spaltenweise hinterlegt werden. Im folgenden Beispielsollen drei Datensätze mit den Attributen: id, name und alter gespeichert werden. Ineiner relationalen Datenbank sind die Daten folgendermaßen im Speicher hinterlegt:

1, luedicke, 26, 2, stallenberger, 27, 3, schleicher, 31

Benjamin Lüdicke Seite 12 von 95

Page 18: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

2. Theoretischer Hintergrund Fachhochschule Schmalkalden SS 2011

Abbildung 2.3: Eigene Darstellung zur Kategorisierung von NoSQL-Systemen in An-lehnung an [EFHB10, S. 6]

Bei einer spaltenorientierten Datenbank sieht die Struktur so aus:1, 2, 3, luedicke, stallenberger, schleicher, 26, 27, 31

Durch die spaltenorientierte Speicherung der Datensätze ist ein effizientes analysie-ren der Daten möglich, da die Informationen zu einer Spalte im Speicher hinterein-ander liegen. Werden nun alle Werte eines Attributes benötigt, kann die Hardwareso effizienter auf die benötigten Daten zugreifen. Ein Beispiel ist die Berechnung desdurchschnittlichen Alters aller eingetragenen Personen. Leistungseinbußen entstehenjedoch beim Einfügen oder Lesen von ganzen Datensätzen [EFHB10, S. 53].

Dokumenten-Datenbanken Dokumenten-Datenbanken sind in der Lage struktu-rierte Daten in Form von JSON- oder XML-Dokumenten abzuspeichern. Dabeigehören sie grundsätzlich zu den schemafreien Datenbanken. Wird ein Dokumentgespeichert, muss demnach ein anderes Dokument nicht zwingend die gleiche Struk-tur aufweisen. Darum sind Dokument-Datenbanken sehr flexibel und lassen sichleicht skalieren. Aufgrund der Schemafreiheit kann es jedoch zu Inkonsistenzen undIntegritätsproblemen kommen. Die bekanntesten Dokumenten-Datenbanken sindCouchDB und MongoDB [EFHB10, S.12] [WM].

Graphen-Datenbanken Laut [Tit03, S. 12] wird ein Graph folgendermaßen defi-niert. Ein Graph G = (V, E) wird durch eine Knotenmenge V und eine Kanten-menge E dargestellt, wobei jeder Kante aus E zwei Knoten aus K zugeordnet sind.

Benjamin Lüdicke Seite 13 von 95

Page 19: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

2. Theoretischer Hintergrund Fachhochschule Schmalkalden SS 2011

Ein Vorteil von Graphen-Datenbanken ist das effiziente Erstellen und Abfragen vonkomplexen Beziehungen, die in relationalen Datenbanken nur schwer umzusetzensind. Vorteile von Graphen-Datenbanken sind laut [EFHB10, S. 169]:

• einfacher Umgang mit rekursiv vernetzten Informationen• gute Unterstützung von semistrukturierten Datensätzen• Unterstützung graphenorientierter und semantsicher Operationen• einfache Skalierbarkeit

Anwendungsgebiete von Graphen-Datenbanken sind Geoinformationssysteme, so-ziale Netzwerke oder auch Empfehlungssysteme. Im Kapitel 5.1 wird OrientDB alsein Vertreter der Graphen-Datenbanken vorgestellt, sowie das zugrunde liegendeDatenmodell erläutert.

Benjamin Lüdicke Seite 14 von 95

Page 20: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

3 AnforderungsspezifikationIn diesem Kapitel wird die Ausgangssituation dargelegt, wie derzeitig Informationenbezüglich des Stundenplans und anderen Veranstaltungen an der FachhochschuleSchmalkalden verbreitet werden. Aufbauend darauf werden Anforderungen an dieDatenbank und den Service gestellt, um ein Informations- und Planungssystem um-zusetzen. Diese Anforderungen sind durch Absprachen mit den Projektmitgliedernentstanden. Ferner gab es regelmäßige Veranstaltungen, bei denen Vorschläge zurUmsetzung diskutiert wurden. In dieser Master-Thesis werden die Anforderungenbei der Auswahl einer geeigneten Datenbank berücksichtigt und der Service anhandder festgelegten Anforderungen, sowie die daraus folgenden Anwendungsfälle umge-setzt.

3.1 AusgangssituationWie im Kapitel 1 bereits erwähnt, gibt es an der Fachhochschule Schmalkalden keineinheitliches Informations- und Planungssystem. Die Verteilung von Informationengeschieht über mehrere Plattformen. Ferner ist der Stundenplan nur im statischenHTML verfügbar. Änderungen an dem Stundenplan, bedingt durch Verschiebungoder Ausfällen, sind derzeitig nicht möglich und somit nicht nachvollziehbar. Mitdem Projekt ”spirit@fhs“ wird versucht ein neues System zu entwickeln, welches dieTerminplanung und das Verbreiten von Informationen über Webportale und Han-dyapplikationen ermöglicht. Damit die Applikationen auf den gleichen Datenbestandzugreifen können, ist es notwendig die Daten an einer zentralen Stelle zu halten.

3.2 Anforderungen an den Datenbank-Service1. die Datenbank ist für die anderen Teilprojekte nur über den Datenbank-Service

zu erreichen2. für die Kommunikation mit den anderen Applikation ist eine einheitliche

Schnittstelle bereitzustellen3. es dürfen nur ausgewählte Applikationen mit dem Service Verbindung aufneh-

men4. der Datenbank-Service stellt Filterfunktionen über die Schnittstelle bereit5. der Service ermöglicht das Austauschen der Datenbank, ohne das die Schnitt-

stelle zu den Teilprojekten geändert werden muss6. es wird eine Schnittstelle angeboten, welche die Authentifizierung gegen einen

LDAP-Server ermöglicht

Benjamin Lüdicke Seite 15 von 95

Page 21: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

3. Anforderungsspezifikation Fachhochschule Schmalkalden SS 2011

Damit die Applikationen der Teilprojekte, bei Änderung an der Datenbank, nicht an-gepasst werden müssen, kapselt der Datenbank-Service die Datenbank. Ferner wirdsomit sichergestellt, dass nur authentifizierte Applikationen auf die Datenbank zu-greifen können. Außerdem ist somit eine Brut-Force-Attacke gegen den LDAP-Servernicht direkt möglich. Über die bereitgestellten Filterfunktionen soll es möglich sein,gezielt nach Daten zu suchen. Die Bereitstellung der Daten erfolgt über einen REST-ful Web Service, welcher die Übertragungsformate XML und JSON unterstützt.

3.3 Anforderungen an die Datenbank1. die Datenbank ermöglicht ein einfaches Erstellen von Backups2. die Datenbank muss sehr gut dokumentiert sein und in einer stabilen Version

vorliegen3. die Datenbank sollte horizontale Skalierung unterstützen1

4. alle von den Teilprojekten gesendeten Daten müssen konsistent gespeichertwerden

5. die Datenbank ist kostenlos ohne Einschränkungen zu nutzen6. die Datenbank muss unter Linux lauffähig sein

Damit die Daten bei einem Totalausfall der Hard- oder Software nicht komplettverloren gehen, soll es eine einfache Möglichkeit geben ein Backup zu erstellen. Fer-ner sollte die Datenbank horizontal skalierbar sein, um die Systemlast auf andereKnoten zu verteilen. Eine ausführliche Dokumentation ist notwendig, um neuenProjektmitgliedern einen leichten Einstieg in den Umgang mit der Datenbank zu er-möglichen. Außerdem ist dadurch die Wartung und Administration der Datenbankfür neue Projektmitglieder einfacher. Weil zukünftige Änderungen im Datenschemanicht ausgeschlossen werden können, soll die Datenbank leicht zu erweitern sein. DesWeiteren ist der Einsatz eines Linux-Betriebssystems als Server vorgesehen, weshalbdie Datenbank unter Linux lauffähig sein muss.

1unter horizontalen Skalieren wird das Einbinden eines weiteren Knoten verstanden, welcher einenTeil der Last/Daten übernimmt [EFHB10]

Benjamin Lüdicke Seite 16 von 95

Page 22: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

4 AnforderungsanalyseIn diesem Kapitel wird untersucht, welche Art von Daten in der Datenbank gespei-chert werden und wie diese in Beziehung zueinander stehen. Aufgrund dessen, dassunterschiedliche Daten ungleiche Anforderungen an die Datenbank stellen, wird da-bei die Auswahl möglicher Datenbanken weiter eingegrenzt [EFHB10, S. 277]. Dieaus diesem Kapitel resultierenden Ergebnisse sind außerdem Grundlage für das zuerstellende Datenmodell.

4.1 MiniweltAls Miniwelt bezeichnet man den zu modellierenden Teilausschnitt der realen Welt,welcher in der Datenbank abgebildet werden soll [Sau02, S. 19]. Ziel der Miniweltist das Identifizieren von Objekten sowie das Abbilden deren Beziehung für das zuerstellende System. Anhand des Diagramms in Abbildung 4.1 wird die Miniwelt(Fakultät Informatik) dargestellt. Das Objekt Veranstaltung kann eine Vorlesung,Übung oder ein sonstiges Event sein, welches von Gruppen, Klassen oder einzel-nen Studenten besucht werden kann. Ist die Veranstaltung eine Vorlesung oder eineÜbung, wird diese von einem Dozenten gehalten. Weil es auch möglich ist, dass Tu-torien nicht nur von Dozenten gehalten werden, können auch Studenten Tutorien alsVeranstaltung anlegen. Des Weiteren hat eine Veranstaltung einen Ort an dem diesedurchgeführt wird. Der Ort wird durch einen Raum in einem Gebäude beschrieben.Um Informationen innerhalb der Fakultät zu verbreiten, können Nachrichten vonDozenten und Studenten verfasst werden, die einzelne Gruppen oder Klassen derFakultät betreffen. Ein Student und Dozent hat die Möglichkeit diese Nachrichtenzu lesen und zu kommentieren. Anhand der Miniwelt ergeben sich Anwendungsfälle,welche im nächsten Abschnitt in Anwendungsfalldiagrammen abgebildet sind.

4.2 Interaktion zwischen Anwender und SystemDie Miniwelt ist eine abstrakte Darstellung des Informations- und Planungssystemder Fakultät Informatik. In den folgenden Abbildungen 4.2 und 4.3 sind die An-wendungsfalldiagramme dargestellt, welche die zukünftig möglichen Interaktionenzwischen den Anwendern und dem Datenbank-Service beschreiben. Zu beachten ist,dass wie in der Miniwelt nicht die Teilprojekte von ”spirit@fhs“, sondern Dozen-ten und Studenten als Akteure zu verstehen sind. Zusätzlich gibt es einen Admi-nistrator, welcher keine Einschränkungen bei der Nutzung des Datenbank-Servicehat. Die Datenbank ist in diesen Abbildungen nicht aufgenommen, da diese vomDatenbank-Service gekapselt wird und keine direkte Interaktion zwischen den Ak-

Benjamin Lüdicke Seite 17 von 95

Page 23: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

4. Anforderungsanalyse Fachhochschule Schmalkalden SS 2011

Abbildung 4.1: Eigene Darstellung der Miniwelt für Informations- undPlanungssystem

teuren und der Datenbank stattfinden soll. In dem Anwendungsfalldiagramm 4.2ist zu erkennen, dass die Akteure Student und Dozent, die gleichen Rechte ha-ben um Veranstaltungen, Kommentare und Nachrichten zu verwalten. Diese Rechtebeinhalten die Anwendungsfälle Erstellen, Lesen, Bearbeiten und Löschen. Damitein willkürliches Bearbeiten und Löschen von Objekten unterbunden werden kann,sind diese Anwendungsfälle auf den Erzeuger des Objekts beschränkt. Das Anwen-dungsfalldiagramm 4.3 zeigt den zusätzlichen Akteur Admin. Ein Admin hat keineEinschränkungen und kann den Datenbank-Service somit im vollen Umfang nutzen.Über den Admin ist es möglich neue Mitglieder in der Datenbank aufzunehmen oderdiese zu löschen. Ferner kann der Admin Gebäude und Räume in der Datenbank ver-walten. Dozenten und Studenten haben nur die Möglichkeit ihre eigenen Profildatenzu bearbeiten oder anzeigen zu lassen.

Benjamin Lüdicke Seite 18 von 95

Page 24: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

4. Anforderungsanalyse Fachhochschule Schmalkalden SS 2011

Abbildung 4.2: Eigene Darstellung des Anwendungsfaldiagramms ohneEinschränkungen

Benjamin Lüdicke Seite 19 von 95

Page 25: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

4. Anforderungsanalyse Fachhochschule Schmalkalden SS 2011

Abbildung 4.3: Eigene Darstellung des Anwendungsfaldiagramms mit Administra-tor als Akteur

Benjamin Lüdicke Seite 20 von 95

Page 26: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

4. Anforderungsanalyse Fachhochschule Schmalkalden SS 2011

4.3 BeurteilungIn diesem Kapitel wurden die zu speichernden Daten analysiert. Dabei wurde fest-gestellt, dass viele Beziehungen zwischen den Objekten bestehen. Es handelt sichdemnach nicht um eine lose Datenmenge, wie sie zum Beispiel beim Loggen vonEreignissen anfällt. Eine Datenbank, die Beziehungen gut abbilden kann, ist alsSpeicherlösung zu bevorzugen. Die nach Meinung des Autors geeigneten Datenban-ken werden im Kapitel 5 vorgestellt.

Benjamin Lüdicke Seite 21 von 95

Page 27: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5 Evaluierung möglicherDatenbanken

In dem vorherigen Abschnitt wurden die Objekttypen bestimmt und grob spezi-fiziert, wie diese miteinander in Beziehung stehen. In diesem Kapitel werden dreiDatenbanken untersucht, inwiefern sich diese für das neue Informations- und Pla-nungssystem eignen. Grundlagen für die Beurteilung sind die vorher festgelegtenAnforderungen an die Datenbank, die Abfragemöglichkeiten und wie Beziehungenin der Datenbank abgebildet werden können. Zuerst wird die Graphen-DatenbankOrientDB, dann die Key/Value-Datenbank Riak und zum Schluss die relationaleDatenbank PostgreSQL untersucht. Zu erwähnen ist, dass Riak und OrientDB kei-ne reinen Key/Value- bzw. Graphen-Datenbanken darstellen. Beide besitzen auchEigenschaften anderer Datenbankkategorien. PostgreSQL hingegen ist eine reine re-lationale Datenbank. Dennoch lassen sich durch Plugins neue Funktionen hinzufü-gen.

5.1 OrientDBOrientDB ist eine Graphen-Datenbank, welche 1997 in C++ programmiert undspäter in Java reimplementiert wurde. Die derzeitig aktuelle Versionsnummer ist die1.0rc3 (stand 19.07.2011). In dieser Master-Thesis wurde die Evaluierung der Da-tenbank in der Version 0.9.25 durchgeführt. Das Ziel von OrientDB ist es die bestenEigenschaften anderer Datenbanken in sich zu vereinen und somit ein breites Anwen-dungsspektrum abzudecken. Daher ist es möglich OrientDB als Graphen-Datenbank,Objekt-Datenbank oder Dokumenten-Datenbank zu nutzen [Ori]. Laut [Ori] ist Ori-entDB fähig bis zu 150.000 Einträge pro Sekunde zu speichern, was auf das zugrun-de liegende Datenmodell zurückzuführen ist. Für die Administration von OrientDBstehen die Werkzeuge OrientDB-Studio1 und OrientDB-Console2 zur Verfügung. Indiesem Abschnitt wird das zugrundeliegende Datenmodell von OrientDB erläutertund an Beispielen anschließend die CRUD-Operationen3 vorgestellt. Abschließendwird gezeigt, wie die Replikation funktioniert und eine Bewertung von OrientDBvorgenommen.

1http://code.google.com/p/orient/wiki/OrientDB_Studio2http://code.google.com/p/orient/wiki/ConsoleCommands3(C)reate, (R)ead, (U)pdate, (D)elete

Benjamin Lüdicke Seite 22 von 95

Page 28: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

5.1.1 Datenmodell

Das zugrundeliegende Datenmodell von OrientDB ist das sogenannte Property-Graph-Modell [EFHB10, S. 237]. ”Ein Property Graph ist ein gerichteter, multi-relationaler Graph. Die Knoten und Kanten dieses Graphen bestehen aus Objektenund darin eingebetteten Eigenschaften (Properties)“ [EFHB10, S. 173]. Ein Pro-perty entspricht dabei einen Schlüssel/Wert-Paar. Wie in dem Zitat erwähnt, sindKnoten und Kanten Objekte, was einen leichteren Umgang mit objektorientiertenProgrammiersprachen ermöglicht soll. Zwischen zwei Knoten können beliebig vieleKanten existieren, sofern diese unterschiedliche Typen aufweisen. In OrientDB gibtes die Möglichkeit ein Schema für die Kanten und Knoten zu definieren. Dabei ist esnicht relevant wie viele Schemata existieren. Ferner kann auf ein Schema verzichtetoder ein Mix aus beiden verwendet werden, um die Daten flexibel zu speichern.

5.1.2 Beispielanwendung

Damit die CRUD-Operationen vorgestellt werden können, wird in diesem Abschnittdargestellt, wie eine Datenbank mit OrientDB erstellt wird. Dabei wird die zugrun-deliegende Struktur beschrieben und ein Schema angefertigt. Die Beispielanwendunglehnt sich dabei an die Demo-Datenbank von OrientDB an. In diesem Szenario sollenzu einer Firma die Adressen und Mitarbeiter gespeichert werden, wobei Mitarbeiterwiederum mehrere Adressen besitzen können. Eine Adresse beinhaltet einen Stra-ßennamen, eine Stadt und ein Land.

Inbetriebnahme

Nachdem OrientDB heruntergeladen, entpackt und gestartet wurde, kann über dasKonsolenwerkzeug mit dem folgenden Befehl eine neue Datenbank angelegt werden:

create database remote:localhost/beispieldb user password localDas Schlüsselwort remote beschreibt das Protokoll welches angibt, dass auf dieDatenbank über eine TCP/IP Verbindung zugriffen wird. Der Name der neuen Da-tenbank lautet beispieldb und steht vor dem Host localhost. Zum Anlegen ei-ner Datenbank benötigt man in OrientDB Administratorrechte, welche in der Dateiorientdb-server-config.xml festgelegt sind. Die in dieser Datei hinterlegten Nut-zerdaten werden beim Herunterladen von OrientDB automatisch generiert. Somit istsichergestellt, dass jede Distribution andere Zugangsdaten hat. Das Schlüsselwortlocal legt fest, dass die neue Datenbank auf der Festplatte abgelegt wird. Das hatden Vorteil, dass bei einem Neustart oder Ausfall des Systems keine gespeichertenDaten verloren gehen. Wird statt local das Schlüsselwort memory angegeben, wer-den alle Daten im Hauptspeicher hinterlegt, was einen Performancegewinn zur Folgehat, jedoch keine dauerhafte Persistenz sicherstellt.Nachdem die Datenbank angelegt wurde kann eine Verbindung über folgenden Be-fehl hergestellt werden:

connect remote:localhost/beispielDB user password

Benjamin Lüdicke Seite 23 von 95

Page 29: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

Ist die Verbindung hergestellt, können mittels des Schlüsselwortes help alle unter-stützten Befehle angezeigt werden. Soll ein Schema für einen Knoten in OrientDBangelegt werden, muss eine sogenannte Class mit folgendem Befehl erstellt werden:

create class <classname>Der Platzhalter <classname> muss durch den Namen der anzulegenden Klasse er-setzt werden. Aufgrund dessen, dass das Schema bisher nicht definiert ist, ist eineschemalose Verwendung möglich. Damit jedoch die Typsicherheit gewährleistet ist,muss die Class durch folgenden Befehl mit Eigenschaften gefüllt werden:

create property <classname>.<propertyname> <type>Mit diesem Befehl wird der Class <classname> die Eigenschaft <propertyname> mitdem Typ <type> zugewiesen. Die erzeugten Eigenschaften sind keine Pflichtfelderund müssen somit beim Einfügen von Daten nicht zwingend angegeben werden.Ist das Schema erstellt, ist es möglich bestimmte Eigenschaften zu indizieren. Durcheinen Index können Duplikate vermieden und eine performante Suche erreicht wer-den:

create index <classname>.<propertyname> <indextype>Als Indextyp werden in OrientDB folgende Typen unterschieden (siehe Tabelle 5.1).

unique erlaubt keine Duplikatenot unique erlaubt Duplikate (ist Standard)full-text ermöglicht das Suchen nach bestimmten Schlagwörtern

in einer Eigenschaft

Tabelle 5.1: Indextypen in OrientDB

In dem Listing 5.1 sind alle Befehle aufgelistet, um das Schema für die Beispielan-wendung zu erstellen.c r e a t e c l a s s countryc r e a t e property country . name St r ingc r e a t e property country . populat ion In t eg e rc r e a t e c l a s s c i t yc r e a t e property c i t y . name St r ingc r e a t e property c i t y . populat ion In t eg e rc r e a t e property c i t y . country l i n k countryc r e a t e c l a s s addressc r e a t e property address . s t r e e t S t r ingc r e a t e property address . c i t y l i n k c i t yc r e a t e c l a s s employeec r e a t e property employee . name St r ingc r e a t e c l a s s companyc r ea t e property company . name St r ingc r e a t e c l a s s l i v e s I nc r e a t e c l a s s worksIn

Listing 5.1: Erstellen eines Schemas in OrientDB

Benjamin Lüdicke Seite 24 von 95

Page 30: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

Der Typ linklist <supportedtyp> erlaubt das Speichern einer Liste von Knotenund entspricht einer 1:N Beziehung, wobei der Typ link <supportedtyp> eine 1:1Beziehung abbildet. Dabei wird ausschließlich die ID des anderen Knoten gespei-chert. Somit ist OrientDB in der Lage Beziehungen zwischen Knoten abzubildenund kann auch bestehende Daten aus relationalen Datenbanken importieren. Fernererlaubt OrientDB, durch den Typ embeddedlist <supportedtyp>, das Speichernvon Mengenattributen. Die gespeicherten Daten sind somit kein Verweis auf andereTupel, sondern sind ausschließlich in dieser Liste gespeichert. Die beiden ClasseslivesIn und worksIn sind notwendig, um ein Schema für die später zu erstellendenKanten bereitzustellen. Das erstellte Schema kann mit folgendem Befehl angeschautwerden:

info class <classname>Nachdem das Schema in den Classes erzeugt wurde, können Daten in OrientDBgespeichert werden. Die Daten werden dabei in sogenannten Clustern hinterlegt,welche beim Anlegen von Classes automatisch erzeugt werden. Durch diese Tren-nung ist es möglich einem Cluster ein anderes Schema zuzuweisen. Ferner kann dieSchemaanpassung auch über die Java-API vorgenommen werden.

5.1.3 CRUD

Im vorherigen Abschnitt wurde gezeigt, wie ein Schema in OrientDB erstellt wer-den kann. Im folgenden wird beschrieben, wie die erstellten Cluster mit Daten ge-füllt, diese wieder gelesen, verändert oder gelöscht werden können. Für den Zugriffauf das erstellte Modell wird die Java-API von OrientDB verwendet. Ferner be-steht die Möglichkeit über REST oder die DSL (domain specific language) Gremlin4

auf die Daten zuzugreifen. Eine API für Scala existiert nicht. Lediglich der Hin-weis, dass mit Hilfe der Bibliotheken scala.collection.JavaConverters._ undscala.collection.JavaConversions._, Scala-Collections in die von OrientDB er-warteten Java-Collections, konvertiert werden müssen.

Create

Im Listing 5.2 ist ein Auszug des Quellcodes abgebildet, welcher Daten erzeugt undin Clustern abspeichert. Der komplette Quellcode ist auf der beiliegenden CD-ROMhinterlegt.

1 val db: OGraphDatabase = new OGraphDatabase ("remote:192.168.178.42 :2424/ beispieldb ").open("admin", "admin")

2 def create () = {3 val germany: ODocument = db. createVertex (" country ")4 germany .field("name", " Germany ")5 germany .field(" population ", 81000000)

4http://www.tinkerpop.com

Benjamin Lüdicke Seite 25 von 95

Page 31: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

6

7 val microsoft: ODocument = db. createVertex (" company ")8 microsoft .field("name", " Microsoft Headquarter

Germany ")9

10 val berlin: ODocument = db. createVertex ("city")11 berlin.field("name", "Berlin")12 berlin.field(" population ", 3000000)13 berlin.field(" country ", germany )14

15 val petrasAddress : ODocument = db. createVertex (" address")

16 petrasAddress .field("street", " Kreuzberger Str.")17 petrasAddress .field("city", berlin)18

19 val petra: ODocument = db. createVertex (" employee ")20 petra.field("name", "Petra")21

22 val petrasAddressEdge = db. createEdge (petra ,petrasAddress , " livesIn ")

23

24 [...]25

26 db.save( germany )27 db.save(berlin)28 db.save( petrasAddress )29 db.save(petra)30 db.save( petrasAddressEdge )31

32 db. setRoot ("graph", microsoft )33

34 db.close35 }

Listing 5.2: Create-Operation in OrientDB mit Java-API

In Zeile 1 ist zu erkennen, wie eine Verbindung mit der Datenbank hergestelltwird. Wichtig dabei ist, dass eine Instanz von OGraphDatabase und nicht vonODatabaseGraphTx erzeugt wird. Letztere wird in den nächsten Versionen von Ori-entDB nicht mehr unterstützt. Dem Konstruktor von OGraphDatabase wird dieAdresse der Datenbank mitgegeben und diese mittels der Methode open()geöffnet.Ferner wird über die Methode vertex(<classname>) ein neuer Knoten unter Be-rücksichtigung des angegebenen Schemas erzeugt und eine Instanz von ODocumentzurückgegeben. Dieser Instanz können Schlüssel/Wert-Paare übergeben werden, umden Knoten mit Daten zu füllen. Wie zu erkennen ist, wird dem Attribut countrydes Knoten berlin das Objekt germany übergeben, um eine 1:1 Beziehung darzu-stellen. Damit dem Objekt petra eine Adresse zugewiesen werden kann, muss eine

Benjamin Lüdicke Seite 26 von 95

Page 32: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

Kante zwischen petra und petrasAddress erstellt werden. Dafür muss die Me-thode createEdge(<sourcevertex>, <destinationvertex>, <classname>) auf-gerufen werden. Für den Platzhalter <sourcevertex> wird der Startknoten undfür <destinationvertex> der Zielknoten der Kante angegeben. Ferner kann dieserKante eine Class übergeben werden, welche ebenfalls mit Schlüssel/Wert-Paaren ge-füllt werden kann. Um durch den Graphen von einem bestimmten Knoten aus zutraversieren, gibt es die Möglichkeit einen Startknoten festzulegen. In diesem Bei-spiel ist das der Knoten microsoft mit der Bezeichnung graph. Das Ergebnis nachdem Erstellen der Knoten und Kanten ist in Abbildung 5.1 dargestellt.

Abbildung 5.1: Eigene Darstellung des PropertyGraph nach dem Aufruf der Metho-de create()

Read

In diesem Abschnitt wird gezeigt, wie mittels der Java-API die gespeicherten Datenaus der Datenbank ausgelesen werden können. Die in Listing 5.3 auskommentierten

Benjamin Lüdicke Seite 27 von 95

Page 33: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

Codezeilen sollen alle ausgehenden Kanten des Vertex root zurückgeben. Aufgrundeines Fehlers bei der Übergabe des Vertex root, ist dieser Code jedoch nicht aus-führbar. Ferner erzeugt das Java-Beispiel auf der Projekt-Homepage5 ebenfalls eineIllegalArgumentException. Eine andere Möglichkeit die Datenbank abzufragen, isteine SQL-Abfrage mittels der Klasse OSQLSynchQuery zu erstellen, wie es in Zei-le 6 zu erkennen ist. Das Fragezeichen in der SQL-Abfrage dient als Platzhalter,dessen Wert beim Ausführen in Zeile 8 übergeben wird. In diesem Fall werden alleMitarbeiterinnen mit dem Namen Petra in einer ArrayList gespeichert und da-nach auf der Konsole ausgegeben. Zu erwähnen ist, dass die Methode foreach nichtBestandteil von java.util.ArrayList ist. Aufgrund der importierten Bibliothekscala.collection.JavaConversions._ findet eine implizite Konvertierung in eineScala-Collection statt, so das foreach aufgerufen werden kann.

1 def read () = {2 // Erzeugt IllegalArgumentException3 //val root: ODocument = db.getRoot ("graph")4 //val outEdges = db.getOutEdges(root)5

6 val query3: OSQLSynchQuery [ ODocument ] = newOSQLSynchQuery [ ODocument ]("select from employeewhere name = ?")

7 query3. setDatabase (db)8 val res3: ArrayList [ ODocument ] = query. execute ("Petra

")9 res3. foreach ( document => println ( document .field[

String ]("name")))10

11 val query2: OSQLSynchQuery [ ODocument ] = newOSQLSynchQuery [ ODocument ]("select from employeewhere all () traverse (0,-1) (@class = ’country’ and name = ’USA ’)")

12 query2. setDatabase (db)13 val res2: ArrayList [ ODocument ] = query2. execute ()14 res2. foreach ( document => println ( document .field[

String ]("name")))15

16 db.close17 }18 }

Listing 5.3: Read-Operation in OrientDB mit Java-API

Ferner kann mittels Graphentraversierung nach Daten im Graphen gesucht werden.In Listing 5.3 Zeile 11, ist eine SQL Abfrage abgebildet, die alle Mitarbeiter zu-rückgibt, welche mit dem Land USA in Verbindung gebracht werden können. DerOperator all() gibt an, dass alle Attribute des Clusters employee für die Tra-

5http://code.google.com/p/orient/wiki/GraphDatabaseRaw)

Benjamin Lüdicke Seite 28 von 95

Page 34: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

versierung einbezogen werden. Dies beinhaltet ebenfalls die Attribute INEDGESund OUTEDGES6. Der Operator traverse(<min>, <max>) gibt die Mindest- undMaximaltiefe an, auf welche die darauf folgende Bedingung zutreffen muss, um einErgebnis zurückzugeben. Wird als Maximaltiefe eine -1 angegeben, gilt keine Tiefen-beschränkung. Durch den and Operator werden die Bedingungen @class=‘country‘und name=‘USA‘ miteinander verbunden. Dadurch wird erreicht, dass nur die Attri-bute name aus der Class country die Bedingungen erfüllen können.

Update

Um zu demonstrieren wie ein Knoten geändert werden kann, wird in diesem Ab-schnitt die Einwohnerzahl des Knoten berlin korrigiert. In Listing 5.4 Zeile 2 bis10, ist abgebildet wie ein Update durch die Java-API vorgenommen werden kann.Beim Versuch eine neue Kante zwischen zwei Knoten zu erstellen, kommt es zu ei-ner ClasscastException, sobald die Methode createEdge() in Zeile 22 aufgerufenwird. Dem Autor ist nicht bekannt, wie dieser Fehler vermieden werden kann. DerCode, welcher zu diesem Fehler führt, ist in Listing 5.4 auskommentiert und vonZeile 12 bis 27 abgebildet.

1 def update () = {2 val query: OSQLSynchQuery [ ODocument ] = new

OSQLSynchQuery [ ODocument ]("select from city wherename = ’Berlin ’ ")

3 query. setDatabase (db)4 val res: ArrayList [ ODocument ] = query. execute ()5 if (! res. isEmpty ) {6 val berlin = res.head7 berlin.field(" population ", 5000000)8 db.save(berlin)9 }

10 db.close ()11

12 // Erzeugt ClasscastException13 // val query: OSQLSynchQuery[ODocument] = new

OSQLSynchQuery[ODocument ](" select from employee wherename = ’Steve’ ")

14 // val query2: OSQLSynchQuery[ODocument] = newOSQLSynchQuery[ODocument ](" select from company wherename = ’Microsoft Headquarter Germany ’ ")

15 // query.setDatabase(db)16 // query2.setDatabase(db)17 // val res: ArrayList[ODocument] = query.execute ()18 // val res2: ArrayList[ODocument] = query2.execute ()19 // if (!res.isEmpty && !res2.isEmpty) {

6diese Attribute verweisen auf die eingehenden und ausgehenden Kanten eines Knoten

Benjamin Lüdicke Seite 29 von 95

Page 35: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

20 // val steve = res.head21 // val microsoft = res2.head22 // val edge = db.createEdge(steve , microsoft , "

worksIn ")23 // db.save(steve)24 // db.save(microsoft)25 // db.save(edge)26 // }27 // db.close()28 }

Listing 5.4: Update-Operation in OrientDB mit Java-API

Delete

Damit ein Knoten entfernt werden kann muss sichergestellt werden, dass keine Kan-ten zu anderen Knoten existieren. OrientDB bietet mit der Methode removeVertex()die Möglichkeit zusätzlich alle Kanten zu entfernen, welche auf den zu löschen-den Knoten verweisen. Der Code in Listing 5.5 produziert ebenfalls, wie das Hin-zufügen einer neuen Kante, eine ClasscastException. Ersetzt man die MethoderemoveVertex() durch die Methode delete() wird der Knoten entfernt. Jedochbleiben die Kanten zu dem alten Knoten erhalten, weshalb diese vorher gelöschtwerden müssen.

1 def delete () = {2 val query: OSQLSynchQuery [ ODocument ] = new

OSQLSynchQuery [ ODocument ]("select from employeewhere name = ’Steve ’ ")

3 query. setDatabase (db)4 val res: ArrayList [ ODocument ] = query. execute ()5 if (! res. isEmpty ) {6 val steve = res.head7 // Erzeugt Classcastexception8 //db.removeVertex(steve)9 db.delete(steve)

10 }11 db.close ()12 }

Listing 5.5: Delete-Operation in OrientDB mit Java-API

5.1.4 Backup

Bei einem Totalausfall des Systems ist es notwendig die Daten wieder herstellen zukönnen. Dies kann laut Meinung des Autors auf zwei Arten realisiert werden. Zumeinen durch das Spiegeln der Festplatte auf den die Datenbank installiert ist und

Benjamin Lüdicke Seite 30 von 95

Page 36: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

zum anderen durch das Erstellen eines Backups der Datenbank. Letztere Variantehat den Vorteil, dass nicht nur die Daten gesichert sind, sondern dass auch bei einemVersionswechsel die Daten in die neue OrientDB-Version importiert werden können,ohne Daten zu verlieren. Aufgrund dessen erfolgt der Export in eine JSON-Datei. Istder Benutzer über OrientDB-Console bei der zu sichernden Datenbank eingeloggt,wird mit folgendem Befehl ein Backup erstellt:

export database <dateiname>.exportDie dabei erstellte Datei wird im Unterordner /bin von OrientDB abgelegt. Soll einBackup wiederhergestellt werden, muss dieses in eine geöffnete Datenbank importiertwerden. Für einen erfolgreichen Import muss die Datei einen gültigen JSON-Stringbeinhalten. Folgender Befehl importiert Daten aus einer JSON-Datei:

import database <dateiname>.export

5.1.5 Skalierung und Replikation

Für die Skalierung und Replikation unter OrientDB, muss die Dateiorientdb-server-config.xml im Verzeichnis /config angepasst werden. Dabeiist darauf zu achten, dass die Parameter name und security.key für alle Knotenim Cluster die jeweils gleichen Werte haben. Wurden beide Parameter angepasst,muss man sich über OrientDB-Console, bei dem Knoten mit der zu replizierendenDatenbank, als root einloggen und folgenden Befehl eingeben:

share database <db-name> <db-user> <db-password> <server-name> <mo-de>

Als <db-name> muss der Name der zu replizierenden Datenbank angegeben werdenund über <mode> kann man durch synch oder asynch festlegen, ob der Datenabgleichsynchron oder asynchron stattfinden soll. Für den Platzhalter <server-name> ist derKnoten anzugeben, auf dem die Datenbank repliziert werden soll. OrientDB nutztbei der Replikation das sogenannte Master-Slave Prinzip, wobei es einen Master undmehrere Slave gibt. Die Kommunikation der Clients erfolgt dabei ausschließlich überden Master, welcher daraufhin die Lastverteilung und Replikation steuert. Um dieDatenbank beispieldb synchron zu replizieren, könnte der Befehl folgendermaßenaussehen:

share database beispieldb admin admin debian1.local:2425 synch

5.1.6 Bewertung

Vorteile:• horizontale Skalierung und Replikation ist einfach umzusetzen• Backups sind versionsunabhängig• es können komplexe Beziehungen abgebildet werden• unterstützt erweiterte Untermenge von SQL, so dass auch Graphen durchlau-

fen werden können

Benjamin Lüdicke Seite 31 von 95

Page 37: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

Nachteile:• Java-API ist laut Meinung des Autors nicht fehlerfrei und stimmt nicht mit

der Dokumentation überein• die Einbindung der Abfragesprache Gremlin in ein Java-Programm ist nicht

dokumentiert und wurde deswegen in dieser Master-Thesis nicht behandelt• die auf der Homepage veröffentlichten Java-Beispiele sind nicht fehlerfrei und

somit nicht einfach anzuwenden• OrientDB-Console unterstützt noch nicht alle grundlegenden Befehle wie zum

Beispiel das Ändern einer Kante oder eines KnotenWie an den Vor- und Nachteilen zu erkennen ist, wäre OrientDB laut Meinungdes Autors eine gute Datenbank für das neue Informations- und Planungssystem.Jedoch ist die Dokumentation nicht ausreichend und die Java-API fehlerhaft, wasein effizientes programmieren erschwert.

5.2 RiakRiak gibt es seit dem Jahr 2007 und wurde von Basho Technologies in den Program-miersprachen Erlang, C und JavaScript entwickelt. Derzeitig liegt Riak in der Version0.14.2 vor (stand 08.08.2011). Für die Evaluierung in dieser Master-Thesis wurdeRiak in der Version 0.14.1 verwendet und unter Debian Squeeze 64 Bit installiert. Ri-ak lässt sich in die Kategorie der Key/Value-Datenbanken einordnen und speichertDaten ausschließlich auf der Festplatte und nicht im Hauptspeicher. Demzufolgeist eine höhere Datensicherheit gewährleistet, welche jedoch die Performance nega-tiv beeinträchtigt. Laut [Riab] wird deshalb die Verwendung von RAID-Systemenoder SSDs empfohlen, um schnelle Ein-/Ausgabeoperationen durchzuführen. In denfolgenden Abschnitten wird zunächst auf das Datenmodell von Riak eingegangen.Ferner werden anhand eines Beispiels die CRUD-Operationen mittels der Java-APIvorgestellt. Danach wird gezeigt wie die horizontale Skalierung sowie die Replikati-on und das Erstellen von Backups durchgeführt werden können. Abschließend findeteine Bewertung von Riak statt.

5.2.1 Datenmodell

Riak gehört zu den Key/Value-Datenbanken, obwohl im eigentlichen Sinn Doku-mente, wie bei Dokumenten-Datenbanken, gespeichert werden. Eine Vorgabe in wel-chem Format die Daten gespeichert werden sollen gibt es nicht, jedoch wird JSONlaut [EFHB10, S. 159] derzeitig am besten unterstützt. Um Daten in Riak struk-turiert abzulegen gibt es sogenannte Buckets in denen Keys hinterlegt sind, welchewiederum auf Dokumente verweisen. In Abbildung 5.2 ist dieses Prinzip verdeutlicht.Was Riak von anderen Dokumenten- oder Key/Value-Datenbanken unterscheidetist die Möglichkeit innerhalb der Dokumente Verlinkungen zu anderen Dokumen-ten abzubilden. Somit ist es möglich Riak einzusetzen, wenn Beziehungen zwischenDaten von Bedeutung sind.

Benjamin Lüdicke Seite 32 von 95

Page 38: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

Abbildung 5.2: Eigene Darstellung des Namensraum in Riak in Anlehnung an[EFHB10, S. 157]

5.2.2 CRUD

In diesem Abschnitt wird erläutert wie die Beispielanwendung mittels der Java-APIumgesetzt werden kann. Diese API nutzt den Apache http-Client, um Daten zwi-schen Riak und dem Client auszutauschen. Die zwei älteren Community-ProjekteRiakka7 und Ryu8 sind eine Möglichkeit Riak mittels Scala zu nutzen. Aufgrunddessen, dass diese Projekte schon länger nicht weiterentwickelt wurden, wird in die-ser Maste-Thesis auf eine Evaluierung dieser APIs verzichtet. Ferner kann über eineREST-Schnittstelle mit Riak kommuniziert werden.Zum Vorstellen der CRUD-Operationen wird die gleiche Beispielanwendung umge-setzt, wie in Abschnitt 5.1.2 beschrieben.

Create

Um eine Verbindung mit Riak herzustellen, muss eine Instanz von RiakClient wiefolgt angelegt werden:

riakClient = new RiakClient("http://192.168.178.33:8098/riak")Anders als bei OrientDB, wo die Adresse des Master-Knoten übergeben werdenmuss, kann in Riak ein beliebiger Knoten im Cluster adressiert werden. Das istmöglich, da in Riak jeder Knoten gleichwertig ist [EFHB10, S. 166].Ein Auszug der Create-Operation mittels der Java-API, ist in Listing 5.6 dargestellt.Dabei ist auffällig, dass zuvor kein Schema festgelegt wurde, um Typsicherheit zugewährleisten. Dies liegt daran, weil Riak keine Vorgaben über die zu speicherndenDaten macht. Aufgrund dessen, können zum Beispiel einfacher Text, XML, JSONoder Binärdaten abgelegt werden. In diesem Beispiel wird JSON-Text abgespei-chert.

1 def create () = {2 val microsoft = new RiakObject (" company ", " Microsoft "

)3 microsoft . setContentType (" application /json")4 microsoft . addLink (new RiakLink (" address ", " Microsoft "

, " livesIn "))5

6 val germany = new RiakObject (" country ", " Germany ")7 germany . setContentType (" application /json")

7https://github.com/timperrett/riakka8https://github.com/softprops/ryu

Benjamin Lüdicke Seite 33 von 95

Page 39: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

8 germany . setValue ("{\" population \":81000000} ")9

10 val berlin = new RiakObject ("city", "Berlin")11 berlin. setContentType (" application /json")12 berlin. addLink (new RiakLink (" country ", " Germany ", "

isIn"))13

14 val microsoftsAddress = new RiakObject (" address ", "Microsoft ")

15 microsoftsAddress . setContentType (" application /json")16 microsoftsAddress . setValue ("{\" street \":\"

Hauptstrasse \"}")17 microsoftsAddress . addLink (new RiakLink ("city", "

Berlin", "isIn"))18

19 val petra = new RiakObject (" employee ", "Petra")20 petra. setContentType (" application /json")21 petra. addLink (new RiakLink (" address ", "Petra", "

livesIn "))22 petra. addLink (new RiakLink (" company ", " Microsoft ", "

worksIn "))23

24 riakClient .store( microsoft )25 riakClient .store(petra)26 riakClient .store( microsoftsAddress )27 riakClient .store(berlin)28 riakClient .store( germany )29 }

Listing 5.6: Create-Operation in Riak mit Java-API

In der Zeile 2 wird ein neues Objekt der Klasse RiakObject angelegt. Dabei wirddem Konstruktor der Klasse, der Name des Bucket und des Key übergeben, un-ter dem die Daten abgelegt werden sollen. Wird zweimal der gleiche Bucket undKey zum Speichern genutzt, werden die vorher angelegten Daten überschrieben so-fern keine Siblings9 erlaubt sind. Wie bereits erwähnt macht Riak keine Vorga-ben über die zu speichernden Daten. In Zeile 7 wird der Content-Type des http-Header gesetzt. Das ist von Vorteil, da beim Abrufen der Daten überprüft wer-den kann, um welche Art von Daten es sich handelt und wie diese zu verarbeitensind. Die Methode setValue() füllt das RiakObject mit Daten. In Zeile 8 ist dar-gestellt, wie als JSON-Text die Einwohnerzahl von Deutschland übergeben wird.Um eine Verbindung zwischen zwei Dokumenten aufzubauen, muss die MethodeaddLink(<bucket>, <key>, <tag>) aufgerufen werden. Als Parameter werden derBucket und der Key des Ziel-Dokuments angegeben. Der Platzhalter <tag> bestimmtden Namen der Verbindung. In Zeile 22 wird eine Verbindung zwischen der Instanz

9Siblings sind in Riak unterschiedliche Versionen von Daten, welche angelegt werden wenn mehr-mals unter demselben Bucket und Key gespeichert wird

Benjamin Lüdicke Seite 34 von 95

Page 40: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

petra und der Instanz microsoft, mit dem Namen worksIn, erstellt. Dabei sollverdeutlicht werden, dass Petra für Microsoft arbeitet. In Riak sind solche Verbin-dungen unidirektional. Semantisch bedeutet dass, das Microsoft keine Kenntnisseüber seine Mitarbeiter hat. Ferner kann ein Verweis auf einen Bucket und Key be-stehen, ohne das Daten innerhalb dieser gespeichert wurden oder diese überhauptexistieren, wie in den Zeilen 24 bis 28 zu sehen ist.

Read

Nachdem die Datenbank mit Daten gefüllt wurde, können diese wieder mittels derJava-API Abgerufen werden. In diesem Abschnitt wird dabei auf das abrufen einesgewöhnlichen JSON-Text sowie dessen Siblings eingegangen. Ferner wird gezeigt,wie mit dem sogenannten Link-Walking die Verbindungen zwischen Dokumententraversiert werden können und komplexe Abfragen mittels Map/Reduce zu formu-lieren sind.

Abfrage und SiblingsDas einfache Abfragen von Daten aus Riak ist in Listing 5.7 abgebildet.

1 val res: FetchResponse = riakClient .fetch(" country "," Germany ")

2 if (res. hasObject ) {3 val germany: RiakObject = res. getObject4 println ("Value: " + germany . getValue )5 }6

7 if (res. hasSiblings ) {8 val germanySiblings = res. getSiblings9 for ( sibling <- germanySiblings ) {

10 println ("Value " + sibling . getValue )11 }12 }

Listing 5.7: Read-Operation in Riak mit Java-API

Das Abrufen der Daten wird mittels der Methode fetch(<bucket>, <key>) rea-lisiert. In der Zeile 1 bekommt diese Methode den Bucket country und den KeyGermany übergeben, woraufhin eine FetchResponse zurückgegeben wird. In derZeile 2 wird geprüft, ob unter diesen Parametern Daten hinterlegt sind. Ist dieBedingung erfüllt, wird durch den Aufruf der Methode getObject() das zuvor ge-speicherte RiakObject zurückgeben und mittels der Methode getValue() der Inhaltdessen auf der Konsole ausgegeben. Sofern unter dem Bucket country und dem KeyGermany mehrmals ein RiakObject abgespeichert wurde, exisitieren Siblings. Um zuPrüfen ob Siblings vorhanden sind, wird die Methode hasSiblings() aufgerufen.Gilt die Bedingung in Zeile 7 als erfüllt, können durch die Methode getSiblings()alle vorhandenen Siblings abgerufen werden. In den Zeilen 9 und 10 wird der Inhaltdes jeweiligen Sibling auf der Konsole ausgegeben.

Benjamin Lüdicke Seite 35 von 95

Page 41: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

Link-WalkingUm die in Listing 5.7 erstellten Verweise zu traversieren, gibt es in Riak die Mög-lichkeit des sogenannten Link-Walking. In Listing 5.8 ist dargestellt, wie das in Riakumgesetzt ist. Wie bei den einfachen Abfragen wird in Zeile 1 das RiakObject geholt.Möchte man nun über die Verweise traversieren, muss die Methode walk(<bucket>,<tag>, <keep>) aufgerufen werden, wie es in Zeile 4 zu sehen ist. Der Platzhalter<bucket> gibt an, in welchem Bucket sich die verlinkten Daten befinden. Durchden Platzhalter <tag> wird der Name des Verweises angegeben und der Platzhalter<keep> legt fest, ob die ermittelten Daten in das Ergebnis einfließen. Dies ist vonVorteil, wenn auf das Ergebnis der Methode walk() wieder Link-Walking angewen-det wird und nur das letzte Ergebnis zurückgeliefert werden soll. Ferner können diePlatzhalter <bucket> und <tag> durch die Wildcard "_" ersetzt werden. Damit istes möglich nicht nur Verweisen innerhalb eines bestimmten Bucket und Namen zufolgen, sondern alle Verweise zu traversieren.

1 val res2: FetchResponse = riakClient .fetch(" employee ", "Petra")

2 if (res2. hasObject ) {3 val petra = res2. getObject4 val response: WalkResponse = petra.walk(" address ",

" livesIn ", true).run5 val steps = response . getSteps6 for (step <- steps) {7 for ( address <- step) {8 println (" Address: " + address . getValue )9 }

10 }11 }

Listing 5.8: Link-Walking in Riak mit Java-API

Im Listing 5.8 ist abgebildet, wie der Verweis zum Bucket address mit dem Na-men livesIn, der Instanz petra, verfolgt wird. Aufgrund dessen, das es mehre-re Verweise mit diesem Namen und Bucket geben kann, welche wiederum auf an-dere Daten verweisen, ist der Rückgabetyp der Methode getSteps() in Zeile 5List[_ <: List[RiakObject]]. In den Zeilen 6 bis 10 werden die Listen durchlau-fen und alle Adressen von Petra auf der Konsole ausgegeben.

Map/ReduceWerden die Daten wie in dem vorherigen Abschnitt beschrieben abgerufen, ist dasAnwenden von Filtern nicht möglich. Ferner können keine komplexen Berechnungendurchgeführt werden, ohne die Daten zuvor in dem Client zu sammeln. Somit würdeeine hohe Netzlast entstehen, wenn viele Daten angefordert werden. Besser wäre es,wenn die Berechnung auf den jeweiligen Knoten durchgeführt wird, welcher die fürdie Berechnung notwendigen Daten enthält. Durch Map/Reduce ermöglicht Riakden Code für die Berechnung vom Client zu den jeweiligen Knoten zu transferieren,welcher dann das gewünschte Ergebnis zum Client zurücksendet. Bevor beschrie-

Benjamin Lüdicke Seite 36 von 95

Page 42: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

ben wird wie Map/Reduce mittels der Java-API umzusetzen ist, soll anhand derAbbildung 5.3 das Verfahren genauer betrachtet werden.

Abbildung 5.3: Eigene Darstellung des Map/Reduce-Verfahren in Anlehnungan [EFHB10, S. 18]

In der Map-Phase wird eine selbst definierte Funktion, für alle eingehenden Datenausgeführt. Dabei ”[...] werden alle Eingabedaten auf verschiedene Map-Prozesseaufgeteilt“ [EFHB10, S. 17]. Die einzelnen Zwischenergebnisse werden danach ineiner Liste zusammengefasst und in der Reduce-Phase auf verschiedene Reduce-Prozesse aufgeteilt, in denen eine selbst definiert Funktion auf die einzelnen Zwi-schenergebnisse angewendet wird. Das Ergebnis aus der Berechnung in der Reduce-Phase wird an den Aufrufer des Map/Reduce-Algorithmus zurückgegeben.

1 val res3: MapReduceResponse = riakClient .mapReduceOverBucket (" country ")

2 .map( JavascriptFunction .anon(""" function (v) {return [JSON.parse(v.values [0]. data). population]; }"""), false)

3 .reduce( JavascriptFunction .anon(4 """ function (v) {5 var total = 0;6 for (var value=0; value < v.length; value ++) {7 total += v[value ];8 }

Benjamin Lüdicke Seite 37 von 95

Page 43: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

9 var average = total / v.length;10 return [ average ];11 }"""), true).submit ()12

13 if (res3. isSuccess ) {14 println (" Average population : " + res3. getResults .

get (0))15 }

Listing 5.9: Map/Reduce in Riak mit Java-API

In Listing 5.9 ist ein Beispiel für die Anwendung des Map/Reduce-Verfahrens ab-gebildet. Das Ziel ist, die durchschnittliche Einwohnerzahl aller abgespeicherten Län-der im Bucket country zu berechnen. Dafür wird in Zeile 1 die MethodemapReduceOverBucket(<bucket>) aufgerufen, die als Parameter den Bucketcountry übergeben bekommt. Um für die Map-Phase eine Funktion bereitzustellen,muss die Methode map(<MapReduceFunction>, <keep>) aufgerufen werden. Diefür den Platzhalter <MapReduceFunction> zu übergebene Funktion kann entwederin den Programmiersprachen Erlang oder JavaScript programmiert sein. In diesemBeispiel wird eine anonyme JavaScript-Funktion übergeben. Diese Funktion wandeltdie Eingabedaten in ein JSON-Objekt, liest den Wert des Schlüssels populationund speichert diesen als Zwischenergebnis ab. Für den Platzhalter <keep> wirdangegeben, ob die Zwischenergebnisse in das Endergebnis einfließen. Nachdem alleZwischenergebnisse berechnet wurden, wird die anonyme JavaScript-Funktion in derReduce-Phase aufgerufen. Diese Funktion addiert die eingehenden Zwischenergeb-nisse, in den Zeilen 6 bis 8 und errechnet den Durchschnitt in Zeile 9. Anschließendwird das Ergebnis zurückgegeben und in Zeile 14 auf der Konsole ausgegeben.

Update

Die Daten unter einem Bucket und Key können entweder aktualisiert oder durch dasSpeichern eines neuen RiakObject überschrieben werden. Im Listing 5.10 ist abge-bildet, wie die Einwohnerzahl von Deutschland um den Wert 1.000 erhöht wird.In der Zeile 4 wird das RiakObject mit dem Namen germany, welches unter demBucket country mit dem Key Germany hinterlegt ist, aus der Datenbank abgefragt.Um die Daten in dem RiakObject verarbeiten zu können, wird aus ihnen in Zeile5 ein JSONObject erstellt und in Zeile 6 die Einwohnerzahl ausgelesen. In Zeile 7wird die Einwohnerzahl um den Wert 1.000 erhöht und in Zeile 8 wird der neueWert im RiakObject abgespeichert. Beim Update eines Dokuments wird eine soge-nannte Vector Clock verwendet, um Konflikte aufzulösen. Standardmäßig ist Riakso konfiguriert, dass das letzte Update gewinnt. Dies kann jedoch in der Konfigu-ration geändert werden, so dass der Konflikt in der Anwendung aufgelöst werdenkann [Riaa].

1 def update () = {2 val res: FetchResponse = riakClient .fetch(" country ",

" Germany ")3 if (res. hasObject ) {

Benjamin Lüdicke Seite 38 von 95

Page 44: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

4 val germany: RiakObject = res. getObject5 val jsonObject = new JSONObject ( germany . getValue )6 val popoulation : Int = jsonObject .get(" population ")

. asInstanceOf [Int]7 jsonObject .put(" population ", ( popoulation + 1000))8 germany . setValue ( jsonObject . toString )9 riakClient .store( germany )

10 }11 }

Listing 5.10: Update in Riak mit Java-API

Delete

Das Löschen von Daten wird im Listing 5.11 beschrieben. Dabei muss lediglich derBucket und der Key in der Methode delete(<bucket>, <key>) angegeben werden,unter welchen die zu löschenden Daten abgelegt sind.

1 def delete () = {2 riakClient .delete(" country ", " Germany ")3 }

Listing 5.11: Delete in Riak mit Java-API

5.2.3 Backup

Wie auch bei anderen Datenbanken, ist es in Riak möglich ein Backup zu erstellen.Um dieses anzulegen muss Riak gestartet sein und folgender Befehl in der Komman-dozeile ausgeführt werden, wobei die Parameter in der Tabelle 5.2 erläutert sind:

riak-admin backup <node> <cookie> <filename> [node|all]Für die Wiederherstellung muss folgender Befehl ausgeführt werden:

riak-admin restore <node> <cookie> <filename>Die dabei verwendeten Parameter sind ebenfalls in der Tabelle 5.2 beschrieben. DerBackup-Befehl für die erstellte Beispieldatenbank sieht wie folgt aus:

riak-admin backup [email protected] riak ./backup.dets all

5.2.4 Skalierung, Replikation und Konfiguration

Um die Skalierung und Replikation in Riak nachvollziehen zu können, wird zunächstauf die Struktur und Konfiguration von Riak eingegangen. Riak verwaltet mittels desConsistent-Hashing-Verfahren10 einen Ring, welcher einen 2160 großen Schlüsselraum

10Ziele des Consistent-Hashing-Verfahren ist es einen festen Speicherort für ein Objekt, in einerverteilten Umgebung, zu finden [EFHB10, S. 37]

Benjamin Lüdicke Seite 39 von 95

Page 45: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

<node> gibt an, auf welchem Knoten das Backup ausgeführt werden soll<cookie> Cookie gibt an, ob Zugang gewährt wird oder nicht - Cookie muss

bei allen Knoten im Cluster gleich sein<filename> legt den Namen der Backup-Datei fest - dabei muss der komplette

Pfad angegeben werdennode/all gibt an, ob nur der einzelne Knoten oder das ganze Cluster gespei-

chert werden soll

Tabelle 5.2: Backup-Optionen in Riak

abbildet (somit können ca. 1048 Dokumente hinterlegt werden) [EFHB10, S. 164].Dieser Ring wird in Partitionen aufgeteilt, wobei jeder Knoten im Cluster einenbestimmten Anteil der Partitionen verwaltet. Ein Beispiel für die Partitionierungdes Rings ist in Abbildung 5.4 dargestellt.

Abbildung 5.4: Eigene Darstellung des 160 bit Hash-Ring mit vier Knoten und 32Partitionen

Dabei gilt, jeder Knoten hat 1/(Anzahl von physikalischen Knoten) Partitionen.Ferner hat jeder Knoten virtuelle Knoten (sogenannte vnodes) in denen die Da-ten gespeichert werden. Die Anzahl der virtuellen Knoten wird durch die Formel(Anzahl der Partitionen)/(Anzahl der physikalischen Knoten) berechnet. Die vir-tuellen Knoten werden über den Ring gleichmäßig verteilt. Wird ein neuer Knotenhinzugefügt, werden unter Verwendung des Consistent-Hashing-Verfahrens die be-reits gespeicherten Daten neu verteilt. Im umgekehrten Fall, wenn ein Knoten denRing verlässt, verteilt dieser zuvor die Daten an seine Nachbarn im Ring. Um einen

Benjamin Lüdicke Seite 40 von 95

Page 46: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

Knoten zu einem Cluster hinzuzufügen, muss folgender Befehl ausgeführt werden:riak-admin join [email protected]

Die dabei angegebene IP-Adresse muss mit der des hinzuzufügenden Knoten über-einstimmen. Soll ein Knoten entfernt werden, muss statt dem Schlüsselwort join dasSchlüsselwort remove angegeben werden. Die Replikation von Daten in Riak erfolgtautomatisch und ist standardmäßig auf den Wert drei eingestellt. Diese Replikatewerden dann auf unterschiedliche virtuelle Knoten verteilt, wie es in Abbildung 5.4zu sehen ist. Die Eigenschaft n_val bestimmt die Anzahl der Replikate im Clusterund kann ausschließlich über die REST-Schnittstelle angepasst werden. Ferner kannn_val für jeden Bucket einen anderen Wert annehmen. Folgender Aufruf mit Curl11

erhöht die Anzahl der Replikate für den Bucket country von drei auf fünf:curl -X PUT -H "Content-Type: application/json"

-d ’"props":"n_val":5’ http://192.168.178.33:8098/riak/countrySomit sind Daten in Riak hochverfügbar und single point of failure12 sind nicht mög-lich. Riak stützt sich dabei auf die Verfügbarkeit (availability) und Ausfalltoleranz(partition tolerance) des CAP-Theorem13. Die Konsistenz der Daten ist somit inRiak zweitrangig, wodurch die Daten erst nach einer unbestimmten Zeit konsistentvorliegen. Das von Riak verwendete Konsistenzmodell bezeichnet man als BASE14.

5.2.5 Bewertung

Vorteile:• bei der horizontalen Skalierung ist jeder Knoten gleichberechtigt, was single

point of failure ausschließt• Replikation und Lastverteilung erfolgt im Cluster automatisch• unidirektionale Beziehung können abgebildet und traversiert werden

Nachteile:• die Dokumentation von Riak ist besser als bei OrientDB, jedoch nicht sehr

umfangreich• eine gute Geschwindigkeit ist nur mit dem Einsatz von SSDs oder RAID-

Systemen zu erreichen• Java-API für nächste Version hat sich geändert und erfordert eine neue Eva-

luierung• Abfragen über Map/Reduce-Verfahren sind laut Meinung des Autors sehr um-

ständlich und erfordern Kenntnisse in JavaScript oder ErlangRiak ist eine gute Datenbank, wenn Verfügbarkeit wichtiger als Konsistenz ist. Durchdas Map/Reduce-Verfahren ist es möglich, komplexe Anfragen zu formulieren und11http://curl.haxx.se12unter single point of failure versteht man, wenn ein Ausfall eines einzelnen Knotens den Ausfall

des gesamten Systems verursacht13das CAP-Theorem bedeutet, (C)onsisteny (A)vailability (P)artition tolerance und besagt, dass

ein verteiltes System lediglich zwei dieser Kompetenzen vollständig umsetzen kann14(B)asically (A)vailable (S)oft State (E)ventually Consistent [EFHB10, S. 33]

Benjamin Lüdicke Seite 41 von 95

Page 47: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

innerhalb der Knoten ausführen zu lassen. Jedoch sind die dafür notwendigen Funk-tionen umständlich zu erstellen.

5.3 PostgreSQLPostgres wurde von 1986 bis 1994 an der UCB15 entwickelt. Danach nahm die FirmaIllustra Information Technologies16 den Quellcode und kommerzialisiert diesen. DieEinstellung des Projekt an der UCB erfolgte im gleichen Jahr, weil die Wartungdes Quellcodes zunehmend Zeit in Anspruch nahm. Die zwei Doktoranden AndrewYu und Jolly Chen entwickelten für Postgres einen SQL Interpreter und veröffent-lichten Postgres95 als Open-Source. 1996 wurde Postrges in PostgeSQL umbenannt,damit die Verwendung von SQL klar zum Ausdruck kommt. PostgreSQL gilt als sehrstabile Datenbank und wird von vielen Instituten eingesetzt [Posb]. Aufgrund des-sen ist der Autor der Meinung, dass PostgreSQL als relationale Datenbank, für dieVerwendung innerhalb des neuen Informations- und Planungssystems, zu evaluierenist. In den folgenden Abschnitten werden auf die CRUD-Operation, das Erstellenvon Backups und Replikation eingegangen. Das relationale Datenmodell ist im Ab-schnitt 2.4.1 beschrieben, weshalb in diesen Kapitel nicht näher drauf eingegangenwird. Abschließend erfolgt eine Bewertung der getesteten Datenbank, welche in derVersion 9.0.4 vorliegt.

5.3.1 CRUD

Anders als bei den bisher vorgestellten Datenbanken hat PostgreSQL keine exklu-sive API, um auf die Datenbank zuzugreifen, sondern ermöglicht das Verwendeneines JDBC-Treiber17. ”JDBC ist ein Java-Standard [...] zum datenbankunabhän-gigen Zugriff auf relationale Datenbanken“ [Kud07, S. 168]. Durch die Verwendungeines standardisierten Treiber ist es möglich, Anwendungen zu entwickeln die flexibelzwischen verschiedenen Datenbanken wechseln können, ohne das der Quellcode starkangepasst werden muss. In diesem Abschnitt wird vorgestellt, wie über JDBC eineVerbindung zu PostgreSQL aufgebaut wird und die CRUD-Operationen umzusetzensind.

Inbetriebnahme

Die in diesem Abschnitt verwendete Beispielanwendung ist die gleiche wie in Ab-schnitt 5.1.2 beschrieben. Um in PostgreSQL die CRUD-Operationen vorzustellen,muss ein Datenbankschema vorhanden sein. Bevor dies jedoch angelegt werden kann,is es notwendig zunächst eine Datenbank mit folgendem Befehl zu erstellen:

createdb -U postgres beispieldatenbank

15University of California at Berkeley16Illustra Information Technologies fusionierte später mit Informix, welches seit 2001 zu IBM

gehört17Java Database Connectivity

Benjamin Lüdicke Seite 42 von 95

Page 48: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

Die vom Nutzer postgres erstellte Datenbank hat den Namen beispieldatenbankund in dieser kann im nächsten Schritt das Datenbankschema erstellt werden. Fallsdas Schema später nochmal verwendet oder abgeändert werden soll, kann dies ineiner SQL-Datei abgespeichert werden. In Listing 5.12 sind die, für das Erstellendes Schemas, notwendigen DDL-Befehle dargestellt.

1 CREATE TABLE country (2 name VARCHAR (50) PRIMARY KEY ,3 population INTEGER4 );5

6 CREATE TABLE city (7 city_id SERIAL PRIMARY KEY ,8 country_fk VARCHAR (50) REFERENCES country ON DELETE

CASCADE ,9 name VARCHAR (50)

10 );11

12 CREATE TABLE address (13 address_id SERIAL PRIMARY KEY ,14 city_fk INTEGER REFERENCES city ON DELETE CASCADE ,15 street VARCHAR (50)16 );17

18 CREATE TABLE company (19 company_id SERIAL PRIMARY KEY ,20 address_fk INTEGER REFERENCES address ,21 name VARCHAR (50)22 );23

24 CREATE TABLE employee (25 employee_id SERIAL PRIMARY KEY ,26 address_fk INTEGER REFERENCES address ,27 company_fk INTEGER REFERENCES company ,28 name VARCHAR (50)29 );

Listing 5.12: Datenbankschema für die Beispieldatenbank in PostgreSQL

Eine Besonderheit beim Anlegen des Schemas, ist die Verwendung des DatentypsSERIAL. Dieser veranlasst PostgreSQL eine Sequenz zu erstellen, welche einen Integer-Wert beim hinzufügen eines neuen Tupel mit eins akkumuliert. Ferner sind die ge-nerierten Integer-Werte eindeutig, weswegen sie als Primärschlüssel definiert sind.Damit eine Beziehung zwischen den Tabellen hergestellt werden kann, verweisenFremdschlüssel auf die Primärschlüssel einer anderen Tabelle, wie es in den Zeilen8, 14, 20, 26 und 27 zu erkennen ist. Sofern einer Referenz der Befehl ON DELETECASCADE angehängt ist, wird das Ändern oder Entfernen von Primärschlüsseln andie Tupel, welche auf die betroffenen Primärschlüssel verweisen, weitergegeben.

Benjamin Lüdicke Seite 43 von 95

Page 49: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

Create

Im Listing 5.13 ist auszugsweise dargestellt, wie Daten in PostreSQL hinzugefügtwerden können.

1 val dbDriver = Class. forName ("org. postgresql .Driver")2 val url = "jdbc:postgresql: //192.168.178.41 :5432/

beispieldatenbank "3 val user = " postgres "4 val password = " password "5 val connection = DriverManager . getConnection (url , user ,

password )6

7 [...]8

9 def create () = {10 // Insert countries11 val countryStmt : PreparedStatement = connection .

prepareStatement ("INSERT INTO country (name ,population ) VALUES (?, ?)")

12 countryStmt . setString (1, " Germany ")13 countryStmt .setInt (2, 81000000)14 countryStmt . execute ()15

16 // Insert cities17 val cityStmt : PreparedStatement = connection .

prepareStatement ("INSERT INTO city ( country_fk ,name) VALUES (?, ?)")

18 cityStmt . setString (1, " Germany ")19 cityStmt . setString (2, "Berlin")20 cityStmt . execute ()

Listing 5.13: Create in PostgreSQL mit JDBC-Treiber

Für den Verbindungsaufbau zu dem PostgreSQL-Server ist es notwendig, den Na-men des verwendeten JDBC-Treiber und den Pfad zum Server festzulegen. Fernermuss von einem autorisierten Nutzer der Benutzername und das Passwort angege-ben werden. Diese Parameter werden in den Zeilen 2 bis 4 festgelegt und in Zeile5, der Methode getConnection(<url, <username>, <password>), übergeben. Diesomit eingerichtete Verbindung wird in den folgenden Codebeispielen für die Ma-nipulation der erstellten Tabellen verwendet. In Zeile 11 wird ein SQL-String derMethode prepareStatement(<sqlString>) übergeben. Die im String enthaltenen? müssen im folgenden durch gültige Werte ersetzt werden. Durch die Verwendungvon prepareStatement wird serverseitig ein Objekt erzeugt, welches alle benötig-ten Parameter für die Ausführung des SQL-Strings analysiert. Durch das einmaligeGenerieren des Objekts und dessen Wiederverwendung, kann die Leistung von Post-greSQL optimiert werden [Posa]. In den Zeilen 12 und 13 werden die Werte für dieAttribute name und population gesetzt. Der Befehl execute() führt das State-

Benjamin Lüdicke Seite 44 von 95

Page 50: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

ment aus. Die Verbindung zwischen den Tabellen country und city wird durch dasangeben des Fremdschlüssels in Zeile 18 erreicht.

Read

In diesem Abschnitt wird gezeigt, wie die zuvor erstellten Daten wieder aus Postgre-SQL abgefragt werden können (siehe Listing 5.14). Dabei wird wie im Abschnitt 5.3.1beschrieben, ein PreparedStatement erzeugt. Ziel der Abfrage ist es, alle Länderauszugeben, welche eine größere Einwohnerzahl als 70 Millionen haben.

1 def read () = {2 val readStmt : PreparedStatement = connection .

prepareStatement ("SELECT * FROM country WHEREpopulation > 70000000 ")

3 val resultSet: ResultSet = readStmt . executeQuery ()4 val resultSetMetaData : ResultSetMetaData = resultSet .

getMetaData ()5 val columns = resultSetMetaData . getColumnCount6 while ( resultSet .next) {7 for (column <- 1 to columns ){8 print( resultSet . getObject (column). toString + "\t"

)9 }

10 println ()11 }12 }

Listing 5.14: Read in PostgreSQL mit JDBC-Treiber

In der Zeile 3 wird das Statement mit dem Befehl executeQuery() ausgeführt undein Objekt vom Typ ResultSet zurückgegeben. Da dem Statement ein String über-geben wurde, ist nicht klar welche Struktur die zurückgegeben Daten haben. Es istlediglich bekannt, dass im ResultSet eine Menge von Tupeln enthalten sind. Um einkomplettes Tupel auszugeben, muss zuvor die Anzahl der zurückgegebenen Spaltenermittelt werden (siehe Zeile 5). In den beiden Schleifen wird dann jedes Tupel derzurückgelieferten Ergebnismenge, mit allen Attributen, ausgegeben. Ferner könntejedes Tupel in ein passendes Objekt abgespeichert werden. Die aus Sicht des Autorsumständliche Umwandlung der Ergebnismenge in Java-Objekte wird als impendancemismatch bezeichnet [Kud07, S. 153].

Update

Ein Update wird, wie zuvor auch ein Create oder Read, über das PreparedStatementdurchgeführt. In Listing 5.15 ist dargestellt, wie die Einwohnerzahl von Deutschlandauf 82 Millionen gesetzt wird. Eine Besonderheit ist das Ausführen des Statementdurch die Methode executeUpdate(). Diese Methode liefert als Rückgabewert einenInteger, welche aussagt wie viele Tupel von dem Update betroffen waren.

Benjamin Lüdicke Seite 45 von 95

Page 51: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

1 def update () = {2 val updateStmt : PreparedStatement = connection .

prepareStatement ("UPDATE country SET population =82000000 WHERE name = ’Germany ’")

3 val affected: Int = updateStmt . executeUpdate ()4 println ( affected + " row(s) affected ")5 }

Listing 5.15: Update in PostgreSQL mit JDBC-Treiber

Delete

Das Löschen von Tupeln erfolgt ebenso wie das Update, welches im Abschnitt 5.3.1beschrieben wurde. Lediglich der SQL-String unterscheidet sich wie in Listing 5.16zu erkennen ist.

1 def delete () = {2 val updateStmt : PreparedStatement = connection .

prepareStatement ("DELETE FROM employee WHERE name= ’Steve ’")

3 val affected: Int = updateStmt . executeUpdate ()4 println ( affected + " row(s) affected ")5 }

Listing 5.16: Delete in PostgreSQL mit JDBC-Treiber

5.3.2 Backup

Ein Backup kann in PostgreSQL auf verschiedene Art und Weise durchgeführt wer-den. Die einfachste Möglichkeit ist das Erzeugen einer Textdatei, in der alle Tabelleninklusive deren Inhalte abgelegt sind. Diese Textdatei wird in PostgreSQL als Text-Dump bezeichnet. Um ein Text-Dump zu erzeugen, muss die Datei pg_dump im /binVerzeichnis der PostgreSQL-Installation wie folgt aufgerufen werden:

pg_dump –file=dump.sql beispieldatenbankIn diesem Beispiel wird die Datenbank beispieldatenbank gesichert und das Text-Dump dump.sql im Verzeichnis /bin hinterlegt. Für das Wiederherstellen der Da-ten, muss folgender Befehl verwendet werden:

psql -f dump.sql beispieldatenbankBei der Wiederherstellung ist sicherzustellen, dass die Datenbankbeispieldatenbank in PostgreSQL existiert [Posa]. Eine andere Möglichkeit einBackup zu erstellen, ist das Verwenden der sogenannten WAL-Archivierung18. Beidiesem Verfahren werden alle Schreiboperationen im Datenbanksystem aufgezeich-net und können bei Bedarf wiederholt werden. Um die WAL-Archivieung nutzen18Write-Ahead-Log

Benjamin Lüdicke Seite 46 von 95

Page 52: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

zu können, muss in der Datei postgresql.conf die Variable archive_mode aufden Wert on gesetzt und Postgre-SQL neu gestartet werden. Weil bei der WAL-Archivierung nur die Schreiboperationen und nicht der derzeitige Datenbestand ge-sichert wird, muss eine Basis-Sicherung durchgeführt werden. Durch den Befehl:

psql -c ";SELECT pg_start_backup(’Backup’)";wird in PostgreSQL der Backup-Modus für Basis-Sicherung gestartet. Dies ist wich-tig, um einen doppelten Zugriff auf das Datenverzeichnis /data zu unterbinden. Derin Klammern angegebene String, ist lediglich ein Hinweis zu dem Backup und kannbeliebigen Text enthalten. Ist der Backup-Modus gestartet, kann eine Sicherung desDatenverzeichnis erfolgen. Nachdem das Kopieren abgeschlossen ist, beendet derBefehl:

psql -c ";SELECT pg_stop_backup()";den Backup-Modus. Anschließend muss das Verzeichnis pg_xlog, in welchem sichdie aufgezeichneten Schreiboperationen befinden, gesichert werden. Vorteil gegen-über der zuerst vorgestellten Variante ist, dass so auch inkrementelle Sicherungenmöglich sind, die bei einer größeren Datenbank das Datenvolumen der Sicherungenreduzieren [EH09, S. 85 ff.].

5.3.3 Replikation

In PostgreSQL ist es seit der Version 9 möglich eine Replikation auf mehrere Standby-Server19 durchzuführen. Um die Replikation auf einen Standby-Server zu ermögli-chen, müssen folgende Schritte durchgeführt werden:

1. Anpassen der Datei postgresql.confa) listen_address = ’192.168.178.42’b) wal_level = hot_standbyc) max_wal_senders = 1

2. Anpassen der Datei pg_hba.confa) host replication all 192.168.178.42/32 trust

3. Erstellen einer Basissicherung (siehe Abschnitt 5.3.2) auf Primär-Servers unddieses anschließend auf den Standby-Server kopieren

4. im Datenverzeichnis des Standby-Server die Datei recovery.conf erstellenund anpassena) standby_mode = ’on’b) primary_conninfo = ’host=192.168.178.41’

5. Starten des Standby- und Primär-ServersIm Punkt eins wird die Datei postgresql.conf angepasst, wobei die IP-Adressender jeweiligen Standby-Server anzugeben sind. Der Wert hot_standby erlaubt esdem Nutzer auf den Standby-Server lesend zuzugreifen und mit wal_senders wirddie Anzahl dieser festgelegt. Weil der Standby-Server die Erlaubnis haben muss

19ein Standby-Server übernimmt die Aufgaben des Primär-Servers, wenn dieser ausfällt

Benjamin Lüdicke Seite 47 von 95

Page 53: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

auf den Primär-Server zuzugreifen, ist in der Datei pg_hba.conf die Zeile unterPunkt 2. b) anzugeben. Das Schlüsselwort replication signalisiert, dass die einge-hende Verbindung für die Replikation der Daten genutzt wird. Ferner braucht derStandby-Server keine Zugangsdaten für die Verbindung angeben, da das Schlüssel-wort trust gesetzt ist. Nachdem die Basissicherung auf dem Standby-Server kopiertwurde, muss die Datei recovery.conf angelegt werden. Die darin enthaltenen An-gaben veranlassen PostgreSQL als Standby-Server zu starten und eine Verbindungmit dem Primär-Server einzugehen [Posc].PostgreSQL unterstützt bei der eben vorgestellten Replikation keine horizontaleSkalierung. Durch Plugins, wie zum Beispiel Slony-I, kann PostgreSQL jedoch soerweitert werden, dass eine horizontale Skalierung umgesetzt werden kann. Slony-Inutzt dafür, wie auch OrientDB, das Master-Slave Prinzip, wobei alle Schreibope-rationen über den Master-Knoten durchgeführt werden. Leseoperationen werden andie Slave-Knoten verteilt, wodurch eine gleichmäßige Auslastung der Server erreichtwird. Aufgrund der hohen Komplexität bei der Einrichtung von Slony-I, wird diesin dieser Master-Thesis nicht demonstriert und auf die Homepage20 von Slony-Iverwiesen.

5.3.4 Bewertung

Vorteile:• ausführliche Dokumentation• benutzt SQL als Abfragesprache und ist somit für viele Anwender bekannt• da ein JDBC-Treiber vorhanden ist, muss beim Wechsel zu einer anderen Da-

tenbank, die einen JDBC-Treiber anbietet, der Quellcode nur minimal ange-passt werden

• liegt in einer stabilen Version vor• Beziehungen können einfach über Fremdschlüssel abgebildet werden

Nachteile:• Replikation ist umständlicher, als bei den vorgestellten NoSQL Datenbanken,

einzurichten• horizontale Skalierung ist nur durch zusätzliche Plugins möglich, welche eben-

falls einen hohen Konfigurationsaufwand habenBei der Evaluierung von PostgreSQL, sind bei den CRUD-Operationen keine Fehleraufgetreten und alle Beispiele funktionierten wie auf der Homepage und im Wikibeschrieben. Ferner konnten alle Beispiele für die Replikation nachvollzogen undumgesetzt werden. Aufgrund dessen ist der Autor der Meinung, dass PostgreSQLeine sehr gute Dokumentation hat, welche wichtig für zukünftige Mitglieder des Pro-jekt ”spirit@fhs“ ist. Beziehungen zwischen den Daten können durch das relationaleParadigma einfach umgesetzt werden. Lediglich die Replikation und horizontale Ska-lierung ist aufwändig umzusetzen. Haben die Skalierung und Replikation nicht die

20http://slony.info/

Benjamin Lüdicke Seite 48 von 95

Page 54: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

höchste Priorität bei der Auswahl einer passenden Datenbank, ist PostgreSQL fürdas neue Informations- und Planungssystem gut geeignet.

5.4 EclipseLink als Object-Relational MapperWie im Abschnitt 2.3 bereits erwähnt, wird Mapper von Lift zukünftig durch Recordabgelöst. Eine Verwendung als ORM kommt deshalb in dieser Master-Thesis nicht inFrage. Da in Scala auch ORMs genutzt werden können, die für Java-Anwendungenentwickelt wurden, kann sowohl Hibernate21 als auch EclipseLink22 genutzt werden.In dieser Master-Thesis wird EclipseLink in der Version 2.3 verwendet, da es dieReferenzimplementierung für die JPA 2.023 darstellt und somit eine hohe Standard-konformität aufweist. EclipseLink basiert auf den ORM TopLink der Firma Oracleund wurde 2008 in der Version 1.0 veröffentlicht. Durch den Einsatz eines ORM gibtes keinen impendance mismatch zwischen der Datenbank und Scala. Ferner ist esmöglich Abfragen mittels Expressions zu abstrahieren, so dass keine SQL-Befehlevom Anwendungsprogrammierer erstellt werden müssen. Dies hat laut [Fou] gegen-über SQL folgende Vorteile:

• Expressions sind leichter zu Pflegen, da die Datenbank abstrahiert wird• Änderungen an Tabellen haben keine Einfluss auf die Abfragestruktur• Expressions machen Abfragen lesbarer• besteht zwischen zwei Tabellen eine Beziehung, können Attribute beider Ta-

bellen abgefragt werden - EclipseLink generiert dafür automatisch einen Join• Expressions verbergen die Komplexität von SQL-Abfragen

Wie im Abschnitt 5.3 zu sehen ist, muss ein Datenbankschema in PostgreSQL erstelltwerden, um Daten abspeichern zu können. Damit der Programmierer sich nichtzusätzlich mit der DDL auseinandersetzen muss, kann er EclipseLink das Schemaerstellen lassen. Dafür ist es notwendig EclipseLink das Datenmodell der Anwendungverständlich zu machen. Dies wird über Annotationen in den Klassen oder übereine externe XML-Datei ermöglicht. Beide Varianten haben Vor- und Nachteile.Entscheidet sich der Programmierer für Annotationen, wird der Quellcode wenigerlesbar und zusätzliche Abhängigkeiten werden geschaffen. Der Vorteil jedoch ist, dassAnnotationen leichter umzusetzen sind als die Definition des Schemas in einer XML-Datei zu hinterlegen. Ein weiterer Vorteil von EclipseLink ist, das die Möglichkeitbesteht ein Datenbankcluster zu erstellen, selbst wenn die verwendete Datenbankdies nicht unterstützt. Die Lastverteilung wird dabei ausschließlich von EclipseLinkübernommen.

21http://www.hibernate.org/22http://www.eclipse.org/eclipselink/23die Java-Persistence-API ist eine Schnittstelle zur Übertragung von Objekten zu einer realtio-

nalen Datenbank

Benjamin Lüdicke Seite 49 von 95

Page 55: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

5. Evaluierung möglicher Datenbanken Fachhochschule Schmalkalden SS 2011

5.5 Auswahl einer DatenbankIn den vorherigen Kapiteln wurden drei mögliche Datenbanken darauf hin unter-sucht, inwiefern diese sich für das neue Informations- und Planungssystem eignen.In allen drei Datenbanken ist die Darstellung von Beziehungen zwischen Objekten-typen einfach umzusetzen. Wobei OrientDB als Graphen-Datenbank besonders gutbidirektionale Beziehungen abbilden kann, müssen in den beiden anderen Datenban-ken dafür zusätzliche Beziehungen angelegt werden. Für die Manipulation und dasErstellen von Daten haben OrientDB und Riak jeweils eine eigene API bereitgestellt,welche laut Meinung des Autors nicht ausgereift sind. Insbesondere bei der API vonOrientDB sind dem Autor Fehler aufgefallen und das Map/Reduce-Verfahren vonRiak ist zu aufwändig bei der Programmierung. Der JDBC-Treiber von PostgreSQLdagegen ist ausgereift und alle Beispiele in der Dokumentation, sowie im Wiki, konn-ten umgesetzt werden. Zusätzlich ermöglicht der JDBC-Treiber die Verwendung vonEclipseLink als ORM. Die Dokumentation von PostgreSQL ist sehr ausführlich, wasbei der Einarbeitung neuer Mitglieder im Team ”spirit@fhs“ von Vorteil ist. EinNachteil von PostgreSQL gegenüber den anderen evaluierten Datenbanken ist, diekomplizierte Konfiguration der Replikation und horizontalen Skalierung. Aufgrunddessen, dass keine hohe Systemlast in dem neuen Informations- und Planungssys-tem zu erwarten ist, entscheidet sich der Autor für PostgreSQL, in Verbindung mitEclipseLink, als Datenbankmanagementsystem.

Benjamin Lüdicke Seite 50 von 95

Page 56: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

6 Festlegen des DatenmodellIn diesem Abschnitt wird das Datenmodell für das neue Informations- und Pla-nungssystem vorgestellt. Als Grundlage dienen die im Abschnitt 3 erstellte Miniwelt,sowie die Anwendungsfalldiagramme. In der Miniwelt und den Anwendungsfalldia-grammen ist jedoch nicht ersichtlich, welche Eigenschaften die einzelnen Objekterepräsentieren. In der Abbildung 6.1 sind die Objekttypen1 mit ihren Beziehungabgebildet und werden im folgenden erläutert. Zu erwähnen ist, dass das in diesemKapitel vorgestellte Datenmodell in Zusammenarbeit mit den Teammitgliedern desProjekts “spirit@fhs” entstand, um möglichst allen Forderungen der Teilprojektegerecht zu werden.

Abbildung 6.1: Eigene Darstellung des Datenmodell des zu entwickelndenInformations- und Planungssystems

1“Ein Objekttyp ist eine durch einen Objekttyp-Namen eindeutige benannte Klasse von Objek-ten, über die dieselben Informationen gespeichert werden und die in prinzipiell gleicher Weiseverarbeitet werden” [Jar10, S. 31].

Benjamin Lüdicke Seite 51 von 95

Page 57: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

6. Festlegen des Datenmodell Fachhochschule Schmalkalden SS 2011

6.1 EventIn der Tabelle 6.1 sind die Eigenschaften des Objekttyp Event aufgelistet. Das At-tribut titleShort repräsentiert die Abkürzung der Titelbeschreibung. Somit istes möglich bei der Darstellung im Browser oder auf dem Handy Platz zu sparenund somit Komponenten besser anzuordnen. Sollte die Abkürzung nicht aussage-kräftig genug sein, kann auch die komplette Bezeichnung ausgegeben werden. Wiein der Miniwelt (siehe Abbildung 4.1) dargestellt, existieren verschiedene Events.Aufgrund dessen, dass alle Events eine ähnliche Struktur aufweisen, wurden diesein einem Objekttyp zusammengefasst und anhand des Attributs event_type unter-schieden. Durch das neue Informations- und Planungssystem soll es möglich sein,auch auf den Stundenplan und einzelne Events vergangener Semester zuzugreifen.Damit alte und aktuelle Events unterschieden werden können, definiert die Eigen-schaft expireDate ein Datum an dem die Vorlesung verfällt und diese nicht mehrunter aktuellen Events aufgelistet wird. Ferner können Events aufgelistet werden diekeine Termine haben, aber dennoch bis zu einem bestimmten Datum gültig sind.

Eventevent_id jedes Event ist eindeutig durch eine ID zu identifizierenevent_type legt fest, um welchen Typ es sich handelt - folgende mög-

liche Werte sind festgelegt: Lecture, Tutorial, Lesson,Other

titleShort kurz ist die Abkürzung eines Events - diese wurde imalten Stundenplan angezeigt

titleLong ist die ausgeschriebene Bezeichnung eines EventsexpireDate gibt an, wann ein Event verfallen ist

Tabelle 6.1: Objekttyp Event

6.2 AppointmentDie Eigenschaften des Objekttyp Appointment sind in der Tabelle 6.2 dargestellt.Ein Appointment ist ein Termin für ein bestimmtes Event. Dabei kann ein Eventkeinen oder mehrere Appointments haben. Durch die Attribute startAppointmentund endAppointment wird bestimmt, wie lange ein Appointment dauert. Der Vor-teil dabei ist, dass es keine festen Raster gibt, in die ein Appointment passen muss.Ferner können einzelne Termine verschoben und Änderungen durch das Attributstatus nachvollzogen werden. Somit ist es möglich jedes einzelne Event im Stun-denplan zu planen und anzupassen. Ein statischer Stundenplan, wie er im Momentexistiert, wäre laut Meinung des Autors überflüssig. Auch die Veröffentlichung vonTerminänderungen über News können damit entfallen.

Benjamin Lüdicke Seite 52 von 95

Page 58: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

6. Festlegen des Datenmodell Fachhochschule Schmalkalden SS 2011

Appointmentappointment_id jedes Appointment ist eindeutig durch eine ID zu iden-

tifizierenstartAppointment bestimmt wann ein Appointment beginnt

(yyyyMMddHHmmss)endAppointment kurz bestimmt wann ein Appointment beendet ist

(yyyyMMddHHmmss)status repräsentiert den derzeitigen Status - dieser kann sein

ok, cancelled oder moved

Tabelle 6.2: Objekttyp Appointment

6.3 LocationIn der Tabelle 6.3 ist der Objekttyp Location dargestellt. Eine Location ist anhandder Attribute building und room eindeutig zu identifizieren. Die Location dient alsTreffpunkt für die Events und kann von Appointment zu Appointment variieren.

Locationbuilding ist die Bezeichnung eines Gebäudesroom ist die Bezeichnung eines Raumes

Tabelle 6.3: Objekttyp Location

6.4 DegreeClassDer Objekttyp DegreeClass (siehe Tabelle 6.4) ermöglicht das Erstellen einer Baum-struktur, um die Kurse der Fakultät Informatik abzubilden. Dies ermöglicht einerKlasse mehrere Untergruppen hinzuzufügen, wobei jede Untergruppe wieder Unter-gruppen haben kann. Da an der Fakultät derzeitig nur Kurse Untergruppen habenkönnen, kann das Attribut classType folgende Werte annehmen: Class oder Group.Durch dieses Attribut ist eine schnelle Filterung nach Gruppen oder Kursen möglich.Ferner hat ein DegreeClass-Objekt beliebig viele Mitglieder (Objekttyp Member) undnimmt an beliebig vielen Veranstaltungen (Objekttyp Event) teil.

DegreeClassclass_id jedes DegreeClass Objekt ist durch diese ID eindeutig

zu identifizierenmail ist die E-Mail der jeweiligen Gruppe oder Klassetitle ist die Bezeichnung der Gruppe oder KlasseclassType bestimmt ob es sich um eine Gruppe oder Klasse handelt

- mögliche Werte sind Class oder Group

Tabelle 6.4: Objekttyp DegreeClass

Benjamin Lüdicke Seite 53 von 95

Page 59: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

6. Festlegen des Datenmodell Fachhochschule Schmalkalden SS 2011

6.5 MemberIn der Tabelle 6.5 ist der Objekttyp Member abgebildet. Ein Member ist ein Mit-glied der Fachhochschule Schmalkalden. Aufgrund der sehr ähnlichen Struktur vonDozenten, Studenten und anderen Mitgliedern sind diese in einem Objekttyp zu-sammengefasst. Die Unterscheidung der einzelnen Mitglieder wird durch das Attri-but memberType vorgenommen. Ein Member hat die Möglichkeit an beliebig vie-len Events teilzunehmen und kann mehreren Klassen oder Gruppen (ObjekttypDegreeClass) angehören.Eine Besonderheit bei dem Objekttyp Member ist die Verbindung zum Objekt-typ Event, welche über den Objekttyp MemberEvent erfolgt. MemberEvent ist eineKreuztabelle mit dem zusätzlichen Attribut qualifier, welches eine Unterschei-dung zwischen den Vorlesenden und den Zuhörern ermöglicht. Ferner wird in dieserTabelle der persönliche Stundenplan der Member hinterlegt.

Memberfhs_id jeder Member ist durch seine fhs_id eindeutig zu iden-

tifizierendisplayedName ist der Name, welche beim Erstellen einer News oder

eines Kommentars angezeigt wirdmemberType legt den Typ fest - folgende Werte sind möglich:

Lecturer oder Student

Tabelle 6.5: Objekttyp Member

6.6 NewsÜber News können Nachrichten auf der Homepage der Fachhochschule Schmalkaldenveröffentlicht werden. In der Tabelle 6.6 sind die Attribute einer Nachricht aufge-listet. Beim Erstellen einer Nachricht wird das Erstellungsdatum in den AttributencreationDate und lastModified gespeichert. Unterscheiden sich die Werte der bei-den Attribute, ist im Attribut lastModiefied zu erkennen, wann News das letztemal bearbeitet wurden. Ferner kann eine News nur von einem Mitglied der Fach-hochschule Schmalkalden erstellt werden und kann beliebig viele Kurse betreffen.

Benjamin Lüdicke Seite 54 von 95

Page 60: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

6. Festlegen des Datenmodell Fachhochschule Schmalkalden SS 2011

Newsnews_id jede News ist durch eine ID eindeutig zu identifizierencreationDate gibt an wann die News erstellt wurdeexpireDate legt fest wann eine News verfallen und somit nicht mehr

gültig isttitle ist der Betreff einer NewslastModified gibt an wann eine News das letzte mal bearbeitet wurdecontent ist der Inhalt der News

Tabelle 6.6: Objekttyp News

6.7 NewsCommentDer Objekttyp NewsComment ermöglicht das Speichern von Kommentaren zu einerbestimmten Nachricht (Objekttyp NewsComment), dabei wird beim Anlegen einesKommentars das Erstellungsdatum im Attribut creationDate abgespeichert. Fernerkann ein Kommentar nur von einem Mitglied der Fachhochschule Schmalkaldenerstellt werden.

NewsCommentnewsComment_id jeder Kommentar ist durch eine ID eindeutig zu identi-

fizierencreationDate gibt an wann der Kommentar erstellt wurdecontent ist der Inhalt des Kommentars

Tabelle 6.7: Objekttyp NewsComment

Benjamin Lüdicke Seite 55 von 95

Page 61: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

7 RealisierungIn diesem Kapitel wird die Funktionsweise des Datenbank-Service erläutert. Fernerwird dargestellt, wie die REST-Schnittstelle aufgebaut ist und das Datenmodell inden Datenbank-Service integriert wird.

7.1 GrobentwurfIn diesem Abschnitt soll die Funktionsweise des Datenbank-Service verdeutlicht wer-den. Ziel des Datenbank-Service ist es, die dahinter liegende Datenbank zu kapselnund somit austauschbar zu machen. Durch die Verwendung von EclipseLink, kannPostgreSQL durch eine andere relationale Datenbank, die einen JDBC-Treiber an-bietet, ausgetauscht werden. Die Verwendung einer beliebigen Datenbank, ist je-doch nicht ohne Weiteres möglich. Damit auch andere Datenbanken verwendet wer-den können, muss die REST-Schnittstelle und das Datenmodell von der Datenbankunabhängig sein. Dies wird durch das Fabrik-Entwurfsmuster und Komposition er-reicht. Ferner werden XML und JSON als Datenübertragungsformate unterstützt,wobei der Datenbank-Service intern ausschließlich mit JSON-Dokumenten arbeitet.Somit muss bei eingehenden Verbindungen eine Konvertierung von XML zu JSONund umgekehrt bei ausgehenden Verbindungen durchgeführt werden, sofern XMLals Datenübertragungsformat gefordert ist. Aufgrund dessen, dass unterschiedlicheDatenbanksysteme auch unterschiedliche Fehlermeldungen ausgeben können, müs-sen diese abgefangen und gekapselt werden. Dabei wird sichergestellt, dass der Clientunabhängig vom verwendeten Datenbanksystem stets die gleichen Fehlermeldungenempfängt. Der Ablauf einer eingehenden Anfrage an den Datenbank-Service ist imAktivitätsdiagramm 7.1 dargestellt.

7.2 FeinentwurfBeim Feinentwurf wird festgelegt welche Klassen für den Datenbank-Service de-klariert werden müssen. Anhand von Klassendiagrammen wird erläutert wie derDatenbank-Service umgesetzt werden kann, wobei die Kapselung des Datenmodellsund der REST-Schnittstelle im Fokus des Entwurfs liegen. Die Beschreibung derKlassen und ihre Aufgaben wird ebenfalls vorgenommen.

7.2.1 REST-Schnittstelle des Datenbank-Service

In diesem Abschnitt wird die Struktur der Rest-Schnittstelle erläutert. Die benötig-ten Klassen, um die Schnittstelle vom Datenmodell zu kapseln, sind in Abbildung 7.2

Benjamin Lüdicke Seite 56 von 95

Page 62: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

7. Realisierung Fachhochschule Schmalkalden SS 2011

Abbildung 7.1: Verarbeiten einer eingehenden Anfrage beim Datenbank-Service

dargestellt. Im folgenden werden die einzelnen Klassen vorgestellt und deren Bezie-hungen miteinander beschrieben.

Die Klasse ServiceApi

Die Klasse ServiceApi legt die URLs für die jeweiligen Ressourcen fest. Um ver-schiedene Operationen auf einer Ressource ausführen zu können, werden die http-Methoden PUT, GET, POST und DELETE (siehe Tabelle 2.1) angeboten. Ferner wirdin dieser Klasse die Uhrzeit und das Datum gespeichert, wenn neue Nachrichtenhinzugefügt oder geändert werden. Somit können Clients den Zeitpunkt der letztenÄnderung abfragen und sich die neue Nachricht schicken lassen.

Die abstrakte Klasse Invoke

Die abstrakte Klasse Invoke beinhaltet die Methode invoke(), welche die Methodestart() kapselt und somit doppelten Code vermeidet, in dem die Fehlerüberprüfungnur einmal implementiert werden muss (Strategie-Entwurfsmuster). Die Methodestart() hat als Übergabeparameter eine Funktion, welche den eigentlich Aufrufder gewünschten Ressource enthält und wird in den Basisklassen überschrieben.

Benjamin Lüdicke Seite 57 von 95

Page 63: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

7. Realisierung Fachhochschule Schmalkalden SS 2011

Abbildung 7.2: Klassendiagramm der REST-Schnittstelle des Datenbank-Service

Die Klassen WithBody und WithoutBody

WithBody und WithoutBody sind Subklassen von Invoke. Der Unterschied beiderKlassen besteht lediglich darin, dass bei WithBody eine Überprüfung des http-Headerauf den Content-Type stattfindet und anschließend eine Konvertierung des http-Body in das JSON-Format durchgeführt wird. In der Klasse WithoutBody ist dasnicht notwendig, da diese nur bei lesenden Aufrufen verwendet wird und somit Datenaus dem http-Body nicht relevant sind. Die Funktion, welche als Übergabeparameterbei der Methode start() angegeben werden muss, entspricht der Signatur von denMethoden in der Klasse DBConnector.

Die Klasse DBConnector

Die Klasse DBConnector liegt zwischen dem Datenmodell und der REST-Schnitt-stelle. Als Parameter bekommt der Konstruktor ein Objekt der Klasse DAOFactory.Die Methoden von DBConnector werden in der Klasse ServiceApi an die SubklassenWithBody und WithoutBody übergeben. In den Methoden wird von der übergebe-

Benjamin Lüdicke Seite 58 von 95

Page 64: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

7. Realisierung Fachhochschule Schmalkalden SS 2011

nen Fabrik ein DAO-Objekt angefordert und somit auf die Daten der Datenbankzugegriffen.

Die abstrakte Klasse DAOFactory

Diese Klasse dient als Fabrik und gibt über die Methode getDAOFactory() eine Sub-klasse zurück. Diese Subklasse überschreibt alle Methoden, welche eine Schnittstelleaus dem Paket DAOInterfaces als Rückgabeparameter haben. Durch diese Schnitt-stellen werden die CRUD-Operationen abstrahiert und können für jede Klasse desDatenmodells angepasst werden.

Abbildung 7.3: Klassendiagramm des eingebundenen Datenmodells in denDatenbank-Service

Benjamin Lüdicke Seite 59 von 95

Page 65: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

7. Realisierung Fachhochschule Schmalkalden SS 2011

7.2.2 Einbinden des Datenmodells in den Datenbank-Service

In diesem Abschnitt wird erläutert wie das ausgearbeitete Datenmodell in denDatenbank-Service integriert wird. In der Abbildung 7.3 ist das Klassendiagrammabgebildet, wobei zugunsten der Übersicht die Beziehungen zwischen den Klassendes Datenmodells nicht dargestellt wurden. Jedoch sind diese implementiert und ent-sprechen denen aus der Abbildung 6.1. Ferner ist die Klasse EclipseLinkDAOFactorydieselbe wie in Abbildung 7.2.

Das Paket DAOInterfaces

Das Paket DAOInterfaces beinhaltet alle Schnittstellen, welche dieCRUD-Operationen abbilden. Die Struktur der Schnittstelle NewsDAO ist in derAbbildung 7.3 als Hinweis dargestellt. Dabei ist zu erkennen, dass die CRUD-Operationen ein oder mehrere Objekte der Klasse News zurückliefern. Der Rückgabe-typ variiert zwischen den Schnittstellen, was an den Abhängigkeiten zu erkennen ist.Obwohl alle Schnittstellen die CRUD-Operationen beinhalten, wurde für jede Klassedes Datenmodells eine Schnittstelle bereitgestellt, um diese individuell anpassen zukönnen. Dabei ist zu erwähnen, das lediglich die Schnittstelle DegreeClassDAO einezusätzlich Methode hat, um alle Unterklassen (Kurse und Gruppen) einer bestimm-ten Klasse zu ermitteln.

Die abstrakte Klasse AbstractPersistence

Von der Klasse AbstractPersistence werden alle Klassen abgeleitet, welche eineSchnittstelle aus dem Paket DAOInterface implementieren. Diese Klasse ist für dieAusführung von erstellten Expression verantwortlich und bekommt diese innerhalbeiner Funktion an die Methode invoke(f() => AnyRef) übergeben. Innerhalb derMethode invoke() wird die übergebene Funktion ausgeführt und mögliche Fehler-meldungen, durch EclipseLink oder PostgreSQL, werden abgefangen und in allge-meinere Fehlermeldungen umgewandelt.

Die EclipseLink DAO-Klassen

Alle Klassen, welche die Schnittstellen des Pakets DAOInterfaces implementieren,sind für das Erstellen von Expressions verantwortlich. Dabei werden Parameter,die der URL mitgegeben wurden als Filter verwendet, um die zurückzusendendeDatenmenge einzugrenzen. Ferner wird überprüft, ob semantische Vorbedingungenerfüllt werden. Zum Beispiel darf eine Nachricht nur von demjenigen bearbeitetwerden, der diese erstellt hat. Eine Zusammenfassung über alle URLs und derenFilter sind im Wiki1 aufgelistet und als Screenshot A.2, A.3 und A.4 im Anhang zufinden.

1https://pads.fh-schmalkalden.de/wiki/spirit/database/specification

Benjamin Lüdicke Seite 60 von 95

Page 66: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

7. Realisierung Fachhochschule Schmalkalden SS 2011

7.2.3 Helfer-Klassen

In diesem Abschnitt werden Klassen vorgestellt, welche nicht direkt im Zusammen-hang mit dem Datenmodell oder der REST-Schnittstelle stehen. Diese Klassen sindin Abbildung 7.4 zusammengefasst.Die Schnittstelle FormatedException stellt eine allgemeine Struktur für Fehler-meldungen bereit. Die Methode getErrorAsJson() liefert ein JSON-String zu-rück, welcher bei einem Fehler an den aufrufenden Client gesendet wird. Fernerkann die Fehlermeldung über den Konstruktor geändert werden. Damit zusätzlichzu der Fehlermeldung auch der http-Header angepasst wird, muss die MethodegetHttpStatusCode() aufgerufen werden. Diese Statuscodes sind im RFC 2616spezifiziert und somit für alle Clients verständlich. In der folgenden Tabelle 7.1 sinddie im Datenbank-Service definierten Fehlermeldungen zusammengefasst.

Klasssenname BeschreibungFindByCriteriaException wenn die Ergebnismenge eines lesenden Da-

tenbankzugriffs leer istMappingException wenn die gesendete Datenstruktur an den

REST-Schnittstelle nicht auf das Datenmo-dell projiziert werden kann

PermissionException wenn versucht wird ein Datensatz zu ändernohne dessen Eigentümer/Ersteller zu sein

UnknownErrorException wenn unbekannte Fehler auftreten die nichtbehandelt werden, da noch keine eigene Klas-se für diese Fehlermeldung implementiert ist

UnsupportedOperationException wenn eine CRUD-Operation aufgerufen wirddie noch nicht implementiert ist

Tabelle 7.1: Fehlerklassen im Datenbank-Service

Die Klasse Helper passt das Datum an das ISO 8601 spezifiziert Format an. Weil beiden Abfrage-Parametern Leerzeichen als Wert nur umständlich zu erzeugen sind, istdas Datumsformat als yyyyMMddHHmmss festgelegt wurden. Beim senden als JSON-String jedoch, wird das ISO 8601 spezifizierte Format yyyy-MM-dd HH:mm:ss über-tragen, um das Datum besser lesbar zu machen. Ferner wird es in diesem Formatin der Datenbank abgespeichert. In der Klasse MyDB wird eine Instanz der Klas-se DAOFactory gehalten. Erzeugt wird die Instanz in der Klasse Boot, welche einAnpassen des Lift-Frameworks ermöglicht. Ferner wird in dieser Klasse die Http-Basic-Authentication umgesetzt.

Benjamin Lüdicke Seite 61 von 95

Page 67: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

7. Realisierung Fachhochschule Schmalkalden SS 2011

Abbildung 7.4: Helfer-Klassen des Datenbank-Service

Benjamin Lüdicke Seite 62 von 95

Page 68: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8 ImplementierungDieses Kapitel verdeutlicht, wie die REST-Schnittstelle im Datenbank-Service umge-setzt ist und wie Ressourcen durch die Http-Basic-Authentication geschützt werdenkönnen. Ferner wird erläutert wie PostgreSQL mittels EclipseLink an den Datenbank-Service gekoppelt sowie das Datenmodell zu PostgreSQL übertragen wird. Abschlie-ßend wird auf das Erstellen und Ausführen von Expressions anhand der KlassenELNewsDAO und AbstractPersistence eingegangen.

8.1 Die REST-Schnittstelle undHttp-Basic-Authentication

In diesem Abschnitt wird erläutert wie die REST-Schnittstelle mittels des Lift-Framework umgesetzt wird. Dabei werden die Klassen Boot, ServiceApi, Invokeund WithBody näher beschrieben. Das in Abbildung 7.2 dargestellte Klassendia-gramm, zeigt die Beziehung zwischen diesen Klassen.

8.1.1 Die Klasse Boot

Abbildung 8.1: Abbildung der Klasse Boot

Die Klasse Boot ist in Abbildung 8.1 dargestellt. Sie hat lediglich eine Methode,welche beim Starten des Datenbank-Service ausgeführt wird. Die Aufgabe dieserMethode besteht darin, die Umgebungsvariablen von Lift zu manipulieren und Nut-zerrollen für den Zugriff auf Ressourcen zu erstellen. Im Listing 8.1 ist die Methodeboot abgebildet.

1 def boot {2 val roles =3 AuthRole ("Admin",4 AuthRole (" Standard ")5 )6

Benjamin Lüdicke Seite 63 von 95

Page 69: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

7 LiftRules . httpAuthProtectedResource .append {8 //case Req(_ :: _, _, PutRequest) => roles.

getRoleByName (" Standard ")9 //case Req(_ :: _, _, PostRequest) => roles.

getRoleByName (" Standard ")10 //case Req(_ :: _, _, DeleteRequest) => roles.

getRoleByName (" Standard ")11 case Req(" protected " :: Nil , _, _) => roles.

getRoleByName (" Standard ")12 }13

14 LiftRules . authentication = HttpBasicAuthentication ("code") {

15 case (" Standard ", " Standard2011 ", req) =>16 userRoles ( AuthRole (" Standard "))17 true18 case ("Admin", " Admin2011 ", req) =>19 userRoles ( AuthRole ("Admin"))20 true21 }22

23 MyDB. factory = DAOFactory . getDAOFactory ( DAOFactory .ECLIPSELINK )

24 LiftRules . unloadHooks .append(MyDB. factory .closeConnection )

25

26 LiftRules . statelessDispatchTable .append( ServiceApi )27 }

Listing 8.1: Quellcode der Klasse Boot

In den Zeilen 2 bis 5 werden die Nutzerrollen für die Http-Basic-Authenticationfestgelegt. Dabei ist der Rolle Admin die Rolle Standard untergeordnet. Aufgrunddessen hat ein Nutzer mit der Rolle Admin mehr Rechte, als ein Nutzer mit der RolleStandard. In den Zeilen 7 bis 12 werden URLs an die Nutzerrollen gebunden, wo-bei in diesem Beispiel ausschließlich die Rolle Standard verwendet wird. Durch dieAngaben PutRequest, PostRequest, DeleteRequest werden alle Schreibzugriffe aufallen Ressourcen gesperrt und sind nur für Nutzer mit der Rolle Standard oder höhernutzbar. Weil nicht alle Clients derzeitig eine solche Authentifizierung unterstützen,ist zu Testzwecken nur eine bestimmte URL geschützt, wie in Zeile 11 zu erkennen ist.Abhängig davon auf welchen Host der Datenbank-Service läuft, könnte die geschütz-te URL zum Beispiel https://212.201.64.226:8443/fhs-spirit/protected lau-ten. Damit eine Ressource wirklich geschützt ist, müssen für die vorher definiertenNutzerrollen Zugangsdaten festgelegt werden. In den Zeilen 14 bis 20 ist zu erken-nen, dass die Nutzerrolle Standard das Passwort Standard2011 und die Nutzer-rolle Admin das Passwort Admin2011 haben, wobei die Benutzernamen der jeweili-gen Bezeichnung der Nutzerrolle entsprechen. In der Zeile 23 wird über die Fabrik

Benjamin Lüdicke Seite 64 von 95

Page 70: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

DAOFactory EclipseLink für die Persistenz ausgewählt. Ferner wird Lift eine Metho-de übergeben, welche beim herunterfahren des Datenbank-Service aufgerufen wird.Somit wird erreicht, dass die Verbindung zur Datenbank und EclipseLink ordnungs-gemäß beendet wird. Abschließend wird Lift so konfiguriert, dass keine Sessionsverwaltet werden und der Datenbank-Service somit als zustandslos gilt.

8.1.2 Die Klasse ServiceApi

Abbildung 8.2: Abbildung der Klasse ServiceApi

Das Objekt ServiceApi ist in Abbildung 8.2 abgebildet. Seine Aufgabe ist es, dieURLs für die Ressourcen zu definieren. Dabei wird nach den http-Methoden PUT,POST, GET und DELETE unterschieden. Im Listing 8.2 ist ein Auszug des Quellcodesvom Objekt ServiceApi dargestellt.

1 object ServiceApi extends RestHelper {2

3 println (" Konstruktor der Service API")4 val connector: DBConnector = new DBConnector (MyDB.

factory )5 val withoutBody : Invoke = new WithoutBody6 val withBody: Invoke = new WithBody7 var lastModifiedNews : java.util.Date = new java.util.

Date8

9 serve {10 case "news" :: " comment " :: Nil Put req => {11 lastModifiedNews = new java.util.Date12 withBody .invoke(req , req.params , 201, connector .

putNewsComment )13 }14 case "news" :: AsLong(news_id) :: " comment " :: Nil

Get req => {15 var params = req.params16 params += ("news_id" -> List(news_id. toString ))17 withoutBody .invoke(req , params , 200, connector .

getNewsComment )18 }19 case "news" :: " comment " :: Nil Get req => {

Benjamin Lüdicke Seite 65 von 95

Page 71: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

20 withoutBody .invoke(req , req.params , 200, connector .getNewsComment )

21 }22 case "news" :: " comment " :: AsLong( comment_id) :: Nil

Get req => {23 var params = req.params24 params += " comment_id" -> List( comment_id. toString )25 withoutBody .invoke(req , params , 200, connector .

getNewsComment )26 }27 }28 // Delete29 serve {30 case "news" :: " comment " :: AsLong( comment_id) :: Nil

Delete req => {31 var params = req.params32 params += " comment_id" -> List( comment_id. toString )33 withoutBody .invoke(req , params , 200, connector .

deleteNewsComment )34 }35 }36 //Post37 serve {38 case "news" :: " comment " :: AsLong( comment_id) :: Nil

Post req => {39 var params = req.params40 params += " comment_id" -> List( comment_id. toString )41 withBody .invoke(req , params , 201, connector .

postNewsComment )42 }43 case _ => NotFoundResponse ("Bad URI")44 }45 }

Listing 8.2: Auszug des Quellcodes vom Objekt ServiceApi

In der Zeile 1 ist zu erkennen, dass das Objekt ServiceApi von der KlasseRestHelper aus dem Paket net.liftweb.http.rest erbt. Somit wird ermöglicht,dass die URLs in dem serve-Block erstellt werden können. Um den Aufbau derREST-Schnittstelle zu verdeutlichen, wird als Beispiel die API für das Erstellen,Lesen, Ändern und Löschen von Kommentaren verwendet. In der Zeile 10 bis 13 istdargestellt, wie die URL für das Erstellen eines Kommentars im neuen Informations-und Planungssystem implementiert ist. Durch :: wird die URL konstruiert und mitNil abgeschlossen. Put gibt an, dass nur Anfragen mit der http-Methode PUT fürdiese URL zugelassen sind und in req ist die komplette http-Anfrage hinterlegt.Für die Unterscheidung der einzelnen URLs verwendet Scala pattern matching, wasdurch das Schlüsselwort case eingeleitet wird. In der Zeile 11 wird das Datum der

Benjamin Lüdicke Seite 66 von 95

Page 72: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

Variable lastModiefiedNews gesetzt, um eine Veränderung bei den Nachrichten zuverdeutlichen. Diese Variable ist nur zu Testzwecken implementiert, wobei jeweilseine Variable für Nachrichten und Kommentare zu deklarieren ist, um zwischen Än-derungen differenzieren zu können. Da ein neuer Kommentar angelegt werden soll,sind im http-Body Daten vorhanden die ausgewertet werden müssen. Aus diesemGrund wird withBody.invoke() aufgerufen. Als Parameter bekommt die Methodeinvoke() die komplette http-Anfrage, die Anfrage-Parameter und den Statuscodeder bei erfolgreichen Anlegen des Kommentars zurückgesendet wird und eine Metho-de übergeben. Die übergebene Methode wird in der Klasse Invoke() ausgeführt, woauch die Konvertierung in das angeforderte Datenübertragungsformat stattfindet. Inden Zeilen 14 bis 18 ist zu sehen, wie die Kommentare einer bestimmten Nachrichtabgefragt werden können. Dafür ist es notwendig die ID der Nachricht in der URL an-zugeben. Durch AsLong() wird überprüft, ob sich die ID in einen Wert des DatentypLong konvertieren lässt. Ist dies der Fall, wird die ID in der Variable news_id ge-speichert und im folgenden den Anfrage-Parametern hinzugefügt. Aufgrund dessen,dass es sich um die http-Methode GET handelt, wird without.invoke() aufgerufenund der http-Body nicht ausgewertet. Die folgenden Codezeilen sind ähnlich undunterscheiden sich nur anhand der URL oder der verwendeten http-Methode.

8.1.3 Die abstrakte Klasse Invoke

Abbildung 8.3: Abbildung der abstrakten Klasse Invoke

In der Abbildung 8.3 ist die abstrakte Klasse Invoke dargestellt. Sie ist für die Kon-vertierung der zurückzusendenden Daten in das vorgegebene Datenübertragungsfor-mat verantwortlich. Ferner werden unbehandelte Fehler abgefangen, um eine geeig-nete Fehlermeldung zurückzugeben. Im Listing 8.3 ist der komplette Quellcode derabstrakten Klasse Invoke abgebildet.

1 abstract class Invoke {2

3 protected implicit def toXml(json: JValue): Node = <root >

4 {Xml.toXml(json)}5 </root >6

7 protected implicit def toJson(xml: Node): JValue = Xml.toJson(xml)

8

Benjamin Lüdicke Seite 67 von 95

Page 73: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

9 protected def responseBuilder (req: Req , code: Int , msg:JValue): LiftResponse = {

10 req. accepts match {11 case Full(" application /json") => JsonResponse (msg ,

Nil , Nil , code)12 case Full(" application /xml") => XmlResponse (msg ,

code , "", Nil)13 case _ => new UnsupportedMediaTypeResponse14 }15 }16

17 def invoke(req: Req , params: Map[String , List[String ]],successCode : Int ,

18 f: (JValue , Map[String , List[String]]) => JValue): LiftResponse = {

19 try {20 start(req , params , successCode , f)21 } catch {22 case ex: code. exceptions . FormatedException =>

responseBuilder (req , ex. getHttpStatusCode , ex.getErrorAsJson )

23 case err => {24 println (err. printStackTrace )25 val ex = new code. exceptions .

UnknownErrorException26 responseBuilder (req , ex. getHttpStatusCode , ex.

getErrorAsJson )27 }28 }29 }30

31 protected def start(req: Req , params: Map[String , List[String ]], successCode : Int ,

32 f: (JValue , Map[String , List[String]]) => JValue): LiftResponse

33

34 }

Listing 8.3: Quellcodes der abstrakten Klasse Invoke

Die Methode responseBuilder() in den Zeilen 9 bis 15 überprüft den Header derhttp-Anfrage, ob JSON oder XML als Datenübertragungsformat unterstützt wer-den. Ist dies nicht der Fall, wird eine UnsupportedMediaTypeResponse an denClient zurückgesendet. Unterstützt der Client XML als Datenübertragungsformatwird eine XmlResponse erzeugt, die als Parameter den Inhalt für den http-Bodyund den http-Statuscode übergeben bekommt. Aufgrund dessen, dass die Variablemsg vom Datentyp JValue und nicht vom erwarteten Datentyp Node ist, muss eine

Benjamin Lüdicke Seite 68 von 95

Page 74: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

Konvertierung durchgeführt werden. Dafür ist die Methode toXml() verantwortlich.Das Schlüsselwort implicite gibt an, dass diese Methode automatisch aufgerufenwird, sobald eine Konvertierung benötigt wird. Weil der Rückgabetyp beim AufrufXml.toXml(json) eine NodeSequence und kein Node ist, wird das Ergebnis nochin das XML-Element root verpackt. In der Methode invoke() ist die zu über-schreibende Methode start() eingebettet. Dadurch ist es möglich, den Quellcodefür die Fehlerüberprüfung nur einmal zu implementieren, wobei die Funktionali-tät in der Methode start() austauschbar ist. Diese Umsetzung wird als Strategie-Entwurfsmuster bezeichnet. Tritt innerhalb der Methode start() ein unbekannterFehler auf, wird eine UnknownErrorException erzeugt und dem Client zurückge-sendet. In den Zeilen 25 und 26 ist zu erkennen wie diese Fehlermeldung an dieMethode responseBuilder() übergeben wird.

8.1.4 Die Klasse WithBody

Abbildung 8.4: Abbildung der Klasse WithBody

Die Klasse WithBody ist in Abbildung 8.4 dargestellt. Sie ist für das Konvertieren deshttp-Body in den Datentyp JValue verantwortlich und besteht aus zwei Methoden.Im Listing 8.4 ist der Quellcode der Klasse abgebildet.

1 class WithBody extends Invoke {2

3 private def bodyToJson (req: Req): Box[JValue] = {4 req. contentType match {5 case Full(" application /json") => {6 req.json7 }8 case Full(" application /xml") => req.xml9 case _ => Failure (" unsupported media type")

10 }11 }12

13 override def start(req: Req , params: Map[String , List[String ]], successCode : Int ,

14 f: (JValue , Map[String , List[String]]) => JValue): LiftResponse = {

15

16 bodyToJson (req) match {17 case Full(json: JValue) => {18 responseBuilder (req , successCode , f(json , params)

)

Benjamin Lüdicke Seite 69 von 95

Page 75: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

19 }20 case _ => new UnsupportedMediaTypeResponse21 }22 }23 }

Listing 8.4: Quellcode der Klasse WithBody

Die Methode start(), aus der abstrakten Klasse Invoke, wird in Zeile 13 über-schrieben. Dabei wird die Methode bodyToJson() aufgerufen und geprüft was imHeader für ein Content-Type angegeben ist. Falls der http-Body XML enthält, findeteine implizite Konvertierung in den Datentyp JValue statt. Sollte der Content-Typejedoch leer oder kein unterstütztes Datenübertragungsformat angegeben sein, wirdein Fehler zurückgegeben.

8.2 EclipseLink und PostgreSQLIn diesem Abschnitt wird beschrieben wie EclipseLink eine Verbindung mit Post-greSQL aufbaut und das Datenmodell mit EclispeLink verbunden werden kann.

8.2.1 Das Datenmodell und EclipseLink

Abbildung 8.5: Abbildung der Klassen News und NewsComment

Das in Kapitel 6 vorgestellte Datenmodell soll mittels EclipseLink in PostgreSQLabbgebildet werden. Um das zu ermöglichen, muss EclipseLink das Datenmodellkennen und die Beziehungen zwischen den Klassen verstehen. Dafür kann entwederdie Datei orm.xml im Verzeichnis \resources\META-INF hinterlegt und konfiguriertwerden oder es wird in den jeweiligen Klassen über Annotationen die Konfigurationvorgenommen. Zugunsten einer loseren Kopplung zwischen Konfiguration und Ab-bildung des Datenmodells im Quellcode, hat sich der Autor für das Konfigurieren der

Benjamin Lüdicke Seite 70 von 95

Page 76: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

Datei orm.xml entschieden. Weil der komplette Inhalt der Datei sehr umfangreichist, wird beispielhaft an den Klassen News und NewsComment verdeutlicht, wie überXML das Datenmodell abgebildet wird (siehe Abbildung 8.5). Im Listing 8.5 wirddargestellt, wie die Konfiguration der Klassen News und NewsComment vorgenommenwird. Das Mapping einer Klasse beginnt mit den Tag <entity>, in dem der vollqualifizierte Name der jeweiligen Klasse anzugeben ist. Die Methoden prePersistund preUpdate setzen das Datum von creationDate und lastModified automa-tisch, damit der Client dieses im http-Body nicht mitsenden muss und immer dasDatum des gleichen Systems verwendet wird. Um EclipseLink diese Methoden au-tomatisch ausführen zu lassen, müssen die Befehle in Zeile 3 und 4 verwendetenangegeben werden. In dem folgenden Tag <attributes> werden die Attribute derKlasse beschreiben. Aufgrund dessen, dass es sich bei den IDs der Klassen um au-tomatisch generierte Werte handeln soll, muss eine Sequenz in PostgreSQL erstelltwerden. Auch hierfür ist es nicht notwendig extra PostgreSQL anzupassen. Eclipse-Link bietet einen Sequenzgenerator, welcher konfiguriert werden kann und später inPostgreSQL übernommen wird. In den Zeilen 7 bis 10 ist zu erkennen, wie für dasAttribut news_id ein Sequenzgenerator mit dem Namen und der Sequenzbezeich-nung seq_news erstellt wird. Ferner beginnt die Sequenz mit dem Wert 1, welcherbeim Einfügen eines neuen Tupel um den Wert 1 inkrementiert wird. In den Zeilen 11bis 13 wird beschrieben wie das Attribut content abgebildet wird. Da der Inhalt ei-ner Nachricht sehr groß sein kann, entschied sich der Autor die Anzahl der Zeichenauf den Wert 5.000 festzulegen, wobei content in PostgreSQL auf den DatentypVarchar abgebildet wird. Die folgenden Attribute creationDate, expireDate undlastModified haben den Datentyp TimeStamp. Ähnlich wie die Klasse News wirdauch die Klasse NewsComment abgebildet. Der einzige Unterschied ist das Konfigurie-ren der Beziehung zwischen den beiden Klassen. Wie in Abbildung 8.5 zu erkennenist, besteht zwischen den Klassen eine 1:N Beziehung. Das bedeutet, eine Nachrichtkann keine oder mehrere Kommentare haben und ein Kommentar gehört immer zugenau einer Nachricht. Ferner sollen alle Kommentare gelöscht werden, wenn dieNachricht gelöscht wird zu der sie gehören. Dies wird als kaskadierendes Löschenbezeichnet. In den Zeilen 26 bis 31 wird gezeigt, wie die Beziehung seitens Newskonfiguriert werden muss. Der Tag <one-to-many> gibt an, dass es sich um eine1:N Beziehung handelt. Ferner wird innerhalb des Tags, die Variable der Gegen-seite benannt, mit der die Beziehung umgesetzt wird. In diesem Fall heißt diesenews. Durch den Tag <cascade-on-delete> wird das kaskadierende Löschen ak-tiviert und <cascade-all> veranlasst das weiterreichen aller Operationen. Somitwird zum Beispiel das Update eines Tupel in der anderen Klasse sichtbar. Um dieBeziehung auf der Gegenseite, also für die Klasse NewsComment, zu konfigurierenmuss der Tag many-to-one verwendet werden. Ferner muss das Attribut news_idder Klasse News angegeben werden, da dieses als Primärschlüssel verwendet wird.

1 <entity class="code.model.News">2 <table name="News"/>3 <pre - persist method -name=" prePersist "/>4 <pre -update method -name=" preUpdate "/>5 <attributes >6 <id name="news_id">

Benjamin Lüdicke Seite 71 von 95

Page 77: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

7 <sequence - generator name="seq_news"sequence -name="seq_news" initial -value="1" allocation -size="1"/>

8 <generated -value generator="seq_news"/>9 <column name="news_id"/>

10 </id >11 <basic name=" content ">12 <column length="5000"/>13 </basic >14 <basic name=" creationDate ">15 <temporal >TIMESTAMP </ temporal >16 </basic >17 <basic name=" expireDate ">18 <temporal >TIMESTAMP </ temporal >19 </basic >20 <basic name=" lastModified ">21 <temporal >TIMESTAMP </ temporal >22 </basic >23

24 [...]25

26 <one -to -many name=" comment " mapped -by="news">27 <cascade -on -delete >true </ cascade -on -

delete >28 <cascade >29 <cascade -all/>30 </cascade >31 </one -to -many >32 </attributes >33 </entity >34

35 <entity class="code.model. NewsComment ">36 <table name=" NewsComment "/>37 <pre - persist method -name=" prePersist "/>38 <attributes >39 <id name=" comment_id">40 <sequence - generator name="seq_ newscomment

" sequence -name="seq_ newscomment "initial -value="1"

41 allocation -size="1"/>42 <generated -value generator="seq_

newscomment "/>43 <column name=" comment_id"/>44 </id >45 <basic name=" content ">46 <column length="5000"/>

Benjamin Lüdicke Seite 72 von 95

Page 78: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

47 </basic >48 <basic name=" creationDate ">49 <temporal >TIMESTAMP </ temporal >50 </basic >51

52 [...]53

54 <many -to -one name="news">55 <join -column name="news_id"/>56 </many -to -one >57 </attributes >58 </entity >

Listing 8.5: Auszug des ORM-Mapping der Klassen News und NewsComment inEclipseLink

8.2.2 Anbinden von PostgreSQL an EclipseLink

Nachdem beschrieben wurde wie das Datenmodell mit EclipseLink verbunden ist,müssen die Zugangsdaten für die verwendete Datenbank an EclipseLink übergebenwerden. Diese Konfiguration wird in der Datei persistence.xml vorgenommen. ImListing 8.6 ist ein Auszug aus dieser Datei abgebildet.

1 <persistence -unit name=" TestUnit " transaction -type="RESOURCE_LOCAL">

2 <provider >org. eclipse . persistence .jpa.PersistenceProvider </ provider >

3

4 <class >code.model.Member </class >5 <class >code.model.MemberEvent </class >6 <class >code.model.Lecturer </class >7 <class >code.model.News </class >8 <class >code.model.NewsComment </class >9 <class >code.model.DegreeClass </class >

10 <class >code.model.Event </class >11 <class >code.model.Appointment </class >12 <class >code.model.Location </class >13

14 <properties >15 <property name="javax. persistence .jdbc.driver"

value="org. postgresql .Driver"/>16 <property name="javax. persistence .jdbc.url" value="

jdbc:postgresql: //127.0.0.1 :5432/ Spirit"/>17 <property name="javax. persistence .jdbc.user" value=

"admin"/>18 <property name="javax. persistence .jdbc. password "

value="123456"/>

Benjamin Lüdicke Seite 73 von 95

Page 79: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

19 <!-- <property name=" eclipselink .ddl - generation "value="drop -and -create -tables"/> -->

20 <!-- <property name=" eclipselink .ddl - generation "value="create -tables"/> -->

21 <!-- <property name=" eclipselink . logging .level"value="FINEST"/> -->

22 <!-- <property name=" eclipselink . logging .file"value="output.log"/> -->

23 </properties >24

25 </persistence -unit >

Listing 8.6: persistence.xml

Dabei ist zu erkennen, wie eine persistence-unit1 mit dem Namen TestUnitdefiniert wird (auf diesen Namen wird später im Quellcode verwiesen, um eine Ver-bindung zu PostgreSQL aufzubauen). Der Transaktionstyp RESOURCE_LOCAL gibtan, dass die Anwendung für Transaktionen verantwortlich ist. Wird als Transakti-onstyp JTA2 angegeben, wird die Verantwortung an den Anwendungs-Server abge-geben3 und es können somit verteilte Transaktionen durchgeführt werden. In derZeile 2 wird festgelegt, dass EclipseLink als JPA-Provider verwendet wird. WürdeHibernate als ORM-Mapper genutzt werden, muss stattdessen org.hibernate.ejb.HibernatePersistence dangegeben werden. Ferner muss der passendeJDBC-Treiber im Ordner lib_managed hinterlegt sein. Anschließend werden alleKlassen aufgelistet, welche durch diese persistence-unit verwaltet werden sollen.Die eigentliche Konfiguration der Datenbank erfolgt innerhalb des Tags<properties>. Dabei muss der Treiber für die verwendete Datenbank, die Host-Adresse, der Nutzername und ein Passwort angegeben werden, um den Zugriff aufdie Datenbank zu ermöglichen. Ferner kann durch die auskommentierten Tags ver-anlasst werden, dass bei jedem Neustart des Datenbank-Service das Datenmodellin PostgreSQL erstellt wird, sofern dies noch nicht in der Datenbank existiert. Zu-sätzlich kann zu Testzwecken der Datenbankzugriff aufgezeichnet und in der Dateioutlog.log analysiert werden.

8.2.3 Datenbankabfragen mit EclipseLink

Durch die Verwendung von EclipseLink ist es möglich, Expressions anstelle vonSQL-Abfragen zu nutzen. Dies hat, wie in Kapitel 5.4 aufgelistet, einige Vorteile.Anhand der Klassen ELNewsDAO und AbstractPersistence (siehe Abbildung 8.6)wird beschrieben, wie Expressions im Datenbank-Service genutzt werden, um Zugriffauf die Datenbank zu erhalten.

1in der persistence-unit werden bestimmte Konfigurationen gruppiert2(J)ava (T)ransaction (A)PI3in dieser Master-Thesis wurde Tomcat 6 verwendet, welcher kein JTA beinhaltet - soll Tom-cat dennoch mit JTA verwendet werden, muss ein JTA-Manager, wie zum Beispiel Atomikos,nachinstalliert werden

Benjamin Lüdicke Seite 74 von 95

Page 80: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

Abbildung 8.6: Abbildung der Klassen ELNewsDAO und AbstractPersistence

Die Klasse ELNewsDAO implementiert die Schnittstelle NewsDAO und wird von derKlasse AbstarctPersistence abgeleitet. Aufgrund dessen hat sie vier Methodenzum Erzeugen, Lesen, Ändern und Löschen von Daten. Bevor jedoch an einem Bei-spiel der Quellcode beider Klassen erläutert wird muss geklärt werden, wie Transak-tionen in EclipseLink umzusetzen sind. Dabei ist es wichtig zu wissen, dass Eclipse-Link keine verschachtelten Transaktionen erlaubt. Wird also eine Transaktion gestar-tet, darf keine weitere Transaktion gestartet werden, ohne die vorherige Transaktionzu beenden. Die Verwaltung von Transaktionen wird von der Klasse EntityManagerübernommen. Angelegt wird eine Instanz dieser Klasse immer, wenn eine Instanzvon den EclipseLink DAO-Klassen erzeugt wird. Wird eine solche Klasse inner-halb einer anderen EclipseLink DAO-Klasse gestartet, wird eine Exception mit derMeldung ”Transaction already active“ geworfen. Um dieses Problem zu umgehen,müssen allen weiteren EclipseLink DAO-Klassen den bereits erstellten Entitymangerübergeben bekommen und das Starten weiter Transaktion unterbunden werden. ImBeispiel sollen alle Nachrichten zurückgegeben werden, welche zu den Kursen mitden IDs 2 und 3 gehören. Die URL dafür könnte folgendermaßen aufgebaut sein:

https://212.201.64.226:8443/fhs-spirit/news?class_id=2&class_id=3Das Sequenzdiagram in Abbildung 8.7 zeigt den korrekten Ablauf dieser Abfrage4.

Abbildung 8.7: Sequenzdiagramm - Abfrage nach alle Nachrichten zu den Kursenmit den IDs 2 und 3

4wie das Sequenzdiagramm aussieht wenn der Entitymanger nicht weitergegeben wird, ist imAnhang in Abbildung A dargestellt

Benjamin Lüdicke Seite 75 von 95

Page 81: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

Im Listing 8.7 ist die Methode read() dargestellt, welche in der Klasse DBConnectoraufgerufen wird.

1 def read(params: Map[String , List[String ]]): List[News]= {

2 def function (): AnyRef = {3 val eb = new ExpressionBuilder4 var expressions : List[ Expression ] = Nil5 params.keySet foreach {6 key => {7 key match {8 case "news_id" => return params.get(key).get

map (news_id => getResourceById ( classOf [News], news_id.toLong))

9 case "owner" => expressions ::= eb.get(key).get("fhs_id").equal (( params.get(key)).get.head)

10 case "class_id" => {11 val degreeClassDAO = ELDegreeClassDAO (em)12 val clazzes = degreeClassDAO .read(params)

flatMap ( degreeClassDAO .readWithSubClasses (_))

13 expressions ::= concatQuerysWithOr ( clazzesmap (clazz =>

14 eb.anyOf(" degreeClass ").get(key).equal(clazz.class_id)))

15 }16 case " creationDate " => expressions ::= {17 eb.get(key). greaterThanEqual (Helper.

pathParamToDate (params.get(key).get.head))

18 }19 }20 }21 }22 if (! params. contains (" creationDate "))23 expressions ::= eb.get(" expireDate "). greaterThan (

eb. currentDate ())24 addOrderBy (eb.get(" lastModified "). descending ())25 getResourceByExpression ( expressions )26 }27 invoke( function ). asInstanceOf [List[News ]]28 }

Listing 8.7: Quellcode der Methode read() aus der Klasse ELNewsDAO

Die Methode read() gibt eine Liste von Nachrichten zurück, wenn bestimmte Fil-terkriterien zutreffen. Diese Filterkriterien werden über die Variable params be-

Benjamin Lüdicke Seite 76 von 95

Page 82: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

reitgestellt. In der Zeile 2 ist zu erkennen, dass innerhalb der Methode read()eine zweite Funktionen definiert wird, welche als Rückgabetyp AnyRef hat. DieseFunktion beinhaltet die eigentliche Funktionalität und wird in Zeile 27 der Metho-de invoke(), welche von AbstractPersistence geerbt wurde, übergeben. Dabeikommt das Strategie-Entwurfsmuster zum Einsatz, um den Code für die Transakti-onsverwaltung nur einmal implementieren zu müssen. In der Funktion function()wird eine Instanz der Klasse ExpressionBuilder erzeugt, damit Expressions ver-wendet werden können. Ferner gilt, dass für jeden Filter eine eigene Expression er-zeugt und in der Liste expressions abgelegt wird. In der Zeile 5 wird die Liste derkeys durchlaufen und mittels pattern matching geprüft, ob ein Filterkriterium ange-geben wurde. In der Zeile 10 wird der Filter class_id behandelt. Weil die zu filtern-den Kurse nicht Bestandteil einer Nachricht sind, müssen diese über ELDegreeClassgesucht werden. Wie im Sequenzdiagramm (siehe Abbildung 8.7) abgebildet ist, wirddem Konstruktor5 der bereits erstellte Entitymanger übergeben. In der Zeile 12 wirddie Methode read der Klasse ELDegreeClassDAO aufgerufen und die gesuchten Kursezurückgegeben. Weil jedoch die zurückgegebenen Kurse Untergruppen haben könnenund Nachrichten zu diesen ebenso für den Client interessant sein könnten, werden alleUntergruppen mit der Methode readWithSubClasses() ausgelesen. Ferner werdendie Ergebnisse durch den Aufruf von flatMap in einer Liste gespeichert. Nachdemalle relevanten Kurse bekannt sind, kann die Expression erstellt werden. Zu diesemZweck wird für jeden Kurs eine Expression erstellt, welche anschließend mit demlogischen Operator OR6 verknüpft werden. In der Zeile 14 ist zu erkennen wie eineExpression konstruiert ist. Dabei muss der ExpressionBuilder aufgerufen werden,welcher ausgehend vom Objekt News, in der Liste degreeClass, von allen Objektendas Attribut class_id, mit den IDs der ermittelten Kurse vergleicht. Anschließendwird das Ergebnis an die Liste expressions angehängt. In der Zeile 22 findet eineÜberprüfung auf den Filter creationDate statt. Ist bei diesem Filter ein Datumangegeben, werden alle Nachrichten ab diesem Datum ausgegeben und das Ver-fallsdatum expireDate ignoriert. Sollte der Filter creationDate nicht angegebensein, werden nur Nachrichten zurückgegeben dessen Verfallsdatum noch nicht über-schritten ist. In der Zeile 25 wird die Methode getResourceByExpression() mitder Liste expressions aufgerufen. Diese sowie die Methode concatsQueryWithOrwurden von der Klasse AbstractPersistence geerbt. Ein Auszug des Quellcodesder Klasse AbstractPersistence ist im Listing 8.8 dargestellt.

1 abstract class AbstractPersistence [T <: AnyRef :ClassManifest ](em: EntityManager ) {

2 private[this] val readAll = new ReadAllQuery (classManifest [T]. erasure )

3

4 def concatQuerysWithOr (exp: List[ Expression ]):Expression = {

5 val complex: Expression = null6 exp. foldLeft ( complex ) {

5genau genommen ist das der Aufruf des companion Objekt, welches die Methoden apply() undapply(em: EntityManager) anbietet, in denen eine Instanz erzeugt und zurückgegeben wird

6Oder-Verknüpfung

Benjamin Lüdicke Seite 77 von 95

Page 83: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

7 case (r, c) if (r == null && c != null) => c8 case (r, c) if (r != null && c != null) => r.or(c)9 case (r, c) if (r == null || c == null) => r

10 }11 }12

13 def addOrderBy ( orderExpression : Expression ): Unit =readAll . addOrdering ( orderExpression )

14

15 def getResourceByExpression ( expressions : List[Expression ]): List[T] = {

16 val jpaEm = JpaHelper . getEntityManager (em)17 val exp: Expression = concatQuerysWithAnd ( expressions

)18 readAll . setSelectionCriteria (exp)19 val query: Query = jpaEm. createQuery ( readAll )20 val result: List[T] = query. getResultList .toList.

asInstanceOf [List[T]]21 if (result. isEmpty )22 throw new FindByCriteriaException23 result24 }25

26 def invoke (f:()=> AnyRef): AnyRef = {27 var tx: EntityTransaction = em. getTransaction28 try {29 if (!tx. isActive ) tx.begin30 val newObj = f()31 if (!tx. isActive ) tx.commit32 newObj33 } catch {34 case ex: code. exceptions . FormatedException => {35 if (!tx. isActive ) tx. rollback36 throw ex37 }38 case ex => {39 if (!tx. isActive ) tx. rollback ()40 throw new code. exceptions . UnknownErrorException41 }42 } finally {43 if (!tx. isActive ) em.close44 }45 }}

Listing 8.8: Auszug des Quellcodes der Klasse AbstractPersistence

In der Zeile 1 ist zu erkennen das die Klasse AbstractPersistence den Entity-

Benjamin Lüdicke Seite 78 von 95

Page 84: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

8. Implementierung Fachhochschule Schmalkalden SS 2011

manger übergeben bekommt. Ferner wird festgelegt welche Typen T repräsentierendarf. Die Angabe des ClassManifest ist notwendig, da Typen in Scala auf typeerasure7 basieren. In diesem ClassManifest sind alle Informationen vorhanden, umT den passenden Typen zuzuordnen [Bra11, S. 156]. In der Zeile 3 wird eine Instanzvon ReadAllQuery erzeugt. ReadAllQuery ermöglicht es Expressions um bestimmteFunktionen zu erweitern, wie es in Zeile 15 dargestellt ist (hinzufügen eines ”orderby“). Die in der Methode concatQuerysWithOr wird zum konkatenieren der Expres-sions verwendet und ist in den Zeilen 5 bis 12 dargestellt. Die Liste expressionswird durch den Aufruf von foldLeft rekursiv durchlaufen, wobei die Variable r derAkkumulator und die Variable c das aktuelle Elemente der Liste darstellt. Fernerwird als Startwert eine Expression mit null initiiert. Die drei folgenden Zeilen Quell-code werden so oft durchlaufen, bis alle Element der Liste expressions abgearbeitetsind. In der Zeile 8 wird geprüft, ob der Akkumulator leer ist und ein Element vor-handen ist. Ist diese Bedingung wahr, ist das Ergebnis das aktuelle Element. In derZeile 9 wird überprüft ob der Akkumulator nicht leer ist und ein Element vorhan-den ist. Ist diese Bedingung wahr, wird das aktuelle Element an das Element imAkkumulator angehängt. In der Zeile 10 wird geprüft, ob weder im Akkumulatoroder das aktuelle Element leer ist. Ist dies der Fall, wird der leere Akkumulator zu-rückgegeben. In der Methode getResourcebyExpression() werden alle Expressions(Filter) mit der Methode concatQuerysWithAnd konkateniert. Diese Methode istmit concatQuerysWithOr identisch, bis auf dass die Expressions in diesem Fall mitdem logischen Operator AND8 verknüpft werden. Anschließend findet in den Zeilen21 und 22 eine Konvertierung der Expressions in ein SQL-Statement statt, welchesin Zeile 23 ausgeführt wird. Abschließend wird die Methode invoke() vorgestellt,welche die in read() implementierte Funktion ausführt. Um alle Datenbankzugriffein einer Transaktion auszuführen, muss eine Instanz vom Typ EntityTransactionerzeugt werden. Das wird durch den Aufruf der Methode getTransaction() vomEntitymanager erreicht. Aufgrund dessen, dass keine verschachtelten Transaktionenin EclipseLink unterstützt werden, muss vor dem Starten einer Transaktion geprüftwerden, ob schon eine andere Transaktion aktiv ist. Ist keine Transaktion aktiv,kann über die Methode begin() eine neue Transaktion gestartet und die übergebe-ne Funktion ausgeführt werden. Sofern keine Fehler bei der Ausführung aufgetretensind, werden die Änderungen durch den Aufruf commit() in der Datenbank persis-tent gemacht. Ist jedoch ein Fehler aufgetreten können alle Änderungen vom Startder Transaktion bis zum Auftreten des Fehlers, durch die Methode rollback()rückgängig gemacht werden.

7” [...] die Typ- parameter werden zum Übersetzungszeitpunkt überprüft und nach erfolgreicherPrüfung entfernt“ [Bra11, S. 156].

8Und-Verknüpfung

Benjamin Lüdicke Seite 79 von 95

Page 85: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

9 TestFür den Produktiveinsatz muss das entwickelte System verschiedenen Tests unter-zogen werden. Zum einen muss überprüft werden, ob die zum Datenbank-Servicegesendeten Daten korrekt verarbeitet und gespeichert werden. Und zum anderenmüssen Last-Tests durchgeführt werden, um zu ermitteln wann die Lastgrenze er-reicht ist und eine horizontale oder vertikale Skalierung vorgenommen werden muss.In dieser Master-Thesis wurden bei der Entwicklung dieses Prototypen keine derarti-gen automatisierten Tests erstellt, um den korrekten Ablauf des Systems zu überprü-fen. Aufgrund dessen, dass es sich um ein überschaubares Projekt handelt, wurdenDaten mittels Curl an den Datenbank-Service gesendet, abgefragt und anschließendverglichen. Ferner wurde eine extra Anwendung1 implementiert, welche den ApacheHttp-Client verwendet, um größere Datenmengen zu senden oder zu empfangen. ImListing 9.1 ist ein Auszug des Quellcodes von diesem Programm abgebildet. Zweckvon diesem Test ist es, eine neue Nachricht an den Datenbank-Service zu sendenund die Antwort mit den gesendeten Informationen abzugleichen.

1 def main(args: Array[String ]) {2

3 val httpclient = new DefaultHttpClient ()4

5 //News erstellen6 val send: JValue =7 "news" -> (8 ("title" -> "Test") ~9 (" content " -> "Das ist ein Test") ~

10 (" expireDate " -> "2011 -12 -24 12:00:00") ~11 (" degreeClass " -> (List (5) map (class_id =>12 ("class_id" -> class_id)13 ))) ~14 ("owner" -> ("fhs_id" -> "knolle"))15 ))16

17 val httpput: HttpPut = new HttpPut ("http:// localhost:8080/ lift -sbt - template_2.8.1 -0.1/ news");

18 httpput . setHeader ("Content -Type", " application /json")19 httpput . setHeader ("Accept", " application /json")20 println ("Senden:" + pretty(render(send)))21 var sendEntity: HttpEntity = new StringEntity ( compact

(render(send)))

1der komplette Quellcode dieser Anwendung ist auf der beigelegten CD-ROM hinterlegt

Benjamin Lüdicke Seite 80 von 95

Page 86: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

9. Test Fachhochschule Schmalkalden SS 2011

22 httpput . setEntity ( sendEntity )23 val response = httpclient . execute ( httpput )24 val responseEntity = response . getEntity25 println (" Antwort: " + response )26 val content = convertStreamToString ( responseEntity .

getContent )27 println ( content )28 httpput .abort ()29 }

Listing 9.1: Auszug des Quellcodes zum Testen des Datenbank-Service

In der Zeile 2 wird ein Objekt des Typs DefaultHttpClient erstellt und anschlie-ßend eine neue Nachricht im JSON-Format generiert. In der Zeile 17 wird durchHttpPut angegeben, dass die http-Methode PUT verwendet werden soll. Dies er-möglicht den Datenbank-Service den Zweck der Verbindung zu bestimmen. Fernerwird die URL des Datenbank-Service als String übergeben. Danach wird der http-Header so konfiguriert, dass der Server ein JSON-String als Antwort sendet. Durchdie Methode execute() wird die Anfrage an den Datenbank-Service gesendet undanschließend wird die Antwort des Datenbank-Service auf der Konsole ausgegeben.

Benjamin Lüdicke Seite 81 von 95

Page 87: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

10 Zusammenfassung und AusblickIn dieser Master-Thesis wurde die Entwicklung und Konzeption eines Informations-und Planungssystems beschrieben. Ziel dieses Systems soll es sein, einen persön-lichen Terminkalender anstelle des statischen Stundenplans zu verwenden. Somitist es möglich Änderungen am Stundenplan nachzuvollziehen und Tutorien für be-stimmte Kurse zu planen, welche im persönlichen Terminkalender angezeigt werdenkönnen. Außerdem soll es ermöglicht werden Nachrichten, welche auf der Homepageder Fachhochschule Schmalkalden veröffentlicht werden, zu kommentieren. Ausge-hend von Anwendungsfällen und daraus folgenden Anforderungen, sind drei Da-tenbanken evaluiert wurden, wobei sich PostgreSQL zusammen mit EclipseLink,laut Meinung des Autors, als beste Alternative erwies. Ferner wurde ein prototy-pischer Datenbank-Service mit dem Framework Lift umgesetzt, welcher die ausge-wählte Datenbank kapselt und austauschbar macht. Zusätzlich ist durch Anwendungdes Fabrik-Entwurfsmusters die konzipierte REST-Schnittstelle von der verwende-ten Datenbank unabhängig. Für die Verwendung im produktiven Einsatz müsstenzukünftig Tests entwickelt werden, um festzustellen ob alle Erwartungen an denDatenbank-Service erfüllt werden. Zusätzlich können diese Tests hilfreich sein, umFehler nach Änderungen am Quellcode aufzudecken. Eine neue Funktionalität, wel-che der Autor für sinnvoll erachtet ist zum Beispiel eine REST-Schnittstelle für Ad-ministratoren, wie sie im Kapitel 4 vorgestellt wurde. Ferner kann diese durch dieimplementierte Http-Basic-Authentication in Verbindung mit SSL geschützt werden.Ferner wäre es möglich die Authentifizierung von Fachhochschulmitgliedern, welchevon Clients selbständig durchgeführt wird, auf den Datenbank-Service zu verlagern.

Benjamin Lüdicke Seite 82 von 95

Page 88: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Literaturverzeichnis[Bra11] Braun, Oliver: Scala - Objektfunktionale Programmierung. Carl Hanser

Verlag München, 2011

[CBDW] Chen-Becker, Derek (Hrsg.) ; Danciu, Marius (Hrsg.) ; Weir, Ty-ler (Hrsg.): Exploring Lift. http://exploring.liftweb.net/master/,Abruf: 20. Jul. 2011

[EFHB10] Edlich, Stefan ; Friedland, Achim ; Hampe, Jens ; Brauer, Benja-min: NoSQL Einstieg in die Welt nichtrelationaler Web 2.0 Datenbanken.Carl Hanser Verlag München, 2010

[EH09] Eisentraut, Peter ; Helmle, Bernd: PostgreSQL-Administration.O’Reilly Media, Inc., 2009

[Fie00] Fielding, Roy T.: Architectural Styles and the Design of Network-basedSoftware Architectures, University of California, Irvine, Diss., 2000

[Fou] Foundation, Eclipse (Hrsg.): EclipseLink Documentation.http://wiki.eclipse.org/EclipseLink/Documentation_Center,Abruf: 20. Jul. 2011

[HM04] Harold, Elliotte R. ; Means, William S.: XML in a Nutshell: A DesktopQuick Reference. O’Reilly Media, Inc., 2004

[Jar10] Jarosch, Helmut: Grundkurs Datenbankentwurf - Eine beispielorien-tierte Einführung für Studenten und Praktiker. Vieweg + Teubner, 2010

[KE01] Kemper, Alfons ; Eickler, André: Datenbanksysteme eine Einführung.Oldenbourg Verlag München Wien, 2001

[Kud07] Kudraß, Thomas: Taschenbuch Datenbanken. Carl Hanser Verlag Mün-chen, 2007

[Ori] OrientDB (Hrsg.): What is Orient? http://code.google.com/p/orient/, Abruf: 31. Jul. 2011

[Posa] PostgreSQL (Hrsg.): Documentation of PostgreSQL. http://www.postgresql.org/docs/9.0/static/, Abruf: 12.Aug. 2011

[Posb] PostgreSQL (Hrsg.): History of PostgreSQL. http://www.postgresql.org/about/history, Abruf: 12.Aug. 2011

Benjamin Lüdicke83

Page 89: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Literaturverzeichnis Fachhochschule Schmalkalden SS 2011

[Posc] PostgreSQL (Hrsg.): Wiki of PostgreSQL. http://wiki.postgresql.org/wiki/Binary_Replication_Tutorial, Abruf:18.Aug. 2011

[Riaa] Riak (Hrsg.): An Introduction to Riak. http://wiki.basho.com/An-Introduction-to-Riak.html, Abruf: 10.Aug. 2011

[Riab] Riak (Hrsg.): System Requirements. http://wiki.basho.com/System-Requirements.html, Abruf: 10.Aug. 2011

[Rie09] Rieber, Philipp: Dynamische Webseiten in der Praxis: PHP, MySQL,CSS, Javascript, XHTML und Ajax. mitp, eine Marke der VerlagsgruppeHüthig Jehle Rehm GmbH, 2009

[RR07] Richardson, Leonard ; Ruby, Sam: Web Services mit REST. O’ReillyMedia, Inc., 2007

[Sau02] Sauer, Hermann: Relationale Datenbanken - Theorie und Praxis.Addison-Wesley, 2002

[Tit03] Tittmann, Peter: Graphentheorie eine anwendungsorientierte Einfüh-rung. Fachbuchverlag Leipzig, 2003

[WM] Walker-Morgan, Dj (Hrsg.): NoSQL im Überblick. http://www.heise.de/open/artikel/NoSQL-im-Ueberblick-1012483.html, Ab-ruf: 05. Jul. 2011

Benjamin Lüdicke84

Page 90: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

A Anhang

Benjamin Lüdicke85

Page 91: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

A. Anhang Fachhochschule Schmalkalden SS 2011

Abbildung A.1: Statischer Stundenplan in HTML

Benjamin Lüdicke86

Page 92: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

A. Anhang Fachhochschule Schmalkalden SS 2011

Abbildung A.2: Interface-Spezifikation Teil einsBenjamin Lüdicke

87

Page 93: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

A. Anhang Fachhochschule Schmalkalden SS 2011

Abbildung A.3: Interface-Spezifikation Teil zwei

Benjamin Lüdicke88

Page 94: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

A. Anhang Fachhochschule Schmalkalden SS 2011

Abbildung A.4: Interface-Spezifikation Teil drei

Benjamin Lüdicke89

Page 95: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

A. Anhang Fachhochschule Schmalkalden SS 2011

Abbildung A.5: Sequenzdiagramm - Abfrage nach alle Nachrichten zu den Kursenmit den IDs 2 und 3 (fehlerhafter Ablauf)

Benjamin Lüdicke90

Page 96: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Abbildungsverzeichnis

2.1 Eigene Darstellung einer Relation in Anlehnung an [Kud07, S. 74] . . 92.2 Eigene Darstellung einer N:M Beziehung zwischen Relationen . . . . 102.3 Eigene Darstellung zur Kategorisierung von NoSQL-Systemen in An-

lehnung an [EFHB10, S. 6] . . . . . . . . . . . . . . . . . . . . . . . 13

4.1 Eigene Darstellung der Miniwelt für Informations- und Planungssystem 184.2 Eigene Darstellung des Anwendungsfaldiagramms ohne Einschrän-

kungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194.3 Eigene Darstellung des Anwendungsfaldiagramms mit Administrator

als Akteur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

5.1 Eigene Darstellung des PropertyGraph nach dem Aufruf der Methodecreate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

5.2 Eigene Darstellung des Namensraum in Riak in Anlehnung an [EFHB10,S. 157] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

5.3 Eigene Darstellung des Map/Reduce-Verfahren in Anlehnung an [EFHB10,S. 18] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

5.4 Eigene Darstellung des 160 bit Hash-Ring mit vier Knoten und 32Partitionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

6.1 Eigene Darstellung des Datenmodell des zu entwickelnden Informations-und Planungssystems . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

7.1 Verarbeiten einer eingehenden Anfrage beim Datenbank-Service . . . 577.2 Klassendiagramm der REST-Schnittstelle des Datenbank-Service . . . 587.3 Klassendiagramm des eingebundenen Datenmodells in den Datenbank-

Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597.4 Helfer-Klassen des Datenbank-Service . . . . . . . . . . . . . . . . . . 62

8.1 Abbildung der Klasse Boot . . . . . . . . . . . . . . . . . . . . . . . . 638.2 Abbildung der Klasse ServiceApi . . . . . . . . . . . . . . . . . . . . 658.3 Abbildung der abstrakten Klasse Invoke . . . . . . . . . . . . . . . . 678.4 Abbildung der Klasse WithBody . . . . . . . . . . . . . . . . . . . . . 698.5 Abbildung der Klassen News und NewsComment . . . . . . . . . . . 708.6 Abbildung der Klassen ELNewsDAO und AbstractPersistence . . . . 758.7 Sequenzdiagramm - Abfrage nach alle Nachrichten zu den Kursen mit

den IDs 2 und 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

A.1 Statischer Stundenplan in HTML . . . . . . . . . . . . . . . . . . . . 86A.2 Interface-Spezifikation Teil eins . . . . . . . . . . . . . . . . . . . . . 87

Benjamin Lüdicke91

Page 97: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Abbildungsverzeichnis Fachhochschule Schmalkalden SS 2011

A.3 Interface-Spezifikation Teil zwei . . . . . . . . . . . . . . . . . . . . . 88A.4 Interface-Spezifikation Teil drei . . . . . . . . . . . . . . . . . . . . . 89A.5 Sequenzdiagramm - Abfrage nach alle Nachrichten zu den Kursen mit

den IDs 2 und 3 (fehlerhafter Ablauf) . . . . . . . . . . . . . . . . . . 90

Benjamin Lüdicke92

Page 98: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Tabellenverzeichnis

2.1 http-Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.2 Teilsprachen von SQL laut [Kud07, S. 108] . . . . . . . . . . . . . . . 11

5.1 Indextypen in OrientDB . . . . . . . . . . . . . . . . . . . . . . . . . 245.2 Backup-Optionen in Riak . . . . . . . . . . . . . . . . . . . . . . . . 40

6.1 Objekttyp Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526.2 Objekttyp Appointment . . . . . . . . . . . . . . . . . . . . . . . . . 536.3 Objekttyp Location . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536.4 Objekttyp DegreeClass . . . . . . . . . . . . . . . . . . . . . . . . . . 536.5 Objekttyp Member . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546.6 Objekttyp News . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556.7 Objekttyp NewsComment . . . . . . . . . . . . . . . . . . . . . . . . 55

7.1 Fehlerklassen im Datenbank-Service . . . . . . . . . . . . . . . . . . . 61

Benjamin Lüdicke93

Page 99: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Listings

5.1 Erstellen eines Schemas in OrientDB . . . . . . . . . . . . . . . . . . 245.2 Create-Operation in OrientDB mit Java-API . . . . . . . . . . . . . . 255.3 Read-Operation in OrientDB mit Java-API . . . . . . . . . . . . . . . 285.4 Update-Operation in OrientDB mit Java-API . . . . . . . . . . . . . 295.5 Delete-Operation in OrientDB mit Java-API . . . . . . . . . . . . . . 305.6 Create-Operation in Riak mit Java-API . . . . . . . . . . . . . . . . . 335.7 Read-Operation in Riak mit Java-API . . . . . . . . . . . . . . . . . 355.8 Link-Walking in Riak mit Java-API . . . . . . . . . . . . . . . . . . . 365.9 Map/Reduce in Riak mit Java-API . . . . . . . . . . . . . . . . . . . 375.10 Update in Riak mit Java-API . . . . . . . . . . . . . . . . . . . . . . 385.11 Delete in Riak mit Java-API . . . . . . . . . . . . . . . . . . . . . . . 395.12 Datenbankschema für die Beispieldatenbank in PostgreSQL . . . . . . 435.13 Create in PostgreSQL mit JDBC-Treiber . . . . . . . . . . . . . . . . 445.14 Read in PostgreSQL mit JDBC-Treiber . . . . . . . . . . . . . . . . . 455.15 Update in PostgreSQL mit JDBC-Treiber . . . . . . . . . . . . . . . 465.16 Delete in PostgreSQL mit JDBC-Treiber . . . . . . . . . . . . . . . . 46

8.1 Quellcode der Klasse Boot . . . . . . . . . . . . . . . . . . . . . . . . 638.2 Auszug des Quellcodes vom Objekt ServiceApi . . . . . . . . . . . . . 658.3 Quellcodes der abstrakten Klasse Invoke . . . . . . . . . . . . . . . . 678.4 Quellcode der Klasse WithBody . . . . . . . . . . . . . . . . . . . . . 698.5 Auszug des ORM-Mapping der Klassen News und NewsComment in

EclipseLink . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 718.6 persistence.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 738.7 Quellcode der Methode read() aus der Klasse ELNewsDAO . . . . . . 768.8 Auszug des Quellcodes der Klasse AbstractPersistence . . . . . . . . . 77

9.1 Auszug des Quellcodes zum Testen des Datenbank-Service . . . . . . 80

Benjamin Lüdicke94

Page 100: Evaluierung und Konfiguration einesDBMS sowie die Konzeption undEntwicklung eines Datenbank-Serviceauf Basis von RESTful Web Servicesin Scala

Eidesstattliche ErklärungIch versichere an Eides Statt durch meine eigenhändige Unterschrift, dass ich dievorliegende Arbeit selbstständig und ohne fremde Hilfe angefertigt habe. Alle Stel-len, die wörtlich oder dem Sinn nach auf Publikationen oder Vorträgen andererAutoren beruhen, sind als solche kenntlich gemacht. Ich versichere außerdem, dassich keine andere als die angegebene Literatur verwendet habe. Diese Versicherungbezieht sich auch auf alle in der Arbeit enthaltenen Zeichnungen, Skizzen, bildlichenDarstellungen und dergleichen.

Die Arbeit wurde bisher keiner anderen Prüfungsbehörde vorgelegt und auch nochnicht veröffentlicht.

Winterstein,den 28. September

2011Ort, Datum Benjamin Lüdicke

Benjamin Lüdicke95