Sunday, November 23, 2014

Unit Test mit Xamarin.Android

Mit Xamarin werden auch 2 Unit-Test-Projekt-Templates mit installiert.

Und zwar jeweils eines für iOS und eines für Android.

clip_image002clip_image004

Verwendet wird dabei eine leicht abgewandeltes NUnitLite.

Wird ein neues Unit Test App Projekt (Android) angelegt, wird die Referenz zu Xamarin.Android.NUnitLite in diesem Test-Projekt hinzugefügt. Im nächsten Schritt muss euer Projekt als Referenz zu eben diesem Testprojekt hinzugefügt werden – in meinem Beispiel die XamarinFormsSample.PCL, dann kann es schon losgehen mit dem Test.

clip_image005

Es wird ebenfalls eine Beispieldatei angelegt, die TestSample.cs. Wenn man sich diese näher ansieht, dann erkennt man, dass diese bereits eine sehr gute Ausgangsbasis für die eigenen Tests ist.

Die Datei beginnt mit den folgenden Attributen:

· TestFixture - Dieses Attribut markiert die Klasse als “Testklasse”, d. h. diese beinhaltet Unit-Tests, eine optionale Setup Methode und eine optionale Teardown Mothode.

Das Attribut alleine reicht noch nicht, diese so markierte Klasse muss einen Default-Konstruktor

· SetUp - Dieses Attribut wird innerhalb einer Klasse mit dem Attribut TestFixture dazu verwendet, um Funktionalität auszuführen, die VOR jeder Testmethode aufgerufen werden muss, also der ideale Platz um den Testfall zu initialisieren.

· TearDown – Dieses Attribut markiert eine Methode, die NACH jeder Testmethode aufgerufen wird, also ideal zum “Aufräumen”.

Eine Klasse, die mit dem Attribut TestFixture markiert wurde kann nur eine SetUp und eineTearDown Methode beinhalten. Wenn es mehrere davon gibt, wird das Projekt zwar erfolgreich kompiliert, aber die Methoden werden während der Laufzeit nicht ausgeführt.

clip_image006

Soweit zum generellen Aufsetzen der Unit-Test-Klasse. Jetzt fehlen noch die Testmethoden, das sind Methoden die mit folgendem Attribut markiert werden:

· Test - Das Test Attribut markiert eine Methode, die sich innerhalb einer Klasse befindet, die als TestFixture markiert wurde als Test-Methode. Diese darf KEINE Parameter aufweisen. Werden Parameter definiert, dann kann zwar kompiliert werden, der Test wird allerdings nicht ausgeführt werden und scheint später in dem “Test Not Run“-Bereich auf.

Das Ergebnis der Test-Methode wird mit der Assert Klasse und deren Methoden festgelegt. Es gibt insgesamt 18 davon, ich möchte nur die aus der Beispiel-Datei herausgreifen:

· Asstert.True(<condition>) - Die <condition> muss true ergeben, dann ist der Testfall in Ordnung.

· Asstert.False(<condition>) - Die <condition> muss false ergeben, dann ist der Testfall in Ordnung.

· Asstert.Inconclusive – das Ergebnis sollte manuell überprüft werden.

clip_image007 clip_image009

Lässt man das Testprojekt ablaufen, sieht das im Microsoft Android Emulator so aus:

clip_image011 clip_image013 clip_image015

Die Dokumentation zu NUnit, bzw. NUnitLite findet ihr hier.

Friday, November 21, 2014

Visual Studio 2015 und Android Emulator mit Xamarin startet nicht?

Falls Ihr eine Xamarin.Android Applikation aus Visual Studio 2015 zum Microsoft Android Emulator deployen wollt und ihr bekommt folgende Meldung im Output

In mgmain JNI_OnLoad
Couldn't connect to logcat, GetProcessId returned: 0

dann vergesst nicht das Häkchen in den Android Projekteinstellungen für

Use Fast Deployment (debug mode only)

zu entfernen.


Thursday, November 20, 2014

Codefest.at: Xamarin.Forms, oder: Knapp 100% Code-Reuse auf mobilen Plattformen

Xamarin.Forms, einfach genial. Vielen lieben Dank an das CodeFest.atTeam für die Veröffentlichung!
us gegebenem Anlass möchte ich euch gerne den Einstieg in die mobile Entwicklung mit Xamarin und speziell Xamarin.Forms näherbringen. Ihr fragt euch möglicherweise, was denn dieser „Anlass“ sein könnte?
clip_image002
Nun, zum Ersten ist es so, dass die Visual Studio 2015 Preview den Android Emulator mitliefert, was die Entwicklung vereinfacht und die Developer-Experience merklich erhöht, mehr dazu findet ihr hier.
Zum Zweiten ist es so, dass ich nächste Woche wieder einen Xamarin Kurs abhalte und ich gerade wieder einmal meine Unterlagen überarbeite und ich dabei meine treuen Blog-Leser auch teilhaben lassen möchte.

Drittens, und das ist für euch bestimmt noch interessanter, ist die Draft-Version des Xamarin.Forms Buches von Charles Petzold in der Microsoft Virtual Academy als Gratis-Download verfügbar. Und zwar genau hier.clip_image003
Alles gute Gründe, sich Xamarin und Xamarin.Forms genauer anzusehen, aber zuvor sollten wir die Frage klären:

 

Was ist Xamarin und was kann es für mich tun?

Nun, jeder Entwickler, der mobile Applikationen mit
· C# und
· nativer Performance und
· nativem Look & Feel
für Windows Phone UND iOS UND Android erstellen möchte, sollte sich Xamarin genauer ansehen. Xamarin stellt 100% der nativen APIs für iOS, Android und Windows zur Verfügung.
Als Entwicklungsumgebung liefert Xamarin zwar auch das Xamarin Studio zur Entwicklung mit, aber es ist auch möglich, den gesamten Code in Visual Studio zu erstellen, allerdings benötigt ihr dann auch zumindest die Business-Lizenz. Der Vorteil ist, dass eure gewohnten Tools, wie z. B. Resharper, weiterhin verwendet werden können, ihr aber eben mit dem Xamarin SDK die mobile Plattform eurer Wahl anprogrammiert.
Es werden immer native und keine interpretierten Applikationen für die gewählte Zielplattform erstellt.
clip_image005
Dies wurde dadurch ermöglicht, dass 100% des Android SDKs und 100% des iOS SDKs auf C# gemappt wurden. Kurz gesagt: wenn man es in Java für Android programmieren kann, klappt das auch mit Visual Studio, C# und Xamarin.Android. Das Gleiche gilt eben genauso für XCode mit Objective-C und Visual Studio, C# und Xamarin.iOS.

 

