All Posts By

Stefan Zörner

Betragsbild_Blog_Bauteil_3

Figuren ziehen mit Single Page Application in Vue.js (Micro Moves, Bauteil 3)

By | Inhaltliches | 2 Comments

Blog-Serie Micro Moves -- LogoMit den ersten beiden Bauteilen der Micro Moves Blog-Serie sind zwei Services unserer Online-Schachplattform entstanden. Der games-Service für die laufenden Partien bietet eine REST-Schnittstelle (Folge 1), der chess-diagrams-Service liefert auf HTTP-Anfrage eine PNG-Bild mit der Situation auf dem Schachbrett (Folge 2).

In dieser Folge machen wir nun erste Schritte Richtung „echtes“ Frontend und kombinieren die beiden. Ziel ist es im Web-Browser eine neue Partie zu eröffnen und Züge zu machen. Ein zweiter Spieler kann sie sehen und seinerseits ziehen. Ihr könnt dann zu zweit gegeneinander Schach spielen immerhin schon. Schönes Iterationsziel also.

Um was geht es — ein Überblick

Diese Folge liefert sowohl ein Beispiel für ein klassisches Request-Response-basiertes Frontend, als auch eine Single Page Application (kurz SPA). Das klassische Frontend bauen wir im games-Service ein (im Bauplan unten die (1)). Der SPA spendieren wir ein neues Modul play; sie nutzt die beiden Services. Die rote (3) markiert deren Standpunkt der SPA im Gesamtbild („Sie befinden sich hier.“).

Überblick FLEXess

In dieser Folge kommen Spring Web MVC mit Thymeleaf als Template-Mechanismus zum Einsatz und das JavaScript-Framework Vue.js für die SPA. Wenn ein Spieler einen Zug macht, muss sein Gegner diesen sehen. Für diese Kommunikation vom Server zu den Clients nutzen wie WebSocket.

Aber der Reihe nach …

Die UI-Frage

Im Zusammenhang mit Microservices finde ich die Frage, wie man mit dem User Interface umgeht, besonders spannend. Martin Fowler und James Lewis sprechen in ihrer „Definition“ des Architekturstils von einer Anwendung, die aus unabhängigen Prozessen besteht. D.h. für den Benutzer sollte es sich wie ein UI anfühlen, obwohl die Lösung aus technologisch unterschiedlich realisierten Teilen besteht. Wie unser FLEXess hier auch. Wie stellt man das an?

In diesem Zusammenhang gibt es reichlich zu entscheiden. Rich Client vs. Web, im Falle Mobiler Endgeräte Native vs. Hybrid etc. Konzentrieren wir uns auf den häufigen Fall einer Webapplikation! Auch hier gibt es unterschiedliche Spielarten (Request/Response vs. SPA sehen wir später noch, und auch hier gibt es Hybrid-Ansätze).

Im Zuge vertikaler Architekturstile entscheidet unabhängig davon eine Frage: Trägt eine einzelne Vertikale (z.B. ein Microservice) sein UI mit sich, oder sind die Vertikalen UI-los. Die folgende Abbildung illustriert die beiden Extreme (auch hier gibt es Lösungen dazwischen).

UI-Optionen

Konkret kann das so aussehen, dass in Modell 1 links im Bild jeder Service neben der Business-Logik (BL) ein Webfrontend in sich trägt. Die Integration findet im Browser etwa über Links statt. Im Modell 2 bieten die Services die Business-Logik z.B. über eine REST-Schnittstelle an, Eine übergeordnete UI (etwa native Apps oder eine SPA) nutzt diese.

Im ersten Modell haben Teams den kompletten Technologie-Stack inkl. Frontend in der Hand und können z.B. die UI-Technologie zu einem gewissen Grad frei wählen. Dafür ist es bei diesem Ansatz fordernd, dem Anwender eine Anwendung aus einem Guss zu präsentieren. Modell 2 ermöglicht tendenziell eine bessere User Experience, aber unter Verzicht einer unabhängigen Entwicklung der einzelnen UI-Teile und echt Cross-funktionaler Teams (für das übergeordnete UI ist oft ein separates Team zuständig).

Der Widerspruch User Experience vs. unabhängige Entwicklung lässt sich abschwächen, etwas durch eine Integration im Build.

Web-Applikation mit Spring Web MVC und Thymeleaf

Ein technologisch „klassischer“ Ansatz gemäß Modell 1 (Vertikale mit UI Huckepack) erzeugt die Oberfläche serverseitig mit einem geeigneten Framework, und liefert an den Browser HTML-Seiten. Vielleicht angehübscht mit CSS und ein bisschen JavaScript für dynamische Aspekte, damit es nicht ganz so 90er rüberkommt. Eine Interaktion mit dem Nutzer läuft über einen Request/Response-Zyklus ab. Der Browser sendet ausgelöst durch einen Link oder das Absenden eines Formulars eine Anfrage, der Server antwortet mit dem neuen Seiteninhalt.

Zur Illustration dieses Ansatzes erweitern wir hierzu unser games-Modul für die Schachpartien entsprechend (Quelltext hier). Mit Spring Web MVC (Model View Controller) ist das flink gemacht. Insbesondere da wir in Folge 1 die Geschäftslogik getrennt von der REST-API gehalten haben. Die Klassen für die Weboberfläche findet Ihr im Paket org.flexess.games.web, das analog zur REST-API auf die Services zugreift:

Pakete im games-Modul (Diagramm: Teamscale)

Annotationen an den Controller-Klassen legen das Mapping von URLs zu Verhalten fest. Das Generieren der Seiten übernimmt Thymeleaf (Verwendung im Build-File Gradle angeben). Thymeleaf versteht sich als  moderne serverseitige Java-Template-Engine.

Thymeleaf LogoFür mehr Details: Der Beitrag „Getting Started: Serving Web Content with Spring MVC“ nutzt ebenfalls Thymeleaf und zeigt die Integration in Spring Boot. Etwas mehr zum Funktionsumfang der Template-Engine selbst zeigt Eugen Paraschiv in seinem Artikel „Introduction to Using Thymeleaf in Spring“.

Die Templates für unser games-Modul liegen im Verzeichnis src/main/resources/templates. Sie sind mit Bootstrap angehübscht. Die Startseite erreicht Ihr aktuell mit http://localhost:8080, wenn Ihr den Service wie in Folge 1 baut und startet. Weitere Seiten sind von dort verlinkt (Screenshots siehe Abbildung unten).

Später steuert games einen Beitrag zur Gesamtoberfläche von FLEXess gemäß UI-Modell 1 bei. Das diskutieren wir, wenn ein zweites Bauteil mit eigenem UI hinzu kommt, und die beiden sich aus einem Guss präsentieren wollen.

Screenshots Web Application

Grundsätzlich ließe sich mit dem Ansatz die ganze Oberfläche bauen. Die größte Herausforderung liegt in der Interaktion während einer Partie. Jeder Schachzug müsste mit einem Request zum Server gelangen, und der Gegner (anderer Client, anderer Browser) ihn auch sehen, um seinerseits mit einem Zug zu antworten.

Die Dynamikanforderungen an das UI nehmen wir zum Anlass, um als Alternative zur Request/Response-basierten Oberfläche eine Single Page Application (kurz SPA) zu zeigen. Ihr könnt dieses Teil als Blaupause für ein UI nach Modell 2 sehen.

Single Page Application mit Vue.js

Bei einer SPA liefert der Server eine einzelne (HTML-)Seite an den Client. Jede weitere Interaktion läuft mit Hilfe von JavaScript im Browser ab. Mit dem Server kommuniziert eine SPA typischerweise via REST. Passenderweise hält das games-Modul eine solche Schnittstelle bereit (vergleiche Folge 1, die Rolle von curl und Postman dort übernimmt jetzt die SPA).Vue.js Logo

Vue.js ist ein JavaScript-Framework zur Entwicklung eben solcher SPAs. Vergleichbare Lösungen (und Mitbewerber) wären React oder Angular.js. Die Vue.js-Homepage bietet einen guten Einstieg in die Entwicklung mit dem Framework.

Für unseren Fall hier haben wir lediglich das Spielen einer Partie als SPA umgesetzt. Aus der klassischen Web-Oberfläche gelangt man über einen Link zu ihr (siehe Screenshot oben, grüner Button „Play Game!“). Die zu spielende Partie wird via ID als Request-Parameter übergeben und von der play-SPA ausgelesen.

Die Quelltexte zur SPA findet Ihr hier. Sie sind überschaubar: Lediglich eine HTML-Seite (SPA halt ;-)) und dort eingebettet drei JavaScript-Dateien. Die folgende Tabelle gibt einen Überblick:

