System-of-Systems im SCS-Architekturstil

Der Self-Contained-System (SCS) Architekturstil ist seit einigen Jahren auf dem Vormarsch und verfolgt im wesentlichen dieselben Ziele wie Microservice basierte Architekturen. Die Gruppierung nach sinnvoll geschnittenen fachlichen Domänen, um u.a. den operativen Footprint und die Beziehungskomplexität zu verringern, ist ein großer Vorteil, der den Siegeszug der SCSe mitbegründet. Doch ebenso wie bei Microservices steht man bei den SCSen vor der großen Herausforderung, aus den völlig voneinander unabhängigen Systemen ein oder mehre System-of-Systems zu erstellen. Ein System-of-System ist beispielsweise eine Shop-Anwendung für den Kunden oder der Admin-Bereich. Beide Gesamtsysteme bedienen sich der gleichen Ressourcen der SCSe allerdings fordern sie diese in unterschiedlichen Repräsentationen an. Durch jahrelange Erfahrung in der Umsetzung und dem Betrieb unterschiedlicher SCS basierten Systeme, haben wir eine Reihe von „Contracts“ definiert, die in den meisten Fällen notwendig sind, um System-of-Systems also Gesamtsysteme daraus zu erschaffen.

Entstehung von System-of-Systems über Contracts

Vier System-of-Systems: Shop, Tech-Admin, Support, Manager

Repräsentations-Contract

Jedes SCS beinhaltet seine eigenen Repräsentationen z.B. als Shop-Login-Partial aus der User-Vertikalen. Wird eine solche Ressource angefordert, wird ihr der angeforderte System-of-System Context z.B. als HTTP Header mitgegeben. Beim rendern dieser Ressource kann dann ein Strukturtemplate wie beispielsweise ein Freemarker-Macro oder Pageframe als Repräsentations-Contract von dem SCS verwendet werden. Dieses Macro wird von allen SCSe verwendet, welche am entsprechenden System-of-System teilnehmen möchten. In diesem Macro steht dann beispielsweise, dass oben eine Navi ist, darunter eine Suche etc. Die Inhalte dieser Strukturelemente werden jedoch von der verantwortlichen Vertikale angefordert. An dieser Stelle muss die Entscheidung getroffen werden ob der Struktur-Content an einer zentralen Stelle liegt oder in jedes SCS kopiert wird. In der Praxis hat sich gezeigt, dass das Duplizieren also Kopieren weniger Probleme mit sich gebracht hat als das Wiederverwenden, da dieses immer mit indirekten Abhängigkeiten bezahlt werden muss. Das folgende Code-Snippet zeigt ein vereinfachtes Freemarker-Macro, welches diesen System-of-System Contract implementiert:

<#macro page>
<!--# include virtual="/navi" -->
<!--# include virtual="/search" -->

<#nested>

<!--# include virtual="/footer" -->
</#macro>
<@page>Here is my vertical specific content</@page>

Design-Contract

Dieser Contract beschäftigt sich nicht mit dem was eine Ressource darstellen soll, sondern wie diese aussehen soll. Bei HTML basierten Web-Systemen wird dieser Design Contract über einen CSS-Styleguide definiert. Über den Struktur-Contract wird die Verknüpfung zum Design-Contract hergestellt, indem im Macro oder Pageframe ein Verweis auf das Design ist. Dies führt dazu, dass alle Ressourcen der teilnehmenden SCSe gleich aussehen und für den Benutzer nicht zu erkennen ist, dass die einzelnen Teile aus völlig unterschiedlichen Systemen kommen.

URL-Contract

