RRZE – Projekte & Prozesse (P&P)

Das Blog der RRZE Stabsstelle "Projekte & Prozesse"


Refactoring WAID

WAID is build-up of various, separately developed, components which are combined in a monolithic application. The application is structured and deployed as a single web application archive(war). The above mentioned components are of different granularity and perform tasks related to business logic, data fetching, presentation, transformation and so on. Refer to Fig.1 for a simplified diagram:

Architektur (Komponenten) von WAID

Splitting the application into small parts during the development cycle proved to be more than useful for code maintenance and rapid on-demand changes. Similar component-based approach is now proposed for the runtime structure of the application. The idea is to break up the application into smaller business-logic-based parts which can be easily exchanged during runtime without or with insignificant downtimes. Downtimes should occur only at redeployment of components which are directly related to user sessions. The exchange of all other underlying components should happen transparent to the users of the application. A simplified version of WAID’s current runtime architectural design can be seen on Fig.2. The application is started by deploying the web application archive into a JBoss AS. The JBoss server initializes a Spring (springframework) context, which is depicted by orange on Fig.2. The Spring framework is responsible for linking together the different runtime components. The most important component is idmone-core. This module is itself a Spring project which is developed separately and is responsible for the back-end functionality related to interacting with MetaDirectory. This project is only configured and used within the web application. Security is provided by the spring-security module, which is not shown on the Fig.2 but it closely couples with the Tapestry module, so these are represented by a single block. The Tapestry module is responsible for rendering the web page templates. Other required components are added within the Spring context to provide additional functionality. The pdf-generator module is shown on Fig.2 as an example of these type of components. The current implementation is focused on combining different projects into a single web application. The Spring framework provides the necessary flexibility and configuration options. The newly proposed component paradigm does the same but at runtime. Components are bound together when requested and not at initialization time. This allows for changing the underlying components implementation without re-deployment of the dependent applications. This would also allow for a better load distribution because different components can run on different machines. Generating pdf files, for example, can consume quite a lot of CPU cycles and memory. Distributing components to different machines can provide better performance but at the same time can make components reusable. Thus it would be possible to share a runtime component between applications – for example, pdf generation utilities can be used by several applications. An additional advantage is that in case of a bug fix only a single instance of a component is to be replaced. This would clearly prevent repackaging all applications that use it.

Struktur von WAID vor Refactoring

At the same time the proposed paradigm enables a major conceptual shift to Service Oriented Architecture(SOA). To put it short, the idea is instead of combining smaller projects into bigger applications, to start building up composite applications. These will consist of different runtime-bound services. The services will provide distributed business logic instead of packaged functionality. Once a certain degree of “service orientation” is achieved it would be possible to start using enterprise integration design patterns to accommodate better communication between the different systems involved. A proof of concept has been developed and a schematic view of the proposed solution is shown on Fig.3.

WAID Struktur nach Refactoring

At first glance there is not much of a difference. However, the yellow components are Enterprise Java Beans(EJBs) and run outside the web application. These can be looked up by the web application and used. EJBs have two type of interfaces local and remote. On the figure the local interface is depicted in pale blue and is the one connected with WAID. Technically this type of interface is used in the case when both modules run within the same application server, thus enabling data exchange with better performance. Although idmone-core exposes its functionality in the form of EJBs these are still initialized by a Spring context, depicted with green on Fig.3. Several developers share the opinion that Spring and JEE are excluding and competing standards but in our case these seem to form a symbiosis.

At the same time a proposal is evaluated to deploy the application as an exploded war file to accommodate on-the-fly changes. This proposal is done for the purpose of fixing typos, translation errors and similar. The same technique was tested, as a proof of concept, for implementing complex changes such as registering or unregistering existent Tapestry components on a page. So far , the concept seems useful but raises questions related to stability, reliability and can lead to inconsistencies if not thoroughly thought through. By inconsistencies are meant different versions of code on the productive system and the one tagged in the repository. In emergency cases there exists the possibility that updates are introduced in the productive system and these are later not propagated into the source code. In general managing a single web application archive seems to be a better way of handling tagging. Thus a system restore can be done by copying a single file instead of hundreds of small ones. This operation is also much more time efficient in the above mentioned case. At the time being, deploying WAID as an exploded archive is not considered harmful. However, unless the above mentioned issues are properly address and tested, changes of files under the exploded directory is granted only in exceptional situations.