Datei Beschreibung
index.html Trägt die initiale HTML-Seite mit Layout, Navigation etc. und verweist auf die JavaScript-Dateien
src/main.js Die eigentliche Vue.js-Anwendung mit Daten und Verhalten
src/games.js Funktionen für die REST-Calls gegen die API des games-Moduld (z.B. Ziehen) sowie für die WebSocket-Kommunikation mit games.
src/chess-diagrams.js Funktionen für die Einbindung der Schach-Diagramme des chess-diagrams-Moduls.
package.json Informationen für npm. (Siehe unten)

Neben diese Dateien sind noch einige Fremdbibliotheken erforderlich. Vor allem Vue.js natürlich, aber auch Bootstrap für das Layout und Bibliotheken für WebSocket (siehe unten). Ich habe es mir hier einfach gemacht, und die Abhängigkeiten als Links auf ein CDN (Content Delivery Network) eingepflegt. Somit lädt der Browser sie einfach aus dem Internet. Alternativ wäre auch ein Build-Prozess mit geeigneten Tools denkbar. Das hebe ich mir für einen späteren Beitrag auf, wenn wir mehr mit JavaScript machen.

Die Anwendung starten und verwenden

Theoretisch könnte man die Anwendung lokal im Web-Browser öffnen. Sehr realistisch wäre das aber nicht — die Spieler müssen ja irgendwie an den Client kommen. Besser wäre da schon eine Verteilung über das games-Modul, das ja bereits Seiten per HTTP ausliefert (siehe oben).

Ich habe mich für einen separaten Serverprozess für play entschieden, um die Sachen voneinander entkoppelt zu halten (Angelehnt an Modell 2). Eine recht schlanke Lösung ist ein HTTP-Server, der sich via Node.js betreiben lässt (von Node.js werden wir später in dieser Serie noch mehr hören).

„Installation“ und Betrieb können bei installiertem npm (Node Package Manager, liegt Node.js bei) so erfolgen:

$ git clone https://github.com/embarced/micro-moves.git
Cloning into 'micro-moves'...
$ cd micro-moves/modules/play/
$ npm install
$ npm start

> play@0.1.0 start /Users/stefanz/Documents/GitHub/micro-moves/modules/play
> httpserver -p 7000

lo0: 127.0.0.1
utun0: null
vboxnet1: 192.168.99.1
en5: 192.168.2.124
server started: http://0.0.0.0:7000
$

 

Der verwendete Port 7000 ist in package.json hinterlegt. Die Spring Web MVC-Applikation oben ist schon vorbereitet. Deren „Play Game!“-Link verweist genau auf diese Adresse mit der ID der Partie als Parameter. Die SPA stellt sich dann so im Browser dar:

SPA play in Aktion

Die SPA setzt nach laden der index.html einen REST-Call gegen das games-Subsystem ab. Sie holt sich Partie-Informationen zur ID, die sie zum Beispiel in der Titelzeile (Namen der Spieler) anzeigt. Hingucker ist sicherlich die Darstellung des Brettes. Unter der Haube ein Bild aus dem chess-diagrams-Service (HTML-Tag img mit geeigneten src-Attribut. Die URL wird mit dem FEN-Wert aus den Spielinformationen als Parameter versorgt). Damit das Ganze funktioniert muss neben play (lokal, Port 7000) und dem games-Services (lokal, Port 8080) auch der chess-diagrams-Service (lokal, Port 5000, vgl. Folge 2) laufen.

Die Eingabe des Zuges erfolgt entweder als Text im Input-Feld (z.B. „e2e4“ für e2 nach e4), oder durch klicken in die Brettdarstellung. Eine Funktion aus chess-diagrams.js ermittelt die Koordinaten (z.B. „h4“) und fügt sie ins Input-Feld ein. Keep it simple.

Aktuell überprüft die Anwendung noch nicht, ob der Browser-Benutzer überhaupt an der Partie beteiligt ist. Den Themen Authentifizierung und Autorisierung widmen wir einen späteren Beitrag. Folgerichtig kann ein Benutzer jetzt einfach auf dem Brett gegen sich selbst spielen.

Der Screenshot oben ist in einer neuen Partie nach einem weißen und einem schwarzen Zug entstanden, gefolgt von einem weiteren Versuch den schwarzen Springer auf f6 zu bewegen. Allzu viel prüft der games-Service aktuell nicht (später übernimmt das der Spielregeln-Service). Zu Testzwecken checkt er zumindest, ob die Farbe der Figur passt. Daher die Warnmeldung im Screenshot.

Kommunikation mit Web Socket

Wie läuft die Kommunikation nun genau ab? Nach Eingabe des Zuges und Abschicken des Formulars  (Button „Send Move“) setzt die SPA einen REST-Call (POST Request) gegen den games-Service ab (Funktion sendMove() in games.js). Der landet dann in der Methode createMove() des GameRestController von games. Im Falle eines Fehlers (wie oben, Figur falscher Farbe) liefert diese einen passenden HTTP-Fehlercode zurück.

Playing ChessWenn der Zug akzeptabel ist speichert games ihn, führt ihn aus (ermittelt also die neue Spielsituation) und aktualisiert die Game-Entität (speziell: wie sieht das Brett aus, wer ist am Zug …?). Das erfolgt in der Methode createAndPerformMove() aus der Klasse GameService in games.

Die SPA könnte sich jetzt den neuen Zustand der Partie via GET-Request gegen games holen — sie „weiß“ ja, dass sich die Spielsituation durch Ausführung des Zuges geändert hat. Das ist allerdings nur die halbe Miete. Denn es gibt ja in der Regel noch einen zweiten Spieler mit einem anderen Browser, der ebenfalls über die Änderung informiert werden muss, um dann seinerseits einen Zug zu machen. Die Spieler ziehen ja abwechselnd.

Die SPA verbindet sich daher stattdessen per WebSocket mit dem games-Server, und lauscht auf Ereignisse. Der andere Spieler tut es ihm mit seinem Browser gleich. Im Falle einer neuen Spielsituation sendet games eine Nachricht an ein Topic, welche die neue Spielsituation enthält. Wenn beide Spieler mit ihren SPA dieses Topic abonnieren kriegen sie es mit. Das Topic lautet bei uns /topic/game_XY, wobei XY die ID der Partie ist.

Die Rolle des WebSocket-Servers übernimmt die Spring Boot-Applikation games. Die Konfiguration steckt in der Klasse org.flexess.games.web.WebSocketConfig. Auf Client- (also SPA-)Seite sind die betreffenden JavaScript-Funktionen in games.js implementiert (webSocketConnect() etc.). Die folgende Abbildung illustriert das Zusammenspiel zwischen zwei SPAs (Weißer und Schwarzer Spieler) und dem games-Service als Sequenzdiagramm. Weiß und Schwarz spielen jeweils einen Zug.

Sequenzdiagramm (plantUML)

Bei der Umsetzung habe ich mich am Beitrag „Using WebSocket to build an interactive web application“ orientiert, der ein „Hello World“ mit Spring Boot und WebSocket beschreibt.

Weitere Informationen — und wie es weiter geht …

Das Zusammenspiel der drei Einzelteile play, games und chess-diagrams ist im Moment noch „etwas“ fragil. Als Showcase mag es taugen, aber alle Teile laufen auf localhost und die Adressen und Ports sind in der Vue.js-Applikation als Konstanten fest verdrahtet (zu Beginn von games.js und chess-diagrams.js).

The Majesty of Vue.js 2Idealerweise sollte die SPA nicht alle unterschiedlichen Services persönlich kennen. Und bei horizontaler Skalierung sollten auch mehrere Exemplare der Services laufen können — unsichtbar für den Client. Derartige Themen adressieren wir mit dem nächsten Bauteil. Dann ziehen wir einen Reverse-Proxy ein.

Wenn Ihr mehr zu Vue.js erfahren wollt möchte Ich Euch noch das schöne Buch „The Majesty of Vue.js 2“ ans Herz legen (erschienen bei Leanpub, Cover rechts). Es führt mit vielen kleinen Beispielen lebendig in alle Aspekte ein, die wir hier verwendet haben (z.B. Computed Values zur Aktualisierung der Schachbrett-Graphik nach einem Zug).

Ach ja: Fragen und Anregungen sind natürlich jederzeit gerne Willkommen. Per Kommentar hier im Blog oder gerne auch per Mail direkt an mich …

Zur Blog-Serie Micro Moves

Beitragsbild_Bauteil_2

Service für Schach-Diagramme mit Python und Flask (Micro Moves, Bauteil 2)

By | Inhaltliches | No Comments

Blog-Serie Micro Moves -- LogoIn der ersten Folge der Micro Moves Blog-Serie haben wir einen Service auf Basis von Java und Spring Boot an den Start gebracht. Inhaltlich ging es um die laufenden Partien unserer Schach-Online-Plattform FLEXess.

In dieser Folge gibt es einen zweiten Service in Python. Ist eine andere Programmiersprache was tolles? Was spricht dagegen, den Service auch in Java zu bauen?

