Make your Software agile Karsten Besserdich Besserdich und Redmann GmbH Berlin Schlüsselworte Modularisierung, Agilität, Transformation, Continuous Integration, Java, Oracle, Projektbericht Einleitung Die Wartung und Weiterentwicklung von monolithischen Anwendungen sind eine Qual. Mit der Einführung agiler Entwicklungsmethoden ändert sich daran grundsätzlich nichts. Erst durch die „Agilisierung“ der Software können SCRUM und andere agile Entwicklungsmethoden ihre ganzen Vorteile ausspielen. In diesem Projektbericht geht es um die Zerschlagung von Monolithen im „automatischen Verfahren des Zulagesystems“ der Deutschen Rentenversicherung Bund. Auf Basis des Agile Development LifeCycle werden die Änderungen und daraus resultierenden positiven Effekte dargestellt. Über den Autor Karsten Besserdich ist seit 15 Jahren in der Softwareentwicklung zuhause und beschäftigt sich seit längerem intensiv mit agilen Entwicklungsmethoden im skalierten Umfeld. Den größten Teil seiner Zeit verbrachte er in Großprojekten im öffentlichen Sektor sowie in der Energiewirtschaft. Er ist einer von zwei geschäftsführenden Gesellschaftern der Besserdich & Redmann GmbH. Karsten Besserdich und Tobias Redmann unterstützen gemeinsam mit ihren Mitarbeitern ihre Kunden bei der Planung, Durchführung und Steuerung von IT Projekten in den Bereichen Oracle und Webentwicklung. Agenda In diesem Vortrag wird aus einem aktuellen Projekt berichtet. Zuvor werden ein paar theoretische Begrifflichkeiten wiederholt. Bei dem Projektbericht werden folgende Schwerpunkte gesetzt: Organisatorische und technische Ausgangssituation Die Schmerzen Umsetzung Ergebnisse Abschließend erfolgt ein subjektives Fazit sowie ein Ausblick auf kommende Herausforderungen im weiterhin laufenden Projekt. Abgrenzung Es erfolgt keine Beschreibung wie SCRUM im skalierten Umfeld funktioniert. Auch technische Umsetzungen und Konfigurationen von Tools werden nicht erläutert. Begriffe Monolithische Anwendungen Eine monolithische Softwarearchitektur1 folgt nicht dem Ansatz einer expliziten Gliederung in Teilsysteme oder Komponenten. Ein monolithisches IT-System2 ist eine untrennbare Einheit, woraus sich u.a. folgende Nachteile ergeben: weder wartbar noch erweiterbar (nur mit erheblichen Aufwand) nicht mehr beherrschbar – bei Änderungen kann es zu nicht vorhersehbaren Nebeneffekten kommen keine Wiederverwendung von Teilen des Softwaresystems starre Kopplungen verhindern u.U. Lastverteilung auf verteilten Systemen Agile Entwicklungsmethoden Agile Softwareentwicklung versucht mit geringem bürokratischem Aufwand, wenigen Regeln und meist einem iterativen Vorgehen auszukommen3. Frameworks wie Adaptive Software Development (ASD), Crystal, Extreme Programming (XP), Kanban und das wohl bekannteste Vorgehensmodell SCRUM sind hier zu nennen. Im skalierten SCRUM sind wiederum Frameworks wie Nexus, SCRUM at Scale, SAFe und LeSS zu erwähnen. Dies sind Methoden, um agile Vorgehensweisen in großen Organisationen mit vielen Teams erfolgreich einzusetzen und diese entsprechend zu synchronisieren. 1 http://www.itwissen.info/definition/lexikon/Monolithische-Software-Architektur.html 2 http://www.enzyklopaedie-der-wirtschaftsinformatik.de/lexikon/ismanagement/Systementwicklung/Softwarearchitektur/Architekturparadigmen/Monolithisches-ITSystem 3 https://de.wikipedia.org/wiki/Agile_Softwareentwicklung Projektbericht Organisatorische Ausgangssituation Die betroffene Abteilung hat mit der Transformation in die „SCRUM-Welt“ Anfang 2015 begonnen. Bei den Produkten handelt es sich um Fachverfahren, welche z.B. Zulagen für die Riester-Rente oder Wohn-Riester berechnen. Diese Produkte befinden sich zum Teil seit über 14 Jahren im produktiven Einsatz und werden ständig den sich ändernden gesetzlichen Anforderungen angepasst. Einzelne Fachverfahren sind je nach Größe einem oder mehreren SCRUM Teams zugeordnet. Die Größenordnung aller beteiligten Personen beträgt ca. 100 -120 Personen. Team 3 Team 1 Team 4 Team 2 Abbildung 1 Organisatorische Projektstruktur Team 5 Technische Ausgangssituation Die „Basis“ Die Fachverfahren teilen sich einen Teil des Sourcecodes, der die „Basis“ genannt wird. Sie beinhaltet viele kleine Funktionalitäten wie z.B. Parameter-, Druck-, Authentifikation-, Logging-Services oder Prozess-Engine. Des Weiteren sind Informationen für den Build-Prozess der Datenbankbestandteile der einzelnen Fachverfahren in der „Basis“ abgelegt. Das bedeutet, dass die „Basis“ steuert, welches Fachverfahren welche DB-Funktionalitäten im Build-Prozess heranzieht. Die Übernahme der Java-Bestandteile der „Basis“ in ein Fachverfahren ist ein manueller Prozess und dementsprechend unbeliebt und fehleranfällig. Fachverfahren 1 Funktion 1 Fachverfahren 2 Funktion 3 Fachverfahren 3 Funktion 5 Funktion 3 Funktion 4 Funktion 1 Basis Funktion 1 Funktion 2 Funktion 3 Funktion 4 Funktion 5 Funktion ... Abbildung 2 Die "Basis" Funktionalitäten der „Basis“ Basis Java Source Java Source Funktion 1 Funktion 2 Java Source Java Source Funktion 3 ... Java SVN-Repository Die „Basis“ besteht aus Java-Sourcen und Datenbank-Bestandteilen, welche jeweils in separaten SVNRepositories verwaltet werden. Nicht nur die Ablage, sondern auch die Auslieferung der Datenbankund Java-Sourcen erfolgt separat. Function Buildinformationen TAB1 TAB4 TAB2 TAB3 PL/SQL Packages Oracle SVN-Repository DB-Schema Basis Procedure MatView Abbildung 3 Architektur der Basis Entwicklungs- & Release-Zyklus Jedes Fachverfahren sowie die „Basis“ hat seine eigenen Entwicklungs- und Release-Zyklen. Sprintdauer sowie Sprintbeginn sind weder in den Fachverfahren noch in der Basisentwicklung identisch. Grund dafür sind unter anderem gesetzliche Anforderungen an die Fachverfahren, welche zu einem bestimmten Zeitpunkt released werden müssen, sowie organisatorische und historische Gründe. Basis Funktion 1 Funktion 3 Funktion 5 Funktion 2 Funktion 4 Funktion ... Abbildung 4 Entwicklungs- & Releasezyklen Die Schmerzen Die beschriebene Ausgangssituation bringt vielerlei Probleme mit sich. Aus Sicht der Fachverfahren werden Anforderungen für Änderungen in der „Basis“ nicht rechtzeitig und in zu schlechter Qualität umgesetzt. Des Weiteren ist die separate Übernahme von Änderungen einer einzelnen Funktionalität nicht möglich. Der komplizierte und teilweise manuelle Übernahmeprozess mit getrennten Datenbankund Java-Sourcen erhöht die Komplexität erheblich. Aus Sicht der Basis-Entwicklung ist keine transparente Zuordnung von zusammengehörigen Datenbank- und Java-Bestandteilen möglich. Die geringe Testabdeckung der einzelnen Funktionalitäten ist unbefriedigend. Die Abhängigkeiten, welche hier in verschiedenen Arten vorhanden sind, erhöhen die Komplexität erheblich und machen einen erfolgreichen Einsatz von SCRUM sowie dessen Skalierung nur schwer möglich. Lösungsfindung Es wurde entschieden, die „Basis“ zu modularisieren. Alternative Lösungsvorschläge wurden umfangreich diskutiert und abgestimmt, darunter z.B. auch die Auflösung der „Basis“ und Integration sowie Weiterentwicklung der benötigten Funktionalitäten in die jeweiligen Fachverfahren. Organisatorisch wurde ein SCRUM-Team (Komponententeam „SYNERGY“) aufgestellt, welches die Aufgabe hat, die Weiterentwicklung der einzelnen Funktionalitäten in der „Basis“ fortzuführen und die Modularisierung der „Basis“ umzusetzen. Team 3 Team 1 Team 4 Team 2 Team 5 Team SYNERGY Abbildung 5 Organisatorische Projektstruktur mit Basisentwicklung Im Folgenden werden die wichtigsten Anforderungen an die Modularisierung der „Basis“ dargestellt. 1. 2. 3. 4. 5. Selektive Übernahme von einzelnen Komponenten durch die Fachverfahren ermöglichen Schnelle Umsetzung von Features ermöglichen Schlanke und gut dokumentierte Komponenten bereitstellen Hohe Qualität der Komponenten sicherstellen Automatisierung der Komponentenintegration in die Fachverfahren ermöglichen Aus diesen fünf wichtigsten Anforderungen wurde eine Vision für das SCRUM-Team der Basisentwicklung formuliert: „Als SYNERGY-Team wollen wir den Fachverfahren qualitativ hochwertige verfahrensunabhängige Komponenten zu Verfügung stellen. Auf Anforderungen aus den Fachverfahren wollen wir schnell reagieren.“ Umsetzung Roadmap Im ersten Schritt wurde eine Roadmap aufgestellt, deren wichtigste Aufgaben in den folgenden Abschnitten erläutert werden. Analyse der „Basis“ Zu Beginn wurden alle Bestandteile der „Basis“ analysiert. Alle Funktionalitäten, welche in der „Basis“ enthalten waren, wurden mit ihren Java- sowie Datenbank-Sourcen identifiziert und in Komponenten aufgeteilt. Zudem wurden Abhängigkeiten zwischen den Funktionalitäten analysiert und dokumentiert. Vorhandene Testfälle, Dokumentationen und Modelle wurden gesichtet und bewertet. Projektstruktur aufsetzen Jede Komponente wurde in einem separaten Projektverzeichnis im SVN abgelegt. Datenbank- und Java-Sourcen sollten von nun an als Einheit betrachtet werden. Vorhandene Modelle und Testfälle wurden den einzelnen Komponenten zugeordnet. Zielarchitektur Komponente 02 Komponente ... Java Source ... ... ... Database Java Source Database Java Source Database Komponente 01 Abbildung 6 Zielarchitektur der Komponenten DB-Bestandteile extrahieren Eine aufwendige Aufgabe war es, die bestehenden Datenbankobjekte zu extrahieren und den einzelnen Komponenten zuzuordnen. Dazu wurde ein Datenmodell je Komponente mittels Reverse-Engineering im Oracle Data-Modeler erstellt. Die Datenbank-Installation einer Komponente konnte somit durch die vom Data-Modeler generierten Skripte erfolgen. Build-Prozess Die Einführung eines modernen und standardisierten Build-Werkzeuges war unerlässlich. Hierbei wurde das bereits im Haus genutzte Tool Maven ausgewählt. Für die Ablage von Artefakten wurde das Tool JFrog Artifactory gewählt. Im Build-Prozess wurden nun Java- und Datenbank-Artefakte generiert und im Artifactory abgelegt. Continuous Integration Für die Komponenten wurde eine eigene Continuous-Integration Umgebung aufgesetzt. Die Jobsteuerung übernahm das Tool Jenkins. Je Komponente wird in definierten Zeitabständen der Sourcecode aus dem SVN ausgecheckt, gebaut und es werden bereits vorhandene Unit-Tests ausgeführt. Testanwendung für Integrationstests Um die Komponenten automatisiert integrativ testen zu können, wurden Testanwendungen entwickelt und in den bestehenden Buildprozess integriert. Ein großer Teil des Aufwandes bestand darin, bestehende Integrationstests aus der „Basis“ zu identifizieren und der entsprechenden Komponente zuzuordnen, um diese dann lauffähig in den Testanwendungen zu integrieren und die Testergebnisse auszuwerten. Deployment CI Nachdem der dreistufige Build-Prozess durchlaufen wurde (1- Build der Java-Sourcen, 2 - Build der DB-Sourcen, 3- Build der Testanwendung) kann nun die Testanwendung auf der CI-Umgebung deployed werden. Der Deploy-Pozess erfolgt in mehreren Schritten: 1. Entpacken der Deployment-Unit (Testanwendungs-Artefakt) 2. Automatisierte Bereitstellung der notwendigen Ressourcen im Application-Server und der Datenbank 3. Deployment der Testanwendung auf dem Application-Server sowie der DB-Bestandteile (DBArtefakt) in die Datenbank Lokaler Build & Deploymentprozess Nachdem der Build- & Deploymentprozess auf der CI-Umgebung stabil und zuverlässig funktionierte, sollte dies auch auf den lokalen Entwicklerrechnern realisiert werden. Dazu wurde ebenfalls Maven als Buildwerkzeug verwendet. Somit können alle SourcecodeÄnderungen lokal verifiziert und nach erfolgreicher Prüfung in das Versionierungstool eingecheckt werden. Releaseprozess Zum Releaseprozess der Komponenten gehört neben den Releasenotes und der Releasebezeichnung auch die automatische Übernahme der neu releasten Komponenten in den Testanwendungen, in denen sie bereits Verwendung finden. Zudem mussten die DB-Skripte zum initialen Aufsetzen sowie zum Upgrade einer Komponente neu erstellt bzw. angepasst werden. Hier ist aktuell noch ein Teil manueller Aufwand enthalten. An einer vollautomatisierten Lösung wird gearbeitet. Produktdokumentation Da aus einem Produkt – der „Basis“ – nun viele separate, eigenständige Produkte entstanden sind (die Komponenten) wurde die Dokumentation ebenfalls so aufgebaut: je Komponente gibt es eine separate Produktdokumentation, die auch alle bis dahin veröffentlichten Releasenotes enthält. Quality-Gates Zur Steigerung der Qualität wurden neben den schon vorhandenen Unit- und Integrationstests QualityGates für die Code-Qualität eingeführt. Mit Hilfe des Tools Sonarqube wurden RuleSets und entsprechende Gates definiert, welche vollautomatisiert im Rahmen der CI geprüft und ausgewertet werden. Komponentenübernahme in die Fachverfahren Vor der Modularisierung wurden Build-Informationen für die einzelnen Fachverfahren teilweise in der „Basis“ vorgehalten. Mit der Einführung von Komponenten wurde dies geändert: Die Information, welches Fachverfahren, welche Komponenten, in welcher Version verwendet, wird nun in den Fachverfahren selbst verwaltet. Die Komponenten der „Basis“ besitzen somit keinerlei Informationen mehr darüber, von welchen Fachverfahren sie verwendet werden. Eine große Hürde für eine vollautomatisierte Komponentenübernahme durch ein Fachverfahren ist das Build-Werkzeug der Fachverfahren selbst. Hier werden heterogene Build-Werkzeuge verwendet, was eine Konfiguration der zu verwendenden Komponenten erheblich erschwert. Um den gewünschten Mehrwert für die Fachverfahren zu erbringen, werden aktuell Lösungsvorschläge erarbeitet. Ergebnisse der Modularisierung Folgende Ergebnisse wurden durch Modularisierung erreicht: - eigenständige Releasezyklen mehrere Teams können unabhängig voneinander an verschiedenen Komponenten arbeiten Erhöhung der Qualität durch Einführung einer CI-Umgebung schlanker Code bessere Testbarkeit Reduzierung von Abhängigkeiten Entwicklungs- & Releasezyklen nach der Modularisierung Ein wesentlicher Unterschied zu vorher ist, dass die „Basis“ nun aus einzelnen Komponenten besteht, welche über eigene Releasezyklen verfügen. Die Fachverfahren sind nicht mehr gezwungen, die komplette „Basis“ einzubinden, sondern können explizit eine bestimmte Version einer einzelnen, konkreten Komponente verwenden. Jedem Fachverfahren steht es nach dem Release einer neuen Komponentenversion frei, diese zu übernehmen. Abbildung 7 Entwicklungs- & Releasezyklen der Komponenten und Fachverfahren nach der Modularisierung Ausblick Die bei der Modularisierung der „Basis“ gewonnen Erkenntnisse können für die Fachverfahren als Grundlage für deren anstehende Modularisierung verwendet werden. Abbildung 8 Ausblick - Modularisierung von Fachverfahren Eine weitere spannende Problemstellung ist die vollautomatisierte Bereitstellung von Infrastruktur und die Verschmelzung von Betrieb und Entwicklung, als Stichworte sind hier „Infrastructure as code4“ und „DevOps5“ zu nennen. Fazit Einer der größten Herausforderungen bestand darin, einen geeigneten Build- und Deploymentprozess auf zuzusetzen. Die Einführung von neuen Tools und Techniken stieß auch auf Skepsis und vereinzelt auf Ablehnung, was Unruhe in die Teams brachte und einen Mehraufwand durch Erklärungsbedarf und Überzeugungsarbeit bedeutete. Die Etablierung von neuen Begriffen und das Schaffen eines Verständnisses bei den übrigen Entwicklungs-Teams, dass es keine separate „Basis“ mehr gibt, sondern man von Komponenten bzw. Produkten spricht, ist ein langwieriger Prozess, der bis heute andauert. Nicht zu unterschätzen war es, ca. 1,5 Jahre lang die „neue“ und „alte“ Welt parallel zu betreiben. Die Modularisierung von monolithischen Anwendungen ist zwangsläufig notwendig, um im agilen Entwicklungsumfeld Erfolg zu haben. Hierbei sollte man sich intensiv mit den XP-Praktiken wie z.B. Continuous Integration auseinandersetzen. 4 http://www.heise.de/developer/artikel/Infrastructure-as-Code-Agile-Entwicklung-muss-ueber-denSoftwarecode-hinausgehen-3046561.html 5 https://de.wikipedia.org/wiki/DevOps Kontaktadresse: Karsten Besserdich Besserdich und Redmann GmbH Hans-Böhm-Zeile 30 D-14165 Berlin Telefon: Fax: E-Mail Internet: +49 175 24 690 29 +49 30 12 089 47 69 [email protected] https://www.besserdich-redmann.com