Eine neue Struktur für WAID

WAID besteht aus verschiedenen, unabhängig entwickelten Komponenten, zusammengefügt zu einer monolithischen Anwendung. Diese Anwendung wird als einfaches web application archive (war) strukturiert und entwickelt. Die oben genannten Komponenten haben unterschiedliche Granularität und erfüllen Aufgaben im Zusammenhang mit Business Logic, Datensammlung, Präsentation, Transformation und so weiter. Abb.1 zeigt ein vereinfachtes Diagramm:

Architektur (Komponenten) von WAID

Die Aufteilung der Anwendung in kleinere Teile erwies sich als vorrteilhaft für Codepflege und schnell gewünschte Änderungen. Eine ähnliche komponentenbasierte Herangehensweise bietet sich nun für die Laufzeitstruktur der Anwendung an. Die Idee besteht darin, die Anwendung in kleinere, auf Business Logic basierende Einheiten aufzubrechen, die einen einfachen Austausch während der Laufzeit erlauben, entweder ganz ohne, oder zumindest mit vernachlässigbaren Ausfallzeiten. Ausfälle sollten nur bei einer Umstrukturierung von Komponenten stattfinden, die direkt mit den Nutzer-Arbeitssitzungen zu tun haben. Änderungen an allen anderen zugrundeliegenden Komponenten sollten so geschehen, dass sie für die Nutzer der Anwendung transparent sind. Eine vereinfachte Version der aktuellen WAID Laufzeitarchitektur ist in Abb.2 dargestellt. Die Anwendung wird gestarted, indem das Webanwendungsarchiv in eine JBoss AS übertragen wird. Der JBoss Server initialisiert einen Spring Kontext, der in Abb.2 orange dargestellt ist. Das Spring framework ist dafür verantwortlich, die verschiedenen Laufzeitkomponenten zu verbinden. Die wichtigste Komponente ist idmone-core. Das Modul ist selbst ein unabhängig entwickeltes Spring Projekt, verantwortlich für die Back-end Funktionalität im Zusammenhang mit der MetaDirectory-Interaktion. Das Projekt wird nur innerhalb der Webanwendung konfiguriert und genutzt. Sicherheit wird durch ein Spring Security Modul gewährleistet. Dieses Modul ist in Abb.2 nicht gezeigt, es ist jedoch eng an das Tapestry Modul gekoppelt, so dass beide durch einen einzelnen Block dargestellt werden. Das Tapestry Modul ist für das Rendern der Web page templates verantwortlich. Andere benötigte Module werden innerhalb des Spring Kontextes hinzugefügt, um zusätzliche Funktionalität bereitzustellen. Das pdf-Generator Modul in Abb.2 dient als Beispiel für diese Art Komponente. Der Fokus der momentanen Implementierung liegt darauf, die verschiedenen Projekte zu einer einzigen Webanwendung zusammenzubringen. Das Spring Framework bietet die dafür nötige Flexibilität und die entsprechenden Konfigurationsmöglichkeiten. Das kürzlich vorgeschlagene Komponentenmodell erfüllt die gleiche Aufgabe auf der Laufzeitebene. Komponenten werden erst auf Anfrage zusammengefasst, und nicht bereits bei der Initialisierung. Dies erlaubt es, die zugrundeliegenden Komponenten auszutauschen, ohne alle abhängigen Komponenten erneut übertragen zu müssen. Es macht zudem eine bessere Lastverteilung möglich, da die jeweiligen Komponenten auf unterschiedlichen Servern laufen können. PDF-Dateien zu generieren, beispielsweise, kann eine Menge CPU-Zeit und Arbeitsspeicher belegen. Durch die Verteilung der Komponenten auf verschiedene Rechner kann sowohl eine bessere Performance, als auch eine Wiederbenutzbarkeit der einzelnen Komponenten erreicht werden. Dadurch wäre es möglich, Laufzeitkomponenten mit verschiedenen Anwendungen zu nutzen – Dienstprogramme für die pdf-Generierung beispielsweise können von mehreren Anwendungen genutzt werden. Ein weiterer Vorteil liegt darin, das bei einem Bugfix nur eine einzige Instanz der Komponente ersetzt werden muss. Dadurch würde verhindert, alle Anwendungen neu packen zu müssen, die die Komponente nutzen.

