All Posts By

Stefan Zörner

meetup_vienna

Interaktiver Vortrag: Softwarearchitektur Speed-Dating beim Meetup in Wien

By | Publikationen, Vorträge | No Comments

 „Softwarearchitektur Speed-Dating“
Interaktiver Vortrag. Impuls und Moderation: Stefan Zörner


Veranstaltung beim Softwarearchitektur Meetup Wien
Mittwoch, 3. April 2019
Platinum Vienna, Untere Donaustraße 21, Wien

Foliendownload (PDF)

Zeitgemäße Softwarearchitektur ist nicht das Werk einzelner. Architekturansätze und Ideen entstehen im Team und werden gemeinsam reflektiert. Alle Entwickler müssen sie zumindest verstehen und mittragen können. Aber was genau müsst Ihr vermitteln? Reicht aufschreiben? Hilft UML?

Stefan Zörner zeigt auf lebendige Weise, wie Ihr Eure Softwarearchitektur wirkungsvoll kommunizieren könnt. Nach kurzen theoretischen Inputs rund um Architekturdokumentation und -bewertung probiert Ihr das Gehörte gleich aus. Ihr lernt die Lösungen anderer Teilnehmer kennen und erfahrt Schritt für Schritt, welche Zutaten in einem Architekturüberblick keinesfalls fehlen sollten – egal wie kurz er ist. Ihr lernt die richtigen Fragen zu stellen und passende Antworten parat zu haben.

Bringt bitte die Bereitschaft mit, Euch über Eure Projekte und Softwarelösungen auszutauschen, und anderen Teilnehmern Feedback zu geben. Die sonst üblichen Speed-Dating-Themen wie Ex-Partner und Kinderwünsche klammern wir aus.

Stefan Zörner - Softwarearchitektur Speed-Dating

follow us on Twitter – @embarced

MicroMoves Folge 7_

Security: Spieler für alle Services anmelden mit JWT (Micro Moves, Bauteil 7)

By | Inhaltliches | No Comments

Blog-Serie Micro Moves -- LogoMittlerweile haben wir mit den Folgen der Micro-Moves-Serie  schon einiges an Funktionalität zusammen. Benutzer von FLEXess können Partien starten und im Browser gegeneinander und gegen einen Computer-Gegner (seit Folge 6) antreten. Das Thema Sicherheit haben wir bisher allerdings komplett ausgespart. Wir ändern das in dieser Folge.

Um was geht es — ein Überblick

Aktuell können anonyme Benutzer über den games-Service (siehe Blog-Folge Bauteil 1) Partien mit zwei beliebigen Spielernamen (Texteingabe) einleiten. Anschließend können sie über die  play-Oberfläche (siehe Blog-Folge Bauteil 3) Züge absetzen. Mittlerweile prüft der rules-Service (siehe Blogfolge Bauteil 5) zwar, ob der Zug regelkonform ist. Wer da am anderen Ende des Browsers sitzt spielte aber keine Rolle bisher. Jeder Benutzer kann bei jeder Partie mitziehen, nicht nur in seinen eigenen. 

 

Mit dieser Folge führen wir einen neuen Service ein: players. Er ist in Python implementiert und ermöglicht es Benutzern, sich als Spieler zu registrieren und am System anzumelden. Die Web-Oberfläche hierzu bauen wir mit Flask (analog zu Bauteil 2 chess-diagrams, aber mit HTML-basierter Oberfläche).

Bei erfolgreicher Anmeldung stellt players ein JWT-Token (siehe unten) aus, mit dem sich der Benutzer auch bei anderen Services authentifizieren kann. Hier ist insbesondere games zu nennen, das ab dieser Folge unter anderem sicherstellt, dass nur angemeldete Benutzer, die mit von der Partie sind, tatsächlich ziehen können.

Eine Warnung: Unsere Implementierung ist eine einfache Lösung zu Illustrationszwecken. In echten Microservices-Vorhaben ist der Einsatz von JWT zwar ebenfalls üblich, nicht aber das Selberstricken der Authentifizierung wie hier in players. Ich diskutiere am Ende gängige Alternativen hierzu.

JWT — JSON Web Token

JSON Web Token, kurz JWT (ausgesprochen: „jot“), ist ein Standard für die sichere Übermittlung von Behauptungen (engl. Claims) bei gleichzeitig geringem Platzbedarf (also Ressourcen-Verbrauch). JWT genießt breite Unterstützung durch (Web-)Frameworks und Bibliotheken in allen nur erdenklichen Programmiersprachen. Unter anderem auch in den in Micro Moves bisher verwéndeten: Java, Python und JavaScript.

Ein JWT-Token sieht so aus (die Zeilenumbrüche gehören nicht zum Token):

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJzdWIiOiJwcGFudGhlciIsIm5hbWUiOiJQYXVsIFBhbnRoZXIiLCJyb2xlcyI6InVzZXIifQ.
cM93rF0CUXk5PxH8elR0paJ4PFqtbr0RbcFNFBocsmQ

Auf den ersten Blick also wüst, tatsächlich aber lediglich drei mit Base64-kodierte Bestandteile, mit Punkten voneinander getrennt:

  • Header mit Meta-Informationen, z.B. zum Signierverfahren
  • Payload (Nutzlast)
  • Signatur

Die Seite jwt.io stellt ein schönes Online-Werkzeug zum Token-Kodieren und -dekodieren zur Verfügung. Kopiert man das obige Token in diese Seite (siehe auch Screenshot unten), kann man Header und Payload lesen.

