Vom Monolithen zum Microservice - Integration von Legacy-Anwendungen

Für einen schweizer Internet Provider portierte und integrierte ich mehrere Legacy-Anwendungen in die bestehende Landschaft mittels Microservices und APIs.
Problemstellung
Mehrere Legacy-Anwendungen wurden Jahrzehnte lang sehr stiefmütterlich behandelt und verfügten über keinerlei Integrationsmöglichkeiten mit anderen Systemen. Dies hinderte den Kunden an der weiteren digitalen Transformation.
Eine Migration auf ein neues System war notwendig, aber nicht ohne Weiteres möglich: Die Systeme waren tief miteinander verzahnt und triggerten eine Vielzahl von Automatismen, die für den Betrieb unerlässlich waren.
Lösung
Durch Reverse-Engineering der Legacy-Anwendungen, deren Datenstruktur und Relationen und durch die Analyse der effektiv genutzten Komponenten, konnten die Datenquellen innerhalb eigener Microservices direkt angebunden und über REST-APIs den Umsystemen zur Verfügung gestellt werden.
Dem Kunden war es am Ende möglich, die Legacy-Systeme über diese standardisierten APIs in seine Workflows zu integrieren, parallel eine Migration in neue Systeme zu starten und die digitale Transformation weiter voranzutreiben.
Umsetzung
Für jedes Legacy-System entwickelte ich einen Microservice mit REST-API, integrierte die diversen Datastores (MySQL, MSSQL) und eine SOAP-API und baute eine serviceorientierte Software-Architektur auf. Durch Reverse-Engineering modellierte ich die Daten-Entitäten und deren relationen zueinander, entwickelte entsprechende Interfaces
und Klassen
und abstrahierte das Datenbankmanagement.
Für jede Datenentität habe ich entsprechende CRUD
-Handler in der API erstellt. Um inkorrekte Daten zu vermeiden, wurden die Input-Daten gefiltert und validiert. Dabei war mir wichtig, dass die Daten der unterschiedlichen Quellen normalisiert und um HAL
-Attribute angereichert wurden. Somit ging ich sicher, dass das Ein- und Ausgabe-Format über alle APIs hinweg identisch war, obwohl dahinter unterschiedliche Datenquellen lagen. Dies sparte enorm viel Zeit bei der weiteren Integration der APIs in die Umsysteme des Kunden.
Meine Arbeiten
- Analyse: Reverse-Engineering der Legacy-Anwendungen.
- Konzeption: Erstellen eines Gesamt-Konzepts, welches einen Parallelbetrieb der Legacy-Anwendungen ermöglichte.
- Proof of Concept: Prüfen der Machbarkeit mittels eines PoCs und lokalen Test-Instanzen aller Komponenten.
- Umsetzung: Entwicklung mehrere Microservices, integrieren der diversen Datastores, der Datenmodelle und dazugehöriger Relationen, eine REST-API und ein UI.
- Testing: Erstellung einer Vielzahl an Unit- und Functional-Tests.
- Deployment: Veröffentlichung als leichtgewichtiger Container auf einem internen Kubernetes-Cluster.
- Dokumentation: Festhalten der Architektur, der Datenstruktur und der API.
Tech-Stack
- REST-APIs:
- Laminas und Laminas\Mezzio
- laminas-di und laminas-servicemanager zur Dependency Injection und als Instanzmanager
- laminas-db als Datenbankabstraktionslayer für die diversen MySQL- und MSSQL-Datenbanken.
- laminas-filter, laminas-validator, laminas-inputfilter zur Filterung und Validierung der API-Endpoints und der übermittelten Daten
- laminas-hydrator zur Hydrierung und De-Hydrierung der Daten/Objekte
- laminas-paginator zur Paginierung der List-Endpoints
- laminas-soap zur Anbindung einer veralteten SOAP-Schnittstelle
- laminas-ldap und laminas-authentication zur Anbindung des internen Active Directory und zur Authentifizierung der internen Benutzer
- laminas-session fürs Session-Handling
- mezzio-cors fürs CORS-Handling
- mezzio-csrf zum Schutz vor CSRF resp. zur Generierung von Nonce-Tokens
- laminas-http zur Anbindung einiger REST-APIs zwecks Datenvalidierung
- laminas-diactoros für PSR kompatible HTTP Request- und Response-Objekte
- mezzio-hal zur Generierung von API-Links innerhalb der JSON-Response (bspw. für die Paginierung) im Hypertext Application Language (HAL) Format
- mezzio-problem-details für standardisierte, domainspezifische Exceptions gemäss PSR
- laminas-log fürs Logging mit entsprechender Middleware für AMQP
- laminas-cache für diverse Caching-Adapter (Object-Cache, MemCache, Redis-Cache)
- Frontend: AngularJs sowie HTML5, CSS3
- Monitoring + Alerting: Via CheckMK und ServiceNow
- DevOps: Github Actions für CI/CD, IaC mittels Kubernetes YAML-Files + HELM, Container Registry mittels Dockerhub
- Deployment: Als Container auf Kubernetes
Fazit
Legacy-Systeme machen oft keinen Spass. An vielen Ecken müssen Einschränkungen in Kauf genommen werden, wie beispielsweise den Einsatz von veralten Bibliotheken oder das Nutzen von unsicheren Techniken und Verfahren. Das Risiko hierbei so gering wie möglich zu halten und dennoch einen Mehrwert zu generieren, war dabei die Hauptaufgabe.