Struktur von WAID vor Refactoring

Gleichzeitig ermöglicht das vorgeschlagene Modell eine wichtige Konzeptverschiebung hin zur dienstorientierten Architektur (Service Oriented Architecture, SOA). Kurz gesagt besteht die Idee darin, Kompositanwendungen zu bauen anstatt kleine Projekte zu großen Anwendungen zusammenzufassen. Diese Kompositanwendungen werden aus verschiedenen Laufzeitgebundenen Diensten bestehen. Die Dienste stellen eine dezentralisierte Business Logik zur Verfügung anstelle einer fertig gepackten Funktionalität. Sobald ein gewisser Grad der “Dienstorientierung” erreicht ist, würde es möglich werden, Unternehmensintegrations-Muster zu nutzen, um eine bessere Kommunikation zwischen den verschiedenen involvierten Systemen zu erreichen. Eine Machbarkeitsstudie ist bereits entwickelt worden und eine schematische Übersiccht der vorgeschlagenen Lösung ist in Abb.3 zu sehen.

WAID Struktur nach Refactoring

Auf den ersten Blick ist kein großer Unterschied zu sehen. Die gelben Komponenten sind jedoch Enterprise Java Beans (EJBs), die ausserhalb der Webanwendung laufen. Sie können von der Webanwendung aufgerufen und genutzt werden. EJBs haben zwei Arten von Schnittstellen, lokal oder remote. In der Darstellung ist die lokale Schnittstelle hellblau dargestellt, verbunden mit WAID. Technisch gesehen wird diese Art der Schnittstelle genutzt, wenn beide Module innerhalb der gleichen Anwendung laufen, um einen Datenaustausch mit besserer Performance zu erreichen. Obwohl idmone-core seine Funktionalität in Form der EJBs offenlegt, werden sie trotzdem durch einen Spring Kontext initialisiert, in Abb.3 dunkelgrün dargestellt. Mehrere Entwickler sind der Meinung, dass SPRING und JEE sich gegenseitig ausschließen und miteinander konkurrieren. In unserem Fall bilden sie jedoch anscheinend eine Symbiose.

Zur gleichen Zeit wird ein Vorschlag bewertet, die Anwendung als entpackte .war Datei einzusetzen, um “fliegende” Änderungen möglich zu machen. Ziel des Vorschlages ist ein vereinfachtes Verbessern von Schreibfehlern, Übersetzungsfehlern und Ähnlichem. Die Technik wurde als Machbarkeitsstudie bei der Umsetzung komplexer Änderungen erprobt, wie dem Registrieren und Entfernen existierender Tapestry Komponenten auf einer Seite. Bisher erscheint das Konzept brauchbar, es wirft jedoch Fragen in Bezug auf Stabilität und Zuverlässigkeit auf, und kann zu Inkonsistenzen führen, wenn es nicht gründlich genug durchdacht ist. Inkonsistenzen beziehen sich in diesem Zusammenhang auf verschiedene Code-Versionen im Produktivsystem und dem Repository. In Notfällen besteht die Möglichkeit, dass Updates im Produktivsystem eingefügt werden, dann aber nicht in den Code übernommen werden. Generell erscheint für die Handhabe des tagging eine einzelne Webanwendung besser geeignet, da eine Systemmwiederherstellung in diesem Fall durch das Kopieren einer einzelnen Datei einfacher ist als durch Hunderte kleiner Dateien. Die Operation verläuft ebenso deutlich effizienter im oben genannten Fall. Zum gegenwärtigen Zeitpunkt wird der Einsatz von WAID als entpacktes Archiv als nicht schädlich beurteilt. Solange jedoch die oben genannten Schwierigkeiten nicht ordentlich angegangen und getestet worden sind, sind Dateiänderungen im entpackten Verzeichnis nur in Ausnahmesituationen gestattet.