Header: {
"alg": "HS256",
"typ": "JWT"
}

Payload: {
"sub": "ppanther",
"name": "Paul Panther",
"roles": "user"
}
 

 

Das Token ist nicht verschlüsselt, sondern lediglich mit dem Verfahren HMAC / SHA-256 (kurz HS256, Angabe im Header) digital signiert (der dritte Teil des Tokens). Hierbei handelt es sich um ein symmetrisches Verfahren. Derselbe Schlüssel wird server-seitig zum Signieren benutzt und auch zum Überprüfen der Signatur (ebenfalls server-seitig, ggf. durch andere Module, der Client kriegt den Schlüssel nicht zu sehen). Auch dieses Überprüfen kann der Debugger auf jwt.io zeigen. Einfach den Schlüssel bei „Verify Token“ eingeben. In unserem Beispiel lautete er „secret123“.JWT Debugger bei jwt.ioDie Payload sind die eigentlichen Daten innerhalb des Tokens, deren „Echtheit“ die Signatur sicherstellt. Konkret handelt es sich hier um den Anmeldenamen (sub, kurz für subject), den Namen eines Benutzer und seine Rolle(n). Bei uns gibt es die Rollen user, admin und engine.

Wie stellen wir nun solche Token aus? Wie übermittelt ein Client das Token an andere Services? Und wie überprüfen diese die digitale Signatur? Schauen wir es uns der Reihe nach an! 

Ein Python-Service zum Anmelden von Spielern

Der Spieler ist als Konzept bisher nicht präsent. Spielernamen tauchen in Form von Zeichenketten im games-Subsystem auf, das wars. Unser neuer Service players ist eine simple Verwaltung von Spielern in Python. Der Quelltext von players ist wie immer auf GitHub verfügbar (unter modules/players). Über Webseiten ermöglicht players

  • … alle Spieler aufzulisten.
  • … einen neuen Spieler zu registrieren.
  • … Spieler an- und abzumelden.

Beim letzten Punkt kommt JWT zum Zuge, um die Information, dass ein Spieler sich erfolgreich am System angemeldet hat, inkl. weiterer Claims sicher an andere Teile des Systems (allen voran games) zu tragen.

Technologisch ähnelt players dem Python-Service chess-diagrams aus Folge 2 dieser Blog-Serie. Es kommen ebenfalls Flask als Web-Framework und gunicorn als Web-Server zum Einsatz. Mit Jinja2 kommt eine Template-Engine hinzu und mit TinyDB eine einfache Persistenzlösung. Für das für JWT nötige Kodieren und Dekodieren nutzt players die Python Bibliothek PyJWT. 

players beinhaltet folgende Seiten und Funktionalität.

Seite (URL) Funktionalität
/ Startseite. Listet alle Spieler in einer Tabelle auf.
/register Formularbasierte Registrierung eines neuen Spielers.
/profile_userid Profilseite für den Spieler mit dem Benutzernamen userid.
/login Anmeldung durch Benutzername und Kennwort.
/logoff Abmelden des angemeldeten Benutzers.
/about Über das Modul players.

Für die Seiten sind unter den URLs Funktionen für Flask im Python-File players.py hinterlegt, die auf entsprechende HTTP-Requests reagieren. Sie delegieren für die Darstellung der resultierenden (einfach gehaltenen) Seiten auf mit Jinja2 realisierte HTML-Templates.

Der neue Service lässt sich separat starten (z.B. via Kommando python3 player.py, Tests analog zu chess-diagrams via tox), ich hab ihm auch wieder ein Dockerfile spendiert und ihn in die Konfiguration von docker-compose mit aufgenommen. Die Seiten sind unter dem Pfad /players/ im Reverse-Proxy eingeklinkt, d.h. http://localhost:9000/players/about liefert in der Konfiguration und bei lokalem Start die About-Seite zum Modul.

players macht sich das Speicherns der registrierten Benutzer und ihrer Rollen sehr einfach und nutzt dazu TinyDB. Da Micro Moves in erster Linie Konzepte erläutert reicht das zur Illustration. Zu Alternativen und ernstzunehmenden Lösungsansätzen weiter unten.Startseite playersKonsequenterweise — den Spielzeugcharakter mit TinyDb im Blick — speichert players keine Kennwörter ab. Auch nicht verschlüsselt oder als Hash. Es erhebt nicht einmal Kennwörter. Die Authentifizierung simulieren wir durch Überprüfen, ob der Benutzer als Kennwort überhaupt etwas eingibt. Dieses „Sicherheitskonzept“ ist natürlich nicht viel besser als eine Admin-Party (alle Partygäste haben Admin-Rechte), wie wir sie vor dieser Folge hatten. Aber zur Illustration reicht es uns hier. — Liebe Kinder, falls Ihr das hier seht: Probiert das nicht zuhause an Eurem Produktionssystem aus!! 😉 

Im Falle der erfolgreichen Anmeldung stellt das players-Modul ein JWT-Token aus und sendet es als HTTP-Cookie an den Browser. Da die Micro Moves Module hinter einem gemeinsamen Reverse Proxy stehen, teilen sie sich für den Client von außen gesehen Hostname und Port. Das Cookie wird daher vom Browser bei Aufrufen — und das ist entscheidend — an alle beteiligte Module gesendet, insbesondere auch an games.