Die URL-Contracts beinhalten die Konventionen der Routen und deren Bereiche, wobei oftmals diese in die folgenden zwei Hauptkategorien eingeteilt werden können.

  1. Öffentlicher Bereich (Ressourcen, die von allen angefordert werden dürfen: „/“)
  2. Interner Bereich (Geschütze Ressourcen: z.B. „/self-care/*“)

Der interne Bereich wird laut Konvention durch “/self-care/” eingeleitet. Alle folgenden Routen sind somit in einem passwortgeschützten Bereich, und können nur von registrierten bzw. autorisierten Benutzern gesehen werden. Ein Beispiel hierfür wäre der Bereich zur Verwaltung seiner Adressen oder Bestellungen eines Online-Shops.

Authentifizierungs-Contract

Jedes System-of-System definiert ein Authentifizierungs- und Autorisierungsverfahren. Alle teilnehmenden Ressourcen müssen sich entsprechend diesem Verfahren verhalten und die geforderten Mechanismen implementieren. Als REST konformeres, skalierbares und sicheres Verfahren hat sich die Arbeit mit signierten Cookies etabliert. Ein weit verbreiteter Standard, den wir häufig einsetzen, sind die sogenannten JWT Cookies. Der Payload eines solchen JSON-Web-Tokens könnte wie folgt aussehen:

{
  "aud": "shop",
  "sub": "ebd7ca25877957a8fc87773522c774bf5aa5cf37",
  "is_guest": "true",
  "profile_id": "user_profile",
  "iss": "print",
  "language": "de-DE",
  "exp": 1565311422,
  "iat": 1563818593,
  "jti": "ef5d1f89-01a9-4ef3-9ecc-a44bddbf28e9",
}

Dieser Payload wird serverseitig generiert und mit einer Signatur gegen Manipulation abgesichert. Aus Cybersecurtiy-Perspektive ist es wichtig darauf zu achten, dass keine technischen IDs oder sensible Daten in dem Cookie abgelegt werden, denn dieser ist lediglich base64 encodiert und kann somit öffentlich einsehbar sein. Technische IDs geben strukturelle Informationen an potentielle Angreifer frei, deshalb sollten hier nur logische Kennung abgelegt werden.

Integration / Orchestrierung-Contract

Dieser Contract definiert Routing und Orchestrierungsegeln. Also: Welche URL führt zu welchem System? Meistens wird dies über einen Reverse-Proxy wie dem NGINX gesteuert. Diese Vorgehensweise ist technisch umstritten, da auf diese Weise Fachlichkeit in Infrastrukturkomponenten abgebildet wird. Wenn man sich dieses Mittels bedient, erhält man eine Reihe von Vorteilen, welche Entwicklungsgeschwindigkeit und Stabilität erheblich erhöhen können. Der NGINX implementiert diverse Resilience Patterns, die out of the Box funktionieren können und verfügt über mächtige Caching Mechanismen. Um den Kritikpunkt der fachlichen Infrastrukturkomponente entgegen zu wirken, empfiehlt es sich, den NGINX zwar auf diese Weise zu verwenden, allerdings nur so viel, wie unbedingt nötig. Ein Architekturziel an dieser Stelle ist, die Logik möglichst einfach und kurz zuhalten. In der Praxis hat sich dieses Vorgehen als effizient zu warten und unkompliziert erwiesen. Im Folgenden ist ein Beispielrouting zu sehen, welches Anfragen, die an „/user“ gehen, an einen bestimmten Server weiter geleitet werden:

location ^~ /user {   
    proxy_pass http://127.0.0.1:8201/user;   
    proxy_redirect http://127.0.0.1:8201/ http://localhost/;
}

Aus der Praxis

Bei der täglichen Arbeit mit unseren Kunden haben wir immer wieder festgestellt, wie schwer es vielen Entwicklern fällt, Systeme wirklich ressourcenorientiert zu bauen und Konzepte umzusetzen, um aus diesen Ressourcen Gesamtsysteme (System-of-Systems) zu erschaffen. Meist wird viel zu stark in Webseiten gedacht und gearbeitet, sodass Inhalte zu eng an Repräsentationen und Kontexte gebunden sind und die eigentliche Vielgestaltigkeit von semantischen Daten verloren geht. Als Architekten und Lead-Entwickler achten wir darauf, dass dieses Umdenken stattfindet und erleben immer wieder Aha-Effekte, wenn eine bestehende Ressource plötzlich Teil eines anderen System-of-Systems wird, ohne dass der Entwickler etwas dafür ändern musste.

Quellen

  1. scs-architecture.org https://scs-architecture.org
  2. jobpushy.de https://www.jobpushy.de/blog/11/self-contained-system-scs-%E2%80%94-architektur-trend
  3. senacor.com https://blog.senacor.com/self-contained-systems/
  4. jwt.io https://jwt.io/introduction/
  5. roca-style.org https://roca-style.org/
  6. restful-api-design.readthedocs.io https://restful-api-design.readthedocs.io/en/latest/methods.html#actions
  7. stormpath.com https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage
  8. nginx.org http://nginx.org/en/docs/http/ngx_http_ssi_module.html
  9. freemarker.apache.org https://freemarker.apache.org/docs/dgui_misc_userdefdir.html
  10. Base64 RFC https://tools.ietf.org/html/rfc4648
  11. Release It! https://www.oreilly.com/library/view/release-it/9781680500264/
  12. Microservices at AWS https://thenewstack.io/led-amazon-microservices-architecture/
  13. Content-Negotiation https://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html
  14. Roy Fielding’s REST Architecture https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

Markus Schnittker

Markus Schnittker ist Senior IT Consultant bei der NEOZO, wo er sich überwiegend mit der Umsetzung skalierbarer IT Architekturen beschäftigt. Sein Schwerpunkt ist die Realisierung von verteilten Java-basierte SCS-Architekturen.

Schreibe einen Kommentar