Um vielen einen Blick über den Tellerrand zu ermöglichen, zeige ich in dieser Blog-Serie unterschiedliche Technologien (und auch Programmiersprachen). Vielfalt ist Teil des Konzeptes. Aber …

Ist polyglott per se schick?

Monolithische Anwendungen stehen in vielen Unternehmen am Pranger. Der Grund dafür ist oft, dass es (zu) lange dauert neue Anforderungen umzusetzen, und/oder in Produktion zu bringen. Release-Zyklen von 3 Monaten und länger sind beispielsweise im Finanzbereich keine Seltenheit.

Mit der Zerlegung in kleine, unabhängige Teile (im Extremfall Microservices, moderater bei Self-contaned Systems) öffnet sich Spielraum, in den Teilen Dinge unterschiedlich zu handhaben. Mitunter wird dies sogar als eine besondere Stärke herausgestellt, für die Teile technologische Entscheidungen passgenau auf das Problem treffen zu können. Ein häufiges Beispiel hier ist die Persistenz. Wenn Services in unterschiedlichen Prozessen laufen, können sie auch leicht in unterschiedlichen Programmiersprachen entwickelt sein. Aber sie müssen nicht. Es sollte Nutzen stiften (in echten Vorhaben ist Vielfalt hier selten ein Wert an sich).

Was macht der Service?

Für verschiedene spätere Folgen benötigen wir Visualisierungen des Schachbretts. Die Forsyth-Edwards-Notation (kurz FEN), wie die die Entität Game aus der letzten Folge benutzt, ist wenig tauglich, um die Spielsituation zu erfassen. Ziel sind Graphiken wie diese:

Schachbrett mit Startaufstellung, generiert mit unserem Python Service

Der Service nimmt eine Spielsituation in FEN entgegen und liefert eine graphische Repräsentation wie oben zurück. Die Funktionalität steht per HTTP bereit, für den ersten Wurf unterstützt er

  • Eingabe in FEN als Request-Parameter
  • Response: Diagramm in fixer Größe (288 x 288 px, Figuren jeweils 32 x 32) und einem Format (PNG).

Es ist noch einiges an Einstellmöglichkeiten (etwa über Parameter) denkbar: andere Größen, Graphikformate, Figurensymbole, Farben … Wir fügen sie hinzu, wenn wir sie im Laufe der Serie brauchen. Die rote (2) markiert Euren Standpunkt im Gesamtbild („Sie befinden sich hier.“).

Lageplan FLEXess, Bauteil 2

Python und Flask

Die Programmiersprache Python (WikipediaHomepage), obgleich recht alt,  erfreut sich gerade aktuell großer Beliebtheit. Der TIOBE-Index (umstritten) führt Python im April 2018 auf Platz 4, RedMonk (umstritten) auf Platz 3. Unbestritten: Trends wie Big Data und Machine Learning erhöhen die Aufmerksamkeit für die Sprache.

Flask Web Development, 2nd EditionPython ist u.a. objektorientiert und in der Regel interpretiert. Ein häufiger Einsatzzweck sind daher Skripte. Ähnlich wie in Java oder .Net liefert Python eine Standardbibliothek mit. Darüber hinaus gibt es noch viel, viel mehr aus der Community. Da wir die Diagramme per HTTP ausliefern wollen brauchen wir eine Web-Applikation. Hier ist Flask recht beliebt und eben genau so ein Framework von Dritten.

Flask bezeichnet sich selbst als Micro-Framework für Web-Applikationen. Es beinhaltet einen Development HTTP-Server und verarbeitet dynamische Anfragen RESTful. Das „Micro“ in Micro-Framework heißt, dass Flask versucht seinen Core einfach aber erweiterbar zu halten. Anders als beispielsweise Django trifft Flask kaum Entscheidungen, etwa welche Datenbanktechnologie zu verwenden wäre. Mehr zu Flask im schönen Buch von Miguel Grinberg (Cover rechts), die zweite Auflage ist gerade frisch raus (März 2018).

Die graphische Arbeit erledigt bei uns Pillow, ein Fork der Python Imaging Library (PIL).

Die Umsetzung

Dank Flask und Pillow ist nicht all zu viel zu tun. Der überschaubare Python-Quelltext des chess-diagrams-Moduls liegt auf GitHub. Ich habe ihn auf zwei Dateien aufgeteilt.

Datei Beschreibung
chess_diagrams.py Enthält die Flask-Applikation mit zwei HTTP-Routen (Test-Seite in HTML und Diagram-Generierung). Abhängigkeiten zu Flask und draw.py
draw.py Enthält Funktionen zur Erzeugung der Diagramme.  Abhängigkeit zu Pillow.

Darüber hinaus liegen die Figurenbilder als PNG im Ordner images, und ein Font für die Brettkoordinaten (a..h, 1..8) im Ordner fonts. Um den Service leicht ausprobieren zu können, ohne FEN in der URL tippen (und enkodieren) zu müssen, liegt eine Test-Seite als HTML im Ordner templates.

Für die Funktion zum Erzeugen einer Diagramm-Graphik ausgehend von einem Web-Request sieht der Call-Graph (generiert mit Doxygen) so aus.

Call Graph (Doxygen)

Die folgende Graphik zeigt die Wirkung der einzelnen draw_xy-Funktionen aus draw.py zum Zeichnen eines Diagramms.

Schritte zum Diagramm in draw.py

Den Service bauen, starten und nutzen

Python ist eine interpretierte Sprache. Übersetzt werden muss der Quelltext daher nicht. Lediglich ein Python-Interpreter muss vorliegen. Getestet habe ich mit den Versionen 2.7 und 3.6. Abhängigkeiten lassen sich mit der Python-eigenen Paketverwaltung pip installieren (pip = pip installs packages). Die Datei requirements.txt zählt  die Pakete auf.

$ git clone https://github.com/embarced/micro-moves.git 
Cloning into 'micro-moves'... 
$ cd micro-moves/modules/chess-diagrams/
$ cat requirements.txt 
Flask
Pillow
$ 

Nach Installation der Pakete ließe sich das Ganze direkt starten. Zuvor lassen wir aber noch Unit- und Integrationtests laufen. Als Testwerkzeug verwende ich pytest. Die Ausführung der Tests in verschiedenen Umgebung (Python 2 und 3) überlasse ich tox. tox ist insbesondere im Umfeld von Continuous Integration beliebt, etwa beim Einbinden in einen CI-Server wie Jenkins. Einfach per pip installieren und tox aufrufen — die Datei tox.ini legt u.a. fest, für welche Versionen die Tests (Dateien mit dem Präfix test_) laufen sollen …

$ pip install tox
$ tox
... 

Test laufen lassen mit tox

Neben Unit-Tests für draw.py sind auch Integrationstests inkl. Flask-Webapplikation enthalten.  Wie Ihr Flask-Anwendungen testet beschreibt diese Seite.

Den Service im Development Web-Server von Flask starten, um ihn z.B. mit einem Browser zu testen, geht am einfachsten so:

$ pip install -r requirements.txt
$ python chess_diagrams.py
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
... 

Der Service lauscht nun auf localhost, und Ihr könnt ihn direkt mit einem Browser ansprechen über http://127.0.0.1:5000/. Die Testseite enthält ein paar Links um Diagramme zu erzeugen, die dann als PNG zurückgeliefert werden.

Testseite und einzelnes Diagramm im Browser

Der Service im Betrieb

Den von Flask mitlieferten HTTP-Server solltet Ihr nur zu Entwicklungszwecken einsetzen. Das Projekt rät selbst von einem Einsatz in Produktion ab und nennt auf seiner Webseite zahlreiche Alternativen, um Flask-Anwendungen in einem Web-Server zu betreiben. Hierzu zählen Public Cloud-Umgebungen wie Amazon (via AWS Elastic Beanstalk) oder Google App Engine eben so wie selbst betriebene HTTP-Server.
Green Unicorn Logo
Als ein Beispiel zu letzteren zeige ich hier gunicorn (für Green Unicorn, Logo rechts) laut „Selbstauskunft“ ein ziemlich schneller Python WSGI HTTP Server für UNIX. Die Installation kann ebenfalls über pip erfolgen. Die folgenden Zeilen Zeichen den Start unseres Service in gunicorn mit 4 Workern.

$ pip install gunicorn
$ gunicorn -w 4 chess_diagrams:app
[2018-05-01 14:38:20 +0200] [14928] [INFO] Starting gunicorn 19.7.1
[2018-05-01 14:38:20 +0200] [14928] [INFO] Listening at: http://127.0.0.1:8000 (14928)
[2018-05-01 14:38:20 +0200] [14928] [INFO] Using worker: sync
[2018-05-01 14:38:20 +0200] [14931] [INFO] Booting worker with pid: 14931
[2018-05-01 14:38:20 +0200] [14932] [INFO] Booting worker with pid: 14932
[2018-05-01 14:38:20 +0200] [14933] [INFO] Booting worker with pid: 14933
[2018-05-01 14:38:20 +0200] [14934] [INFO] Booting worker with pid: 14934
$