Das Erzeugen („Kodieren“) und Auslesen („Dekodieren“) des JWT-Tokens ist in players in web_token.py implementiert. Die Herausforderung dabei ist die digitale Signatur (Signieren beim Ausstellen, Überprüfen beim „Wiederkommen“). Die eigentliche Arbeit übernimmt die Python-Bibliothek PyJWT

Für das hier gewählte Signierverfahren HS256 benötigen wir einen geheimen Schlüssel („Shared Secret“). Wir geben ihn der Einfachheit halber von außen über eine Umgebungsvariable in den Docker-Prozess. Das Ganze lässt sich mit docker-compose recht einfach konfigurieren.  Hier ein Ausschnitt aus der Datei docker-compose.yml


players:

    build: ./players/
    environment:
        – JWT_COOKIE_NAME
        – JWT_SECRET

Die Werte der beiden Variablen sind in der Konfigurationsdatei .env abgelegt. Unter dem Cookie-Namen legt players das JWT-Token im HTTP-Response ab und sendet es an den Browser zurück. Umgekehrt versucht players mit diesem Namen den JWT-Token als Cookie-Wert aus einem HTTP-Request auszulesen.

In Abhängigkeit vom empfangenen Cookie ändert sich der rechte Teil der Navigation. Falls keines da ist, stehen Links zum Registrieren und Anmelden zur Verfügung. Ansonsten ein Dropdown für Benutzerprofil und Abmelden (siehe Abbildung unten). Name und User ID des Benutzers werden dazu aus dem JWT-Token entnommen.der rechte Teil der Navigation

Der Konfiguationsparameter JWT_SECRET ist das „shared secret“ für die digitale Signatur. Wer dieses hat, kann Signaturen aus players überprüfen (siehe z.B. unten im games-Modul). Ein Angreifer könnte damit auch selbst „gültige“ JWT Tokens ausstellen. Der Wert sollte daher nur vertrauenswürdigen Beteiligten zugänglich gemacht werden.

Um dieses Sicherheitsrisiko zu umgehen werden statt HS256 gerne asymmetrische Verfahren mit einem öffentlichen Schlüssel zum Überprüfen (erhalten alle) und einem geheimen Schlüssel zum Signieren (erhält nur der Aussteller) gewählt. Mehr dazu etwa im schönen Beitrag „The Importance of Using Strong Keys in Signing JWTs“.

Autorisierung im Subsystem games (Java)

Das games-Modul interessiert sich sehr für den Benutzer hinter einem Request. Nur ein angemeldeter Benutzer sollte …

  • … neue Partien eröffnen (mit sich selbst als 1. Spieler).
  • … offenen Partien als 2. Spieler beitreten.
  • … Züge in seinen Partien machen.

Für letzteres sollte er zugleich nicht nur Spieler in der zugehörigen Partie sein, sondern auch am Zug.

Gerade das letzte Beispiel zeigt, das die Autorisierung, d.h. die Entscheidung über die Berechtigung, im Modul games gut aufgehoben ist. players kann die Authentifizierung klären, und relativ statische Rollenzugehörigkeiten liefern. Ob der Benutzer irgendwo am Zug ist weiß es nicht.

Anonyme Benutzer lassen wir Partien auflisten und anzeigen, auch das zusehen von Partien anderer Spieler lassen wir zu. Weiterhin ist es angemeldeten Benutzern erlaubt, gegen sich selbst zu spielen. Das aber eher aus didaktischen Gründen — es lässt sich so weiterhin leichter ein wenig herumspielen über das play UI. Administratoren (d.h. Benutzer mit Rolle admin) können den Computer-Spieler Stockfish (vgl. Bauteil 6) gegen sich selbst spielen lassen — „normale“ Benutzer (also nur Rolle user) können nur selbst gegen Stockfish antreten.

Eine neue Partie eröffnenDas Auslesen des JWT-Tokens ist in games als Servlet-Filter realisiert (Klasse JwtCookieFilter im Package org.flexess.games.user). Der Prozess erhält über Umgebungsvariablen den Namen des Cookies und das Shared Secret. Er „fischt“ den Cookie, falls vorhanden, aus dem Request und verifiziert die Signatur des enthaltenen JWT-Tokens mit Hilfe des Shared Secrets. Hier kommt die JWT-Java-Bibliothek von Auth0 zum Einsatz. Im Erfolgsfall baut das Servlet ein User-Objekt mit User ID (z.B. ppanther), Namen (z.B. Paul Panther) und Rollen (z.B. user) und legt es im Request als Attribut ab. 

Die Spring Web MVC-Controller können dann darauf zugreifen, und die oben beschriebenen Überprüfungen durchführen (Beispiel: Ist der Benutzer angemeldet? Ist er am Zug? …). Und sie können Werte automatisch setzen. Wenn zum Beispiel der angemeldete Benutzer einer Partie als 2. Spieler beitritt, kann games dessen User ID in die Partie-Entität eintragen — je nachdem als schwarz oder weiß. Und den Namen im Menu anzeigen und Links aufs Profil gehen auch … 

Informationen auslesen in play (Vue.js)

Für das Spielen im Browser hatten wir in Bauteil 3 eine Single-Page-Application play mit Vue.js gebaut. Hier ist für das Berücksichtigen der neuen Funktionalität vergleichsweise wenig zu tun. Wenn ein Benutzer angemeldet ist, und in die SPA wechselt, sendet der Browser auch von dort unseren Cookie mit dem JWT-Token an die hinter dem Reverse Proxy liegenden Web-Applikationen.