Was benötige ich, um mit Xamarin zu entwickeln?

Das kommt jetzt ein klein wenig darauf an, auf welche mobile Plattform ihr mit eurer Entwicklung abzielt:
· Android: das Android SDK, optional eine Google Developer Subscription (einmalig $25), mehr dazu findet ihr hier – falls ihr die App veröffentlichen wollt, dann ist diese natürlich zwingend notwendig.
· iOS: einen MAC, der als sogenannter Build-Host dient, auf diesem muss XCode installiert sein und ihr benötigt ZWINGEND eine Apple Developer Subscription (jährlich €83), mehr dazu hier. Der Grund ist, dass die Erstellung nativer iOS Applikationen zwingend auf dem MAC mit den Tools von Apple erfolgen muss.
Dann natürlich noch Xamarin selbst, eine der 4 Editionen, oder die Trial Lizenz - diese ist 30 Tage ohne Einschränkungen lauffähig und findet ihr hier zum Download.

 

Was kostet Xamarin?

Es gibt 4 verschiedene Lizenzen:
· Starter (kostenlos, aber bez. Funktionen in sehr eingeschränkter Form)
· Indie ($25/Monat)
· Business ($83/Monat)
· Enterprise ($158/Monat)
Für Studenten gibt es die Indie-Version gratis, mehr dazu findet ihr hier. Für MSDN-Abonnenten gibt es ebenfallsspezielle Rabatte, momentan kostet die Business Edition $799/Jahr und pro Plattform.
Den genauen Unterschied in den Funktionen könnt ihr hier nachlesen, ich empfehle euch zumindest die Indie-Version zu verwenden, ich persönlich habe die Xamarin Business Edition für iOS und Android.

 

Wie funktioniert die Entwicklung mit Xamarin?

Es gibt zwei Möglichkeiten, um mit Xamarin eine native, mobile Applikation zu erstellen:
1. Die GUI wird für die jeweilige Plattform extra erstellt, die Applikations-Logik kann wiederverwendet werden
2. Die GUI wird mit Xamarin.Forms erstellt, damit kann im Idealfall auch die GUI nahezu zu 100% auf jeder der mobilen Plattformen wiederverwendet werden.
clip_image007
Ersteres wird auch der sogenannte Silo-Approach genannt: Drei Säulen – für jede Plattform eine unterschiedliche Implementierung der grafischen Oberfläche.

 

Was ist Xamarin.Forms?

Mit Xamarin.Forms ist es – im Gegensatz zum Silo-Approach – möglich, eine Applikation 1x zu entwickeln, auch die GUI, und zwar mit nahezu 100% gleichem Code. Das heißt, kaum extra Code-Zeilen für eine der drei führenden mobilen Plattformen (Android, iOS und Windows Phone). Möglich wird das, indem Xamarin.Forms die nativen Controls durch eine Zwischenschicht abstrahiert. So gibt es z. B. einen Xamarin.Forms.Button, dieser wird letztendlich ein UIButton, wenn es sich um eine iOS App handelt, zu einem Android Button bei einer Android App und zu einem Windows Phone Button bei einer Windows Phone App (aber dazu später noch genaueres).
clip_image009
Zusätzlich werden von Xamarin.Forms gewisse Unterschiede der mobilen Plattformen per Default eingebaut. So ist eine iOS-Applikation per Default weiß, eine Android App aber eher in schwarz gehalten. Das bedeutet, dass es eben z. B. per Default ein anderes Farbschema für Schriften und Texte verwendet werden muss. Das kann man zu Beginn getrost links liegen lassen, Xamarin.Forms kümmert sich darum.
Um Xamarin.Forms auch für Windows Phone einsetzen zu können, benötigt ihr zumindest eine Xamarin Lizenz für eine der beiden anderen Plattformen.

 

Wie wird eine Xamarin.Forms App erstellt?

Xamarin liefert in der Business-Edition Visual Studio Templates mit, wenn ein neues Projekt angelegt wird. Da eine Xamarin.Forms Applikation erstellt werden soll, sind 3 Templates von Interesse:
· Eine „Blank App (Xamarin.Forms.Portable)“,
· eine „Blank App (Xamarin.Forms.Shared)”,
· eine „Class Library (Xamarin.Forms.Shared)”
clip_image011
Also prinzipiell entscheidet man sich, ob man das Projekt als „Shared Project“, oder als „Portable Class Library“ aufsetzen möchte.
Eine Shared Application kompiliert die Klassen in jede einzelne App. Sollten Unterscheidungen für eine spezielle Plattform notwendig sein, wird häufig eine Kompiler-Direktive verwendet. Der Vorteil ist hier, dass nur eine einzige Quelldatei für alle drei Plattformen existiert.
clip_image013Quelle: Xamarin docs
Die Portable-Class Library vereint den kleinsten gemeinsamen Nenner aller verwendeten Plattformen, es ist also im Prinzip keine Unterscheidung für eine der drei mobilen Plattformen von Nöten, da diese PCL für alle drei Apps die Gleiche ist.
clip_image015Quelle: Xamarin docs
Aber warum eine Entscheidung treffen? Ich erstelle üblicherweise eine „Blank App (Xamarin.Forms.Shared)“ und füge danach eine „Class Library (Xamarin.Forms.Portable)“ hinzu. Damit kann ich alle Vorteile aus beiden Lösungen verwenden. Das sieht dann im Endeffekt so aus:
clip_image016
Es ist das Shared Project zu finden, die Android, sowie die iOS App, danach die PCL und am Ende die Windows Phone App. Die PCL wurde als Referenz zu den drei App-Projekten hinzugefügt.
Es lohnt sich, nach dem Anlegen der finalen Projektstruktur das Xamarin.Forms-Package auf die aktuelle Version zu aktualisieren.
clip_image018

 