Faktoren und Prinzipien für Microservices und die Cloud

Für Anwendungen die einem aktuellen Architekturstil genügen und die sich vielleicht auch in „der Cloud“ wohlfühlen gelten einige Eigenschaften als zentral. Sehr verdichtet finden sich diese in Form von Listen aus Faktoren oder Prinzipien versammelt und diskutiert, von denen die älteste und bekannteste die Twelve-Factor-App ist. Eine etwas neuere Meinung findest sich E-Book „Beyond the Twelve-Factor-App“ von Kevin Hoffman. Weniger Microservices-lastig sind die ISA-Principles (ISA = Independent Systems Architecture) — sie haben (auch) Self-contained Systems im Sinn und kommen aus deren Umfeld.

Hält man den chess-diagrams Service gegen die Faktoren, so fällt insbesondere auf, dass er im Gegensatz zum games-Service rasant startet. Schnelles Starten ist entscheidend, wenn man auf hohe Last dynamisch mit weiteren Exemplaren reagieren möchte.

Der games-Service liegt bei mir bei etwa 10 Sekunden für den Start. Fairerweise ist ein in Spring Boot realisierter Service schneller oben als ein Java EE Application Server inklusive Service. Hauptkritikpunkt für in Java realisierte Services z.B. im Docker/Kubernetes-Umfeld ist allerdings nicht die Startzeit, sondern der Ressourcenhunger, insbesondere in Bezug auf Speicher.

Weitere Informationen — und wie es weiter geht …

Wenn man von Java kommt wie ich ist Entwickeln in Python wie eine Reise in ein fremdes Land. Die Sprache ist ausgereift und natürlich gibt es alles, was Ihr in Java zum Programmieren nutzt, in Python irgendwie auch. Nur wie? Zum Beispiel: Wie testet Ihr Eure Sachen? Wie bindet Ihr Fremdbibliotheken ein? Welche IDE benutzt Ihr? Einige Sachen waren sehr ungewohnt für mich. Zum Beispiel die parallele Existenz von Python 2 und 3.

The Hitchhiker's Guide to Python (Cover) Ein Buch, das mir hier sehr geholfen hat, ist „The Hitchhiker’s Guide to Python“ von Kenneth Reitz (Cover rechts). Es ist dicht gepackt mit Best Practices, Konventionen und gebräuchlichen Werkzeugen aus dem Python-Universum. Und es ist hier frei online verfügbar (!).

Im weiteren Verlauf gibt es noch ein weiteres Bauteil in Python übrigens. Das für die Spieler. In der nächsten Folge verheiraten wir aber erst einmal die Teile aus den ersten beiden Folgen (games und chess-diagrams) und setzen eine Single Page Application (SPA) als Oberfläche drauf. Ziel: Im Browser gegeneinander spielen können …

Ach ja: Fragen und Anregungen sind natürlich jederzeit gerne Willkommen. Per Kommentar hier im Blog oder gerne auch per Mail direkt an mich …

Zur Blog-Serie Micro Moves

Beitragsbild_Bauteil_1

Ein erster Service mit Java und Spring Boot (Micro Moves, Bauteil 1)

By | Inhaltliches | No Comments

Blog-Serie Micro Moves -- LogoNachdem ich in der Intro den fachlichen Rahmen für die Schach-Anwendung FLEXess aufgespannt habe, gibt es in diesem Beitrag den ersten inhaltlichen Service: games. Oder genauer gesagt eine erste Fassung davon — denn der Service wird noch ein paar Verbesserungen erleben über die Zeit (u.a. ein UI). Die Quelltexte für den Service findet Ihr auf GitHub. Die Bezeichner in Quelltext und API (Klassennamen, Methodennamen etc.) sind Englisch. Das erschwert das Verständnis mitunter. Denn die Englischen Schachbegriffe erschließen sich selbst Schachkennern nicht automatisch. Das gilt bereits für grundlegende Dinge wie Figurennamen. Ich habe daher eine kleine Randnotiz dazu geschrieben:  Lady hits farmer … (?) Schachbegriffe auf Englisch. Doch bevor wir in den Quelltext eintauchen … zunächst: Was kann der Service fachlich?

Unser erstes Bauteil: Der games-Service

Bauteil 1Mit diesem Service können Anwender vorhandene Schach-Partien abfragen, inklusive deren Details (z.B. die gespielten Züge). Sie können neue Partien einleiten und sich dabei die Farbe aussuchen. Sie können offenen Partien als zweiter Spieler beitreten. Und sie können Züge ausführen.

Partien besitzen dabei drei Zustände:

  • OPEN: Die Partie ist offen, ein Spieler steht fest, ein weiterer kann beitreten
  • RUNNING: Die Partie läuft und die zwei Spieler machen abwechselt ihre Züge
  • ENDED: Die Partie ist beendet.

Die hier gezeigte Fassung des Services ist der Startpunkt. Einige Dinge fehlen noch und kommen in weiteren Folgen der Serie hinzu. Hierzu zählen insbesondere

  • Fachlich: Die Überprüfung der Schachregeln bei Zügen — das übernimmt später ein eigener Service. In dieser Fassung werden nur wenige Dinge geprüft, um zu sehen, wie der Service auf fehlerhafte Züge reagiert
  • Technisch: Ein User Interface — der Service bietet zunächst lediglich eine REST-Schnittstelle
  • Technisch: Das Thema Security — diesem Aspekt widmen wir einen eigenen Beitrag

Zunächst geht es darum einen ersten integralen Bestandteil von FLEXess mit überschaubarem Aufwand ans Laufen zu bekommen. Die rote (1) markiert Euren Standpunkt („Sie befinden sich hier.“).

Überblick FLEXess inkl. Position des Services games

Als eine charakteristische Eigenschaft von Microservices (und auch Self-containes Systems) wird oft die Freiheit in Technologieentscheidungen angeführt, welche die umsetzenden Teams genießen. Hier ist vor allem die Persistenz ein Thema, aber auch die verwendete Programmiersprache. Unterschiedliche Programmiersprachen innerhalb einer Anwendung sind kein Wert an sich, aber Flexibilität an dieser Stelle eröffnet bei verschiedenen Anforderungen ggf. interessante Optionen.

Der erste Service hier ist in Java umgesetzt. Um einen technologischen Mix zu zeigen folgen später noch Services in Python und JavaScript.

Die Umsetzung — Spring Boot als Microservices Chassis

Microservices Patterns (MEAP)Im Java-Umfeld ist der Einsatz von Spring Boot zur Implementierung leichtgewichtiger Services sehr verbreitet. Folgt man der Nomenklatur von Chris Richardson und seinem Buch Microservices Patterns (Cover siehe links) handelt es sich hierbei (gemeinsam mit Spring Cloud) um die Umsetzung des „Microservice Chassis“-Musters.

Als solches kümmert es sich um querschnittliche Aspekte. Laut Pattern-Beschreibung besteht der große Vorteil eines Microservice-Chassis darin, dass Ihr schnell und einfach mit der Entwicklung eines Microservices beginnen könnt. Oder wir jetzt hier konkret mit Spring Boot und Java.

Spring für sich alleine genommen ist ein verbreitetes, umfangreiches Java-Framework mit langer Geschichte. Spring Boot behauptet von sich selbst eine vorgefertigte Meinung über das Bauen von produktionsreifen Spring-Anwendungen zu haben. Es favorisiert Konventionen über Konfigurationen und ist so gemacht, dass Ihr so schnell wie möglich in Betrieb gehen können.

Die Umsetzung — Implementierung in Java

Microservices und Self-contained Systems sind Architekturstile mit Vertikalen als prägende Elemente. Eine einzelne Vertikale selbst kann geschichtet sein, so auch unser games-Service (wenn auch nicht strikt, wenn wie das folgende Abhängigkeitsdiagramm zeigt).

Abhängigkeiten zwischen den Paketen (Graphik: TeamScale)Die Java-Klassen sind auf drei Pakete verteilt:

Package org.flexess.games… Wesentliche Inhalte
domain Die Entitäten Game und Move und der Zugriff auf die Persistenz mit Spring Data.
service Geschäftslogik in der Klasse GameService. Greift auf die Repositories aus domain zu.
rest REST-Schnittstelle für den Service in der Klasse GameRestController.

Game übernimmt die Rolle eines Aggregates im Sinne von DDD. Objekte der Klasse Move verhalten sich dabei wie Bestellpositionen im kanonischen Aggregate-Beispiel einer Bestellung.

Als Persistenz kommt eine relationale Datenbank zum Einsatz (aktuell die H2), auf die der Service vermöge Spring Data JPA zugreift. Das Schema wird dabei aus den Entitäten generiert — wir wollten ja „schnell“.