Die Interaktion zwischen SPA und games erfolgt über REST — unser ServletFilter greift auch bei diesen Anfragen, fischt den Cookie aus dem HTTP-Request validiert das enthaltene User-Objekt gegen das Shared Secret und legt es als Attribut im Request-Objekt ab.

Die Überprüfung, ob der Benutzer, der einen Zug sendet, tatsächlich am Zug ist, erfolgt in der Java-Klasse GameRestController (Package org.flexess.games.rest) in games. Falls nein gibt es eine Fehlermeldung ( HTTP 403, Forbidden) zurück, die in play fachlich angezeigt wird, siehe Screenshot.Der angemeldete Benutzer ist nicht am Zug.In der SPA play selbst habe ich auf Sicherheitsabfragen verzichtet. Das hätte zwar die Benutzbarkeit erhöht (Beispiel: Man darf nur Züge absenden, wenn man am Zug ist), allerdings könnte ich dann genau solche Überprüfungen nicht gut demonstrieren.

In play ist somit eigentlich gar nichts zu tun. Insbesondere brauchen wir die digitale Signatur des JWT-Tokens nicht verifizieren. Der Browser sendet es einfach unverändert zurück — games verifiziert es auf dem Server. Sollte ein Angreifer auf dem Client ein anderes Token unterschieben, sollte games das merken, da die Signatur nicht stimmt.

Das einzige, was wir in play tun, ist den Benutzer mit User ID und Namen für das Menu anzuzeigen. Da die SPA die ganze Browser-Seite belegt, müssen wir die Funktionalität doppeln (mehr zu diesem Kompromiss in der nächsten Folge dieser Blog-Serie). Dazu müssen wir das JWT-Token allerdings nur auslesen und dekodieren, nicht verifizieren. Hierzu brauchen wir den Schlüssel nicht. Insbesondere muss der Shared Key nicht in die SPA gelangen — was auch fatal wäre. Wegen des symmetrischen Verfahren wäre das Fälschen eines Anmelde-Tokens damit ein Leichtes.

Das Dekodieren eines JWT Tokens in play ist in JavaScript ziemlich leicht. Anders als beim digitalen Signieren in Python (players) und Überprüfen der Signatur in Java (games) und Python (players) kommen wir hier mit Bordmitteln, also ohne Fremdbibliothek durch. Siehe Funktionen getPayloadFromJWT und getUserFromJWT in der Datei players.js in play.

Einschränkungen und Alternativen

Die Benutzerdaten speichert players aktuell lokal über TinyDB in einer Datei ab. Das macht den Docker-Container zustandsbehaftet und damit nicht redundant betreibbar. Eine Persistenz-Lösung außerhalb des Prozesses wäre daher sinnvoll, naheliegend ein Verzeichnisdienst wie Active Directory oder OpenLDAP. Das sind auch seriöse Orte, um Kennwörter abzulegen, die Authentifizierung durchzuführen oder Gruppenzugehörigkeiten zu speichern. Vielleicht zeige ich das nochmal in einer späteren Folge dieser Blog-Serie, und erinnere mich an meine LDAP-Vergangenheit.

Eine andere Option wäre gleich eine Lösung, die Authentifizierung und Single Sign-on für Webapplikationen „hauptberuflich“ implementiert, beispielsweise CAS oder Keycloak. Auch die Möglichkeit, sich via Google-Account etc. anzumelden, ist denkbar. Beim Betrieb in Cloud-Umgebungen oder Container-Orchestrierungen steht Authentifizierung oftmals als Dienst zur Verfügung und wäre auch eine Option.

In den Modulen rules und chess-diagrams habe ich das JWT-Token bisher nicht überprüft. Bei chess-diagrams ist es aktuell nicht auch nötig. Auch nicht angemeldete Benutzer können eine Partie verfolgen. rules ist aktuell von außen nicht erreichbar, bisher greift nur games darauf zu. Hier könnte man das Token bereits jetzt durchschleifen und in rules überprüfen. Den Einbau hole ich mach, wenn wir rules direkt von außen nutzen (kommt noch).

Unsere Schachplattform wächst und gedeiht — das Menu weist nun zwei Bereiche auf. Einen für die Partien (Games), einen für die Spieler (Players). Da die beiden Bereiche separate Webanwendungen sind, und in games auch noch die SPA play steckt, ist das Menu aktuell 3x implementiert. Inkl. der Logik für das Anzeigen des Benutzers bzw. des Login-Links. Das Hinzufügen eines weiteren Bereiches mit eigenem Menu macht das Anfassen an allen anderen Teilen erforderlich, um die Menüpunkt aufzunehmen.

JWT HandbookWeitere Informationen. Und wie es weiter geht.

Wenn Ihr mehr über JWT erfahren wollt lege Euch das schöne E-Book von Sebastián Peyrott ans Herz: JWT Handbook (Cover siehe rechts).

Aktuell wird die Startseite statisch vom Reverse Proxy geliefert. Im nächsten Beitrag in dieser Serie fügen wir mit der Homepage ein weiteres Modul mit UI-Anteil hinzu und diskutieren dabei auch den obigen Kompromiss im Menu (ein neuer Punkt muss in allen Modulen eingefügt werden) und Alternativen dazu. 

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

Zur Blog-Serie Micro Moves

 

 

Softwarearchitektur SpeedDating JUG Karlsruhe

Softwarearchitektur Speed-Dating bei der JUG Karlsruhe

By | Publikationen, Vorträge | No Comments