XAML-Layout und Datenbindung?

Unter iOS und Android gibt es an und für sich keine MVVM-Unterstützung, wie sie in WPF existiert, aber Xamarin.Forms macht das nun für eben diese beiden Plattformen möglich. Inklusive XAML.
Um das in der Praxis zu testen, habe ich mir eine bestehendes MVVM Beispiel geholt, nämlich die „Simple MVVM and Windows Phone 7“-Applikation von hier und diese mit Xamarin.Forms umgesetzt.
Dieses ursprüngliche Beispiel zeigt die Verwendung von MVVM anhand einer Länderliste. Wenn ein einzelnes Land angewählt wird, so gelangt man zu den Details, bzw. erhält weitere Informationen über dieses Land. Da es sich um ein MVVM-Einführungsbeispiel handelt, verwendet es natürlich Models, ViewModels und Views und verwendet die zugehörige Datenbindung. Außerdem beinhaltet die Applikationen ein Verzeichnis mit Bilder, wo die zu jedem Land zugehörige Flagge enthalten ist.
Das Endresultat der Konvrtierung der Windows Phone 7 App mittels Xamarin.Forms sieht auf den drei Plattformen (Android, iOS; Windows Phone 8) so aus:
clip_image020clip_image022clip_image024
Das ist jetzt noch ganz ohne „Tweaks“ für eine bestimmte Plattform, d. h. eine Code-Basis für alle 3 mobilen Clients. Das gilt sowohl für die Business Logik, ALSO AUCH für das Frontend.
Ich möchte hier nur einige der Anpassungen aufgreifen, die gegenüber der originalen Windows Phone 7 App durchzuführen waren:
Generell gilt: WPF, bzw. Silverlight XAML != Xamarin XAML, das ist am deutlichsten an den Controls zu erkennen. Nachfolgend ein Beispiel:
Windows Phone 7 XAML:
image
Xamarin.Forms XAML
image
Auffallend, dass wir statt dem StackPanel ein StackLayout sehen, statt dem TextBlock ein Label und ich die Styles einfach entfernt habe. Erstens gibt es diese nicht mehr und zweitens haben wir hier es nicht nur mit einer Plattform zu tun, sondern mit drei verschiedenen – und da ist es erst einmal schwierig mit einem bestimmten Style „ins Rennen zu gehen“. Xamarin.Forms nimmt uns per Default schon einiges ab, wie es in den Screenshots zu sehen ist, konkret spiele ich auf die Hintergrundfarbe und die Vordergrundfarbe der Controls an.
Generell würde ich empfehlen, wenn es sich um eine Applikation, die mit Xamarin-für mehrere mobilen Plattformen entwickelt wird, eine Plattform als „führende“ zu definieren. Sobald diese einen Stand hat, der für den Test frei gegeben werden kann, kann man die zweite und danach die dritte Plattform anpassen, bzw. feintunen. Damit ist sichergestellt, dass zumindest eine Plattform quasi fertig ist und funktioniert. Die anderen beiden folgen in sehr kurzem Abstand. In dem oberen – zugegeben relativ einfachem - Beispiel wurde wie erwähnt absolut NICHTS angepasst.
Grund für diese eigenen Controls ist die Funktionsweise von Xamarin.Forms. Durch die Plattform-abhängigen Bibliotheken verwandeln sich die Xamarin.Forms-Controls in die jeweils passenden der jeweiligen Zielplattform, wie das nachfolgende Bild anschaulich zeigt.
clip_image026
So wird also aus einem Xamarin.Forms.Button ein UIButton, bzw. ein Android.Widget.Button unter Android und ein System.Windows.Controls Button unter Windows Phone.
Die Datenanbindung wurde von Xamarin gleich umgesetzt, wie wir das schon von WPF, oder der Windows Phone Entwicklung gewohnt sind. Das ViewModel und das Model habe ich nahezu ohne Änderungen übernommen, ich habe nur mit dem Bild getrickst und ein weiteres Property, um den Applikations-Titel nur unter Windows Phone darzustellen eingefügt.
Als Beispiel hier die Liste der Flaggen in der Windows Phone 7 App (der Trigger aus dem Originalcode wurde hier entfernt, da Trigger in Xamarin.Forms noch nicht offiziell unterstützt sind):
image

Und hier die Xamarin.Forms App:
image
Wichtig zu erwähnen ist noch, dass XAML mit Xamarin.Forms nur in einer Portable Class Library funktioniert und nicht in einem Shared Asset Project. Des Weiteren gibt es noch keinen XAML Designer, das könnte euch das Einarbeiten in Xamarin.Forms etwas erschweren, wenn ihr bisher eure XAML-GUI mit Blend, oder in Visual Studio mit dem Designer gebaut habt.

 

Zusammenfassung

Generell kann man sagen, dass Xamarin mit den Xamarin.Forms ein großer Wurf gelungen ist. Es ist zwar erst die erste Version, es lassen sich aber bereits hervorragend Business-Applikationen damit entwickeln. Wir dürfen gespannt sein, was das Xamarin-Team in den nächsten Monaten noch für Überraschungen für uns bereithält.

Friday, November 14, 2014

Codefest.at: Visual Studio 2015. Xamarin und der neue Android Emulator

Die Neuigkeiten der Microsoft Connect sind für Xamarin-Entwickler durchwegs positive Nachrichten gewesen. Aber es waren ja nicht nur „Nachrichten“, nein, es steht ja auch gleich einiges zum Ausprobieren zur Verfügung. Z. B. Visual Studio 2015, inklusive verfügbaren Xamarin Projekt-Templates UND einem integrierten Android Emulator.
Letzteres ist besonders großartig, da es bisher einer gewissen Leidensfähigkeit bedurfte, um mit den Android-Emulatoren aus dem SDK zu arbeiten (Stichworte: langsam, verlorene Verbindungen, usw.).
Also war ich gespannt wie ein Regenschirm und wollte mir das gleich einmal ansehen. Was dabei herausgekommen ist, möchte ich euch gerne nachfolgend beschreiben.

Die Installation von Visual Studio 2015