Die Klasse GameService beinhaltet die oben beschriebene Funktionalität (Partien abfragen, Züge ausführen etc.) als Methoden. Auf dieser Ebene liegen auch die Transaktionen.

Die REST-Schnittstelle nutzt Spring Web MVC und Data Transfer Objects, um die Entitäten für die JSON-Repräsentation anzupassen ohne an den Domain-Objekten herumzufummeln. Eine sehr hilfreiche Informationsquelle für Anpassungen dieser Art ist Jackson Annotation Examples von Eugen Paraschiv.

Den Service bauen und starten

Den Quelltexten liegt ein Build-Skript für Gradle bei. Beim Bauen mit dem Gradle-Wrapper muss lediglich Java 8 (oder höher) installiert sein. Das Skript gradlew (bzw. gradlew.bat) lädt die passende Gradle-Version und startet den Build, der die Abhängigkeiten (wie zum Beispiel Spring) herunterlädt.

Das Target bootRun baut den Service, lässt Tests laufen und startet das Ganze lokal auf Port 8080. Hier eine Sequenz zum Klonen aus GitHub, bauen und starten …

$ git clone https://github.com/embarced/micro-moves.git
Cloning into 'micro-moves'...
$ cd micro-moves/modules/games/
$ ./gradlew bootRun

 

Service games startet mit Spring Boot

Den Service nutzen (Abfragen)

Beim ersten Hochfahren legt der Service eine H2-Datenbank an und ein paar Partien darin ab, damit Ihr ohne größere Umstände direkt abfragen könnt.

Ein guter Einstiegspunkt ist das Auflisten aller Partien mit http://localhost:8080/api/games/, das Ihr im Web-Browser eingeben oder auch in einem Terminal per curl abfragen könnt. Details zu einer einzelnen Partie erhaltet Ihr mit dem Hineinnavigieren mit der gameId in der URL. Hier ein Beispiel mit curl:

$ curl http://localhost:8080/api/games/
[{"gameId":1,"playerWhite":"pinky","playerBlack":"brain","status":"ENDED"},
{"gameId":2,"playerBlack":"peter","status":"OPEN"}]
$ curl http://localhost:8080/api/games/1
{"gameId":1,"playerWhite":"pinky","playerBlack":"brain","status":"ENDED",
"result":"0-1","activeColour":"w",
"fen":"rnb1kbnr/pppp1ppp/8/4p3/6Pq/5P2/PPPPP2P/RNBQKBNR w KQkq - 0 3",
"created":"2018-04-24T11:10:55","modified":"2018-04-24T11:10:55"}
$  

Die Ausgabe im Terminal ist nicht gut lesbar. Web-Browser können das schöner formatieren (hier im Screenshot Safari).

Wer Kommandozeilenfreund und Ästhet zugleich ist wie ich verwendet einen Pretty Printer wie json_pp:

$ curl http://localhost:8080/api/games/1 | json_pp
{
   "gameId" : 1, 
   "playerWhite" : "pinky", 
   "playerBlack" : "brain",
   "status" : "ENDED",
   "result" : "0-1",
   "activeColour" : "w",
   "fen" : "rnb1kbnr/pppp1ppp/8/4p3/6Pq/5P2/PPPPP2P/RNBQKBNR w KQkq - 0 3", 
   "created" : "2018-04-24T11:10:55",
   "modified" : "2018-04-24T11:10:55"
}
$

Eine Partie speichert neben den beteiligten Gegnern auch den aktuellen Zustand auf dem Brett in FEN-Notation ab (zu FEN siehe die Randnotiz Spielsituation als Zeichenkette hier im Blog). Die Abfrage aller Partien bzw. gezielt einer einzelnen Partie erfolgen über GET-Requests, die in den Methoden allGames bzw. gameById der Klasse GameRestController implementiert sind. Es lassen sich auch die Züge einer Partie anzeigen, etwa mit http://localhost:8080/api/games/1/moves/

Eine neue Partie anlegen (via curl und Postman)

Eine neue Partie einleiten erfolgt über einen POST-Request (Methode createGame) der auch über curl abgesetzt werden kann. Die verwendeten Kommandozeilenoptionen: -H kurz für –header, -X kurz für –request, -d kurz für –data).

$ curl -H "Content-Type: application/json" -X POST 
-d '{"playerWhite": "stefan"}' http://localhost:8080/api/games/
Game #3 (stefan-???) created.
$curl http://localhost:8080/api/games/3 | json_pp
{
   "playerWhite" : "stefan",
   "fen" : "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
   "gameId" : 3,
   "status" : "OPEN",
   "activeColour" : "w",
   "created" : "2018-04-24T12:51:47",  
   "modified" : "2018-04-24T12:51:47"
}
$

Das ist etwas mühsam und wäre es noch mehr, wenn weitere Angaben in den Daten erforderlich wären. Weitaus bequemer ist der Einsatz des schönen Werkzeuges Postman. Hier lassen sich u.a. auch Anfragen speichern und recyceln. Der Screenshot unten zeigt einen erfolgreichen POST zum Erzeugen einer neuen Partie. Tabea spielt schwarz.

Screenshot Postman

Ich habe hier ein Postman-Projekt mit den vom games-Service aktuell unterstützten Operationen abgelegt. Ihr könnt es leicht in Eure Postman-Installation importieren. Nicht gezeigt habe ich hier beispielsweise das Ausführen von Zügen, das über POST-Requests auf der …/moves/-Resource  abgebildet ist.

Weitere Informationen — und wie es weiter geht …

API-Design: Praxishandbuch für Java- und Webservice-EntwicklerDer Entwurf einer REST-API folgt Best Practices und Konventionen, die oftmals Projekt-spezifisch sind. Es gibt viele Dertailentscheidungen zu treffen. Etwa zum Aufbau der URLs oder zu Fehlercodes. Zum API-Design hat Kai Spichale ein lesenswertes Buch verfasst (Cover rechts), das auch REST-Schnittstellen behandelt.

Eine Schachpartie mit Postman oder curl zu spielen ist recht mühsam. Der Service braucht offensichtlich noch ein User Interface. Bevor ich mich diesem Thema annehme gibt es aber in der nächsten Folge zunächst noch einen weiteren Service. Diesen dann in Python.

Ach ja: Fragen und Anregungen sind natürlich jederzeit gerne Willkommen. Per Kommentar hier im Blog oder gerne auch per Mail direkt an mich.

Zur Blog-Serie Micro Moves

 

ContextMap_FLEXess_

Micro Moves – Zeitgenössische Softwarearchitektur als Bausatz (Intro)

By | Inhaltliches | No Comments

Logo Micro Moves Vertikale Architekturstile wie Microservices und Self-contained Systems sind in aller Munde. Beispiele für deren Umsetzung mit einer konkreten Technologie, etwa Spring Boot, finden sich reichlich im Netz. Bestimmte Aspekte kommen in der Diskussion meiner Meinung nach allerdings zu kurz — vor allem konzeptionelle. Hierzu zählen etwa die UI-Integration zwischen unterschiedlichen Services und Security-Themen — und ganz generell die Frage nach Makro- und Mikroarchitektur. Was ist für alle Services gleich? Wo profitiert Ihr von speziellen Lösungen? Wie fühlen sich unterschiedliche Technologien an, auch vielleicht im Vergleich zu Sachen die Ihr kennt?

In den nächsten Wochen entsteht hier daher FLEXess (für FLEXible chESS Platform), eine technologisch bunte Online-Schach-Plattform. Zug um Zug zum direkt Nachvollziehen (und Nachbauen). Mit Vertikalen realisiert in unterschiedlichen Programmiersprachen (Java, Python, JavaScript, …). Und querschnittlichen Aspekten wie UIs (von Web-Front mit SPA bis zur nativen App). Sowie der Gelegenheit als menschlicher Spieler gegen den aktuellen Ranglistenersten im Computer-Schach anzutreten.

FLEXess — Zug um Zug eine technologisch bunte Online-Schach-Plattform

Am Beispiel entlang diskutiere ich in dieser Serie wichtige Fragestellungen rund um Technologien und Vorgehen. Ich beantworte sie konkret für unsere Applikation und implementiere sie exemplarisch (Quelltexte auf GitHub). Weiter zeigt die Serie Alternativen auf und skizziert mögliche nächste Schritte. Darüber hinaus verweist jede Folge auf weiterführende Literatur und aus unserer Sicht qualitativ hochwertige Quellen im Netz.

Ihr wollt unterschiedlichste Technologien in einer überschaubaren aber gleichzeitig attraktiven Applikation gemeinsam am Werkeln sehen? Ihr wollt Eurer Wissen zu modernen Architekturstilen und Microservices Patterns auf- oder ausbauen? Und Orientierung in typischen Architekturentscheidungen erhalten.

Na dann los!