JUG Karlsruhe


 „Monolith sucht Resilienz — Softwarearchitektur Speed-Dating“
Interaktiver Vortrag. Impuls und Moderation: Stefan Zörner

Veranstaltung bei der JUG Karlsruhe
Mittwoch, 13.Februar 2019
Synyx GmbH & Co. KG, Gartenstraße 67, 76135 Karlsruhe
#jugka

Foliendownload (PDF)

Zeitgemäße Softwarearchitektur ist nicht das Werk einzelner. Architekturansätze und Ideen entstehen im Team und werden gemeinsam reflektiert. Alle Entwickler müssen sie zumindest verstehen und mittragen können. Aber was genau müsst Ihr vermitteln? Reicht aufschreiben? Hilft UML?

Stefan Zörner zeigt auf lebendige Weise, wie Ihr Eure Softwarearchitektur wirkungsvoll kommunizieren könnt. Nach kurzen theoretischen Inputs rund um Architekturdokumentation und -bewertung probiert Ihr das Gehörte gleich aus. Ihr lernt die Lösungen anderer Teilnehmer kennen und erfahrt Schritt für Schritt, welche Zutaten in einem Architekturüberblick keinesfalls fehlen sollten – egal wie kurz er ist. Ihr lernt die richtigen Fragen zu stellen und passende Antworten parat zu haben.

Bringt bitte die Bereitschaft mit, Euch über Eure Projekte und Softwarelösungen auszutauschen, und anderen Teilnehmern Feedback zu geben. Die sonst üblichen Speed-Dating-Themen wie Ex-Partner und Kinderwünsche klammern wir aus.

Stefan Zörner - Monolith sucht Resilienz

Zur Veranstaltung

follow us on Twitter – @embarced

szoerner_java_aktuell_makro_micro

Artikel in Java aktuell: Microservices und Makro­-Architektur

By | Artikel, Publikationen | No Comments
Microservices und Makro­-Architektur

In der Ausgabe 01/2019 der Java aktuell ist ein Artikel zu Makro-Architektur und Microservices erschienen. Sie finden ihn hier als PDF zum Download.

Java aktuell 01/19 Cover

Drei zentrale Entwurfsfragen bei vertikalen Anwendungsarchitekturen
Autor: Stefan Zörner
Artikel in Java aktuell 01/2019
online erschienen am 27. Dezember 2018
Artikel-Download (PDF)

Moderne Architektur-Stile wie Microservices oder Self-contained Systems lassen Teams, die einzelne Teile entwickeln, viel Freiheit bei Technologieentscheidungen. Drei Themen entpuppen sich jedoch regelmäßig als Kandidaten, um übergreifend adressiert zu werden, damit die Anwendung wie aus einem Guss wirkt oder andere Architekturziele nicht verfehlt. Dieser Artikel stellt die Fragestellungen vor und zeigt Antworten auf.

Artikel als PDF follow us on Twitter – @embarced

IT-Tage 2018_SZoerner_embarc

IT-Tage 2018 – Was (genau) ist eigentlich Architekturbewertung?

By | Inhaltliches, Publikationen, Vorträge | No Comments
„Nörgeln ist einfach. Aber was (genau) ist eigentlich Architekturbewertung?“

IT-Tage 2018

Nörgeln ist einfach. Aber was (genau) ist eigentlich Architekturbewertung?
Sprecher: Stefan Zörner
Vortrag bei den IT-Tagen 2018
Dienstag, 11. Dezember 2018, ab 11:30 Uhr
Frankfurt am Main, im Kongresshaus Kap Europa

Foliendownload (PDF)



Statler: “Das war wirklich mal was zum Lachen!”
Waldorf: “Ja, das ist echt komisch gewesen!”
Statler: “Was glaubst Du – ob das beabsichtigt war?”
(aus der Muppet Show)


Jedes interessante Softwaresystem hat eine Softwarearchitektur. Diese ist kunstvoll geplant oder zufällig entstanden, meist aber irgendwas dazwischen. Hätte man es anders machen sollen? In diesem Vortrag stelle ich vor, wann und wie Ihr Eure Softwarearchitektur bewertet! Seid Ihr auf dem richtigen Weg? Können Eure Architekturideen in der Umsetzung aufgetretene Probleme effektiv lösen? Helfen diese bei der Erreichung Eurer Ziele oder behindern sie diese eher? Architekturbewertung kann Sicherheit schaffen und Risiken aufzeigen und damit helfen die Aufwände im Vorhaben zu fokussieren. Ihr lernt qualitative und quantitative Bewertungsmethoden kennen: Was argumentative, Workshop-basierte Verfahren wie ATAM leisten thematisiere ich ebenso wie welche Aspekte Eurer Architekturziele sich mit Messungen verknüpfen lassen.

Stefan Zörner - Stefan Zörner - Was (genau) ist eigentlich Architekturbewertung

follow us on Twitter – @embarced

szoerner_informatik_aktuell

Architekturbewertung. Artikel von Stefan Zörner in Informatik Aktuell

By | Artikel, Publikationen | No Comments
Nörgeln ist einfach. Aber was (genau) ist eigentlich Architekturbewertung?

Informatik Aktuell Logo

„Was ist eigentlich Architekturbewertung?“
Autor: Stefan Zörner
Artikel in Informatik Aktuell
online erschienen am 06. Dezember 2018