Dazu erst einmal der übliche Download des Installers, diesen findet ihr hier:
clip_image001
Ich habe nur „die notwendigsten“ Features ausgewählt, da auf meiner Maschine z. B. bereits die Windows Phone 8.1 Emulatoren installiert sind, es bleibt euch aber überlassen, gleich einmal alles auf die Festplatte „zu schmeißen“.
clip_image002
Wichtig ist nur, dass ihr nach dem üblichen Setup auch das zweite Setup durchlaufen lässt, um den Android Emulator zu installieren. Solltet ihr etwas zu vorschnell gewesen sein und den Installer bereits geschlossen haben, so könnt ihr das über „Programs and Features“ beheben, indem der „Secondary Installer“ noch einmal mittels „Change“ aufgerufen wird.
clip_image003
Nachfolgend wiederum meine Auswahl, ich habe aber auf der Maschine schon das Android SDK - ihr wollt möglicherweise wieder alles installieren:
clip_image004
Wichtig ist in jedem Fall der Microsoft Visual Studio “Emulator for Android”.

Neues Android Projekt – Versuch 1

Nachdem auch diese Installation durchgelaufen war, dachte ich mir, ich rufe gleich einmal Visual Studio 2015 auf und lege sofort mit einem Beispielprojekt los.
clip_image005
Gesagt, getan – und dann sogleich ein neues Projekt anlegen – soweit der Plan. WOW, es gibt unter Visual C# ein Android Projekt, nun, mir nichts, dir nichts, unverzüglich dieses anwählen und noch einen passenden Namen verpassen.
clip_image007
Soweit so gut, nur…..schade, das war es noch nicht. Ein netter Dialog weist mich darauf hin, dass ich Xamarin installieren sollte.
clip_image009

Xamarin Installation

Gut, auf Download Xamarin geklickt - dafür scheint der Button ja da zu sein - diese Aktion bringt mich zu diesem Link:
Ah, ja. Als Xamarin-Entwickler kennt man diese Webseite bereits, hier kann man sich, falls noch kein Xamarin-Login vorhanden ist, die Xamarin-Trial herunterladen – unter Angabe einiger weniger Informationen.
clip_image011
Gut, ich habe bereits meine Lizenz, aber trotzdem habe ich noch einmal alles eingegeben und den „Download Xamarin for Windows”-Button gedrückt. Das ist wohl eine weise Entscheidung, da die Datei “XamarinInstaller-VS2015.exe” heruntergeladen wird und es somit gut aussieht mit der VS 2015 Integration. Gleich mal „das Ding“ starten und der tollen Dinge harren, die da noch kommen mögen…
clip_image013
Nach der bekannten Installation (Android SDK, IOS-Integration,…) – welche ein klein wenig laaaaaange dauert, wenn man bisher noch kein Java und kein Android SDK installiert hatte, ist alles erledigt und der große Moment ist gekommen.
Nun, das dachte ich zumindest, der Xamarin-Installer verrichtet seine Arbeit sehr brav, allerdings sind in VS 2015 weit und breit keine Templates zu sehen – das dürfte allerdings nur auf Maschinen passieren, wo Xamarin bereits installiert ist.

VS 2015 Xamarin AddIn aktivieren

Um das zu beheben, erst einmal VS 2015 schließen und dann wiederum in „Programs and Features“ und „Xamarin“ anpassen.
clip_image014
Es wurde nämlich nicht automatisch die Integration für VS 2015 installiert, schade, aber das sind ja nur ein paar Mausklicks.
clip_image016 clip_image018

Neues Android Projekt – Versuch 2