Der fachliche Rahmen

FLEXess erlaubt es den Benutzern gegeneinander Schach zu spielen, oder sich mit Computer-Gegnern zu messen. Fachlich zerfällt das ganze in Themen, die wir in unterschiedlichen Teilsystemen implementieren. Für die fachliche Zerlegung größerer Systeme etabliert sich in der Praxis der strategische Teil von Domain-driven Design (DDD). Zentraler Zerlegungsbegriff sind (Sub-)domänen. DDD kategorisiert diese in Core Domains, Supporting Domains und Generic Subdomains  und etabliert Muster der Zusammenarbeit für Teams, welche diese Teile umsetzen.

Ich möchte dem Thema hier gar nicht viel Raum geben — eine grobe Context Map zur Visualisierung der Fachlichkeit soll genügen:

Context Map FLEXess

Subdomäne Begriffe (Auswahl) Aufgabe / Verantwortlichkeit
Laufende Partien Gegner, Partie, Zug Einleiten und verwalten laufender Partien
Spieler Spieler Verwaltung der (menschlichen) Spieler, Registrierung etc.
Spielregeln Position, Züge Überprüfen von Zügen auf Gültigkeit, Test auf Partie-Ende …
Diagramme Bild Generierung von Schachdiagrammen als Graphiken (z.B. als PNG) zur Einbindung in Webseiten, Berichte etc.
Computer-Gegner Chess Engine Anbindung von Computerschachprogrammen

Nick Tune: The Strategic Practices of Domain-Driven DesignStatt der Standardliteratur zu DDD möchte ich Interessierten die schöne Materialsammlung von Nick Tune zum Thema Strategisches DDD ans Herz legen! In dem klasse gestalteten E-Book beschreibt der Autor Techniken wie Business Canvas, Event Storming etc.

In unserer Blogserie soll der Schwerpunkt jedoch auf der Umsetzung liegen.

Unsere Umsetzung: Ein Überblicksbild

Eine allgemein akzeptierte Definition für Microservices gibt es nicht. Und schlußendlich ist es auch egal, ob unsere Umsetzung einen Architekturstil „gültig“ implementiert. Gerade bei Microservices gibt es viel Gestaltungs- und Entscheidungsspielraum.

Martin Fowler und James Lewis beschreiben in Ihrem viel beachteten Blogbeitrag, der gerne als Definitionsersatz für Microservices mißbraucht wird, von einem Ansatz, der eine einzelne Anwendung mit Hilfe kleiner Services umsetzt. Diese laufen in eigenen Prozessen und kommunizieren über leichtgewichtige Mechanismen.

Die folgende Abbildung gibt einen groben Überblick über die Umsetzung von FLEXess, wie sie in den folgenden Wochen hier entstehen soll. Änderungen nicht ausgeschlossen, sondern umgekehrt wahrscheinlich.

Überblick FLEXess

Die folgende Tabelle ordnet die vertikalen Services den fachlichen Subdomänen aus der Context Map oben zu und nennt die wesentlichen verbauten Technologien und den Blogbeitrag, in dem sie erstmalig eingeführt werden …

Service Subdomäne Wesentliche Technologien Blog-Beitrag
chess-diagrams Diagramme Python, Flask, Pillow Folge 2
games Laufende Partien Java, Spring Boot Folge 1
rules Spielregeln
players Spieler

FLEXess unterstützt Web-Browser als UIs, weiterhin bietet es eine native Android-App für einen Teil seiner Funktionalität an (das Spielen von Partien). Als Kommunikation kommen im Wesentlichen HTTP und REST zum Einsatz, asynchrone Kommunikation über Messaging. Ein Reverse Proxy lässt die darunter liegenden Vertikalen (Services), die als eigenständige Prozesse laufen, wie eine Anwendung erscheinen.

Aber der Reihe nach.

Wie geht es weiter?

Wir beginnen in den nächsten Folgen mit der Umsetzung der ersten zwei Services. Anschließend diskutieren wir die UI-Frage — klassische Web-Applikation vs. SPA (Single Page Applikation) etc. — und stellen die zwei Vertikalen in einem Browser zur Verfügung. Den Anfang macht aber das Partien-Subsystem „games“ mit einer rein REST-basierten Schnittstelle …

Ach ja: Fragen und Anregungen sind natürlich jederzeit gerne Willkommen. Per Kommentar direkt hier oder gerne auch per Mail direkt an mich.

Zur Blog-Serie Micro Moves

jug gorlitz

JUG Görlitz: Mikro- vs. Makroarchitektur – Spielraum und Spielregeln

By | Publikationen, Vorträge | No Comments
„Mikro- vs. Makroarchitektur – Spielraum und Spielregeln“

JUG Görlitz Logo

Mikro- vs. Makroarchitektur – Spielraum und Spielregeln
Sprecher: Stefan Zörner
Vortrag bei der Java User Group Görlitz
Dienstag, 20. März 2018, 19:00 – 20:30 Uhr
Hochschule Zittau/Görlitz, Raum 0.10, Brückenstraße 1, 02826 Görlitz

Foliendownload (PDF)

Während in einer klassischen Konzern-IT Standards und Blaupausen für immer gleiche Anwendungsarchitekturen sorgen, betonen Microservice-Ansätze die technologische Freiheit. Zwei extreme Spielarten der Ausgestaltung von Makro- und Mikroarchitektur.

In diesem Vortrag lernt Ihr neben dem Konzept selbst auch die auf Eure Ziele abgestimmte Richtung, die Ihr in dieser Fragestellung einschlagen solltet. Wie sieht in Eurem Kontext die Balance aus – was gebt Ihr für alle Elemente Eurer Anwendung(slandschaft) vor, wo lasst Ihr bewusst Spielraum? Und gibt es auch noch etwas dazwischen? Zu diesem Zweck passen wir organisatorische und technologische Trends wie 2-Speed/Bimodale Architekturen, Cloud und Domänenorientierung in das Entwurfsdoppel Makro und Mikro ein.

Stefan Zörner - Mikro- vs. Makroarchitektur – Spielraum und Spielregeln

follow us on Twitter – @embarced

Meetup_HH

Stefan Zörner beim Softwarearchitektur Meetup in Hamburg: „Vortrag“, zum Mitmachen

By | Publikationen, Vorträge | No Comments
„Mikro- vs. Makroarchitektur – Spielraum und Spielregeln“

Meetup 2018

Mikro- vs. Makroarchitektur – Spielraum und Spielregeln
Sprecher: Stefan Zörner
Vortrag beim Softwarearchitektur Meetup Hamburg
Dienstag, 27. Februar 2018, 18:30 – 20:30 Uhr
iteratec GmbH Hamburg

Foliendownload (PDF)

Während in einer klassischen Konzern-IT Standards und Blaupausen für immer gleiche Anwendungsarchitekturen sorgen, betonen Microservice-Ansätze die technologische Freiheit. Zwei extreme Spielarten der Ausgestaltung von Makro- und Mikroarchitektur. In diesem Mix aus Vortrag und kurzen interaktiven Elemente lernt Ihr neben dem Konzept selbst auch die auf Eure Ziele abgestimmte Richtung, die Ihr in dieser Fragestellung einschlagen solltet. Wie sieht in Eurem Kontext die Balance aus – was gebt Ihr für alle Elemente Eurer Anwendung(slandschaft) vor, wo lasst Ihr bewusst Spielraum? Und gibt es auch noch etwas dazwischen? Zu diesem Zweck passen wir organisatorische und technologische Trends wie 2-Speed/Bimodale Architekturen, Cloud und Domänenorientierung in das Entwurfsdoppel Makro und Mikro ein.

Stefan Zörner - Mikro- vs. Makroarchitektur – Spielraum und Spielregeln

Micro Moves Randnotiz – Spielsituation als Zeichenkette … FEN (Forsyth-Edwards-Notation)

By | Verschiedenes | No Comments

Die Randnotizen ergänzen die Blog-Serie „Micro Moves“ wie ein Anhang. Sie beschreiben querschnittliche Aspekte, die das Verständnis der Quelltexte oder der Fachlichkeit (also Schach bzw. Computerschach) generell erleichtern. Sie passen nicht zu einem speziellen Bauteil/Modul. Stellt es Euch stets am Rand notiert vor.

Daten austauschen im Schach

DatenaustauschIm Computer-Schach gibt es für verschiedene Themen (de facto) Standards, so etwa für den Datenaustausch (Partien, Eröffnungen, …) oder die Kommunikation zwischen Schachprogrammen im Rahmen von Partien oder Turnieren. Eine sehr verbreite Notation für Spielsituationen (Schachstellungen) geht sogar ins 19. Jahrhundert zurück, als man Schachaufgaben effizient in Zeitschriften abdrucken wollte, ähnlich wie in jüngerer Vergangenheit Sudokus (zum Ursprung der Notation siehe Wikipedia).