In Softwarevorhaben stellen insbesondere Neue im Team gerne Fragen wie: „Warum habt ihr das so gemacht? Wäre das nicht anders besser gewesen? Also ich hätte ja …“ – Was genau heißt dann „besser“. Nachher ist man immer schlauer. Und Nörgeln ist bekanntlich einfach … In diesem Artikel diskutiere ich, welche Ansatzpunkte und Methoden es zur Bewertung einer Softwarearchitektur gibt, und welche davon zu welchen Zeitpunkten im Leben einer Software Nutzen stiften.

Artikel Online Lesen

Zum Thema Architekturbewertung

follow us on Twitter – @embarced

JUG_Saxony_Day_2018

JUG Saxony Day 2018: Drei zentrale Entwurfsfragen bei vertikalen Anwendungsarchitekturen

By | Publikationen, Vorträge | No Comments
„Microservices & Makro-Architektur
Drei zentrale Entwurfsfragen bei vertikalen Anwendungsarchitekturen“

Logo JUG Saxony Day

Microservices & Makro-Architektur – Drei zentrale Entwurfsfragen bei vertikalen Anwendungsarchitekturen
Sprecher: Stefan Zörner
Vortrag auf dem JUG Saxony Day 2018
Freitag, 28. September 2018, 11:50 – 12.50 Uhr
Radebeul bei Dresden, im Radisson Blu Park Hotel & Conference Centre
#JSD2018

Foliendownload (PDF)

Rückblick JUG Saxony Day 2018 (auf Youtube)



Moderne Architekturstile wie Microservices oder Self Contained Systems lassen Teams, die einzelne Teile entwickeln, viel Freiheit beim Treffen von Technologieentscheidungen. Drei Fragestellungen entpuppen sich jedoch regelmäßig als Kandidaten, um in der Makro-Architektur (also übergreifend) adressiert zu werden, zumindest zu einem gewissen Grad. Sonst wirkt die Anwendung nicht aus einem Guss oder verfehlt andere Architekturziele (z.B. flexibel reagieren zu können auf Veränderungen). In diesem Vortrag stelle ich die drei Themen entlang eines durchgängigen Beispiels vor. Ich zeige gängige Lösungsoptionen und Einflussfaktoren, die Euch eine informierte Auswahl für Eure Vorhaben ermöglichen. Wechselseitige Beeinflussungen, Kompromisse und Real World-Entscheidungen eingeschlossen.

Stefan Zörner - Mikro- vs. Makroarchitektur

follow us on Twitter – @embarced

Microservices und Makroarchitektur

Vortrag auf dem Java Forum Nord im September in Hannover

By | Publikationen, Vorträge | No Comments
„Microservices & Makro-Architektur — Drei zentrale Entwurfsfragen bei vertikalen Anwendungsarchitekturen“

Logo Java Forum Nord

Microservices & Makro-Architektur –

Drei zentrale Entwurfsfragen bei vertikalen Anwendungsarchitekturen
Sprecher: Stefan Zörner
Vortrag auf dem Java Forum Nord 2018
Donnerstag, 13. September 2018
Hannover, Hotel Dormero, Hildesheimer Straße 34 – 38

Foliendownload (PDF)

Moderne Architekturstile wie Microservices oder Self-contained Systems lassen Teams, die einzelne Teile entwickeln, viel Freiheit beim Treffen von Technologieentscheidungen. Drei Fragestellungen entpuppen sich jedoch regelmäßig als Kandidaten, um in der Makro-Architektur (also übergreifend) adressiert zu werden, zumindest zu einem gewissen Grad. Sonst wirkt die Anwendung nicht aus einem Guss oder verfehlt andere Architekturziele (z.B. flexibel auf Veränderungen reagieren zu können).

In diesem Vortrag stellt Stefan Zörner die drei Themen entlang eines durchgängigen Beispiels vor. Er zeigt gängige Lösungsoptionen und Einflussfaktoren, die Euch eine informierte Auswahl für Eure Vorhaben ermöglichen. Wechselseitige Beeinflussungen, Kompromisse und Real World-Entscheidungen eingeschlossen.

Stefan Zörner - Mikro- vs. Makroarchitektur

MicroMoves_Bauteil 6

Einen Computergegner asynchron anbinden mit RabbitMQ (Micro Moves, Bauteil 6)

By | Inhaltliches | No Comments

Blog-Serie Micro Moves -- LogoIn der vorherigen Folge der Micro-Moves-Serie haben wir einen Service für die Spielregeln im Schach synchron an einen anderen Service angeflanscht. Mit diesem Bauteil zeigen wir nun asynchrone Kommunikation. Konkret ermöglichen wir es Benutzern unserer Online-Schachplattform FLEXess sich mit einem der ganz Großen im Computer-Schach zu messen.

Um was geht es — ein Überblick

Im Bild sieht es aus, als gäbe es dieses Mal gleich zwei Bauteile. Was die Anzahl Prozesse angeht stimmt das auch. Wir integrieren einen Computer-Spieler (Stockfish) und binden ihn via Messaging asynchron an das games-Modul an. Inhaltlich passiert am Ende aber nur eins: Unsere Benutzer können gegen den Ranglisten-Ersten (CCRL 40/40, Stand Juli 2018) im Computer-Schach antreten. Oder auch der Computer gegen sich selbst, wenn wir einfach nur zugucken wollen.

Überblick FLEXess, Bauteil 6

Computerschach