So, jetzt aber, gleich wieder VS 2015 gestartet und die (erwarteten Templates tauchen wieder auf.
clip_image019
Sehr gut, dann kann es ja gleich losgehen mit einem neuen Xamarin.Forms Projekt.
clip_image021
Das sieht jetzt aber wirklich alles sehr gut aus, aber wiederum VORSICHT, falls Xamarin schon installiert war, das Xamarin SDK ist aus dem BETA-Channel und hat die Version 3.9.41 – falls die Meldung kommt, dass ein anderes SDK zur Verfügung steht, dann drückt bitte unbedingt “Abbrechen”, denn dann hattet ihr den Release, oder Beta Channel (wie ich z. B.) für Updates eingestellt.
Wenn alles gut geht, dann ist unser Projekt verfügbar.
clip_image022

Der Android Emulator

Wow, das klappt jetzt offenbar ohne Probleme, aber es wäre ratsam, dem Browserfenster, mit dem Link:
welches nach der Installation von Xamarin aufgepoppt ist, etwas Aufmerksamkeit zu widmen, hier steht nämlich:
“Please make sure that the following project property is NOT checked: Project -> Properties -> Android Options -> "Use Fast Deployment (debug mode only)"
Nun, wenn das schon ausdrücklich erwähnt wird, dann sollte man sich auch daran halten. ACHTUNG! Die CheckboxIST per default gesetzt, also weg mit dem Häkchen!
clip_image024
Jetzt fällt mir nicht mehr viel ein, außer:
· Das Android Projekt als Startprojekt festlegen und
· die Solution komplett erstellen.
Nun noch den Android Emulator starten - dieser scheint zu etwaigen bereits existierenden Emulatoren in dem (gewohnten) Dropdown in der Toolbar als “VS Emulator Android Phone“ bzw. “"VS Emulator Android Tablet” auf.
clip_image025
Gleich einmal auf den “VS Emulator Android Phone” draufgeklickt und was dann zu sehen ist, freut den “mobile Developer” gleich einmal ungemein: Es passiert wirklich etwas - nämlich im Output Fenster – und es kommt auch gleich eine Dialogbox dazu.
clip_image027
Nun, was ist ein Emulator für ein Android Device, ohne Internet? Eben, also auf den „Yes“-Button geklickt und ein wenig gewartet (eine gefühlte Ewigkeit, es waren aber dann doch nur ca. 2 Minuten), das Resultat aber nahezu BERAUSCHEND:
clip_image029 clip_image031
Der Emulator wie er sein sollte, mit der Xamarin.Forms Applikation!

 

Zusammenfassung

Visual Studio 15 und Xamarin waren schon bisher eine sehr gute Kombination, wenn es um mobile, native Entwicklung gegangen ist. Mit der Integration des Android Emulators ist das Erlebnis für Entwickler noch einmal besser geworden. Ich freue mich auf viele weitere Applikationen, die mit dieser Kombination erstellt werden.

Sunday, October 12, 2014

Codefest: Azure unterstützt NoSQL DocumentDB. Ja, und was soll ich damit?

clip_image001


Genau das hat mich einer meiner Kunden unlängst gefragt, als diese Meldung von Microsoft durch alle verfügbaren „Techie“-Kanäle gespült wurde. Dies hat mir wieder gezeigt, dass man als Trainer und Berater zur Zeit die Möglichkeit hat, aber auch die Notwendigkeit besteht, in diesem – für viele Firmen – neuen Umfeld Aufklärungsarbeit zu leisten. Widmen wir uns somit den Möglichkeiten der Datenspeicherung unter Azure und wann man welches der angebotenen Szenarien verwendet.
Um das Ziel Datenspeicherung zu erreichen, haben wir aber einen relativ weiten Weg zu beschreiten. Fangen wir also einmal mit der generellen Unterscheidung an, wie Daten abgelegt werden können:
Zur Verfügung stehen uns
1. relationale Datenbanken und
2. NoSQL Datenbanken.
Zerpflücken wir einmal 1. und danach 2., dann werden wir sehen, dass Microsoft hier wieder einmal mit Azure sehr innovativ unterwegs ist und uns schon heute Optionen für morgen anbietet!

 

Relationale Datenbanken

Ich selbst war sechs Jahre bei Sybase und kann daher voll und ganz verstehen, dass Microsoft den Source Code von Sybase vor langer Zeit gekauft hat und daraus ein großartiges Produkt mit dem Namen Microsoft SQLServer gemacht hat. Aber was macht relationale Datenbanksysteme so großartig? Ich bin mir ziemlich sicher, dass die meisten meiner Leser gelangweilt an die Decke starren, aber da sollten wir kurz durchtauchen, um möglicherweise im Anschluss eine komplett NEUE Welt (der Daten) kennen zu lernen und zu verstehen.
Den Grundstein für relationale Datenbanksysteme (kurz RDBMS) legte ein gewisser Edgar Codd (von IBM), der im Jahre 1970 (also sogar vor meiner Zeit) zwölf Regeln aufstellte (Codd's 12 rules[Ma1] ), die genau definieren, was denn ein System können sollte, um ein RDBMS zu sein. In den frühen 80er Jahren haben sich dann die ersten Hersteller mit diesem Thema auseinandergesetzt, und – voila – die Datenbanken, so wie wir sie (in den meisten Unternehmen) kennen, haben das Licht der Welt erblickt.
Wir verwenden also einen Datenbankserver, der uns eine oder mehrere Datenbanken zur Verfügung stellt. In einer Datenbank befinden sich wiederum eine oder mehrere Tabellen in einem bestimmten Schema, mit Spalten von einem definierten Datentyp und natürlich unseren hoch geschätzten Datenzeilen – ohne die unsere Datenbank recht leer aussehen würde. Wir finden in unseren Datenbanken Primärschlüssel, Fremdschlüssel und (hoffentlich auch) Indexe. Stored Procedures, Funktionen und Views wollen wir natürlich auch nicht vergessen. Wenn Daten geschrieben/gelesen/gelöscht werden, werden dazu von unseren Applikationen Transaktionen verwendet. Dass unsere Datenbank jederzeit konsistent ist (Stichwort ACID - Atomicity, Consistency, Isolation und Durability – sichergestellt durch Transaktionsprotokoll, Locking Mechanismen und Isolation Level) setzen wir natürlich voraus. Beim Design und der Definition der Tabellen verwenden wir die Normalisierung und als Abfragesprache benutzen wir standardisiertes SQL.
Ich denke, das war es im Schnelldurchlauf - zwar recht kompakt, aber hoffentlich verständlich zusammengefasst. In Summe doch etwas Großartiges, was sich in all den Jahren auf Basis dieser 12 Regeln entwickelt hat!

 

CAP-Theorem

RDBMS sind eine feine Sache, allerdings geraten wir mit den, in den letzten Jahren immer häufiger auftretenden, großen Mengen an Daten ein klein wenig in Schwierigkeiten. Diese wollen nicht mehr so recht in einen einzigen Server hineinpassen (irgendwann hat auch das Aufrüsten mit größeren und leistungsstärkeren Festplatten, zusätzlichem Speicher und stärkeren Prozessoren ein Ende erreicht), also werden diese zu einem verteilten System. Das ist aber nicht der einzige Grund. Neben dem Ressourcenmangel gibt es aber noch weitere Gründe:
· Netzwerk-Bandbreite - die Performance auf einem einzigen Server ist abhängig davon, wie schnell eingehende Anfragen empfangen und ausgehende Resultate gesendet werden können. Wenn die Netzwerklast die Kapazität des Netzwerkes übersteigt, kommt es zu Ausfällen und im Endeffekt zu unglücklichen Anwendern.
· Regionsabhängige Server – möglicherweise wird es notwendig, Anwenderdaten in dem Land zu speichern, in dem diese anfallen (unter Azure gibt es die Auswahlmöglichkeit zwischen 15 Regionen, wo die Daten abgelegt werden können). Gründe dafür können gesetzlicher Natur, seine, compliance, oder eben wieder die Performance (Latenz der Datenzugriffe) sein. Wenn Anwender in verschiedenen Teilen der Welt verstreut sind, ist es eben vermutlich besser, mehr als einen Server zur Verfügung zu stellen.
Wenn zumindest einer dieser eben genannten Gründe zutrifft, dann werden relationale Datenbanken verteilt. Nun, das bringt uns zum sogenannten CAP-Theorem, da solche verteilten UND weiterhin leistbaren Systeme nur zwei, der drei folgenden Eigenschaften (die wir an relationalen Datenbanken so schätzen) erfüllen können:
· (C) Strong Consistency - Konsistenz: Jeder Client (gemeint sind Anwendungen, bzw. die Anwender) sieht zur selben Zeit dieselben Daten, auch bei Datenänderungen – eben auch bei Transaktionen mit 2-Phase-Commits.
· (A) High Availability - Verfügbarkeit: Alle Anfragen von Clients an das Datenbanksystem werden jederzeit und mit akzeptabler Antwortzeit beantwortet.
· (P) Partition-Tolerance - Ausfalltoleranz: Das gesamte Datenbanksystem muss weiterhin stabil laufen, auch wenn einer der eingesetzten Server ausfällt oder neue Server hinzugefügt werden. Auch der Ausfall einer Kommunikationsverbindung muss verkraftet werden können, ohne dass die Clients etwas davon bemerken. Damit Daten auch nach Ausfall eines Servers vorhanden sind, werden sie repliziert auf verschiedenen Servern gespeichert.
Relationale Datenbanksysteme sind am ehesten im Bereich CA zu finden. Konsistenz der Daten hat üblicherweise bei den relationalen Systemen oberste Priorität (mittels Transaktionen und ACID). Den Anforderungen nach Ausfalltoleranz und Verfügbarkeit wird man meist durch sehr hochwertige und sehr leistungsfähige Hardware (im wahrsten Sinne des Wortes) Rechnung tragen.
Grafisch lässt sich das so darstellen:
clip_image003
Was ist aber nun mit CP und PA ? Hier können die NoSQL-Datenbanken eine Lücke schließen – und so betreten wir das Land der NoSQL-Datenspeicherung (und wir können an dieser Stelle auch erahnen, warum).

NoSQL Datenbanken

Beginnen wir zuerst mit der Definition von NoSQL: Wir könnten uns mit dem Namen Not only SQL zufrieden geben, aber da steckt mehr dahinter, nämlich die Datenbanken der nächsten Generation, diese sind
· nicht-relational,
· verteilt,
· Open-Source, sowie
· horizontal skalierbar.
Man könnte somit geneigt sein zu sagen: So ziemlich das Gegenteil von dem, was man (zumindest als Entwickler) bisher so geschätzt hat. Aber es kommt noch dicker, es gibt da noch weitere Anregungen, was eine NoSQL-Datenbank so bietet:
· einfache Replikation,
· ein simples API
· sehr grosse Datenmengen
· und das Allerbeste hebe ich mir für den Schluss auf:
EVENTUELL konsistent und Schema-Frei
Ich hoffe, die alteingesessenen Datenbank-Hasen unter euch sitzen immer noch halbwegs gerade auf dem Sessel (dabei habt ihr möglicherweise ‚ein simples API‘ sogar überlesen, was so viel bedeutet, wie non-SQL als Abfragesprache)? Ja, das ist schon starker Tobak, klingt aber durchaus durchdacht, wenn wir uns die fünf NoSQL-Technologien ansehen, die es am Markt gibt:
· Key/Value Stores – speichern der Daten mit einem Partition Key und einem Row Key.
· Column Stores – quasi eine Erweiterung der Key/Value Stores um eine weitere Gruppierung.
· Document Stores – Speicherung von Objektstrukturen im JSON-Format.
· Graph Databases – wenn die Beziehungen zwischen den Daten im Vordergrund liegen
· Big Data Analytics – Analysieren von (unvorstellbar) großen Datenmengen.
Da ein Bild mehr als 1000 Worte sagen kann, möchte ich die NoSQL-Technologien grafisch veranschaulichen:
clip_image005
Ich möchte nun jede einzelne dieser NoSQL-Technologien beleuchten und deren Einsatzgebiete herausstreichen.

Key/Value Stores

Es gibt hier verschiedene Implementierungen, in Microsoft Azure heißt der NoSQL Key/Value Store, Azure Table Storage. Um Daten im Table Storage zu speichern, wird eine Tabelle (heißt zwar so, hat aber keine Ähnlichkeit mit einer relationalen Datenbanktabelle) mit einem 2-teiligen Schlüssel und weitere Spalten für die Daten selbst benötigt. Dieser 2-teilige Schlüssel besteht aus:
· einem Partition-Key, nach diesem wird die Tabelle partitioniert und
· dem Row Key, dieser identifiziert die Zeile eindeutig INNERHALB der Partition (fast so wie der gewohnte Primary Key, aber eben nur beinahe).
Weitere Entitäten (unsere altbekannten Spalten) können nach Belieben angelegt werden und haben einen Namen, einen Datentyp und (vermutlich) einen Wert.
Ich hatte erst vor kurzem einen interessanten Anwendungsfall für einen Key/Value Store:
Es sollte ein Sicherheitssystem mit sechs Kameras realisiert werden, diese laden die Bilder alle zwei Sekunden in die Azure Cloud (als Blob-Storage) hoch. In dem Key/Value Store wurde folgende Information gespeichert:
· Partition Key: Der Name der Applikation
· Row Key: Die ID der Kamera
· Daten: Der Name des aktuellen Azure Blobs und die Aufnahmezeit
Natürlich wäre es möglich gewesen, eine relationale Datenbank zu verwenden, aber hier war der Preis ausschlaggebend, da der Azure Table Storage mit dem Azure Blob Storage sehr günstig ist und diese Lösung nur auf wenige € im Jahr (ca. €25,--) kommt.
Azure Table Storage ist, wie andere Implementierungen auch, auf Massendaten ausgelegt. Die Partitionen einer einzelnen Tabelle können sich über mehrere Maschinen verteilen. Ein Szenario also, wo wir mit relationalen Datenbanksystemen möglicherweise in Schwierigkeiten punkto Kosten kommen, da sie mit Sicherheit höher liegen. Dieses horizontale Partitionieren der Daten wird Sharding genannt. Windows Azure Table Storage führt das Sharding im Hintergrund aus und skaliert damit automatisch bei großen Datenmengen. Aber wie werden die Probleme gelöst, die bei relationalen Systemen auftreten würden?
Jede Abfrage an einem Key/Value Storage kann nur eine Partition ansprechen, Joins sind nicht möglich. Darauf muss natürlich bereits während der Entwicklung der eigenen Applikation Rücksicht genommen werden. Wie eingangs erwähnt: Auch wir Entwickler müssen umdenken und diese neueren Konzepte erst umsetzen lernen. Daten, die also gemeinsam abgefragt werden wollen, müssen auch innerhalb einer Partition liegen – das gilt übrigens auch für Transaktionen, diese gelten nur über eine Partition.

Column Stores

Microsoft Azure bietet HBase (mit HDInsight, also Hadoop) als NoSQL Column Store Implementierung an. HBase, bzw. Column Store-NoSQL-Datenbanken erinnern stark an eine relationale Datenbank, da die Daten in Tabellen gespeichert werden, Zeilen, Schlüsseln, Spaltenfamilien, Spalten und Werte sind auch vorhanden. Also alles wie gehabt, nur ein neuer Name? Mitnichten.
In HBase ist jede Datenzeile durch einen Key definiert, diese Datenzeile beinhaltet eine, oder mehrere Spalten, welche selbst wiederum Key/Value-Pairs darstellen.
Die Spaltennamen müssen nicht vordefiniert werden, das bedeutet, dass das Schema hier ebenfalls wiederum kein fixes ist – im Gegensatz zu relationalen Datenbanken. Die Spalten in einer Datenzeile werden sortiert nach ihrem jeweiligen Namen abgelegt. Zusätzlich speichert HBase zu jeder Zeile einen Zeitstempel – zur Versionierung - mit ab. Würde ein neuer Wert in eine der Spalten eingetragen, bleibt der alte Wert weiterhin erhalten.
Anwendungsfall gefällig? Facebook-Messaging, dort wird genau diese Technologie verwendet, wobei als Zeilenschlüssel die Benutzer-IDs verwendet werden, als Spalten-Bezeichner Wörter, die in den Nachrichten der Anwender vorkommen, allerdings wird der Zeitstempel anders verwendet, da sich gesendete Nachrichten nicht mehr verändern können, es wird die Nachrichten ID abgelegt.
Die beschriebene Art der Datenspeicherung ist ideal, wenn sehr viele Spalten in einer Datenzeile vorhanden sind und spezielle Bereiche gesucht werden. Dieser Satz, umgelegt auf das FaceBook-Messaging Szenario könnte einen zum Nachdenken bringen, was denn wohl alles mit dieser Technologie möglich ist.
Als Entwickler kann man sich das als geschachtelte Hashtable oder Dictionary, mit einer Tiefe von 2 oder 3 Levels vorstellen.
Was die Performance angeht, ist HBase skalierbar, wenn also mit großen Datenmengen von mehreren Gigabyte, oder sogar Terabyte gearbeitet wird, dann ist HBase interessant. Des Weiteren kann HBase Daten schnell replizieren, sodass im Fehlerfall fehlerhafte Knoten recht problemlos wieder hergestellt werden können.

Document Stores

In einem Document Store werden sogenannte Dokumente gespeichert, darunter darf man sich aber nicht z. B Word Dokumente oder PPT-Dateien vorstellen. Was aber könnte es dann sein?
Ein Beispiel: In einer relationalen Datenbank haben wir Tabellen und Spalten. Also ein festgelegtes Schema für die abzulegenden Daten. Was aber ist, wenn die Struktur, die wir als Entwickler verwenden, nicht in dieses Schema passt? Wie oft mussten wir schon das Datenbank-Schema in die Objekt-Struktur pressen, die man in der Anwendung verwendet? Natürlich wieder genau anders herum, wenn die Applikations-Daten persistiert werden sollen. Das war und ist lästig für den Entwickler. Hier wäre es um einiges einfacher, wenn das in der Applikation verwendete Format durchgängig – in einem Document Store - zur Verfügung stehen könnte.
Ein anderes Szenario wäre ein WCF-Service, welches Daten mittels Entity-Framework einliest und diese an einen HTML/JavaScript Client übertragen soll. Das ideale (universelle) Format dafür ist JSON (JavaScript Object Notation). Die Daten, die übertragen werden sind nun ebenso ein Dokument, welches in einem Document Store abgelegt werden könnte. Also eigentlich ein Objekt oder eine Objektstruktur als Dokument.
Ein weiterer Anwendungsfall wäre ein “Einkaufswagen” in einer Shopping-Applikation. Die abgelegten Produkte haben unterschiedliche Eigenschaften – also Objekte mit unterschiedlichen Strukturen - die durch das lose Schema einer JSON-Datei problemlos vorgehalten werden können – was in einer relationalen Datenbank ungleich schwieriger wäre. So ein Einkaufswagen könnte im JSON-Format so aussehen:
clip_image006­­­
In einer DocumentDB können natürlich komplexere und längere Dokumente gespeichert werden, man stelle sich einen Blog-Eintrag und die zugehörigen Kommentare vor, ein Summenfeld mit der Anzahl der Kommentare, Erscheinungsdatum, usw.
Die Azure DocumentDB befindet sich momentan in der Preview-Phase und kann für die neugierigen Entwickler unter euch getestet werden.

Graph Databases

Was wäre, wenn die Verbindung zwischen den Daten genauso wichtig, oder sogar wichtiger wäre als erst einmal die Daten selbst? Ich durfte drei Jahre lang an einem Projekt zur Bekämpfung von Geldwäsche mitarbeiten, wo wir genau den eben angesprochenen Fall hatten. Es ist interessant, wie Überweisungen, Personen und Firmen in Beziehung stehen und zuerst einmal gar nicht die zugrunde liegenden Daten selbst. In so einem Fall sind Graph Databases der geeignete Anwendungsfall.
Unter Azure gibt es keinen Vertreter dieser Gattung, der populärste ist hier Neo4J, welches aber unter Azure verwendet werden kann.
Wie der Name schon erahnen lässt, werden die Daten als Graph abgelegt. In Neo4J werden die Daten als Knoten bezeichnet, die Verbindungen zwischen den einzelnen Knoten sind Beziehungen. Sowohl Knoten als auch Beziehungen können Eigenschaften aufweisen – die uns nun schon gut bekannten Name/Value Pairs. Neo4J arbeitet (mittlerweile wenig überraschend) ohne festem Schema, somit können die Eigenschaften jede beliebige Information beinhalten.
Eine typische Abfrage in Neo4J beinhaltet den Startpunkt (ein einzelner Knoten im Graphen), die zu matchenden Daten, und die Knoten, zu dem Beziehungen und Eigenschaften zu retournieren sind.

Big Data Analytics

Hier sind wir bei einem meiner Lieblingsthemen angelangt. Hadoop, bzw. unter Microsoft Azure HDInsight. Dazu gibt es einen eigenen Blog-Eintrag, auf den ich an dieser Stell gerne verweisen möchte, da die Beschreibung von MapReduce, Hive und Pig dieses Mal den Rahmen sprengen würde.

Datenkonsistenz in NoSQL-Datenbanken

Da Daten zu mehreren Servern repliziert werden - einer verteilt die Daten an mehrere – stellt sich die Frage der Datenkonsistenz beim Zugriff auf ebendiese, da das Verteilen der Daten Zeit benötigt. Was passiert nun, wenn Clients auf diese Daten in der Zeit während die Synchronisation läuft zugreifen? Welche Daten sind denn nun für diese Clients sichtbar? In der NoSQL-Welt unterscheidet man zwischen Strong Consistency und Eventual Consistency. Aus der relationalen Welt sind wir Strong Consistency (read committed) gewohnt, das heißt alle Clients sehen immer die gleichen (korrekten) Daten, auch, wenn sofort – noch während das Schreiben der Daten läuft - gelesen wird.
Wenn das System nun nur Eventual Consistency unterstützt würden Clients alte Daten geliefert bekommen, da diese eventuell auf einen Server zugreifen, wo die Daten noch nicht synchronisiert wurden. Klingt absurd und unbrauchbar? Nun, ist es wirklich so wichtig in einem Blog die allerletzten Kommentare (sofort) zu sehen? Oder in einem FaceBook Beitrag? Man sieht also, es kommt ein wenig auf die Anwendung an, wofür das System eingesetzt wird.
Zwei weitere Consistency Level, die zwischen den beiden genannten liegen sind Bounded Staleness und Session. Ersterer garantiert konsistentes Schreiben mit verzögerten Lesezugriffen für alle Clients, letzterer garantiert die Datenkonsistenz für den aktiven Client für seine eigenen Lese- und Schreibzugriffe.
Wie sieht das unter Microsoft Azure aus?
· Azure Table Storage verwendet Strong Consistency, garantiert also die aktuellen Daten bei einem lesenden und schreibenden Zugriff durch mehrere, bzw. verschiedene Clients.
· Azure DocumentDB lässt uns die freie Wahl zwischen Strong, Bounded Stateless, Session, oder Eventual Consistency.
· HBase verwendet Strongly Consistent Lese- und Schreib-Zugriffe
Die Wahl des Consistency-Levels beeinflusst natürlich die Performance des Systems, wird Strong Consistency eingesetzt ist das die langsamste Variante für Lese- und Schreibzugriffe, Eventual Consistency die Schnellste.

 

RDBMS und/oder NoSQL?

Wie sollen nun neue Projekte entwickelt werden? Setzen wir in Zukunft NUR NOCH auf NoSQL? Fügen wir die NoSQL-Technologien erst einmal zu dem zuvor gezeigten Bild hinzu, so ergibt sich ein Gesamtbild und wir können uns überlegen, wie wir weiter vorgehen könnten:
clip_image008
NoSQL ist typischerweise eine gute Wahl, wenn es sich um unstrukturierte, bzw. Daten ohne festem Schema handelt. Das Schema muss nicht extra er- bzw. gefunden werden, Erweiterungen mit neuen Feldern sind– in Hinsicht auf die Speicherung - problemlos zu verarbeiten.
Eine denormalisierte Form der Daten wird nicht nur favorisiert, sondern ist sogar notwendig, da keinerlei Joins, zumindest in der Art und Weise wie diese in relationalen Systemen gehandhabt werden, Unterstützung finden.
Lösungen, die mittels NoSQL implementiert werden, lassen sich häufig einfach besser skalieren als relationale Datenbanklösungen. Das Hinzufügen weiterer Datenknoten ist einfach, die Daten werden meist repliziert, daraus ergibt sich in Summe auch einen besseren Schutz gegen Datenverlust.
Allerdings bieten die NoSQL-Lösungen nicht die Möglichkeit von ACID-Transaktionen über mehrere "Tabellen". Desweitern gilt natürlich, dass komplexe und/oder dynamische Abfragen, bzw. Berichte am besten von einem relationalen Datenbanksystem bedient werden. Die Abfragemöglichkeiten von NoSQL-Lösungen sind dafür einfach zu limitiert – was ja auch nicht im Sinne der Erfindung wäre.
Wie sehr häufig im Leben gibt es nicht das allgemein gültige Kochrezept, es muss also nicht immer das Eine oder das Andere sein. Für bestimmte Gesamtlösungen kann ich mir ohne Weiteres eine Hybrid-Form - die Kombination eines relationalen Systems mit einem NoSQL-System vorstellen.

Quellen

Relational Database: http://en.wikipedia.org/wiki/Relational_database
Cod’s 12 rules: http://en.wikipedia.org/wiki/Codd%27s_12_rules
CAP-Theorem: http://de.wikipedia.org/wiki/CAP-Theorem
NoSQL Datenbanksysteme: http://nosql-database.org/
FaceBook
 & HBase: https://www.facebook.com/publications/376874985754849/
Neo4J
 unter Azure: http://neo4j.com/blog/announcing-neo4j-on-windows-azure/

 

Zusammenfassung

Microsoft ist mit Azure und den angebotenen Storage-Möglichkeiten im NoSQL-Bereich meiner Meinung nach ein Vorreiter und Visionär. Hier wird Technologie geboten, die die meisten Unternehmen noch nicht ausreichend anzuwenden wissen. Die Möglichkeiten, die sich hier für Entwickler und Firmen bieten, um neue Applikationen und Dienste anbieten zu können, sind großartig und werden vermutlich erst in den nächsten Jahren ihr volles Potential entfalten. Wir alle müssen uns erst auf diese Technologien einlassen und ihnen auch das Vertrauen entgegen bringen, das diese meiner Meinung nach auch verdienen. Es sind nicht neue Technologien, da diese größtenteils schon jahrelang im Einsatz, aber der breiten Business-Community bisher verborgen geblieben sind. Microsoft leistet hier mit der Azure Plattform eine großartige Möglichkeit all diese Technologien zu testen und neue Visionen umzusetzen.

CSharpCodeFormatter