Diese Notation heißt „Forsyth-Edwards-Notation“ (abgekürzt: FEN). Sie erlaubt die Angabe einer kompletten Spielsituation als kompakte Zeichenkette ohne Zeilenumbruch. Sie ist z.B. ideal für den Einsatz bei (Unit-)Tests im Computer-Schach. Da viele Schach-Tools die Notation unterstützen empfehle ich sehr sie auch Eure Schachpläne zu verwenden. FLEXess tut es auch.

Ein Beispiel

Schach, Grundstellung (Diagramm generiert mit chess-diagrams Modul aus Micro Moves)
Die Abbildung zeigt ein Schachbrett zu Beginn einer Partie, am Rand sind die Bezeichnungen für Linien (a-h) und Reihen (1-8) notiert.
In FEN wird die Grundstellung wie folgt notiert (die Gänsefüßchen kennzeichnen String-Anfang und -Ende und gehören nicht zur Notation):

"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"

Die zu Beginn mit Schrägstrichen ‚/‘ getrennten Folgen von Buchstaben und Ziffern beschreiben die Situation auf dem Brett. Kleine Buchstaben stehen für schwarze, große für weiße Figuren. Die Notation verwendet die englischen Bezeichnungen für Figurenarten (Rook für Turm, Pawn für Bauer, …). Der erste Block „rnb…“ liest sich daher „schwarzer Turm, schwarzer Springer, schwarzer Läufer …“. Weitere Informationen der FEN-Zeichenkette beschreiben unter anderem wer am Zug ist, Rochade-Rechte etc. — Alles Dinge, die man den Figuren auf dem Brett allein nicht ansieht.

Das Format im Detail

Das FEN-Format besteht aus 6 Bestandteilen („Gruppen“), jeweils mit Leerzeichen voneinander getrennt:

  1. Figuren auf dem Brett (oben „rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR“)
  2. Spieler am Zug (oben „w“ für weiß, „b“ stünde für schwarz)
  3. Rochade-Rechte (oben „KQkq“)
  4. en passant-Feld (oben ein Minus)
  5. Halbzüge für 50-Züge-Regel (oben „0“)
  6. Nummer des nächsten Zuges (oben „1“)

Die Rochade-Rechte (3.) zeigen an, welche Rochaden noch möglich sind. Die Gruppe ist erforderlich, da die Figuren am Brett allein das nicht erkennen lassen (konkret: ob eine Figur schon einmal bewegt wurde). „K“ und „Q“ für weiß (K = kurze Rochade, Q= lange Rochade), „k“ und „q“ für schwarz (k steht für kingside, q für queenside). Falls eine Rochade nicht mehr möglich ist entfällt der Buchstabe. Ist gar keine Rochade möglich enthält die Gruppe ein Minus (-).

Das en Passant-Feld (4.) enthält das übersprungene Feld, falls im Zug direkt zuvor ein Bauer 2 Felder nach vorn gegangen ist. Bei „e2-e4“ also „e3“. Der Gegner könnte dann en passant schlagen (wenn einer seiner Bauern passend steht). Bei allen anderen Zügen enthält die Gruppe ein Minus (-).

Die 50-Züge-Regel besagt, dass ein Spieler ein Remis reklamieren kann, wenn 50 Züge lang kein Bauer bewegt und keine Figur geschlagen wurde. Die Halbzüge (5.) zählen solche Züge. Nach einem Bauernzug oder dem Schlagen einer Figur ist der Wert wieder 0.

Die Nummer des nächsten Zuges (6.) zählt nach einem schwarzen Zug hoch, d.h. erst macht weiß seinen 1. Zug, dann schwarz seinen 1. Zug, dann weiß seinen 2. Zug usw.

Diagramm generiert mit chess-diagrams Modul aus Micro Moves

Für die Notation des Brettes (1. Gruppe in FEN) hier noch ein weiteres Beispiel!

"6r1/6pp/7r/1B5K/1P3k2/N7/3R4/8 w - - 30 79"

Die Schrägstriche (/) trennen die Reihen des Brettes, angegeben von oben nach unten (also Reihe 8 bis 1). Eine Ziffer (1-8) gibt an wie viele Felder frei sind. Im Beispiel oben die erste Reihe („6r1“): 6 Felder frei, ein schwarzer Turm (r), 1 Feld frei. Die Schrägstriche sind eigentlich redundant und erhöhen lediglich die Lesbarkeit.

Das Beispiel oben entstammt einer langen Partie zwischen zwei (schwachen) Computer-Gegnern. Am Ende wurde herumgeeiert (daher die hohe Zahl bei den Halbzügen für die 50-Züge-Regel), bis schwarz endlich gewonnen hatte (Weiß am Zug ist matt).

Tool-Unterstützung für FEN

Viele Schach-Softwarelösungen (freie und kommerzielle) unterstützen das FEN-Format. Das legt seine Verwendung in eigenen Schach-Programmiervorhaben nahe. Eine Spielsituation ist flink in einem graphischen Editor zusammengeklickt, dann als FEN in die Zwischenablage kopiert, und Standpunkt für einen Unit-Test …

...
String fen = "6r1/6pp/7r/1B5K/1P3k2/N7/3R4/8 w - - 30 79";
Position pos = new Position(pos);
Assert.assertTrue(rules.isMate(pos));
...

Das setzt voraus, dass der eigene Code FEN versteht (wie im Beispiel der Konstruktor für die Position-Klasse). Umgekehrt eignet sich FEN auch prima für LOG-Ausgaben, da es sich leicht aus der Zwischenablage in geeignete graphische Tools kopieren lässt. So lässt sich eine problematische Situation leicht visualisieren.

chessX: Editor für Stellungen

Die Abbildung oben zeigt den Editor des Schachwerkzeuges (chessX). Es kann so einiges mehr neben dem Editieren und dem Im- und Export aus und von FEN. Hier einige freie Softwarelösungen, die unter anderem zum Datenaustausch mit FEN geeignet sind …

  • chessX (Windows, Linux, MacOS)
  • Arena (Windows, Linux)
  • Scid (cross-platform, für Unix/Linux und Windows)

Die folgende Webseite erlaubt das Editieren und kopieren von/nach FEN online:

Einschränkungen des Formats

Eine Regel im Schach besagt, dass ein Spieler ein Remis reklamieren kann, wenn dieselbe Stellung mindestens zum dritten Mal innerhalb einer Partie auftritt. Das FEN-Format enthält nicht genügend Informationen, um eine Stellungswiederholung nachzuvollziehen. Weiterhin bildet FEN alternative Schachregeln (allen voran Chess960) nicht vollständig ab. Hierzu gibt es verschiedene Vorschläge, siehe Wikipedia.

FEN in Micro Moves und FLEXess

Das games-Modul (Bauteil 1) nutzt FEN zur Speicherung des Spielzustandes. Verwendet Ihr etwa die REST-Schnittstelle des Services, um Euch die Details einer Partie abzurufen, seht Ihr:

$ curl http://localhost:8080/api/games/1
{
"gameId":1, "playerWhite":"pinky", "playerBlack":"brain", "status":"ENDED",
"activeColour":"w",
"activePlayer":"pinky",
"fullMoveNumber":3,
"fen":"rnb1kbnr/pppp1ppp/8/4p3/6Pq/5P2/PPPPP2P/RNBQKBNR w KQkq - 0 3",
"created":"2018-04-01T18:39:12","modified":"2018-04-01T18:39:13"
}
$

Der Service des chess-diagrams-Moduls (Bauteil 2) nimmt einen FEN-String als Request-Parameter entgegen und generiert daraus ein PNG. Die Diagramme in diesem Beitrag hier sind damit erzeugt.

(Weitere Bauteile, die FEN nutzen, folgen …)

Fun Fact

Bei StackExchange findet Ihr eine schöne Aufgabe, bei der Ihr einen FEN-String (nur die erste Gruppe) in ASCII-Art verwandelt müsst. Ein eingereichter Beitrag in Perl kommt dazu mit nur 28 Bytes Quelltext aus.

Micro Moves Randnotiz – Lady hits farmer … Schachbegriffe auf Englisch

By | Verschiedenes | No Comments

Die Randnotizen ergänzen die Blog-Serie „Micro Moves“ wie ein Anhang. Sie beschreiben querschnittliche Aspekte, die das Verständnis der Quelltexte oder der Fachlichkeit (also Schach bzw. Computerschach) generell erleichtern. Sie passen nicht zu einem speziellen Bauteil/Modul. Stellt es Euch stets am Rand notiert vor.

Lady hits farmer … (?)

EnglishDer Quelltext zu FLEXess ist Englisch kommentiert, alle Bezeichner (Modul-, Klassen-, Methodennamen usw.) sind ebenfalls Englisch. Auch wenn Ihr solide Schachkenntnisse besitzt, erschließen sich die Englischen Fachbegriffe nicht von selbst. So heißt Dame im Schach nicht etwa Lady, Bauer nicht Farmer und Schlagen auch nicht „to hit“ … (richtig wäre „queen captures pawn“ in der Überschrift).