Ein Jahrhundertraum wie das Fliegen. Eine Machine bauen, die Menschen im Schach bezwingt. Seit Wolfgang von Kempelens berühmten Schachtürken um 1780 haben sich Menschen daran versucht. Das Problem können wir als gelöst ansehen. Claude Shannon hat 1949 mit seinem Aufsatz „Programming a Computer for Playing Chess“ die theoretische Grundlage gelegt. 1996 verlor das erste Mal ein amtierender Schachweltmeister — stellvertretend für die gesamte Menschheit sozusagen — unter Wettkampfbedingungen gegen eine Machine (Deep Blue). Mit dem aktuellen Megatrend Machine Learning hatte das Ganze übrigens nichts zu tun. Deep Blue lernte nicht. Es rechnete einfach brutal schnell.

Erste Schach-Computer für den privaten Gebrauch erschienen bereits 1977 und kosteten noch eine Stange Geld. Der Fortschritt in der Hardware lässt uns heute bequem auf unserem Smartphones gegen eine App verlieren. Der eigentliche (Rechen-)Kern von Schach-Programmen wird dabei als „Engine“ bezeichnet. Engines lassen sich typischerweise in verschiedene Schachoberflächen integrieren. Damit dies einfach möglich ist, und auch damit Engines leicht gegeneinander antreten können, haben sich textbasierte Kommunikationsprotokolle etabliert. Das verbreitetste heute ist UCI (kurz für Universal Chess Interface, Spezifikation siehe hier).Stockfish Logo

Um auch Nutzern von FLEXess die Möglichkeit zu geben, gegen einen ernstzunehmenden Computergegner anzutreten, binden wir in dieser Folge Stockfish an. Das ist eine besonders spielstarke Chess Engine, in C++ implementiert und Open Source. Stockfish ist auf allen Ranglisten vorne dabei (Spitzenreiter zum Beispiel in der CCRL 40/40, Computer Chess Rating Lists, Stand Juli 2018). Das Programm unterstützt das UCI-Protokoll und lässt sich dadurch einfach integrieren.

Stockfish auf der Kommandozeile

Wenn Ihr Stockfish für Eurer Notebook herunterladet findet Ihr auf der entsprechenden Seite auch ein einfaches UI, mit dem sich die Engine interaktiv passabel bedienen lässt. Uns interessiert allerdings die Kommandozeile. Startet Ihr die Stockfish Engine in einem Terminal könnt Ihr Befehle eingeben und die Denkarbeit des Programmes beobachten, inkl. des  „besten Zuges“ nach Ende einer Analyse. Die folgende Abbildung zeigt in einem Terminal, dass Stockfish ein Schäfermatt auch auf der Kommandozeile souverän nach Hause spielt.

Stockfish in der Kommandozeile

Die von mir eingegebenen Befehle waren isready, position, go und quit. Mit position wird die aktuelle Spielsituation gesetzt. Die Eingabe ist in FEN möglich (mit position fen …, Details zu dieser Notation findet Ihr in der zugehörigen Randnotiz). Oder wie oben im Bild durch Angabe der bisherigen Züge ausgehend vom Start (mit position startpos moves e2e4 e7e5 d1h5 …). Die verwendete Züge ermöglichen weiß am Zug ein sogenanntes Schäfermatt. Die schicke Abbildung unten zeigt das Brett nach diesen 6 (Halb-)zügen. Es ist übrigens mit dem chess-diagrams-Modul als Folge 2 dieser Serie generiert.

Spielsituation vor Schäfermatt

Der UCI-Befehl go lässt Stockfish losrechen. Mit dem depth-Parameter habe ich die Suchtiefe beschränkt, damit die Ausgaben nicht das Terminal zutexten und wir die vorherigen Eingaben noch im Screenshot sehen. Mit bestmove gibt Stockfish seinen Zug aus. Dame auf h5 schlägt auf f7 und setzt Matt. Besser geht es nicht.

Mit quit können wir die Session beenden. Wir wollen Stockfish nicht weiter unterfordern.

Stockfish anbinden

Roboter mit SteckerBei der Integration der Schach Engine habe ich mich für Python entschieden, um ein bisschen Gluecode zu schreiben. Ihr findet diesen im Modul computer-player auf GitHub. Die betreffende Datei heißt stockfish.py und umfasst ca. zwei Dutzend Zeilen Quelltext. Die Python-Funktion calculate_move startet Stockfish als Subprozess. Via stdin gibt sie die Befehle (position, go …) an die Engine und holt sich das Ergebnis über dessen stdout ab.

Das Ganze funktioniert nur, wenn stockfish installiert ist. Ein kleiner Integrations-Test mit tox überprüft die Anbindung der Engine, indem er Stockfish u.a. genau das Schäfermatt serviert. Unser Image für Docker basiert auf Ubuntu. Das Dockerfile installiert Stockfish mit apt-get. Damit das Programm aktiv wird, wenn wir ihm Züge vorlegen, verbinden wir es via Messaging.

Die Messaging-Renaissance

Messaging ist eine etablierte Technologie, um Programme miteinander sprechen zu lassen, die dies von Natur aus nicht können. Entsprechende Middleware schaut auf eine lange Geschichte zurück. WebSphere MQ von IBM etwa erblickte als MQSeries bereits Anfang der 90er das Licht der Welt. Der spätere SOA-Hype befeuerte den Einsatz derartiger EAI-Lösungen. Neben kommerziellen Produkten von Firmen wie Oracle oder TIBCO gibt es auch Open Source-Lösungen, etwa Apache ActiveMQ.

RabbitMQ LogoMessaging-Lösungen kennzeichnen sich durch lose Kopplung aus. Die Kommunikationspartner können in sehr verschiedenen Technologien implementiert sein und auf unterschiedlichsten Plattformen laufen. Der Nachrichtenaustausch erfolgt asynchron und oftmals indirekt. Die Partnerprogramme brauchen sich weder kennen, noch gleichzeitig laufen. Das macht Messaging Lösungen für zeitgenössische Architekturstile wie Microservices, die lose Kopplung anstreben, sehr interessant.

Auch wenn die Konzepte die alten sind sehen wir vermehrt neuere, leichtgewichtige Messaging-Löungen auf dem Vormarsch. Ganz vorne dabei ist RabbitMQ. Die in Erlang entwickelte Open Source-Lösung implementiert eine Reihe von Standards, darunter AMQP (Advanced Message Queuing Protocol).

Für unsere Anbindung haben wir ein vorgefertigtes Docker-Image von RabbitMQ genutzt, und in der Konfigurationsdatei für docker-compose als Service vereinbart. Die gewählte Image-Variante beinhaltet die webbasierte Management-Konsole. Dadurch lässt sich RabbitMQ mit seinen Verbinden, Nachrichtenaustauschen und Queues prima von außen beobachten. Die folgende Abbildung zeigt bereits unser FLEXess in Aktion. Also beim Senden und Empfangen von Schachstellungen und Spielzügen als Nachrichten.

RabbitMQ Management Console

games und computer-player tauschen Nachrichten aus

Für die Anbindung zwischen games und computer-player (siehe auch Überblicksbild oben) nutzen wir zwei sogenannte „Direct Exchanges“ in RabbitMQ. Die Middleware bietet verschiedene Austauschmuster an — das direkte ist das einfachste. Die folgende Abbildung zeigt das Zusammenspiel:

Ablauf Messaging

Zwei Queues nehmen Nachrichten im JSON-Format auf. Im Fall eines Zuges, den Stockfish ausführen soll, legt games zunächst eine Nachricht mit der Spielsituation (Schachstellung in FEN) in der Message-Queue positions ab. Ein Computer-Spieler „lauscht“ auf dieser Queue (Implementierung der Funktionen in Python in der Datei stockfish_listener.py). Tatsächlich könnte es mehrere computer-player-Container  geben. Im Falle einer Nachricht liest computer-player die Position aus und nutzt die UCI-Integration wie oben beschrieben zur Ermittlung des besten Zuges aus Stockfishs Sicht. Dieser Zug geht über die Queue moves an games zurück. Über die Game-ID, die jede Nachricht als ein Attribut enthält, kann das games-Modul den Zug dem Spiel zuordnen und ausführen.

Die Aussteuerung von Spielsituationen in die Warteschlange positions erfolgt in games über den Spielernamen „stockfish“. So kann ein Spieler gegen den Computer spielen, indem er einfach eine Partie gegen „stockfish“ startet. Die folgende Abbildung zeigt mich (weiß) im Spiel gegen den Computer-Gegner. Im Moment sieht es noch ausgeglichen aus.

Spiel gegen den Computer-Gegner im Browser

Übrigens lassen sich über das UI des games-Subsyststems auch Partien starten, in denen Stockfish gegen sich selbst spielt. Einfach für beide Spielernamen „stockfish“ im Formular unter „Create a new game“ eintragen. Dann geht das los. Wählt Ihr „Play Game!“ könnt Ihr die „beiden“ Kontrahenten beobachten. Die folgende animierte Abbildung zeigt den Ausschnitt einer solchen Partie in Endlosschleife.

Stockfish gegen Stockfish

Weitere Informationen. Und wie es weiter geht.

Enterprise Integration Patterns: Designing, Building, and Deploying Messaging SolutionsRabbitMQ stellt exzellente Tutorials für alle denkbaren Programmiersprachen und verschiedene Kommunikationsmuster bereit. Ich habe mich für Python daran orientiert. Für die Integration in das games-Modul mit Spring Boot ließ ich mich von einem entsprechenden Beitrag inspirieren: „Getting Started: Messaging with RabbitMQ“.

Die fundierte Quelle für Messaging in Buchform ist meiner Meinung nach immer noch der Klassiker Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions von Gregor Hohpe.

Die Entwicklung von Programmen, die Schach spielen können, geht weiter. Auch heute noch treten Schachprogramme im Wettbewerb gegeneinander an. Mittlerweile mischt die künstliche Intelligenz tatkräftig mit. 2017 schlug Google’s AI-Lösung AlphaZero das traditionelle Spitzenprogramm Stockfish. Es benötigte 4 Stunden, um Schach zu lernen. Und verlor im Anschluss von 100 Partien keine einzige (Bericht hier).

Wie geht es hier mit FLEXess weiter eigentlich? Die Benutzer brauchten sich bisher noch nicht an der Plattform anmelden. Eine Zeichenkette für den Spielernamen einzugeben, genügt. Und jeder kann bei jedem mitspielen. Zeit, dass wir uns diesem offensichtlichen Mangel widmen!

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
 

 

 

 

Stefan Zörner im Juli bei der Java User Group Münster

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

JUG Münster Logo

Mikro- vs. Makroarchitektur – Spielraum und Spielregeln
Sprecher: Stefan Zörner
Vortrag bei der Java User Group Münster
Mittwoch, 4. Juli 2018, 18:30 – 20:30 Uhr
Anmeldung über Xing
LVM Versicherung, Kolde-Ring, Münster

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