Da deutschsprachigen Lesern die Englischen Schachbegriffe also oft nicht geläufig sind, habe ich sie hier zusammengestellt, und bei der Gelegenheit auch kurz erklärt. Details siehe Schachregeln. Die Tabelle ist alphabetisch sortiert nach Englisch. Wenn ich Begriffe übersehen habe, gerne melden. Ich ergänze das Glossar gern!

(Schach-)Englisch – Deutsch

Englisch Deutsch Kurze Erklärung
Attack Angreifen Eine Figur greift eine gegnerische Figur an, wenn sie diese im nächsten Zug schlagen könnte.
Bishop Läufer Figur im Schach. Darf auf ein beliebiges anderes Feld entlang ihrer Diagonalen ziehen.
Capture Schlagen Wenn eine Figur auf ein Feld zieht, das von einer gegnerischen Figur besetzt ist, wird diese geschlagen und vom Brett entfernt.
Castling Rochade Spezieller Spielzug, bei dem der eigene König und ein eigener Turm zugleich bewegt werden.
Chessboard Schachbrett Ein 8 x 8 Gitter aus 64 gleich großen Quadraten, abwechselnd hell und dunkel (die weißen und schwarzen Felder).
Check Schach Im Sinne von „König im Schach“, also König ist angegriffen („king is in check“)
Checkmate Schachmatt siehe Mate.
Colour Farbe Schwarz und Weiß, die Farben der beiden Spieler
Draw Remis Ein Unentschieden im Schach. Es gibt verschiedene Möglichkeiten dazu, eine ist das Patt.
Endgame Endspiel Die Endphase einer Partie. Sie ist dadurch gekennzeichnet, dass nur noch wenige Figurenarten auf dem Brett sind.
en passant en passant Spezieller Bauernzug. Wenn ein Bauer zwei Felder vorgeht, und ein gegnerischer Bauer ihn hätte schlagen können, wäre er nur eins vorgegangen, darf dieser en passant schlagen.
File Linie Die acht senkrechten Spalten auf dem Schachbrett heißen Linien.
Game Partie Eine Schachpartie wird zwischen zwei Gegnern gespielt, die abwechselnd ihre Figuren auf einem Schachbrett ziehen.
Halfmove Halbzug Aktion (Spielzug) eines einzelnen Spielers. Im Gegensatz zu einer Folge von weißem und schwarzem Zug, die z.B. beim Nummerieren als Zug gezählt wird (Englisch: Fullmove).
King König Figur im Schach. Darf auf ein beliebiges angrenzendes Feld ziehen, das nicht von einer gegnerischen Figur angegriffen wird.
Knight Springer Figur im Schach. Zieht vereinfacht zwei Felder gerade, eins zur Seite. Laut offiziellen Spielregeln: Darf auf eines der Felder ziehen, die ihr am nächsten liegen, aber nicht auf gleicher Linie, Reihe oder Diagonalen.
Mate Matt Auch Checkmate (Schachmatt). Ende einer Schachpartie, bei dem der König des am Zug befindlichen Spielers angegriffen ist und nicht ausweichen kann. Der Spieler hat verloren.
Move Zug Ein Spieler „ist am Zug“ (Englisch „have the move“ oder „active“), sobald der Zug seines Gegners ausgeführt wurde.
Opening Eröffnung Erste Phase einer Schachpartie. Das Erfahrungswissen hierzu füllt viele Bücher und umfangreiche Datenbanken.
Opponent Gegner siehe Player.
Pawn Bauer Figur im Schach. Darf vorwärts auf das unbesetzte Feld direkt vor ihr ziehen, im ersten Zug auch zwei vor. Siehe auch en passant.
Piece Figur Es gibt sechs verschiedene Figurenarten im Schach.
Player Spieler Schwarz und Weiß. Der weiße Spieler beginnt die Partie.
Position Stellung Spielsituation. Im Wesentlichen, wie die Figuren auf dem Brett stehen und welcher Spieler am Zug ist. Einige Regeln führen zu weiteren Aspekten, z.B. en passent.
Promotion Umwandlung Ein Bauer, der die gegnerische Grundlinie erreicht, wird in Dame, Turm, Läufer oder Springer umgewandelt.
Queen Dame Figur im Schach. Darf auf ein beliebiges anderes Feld entlang ihrer Linie, Reihe oder Diagonalen ziehen.
Rank Reihe Die acht waagrechten Zeilen auf dem Schachbrett heißen Reihen.
Rook Turm Figur im Schach. Darf auf ein beliebiges anderes Feld entlang ihrer Linie oder Reihe ziehen.
Square Feld Das Schachbrett hat 64 Felder (8 x 8).
Stalemate Patt Ende einer Schachpartie, bei dem der am Zug befindliche Spieler keinen gültigen Zug hat, sein König aber nicht angegriffen ist. Das Spiel endet Remis.

Fehlt was?

Ihr vermisst einen Begriff? Habt beispielsweise in Quelltext oder Entwurf von FLEXess einen schachspezifischen Bezeichner o.ä. gefunden, der hier nicht erklärt wird? Ich ergänze das Glossar gern! Einfach melden …

JUG_Saxony-Day_2017_Keynote_S.Zoerner

Softwarearchitektur­ für alle!? – Video zur Keynote des JUG Saxony Day 2017

By | Publikationen, Video, Vorträge | No Comments
„Softwarearchitektur für alle!? … Softwarearchitektur wird Entwicklerskill“
Logo JUG Saxony Day
Softwarearchitektur für alle!? … Softwarearchitektur wird Entwicklerskill
Sprecher: Stefan Zörner
Videomitschnitt von Stefan’s Vortrag auf Youtube
Foliendownload (PDF)
Keynote auf dem JUG Saxony Day 2017
Freitag, 29. September 2017 in Radebeul b. Dresden

In dieser Eröffnungs-Keynote für den JUG Saxony Day 2017 führe ich aus, was Softwarearchitektur heute für mich ist, und warum es für Entwicklungsteam durch aktuelle Trends interessanter wird, sich damit zu beschäftigen.

Zentrale These: “Moderne Architekturansätze wie beispielsweise Microservices und Self-contained Systems bieten Entwicklerteams mehr Spielraum für konzeptionelle Arbeit. Softwarearchitektur wird Entwickler-Skill.”

Kern des Vortrages sind das Entwurfsdoppel Makro- und Mikroarchitektur, die darin zu treffenden Entscheidungen sowie die Fähigkeiten, die Teams dazu benötigen.

Fazit: Heute machen mehr Entwickler Architektur. Eine Weiterentwicklung in diese Richtung ist heute kein sozialer Aufstieg für wenige, sondern eine logische Konsequenz, wenn Eurer Team auch in der Mikroarchitektur risikogetrieben vorgehen will!

Softwarearchitektur für alle!? ... Softwarearchitektur wird Entwicklerskill

Twitter-Einblicke…
Tweet @jugsaxony
Tweet @tobiasgloeckner
Tweet @BertilMuth

follow us on Twitter – @embarced

sZoerner_Cloud_Prognose_prev_tag17

Cloud-Prognose: Wolkig mit Aussicht auf Beweglichkeit – beim TAG’17

By | Publikationen, Vorträge | No Comments
„Cloud-Prognose: Wolkig mit Aussicht auf Beweglichkeit“

The Architecture Gathering

Cloud-Prognose: Wolkig mit Aussicht auf Beweglichkeit
Sprecher: Stefan Zörner
Vortrag beim The Architecture Gathering
Mittwoch, 11. Oktober 2017, 17 – 18 Uhr
NH München Dornach, Einsteinring 20 in München – Aschheim

Foliendownload (PDF)

Mehr und mehr Unternehmen erkennen das Potential von Cloud-Technologien für die IT. Womöglich beabsichtigt auch Ihre Organisation zukünftig für OpenShift, AWS & Co. zu entwickeln. Der Vortrag zeigt, was das heute bedeutet, wo es Nutzen stiftet und wo nicht. Sie erfahren welche Entscheidungen ganz zu Beginn anstehen.

Falls Sie neue Cloud-Anwendungen entwickeln: Worauf achten sie bei Architekturentwurf und Technologieauswahl? Wenn Sie eine bestehende Anwendung in die Cloud migrieren wollen: Wie gehen Sie vor? Vielleicht gibt es auch Bedenken bezüglich Cloud-Lösungen. Wie entkräften Sie diese? Wo ist was dran? Was sind Hindernisse in einem betont konservativen Umfeld? Zentrale Prinzipien für die Anwendungsentwicklung in der Cloud runden den Vortrag ab.

Cloud-Prognose: Wolkig mit Aussicht auf Beweglichkeit