Geschäftsprozesse, die mittels BPMN2 oder BPEL modelliert und ausgeführt werden, finden immer mehr Anklang. Die schnelle Entwicklung von prozessbasierten Anwendungen durch die Nutzung von Geschäftsprozessengines sowie die Möglichkeit, Prozesse besser zu verwalten und zu kontrollieren, sind wichtige Vorteile dieser Technologie.

Was viele Marketingprospekte jedoch verschweigen, ist die Tatsache, dass die Modellierung ausführbarer Geschäftsprozesse ebenfalls Programmierung ist. Somit treten dort ähnliche (Qualitäts-)Probleme auf wie in anderen Software-Projekten. Neben Unit-Tests sind also vollautomatisierte Builds und Deployments ein Thema. Aufbauend auf diesen ist es auch möglich, Nightly Builds und Continuous Integration aufzubauen, die nochmals die Qualitäts- durch stabile Softwarebuilds steigern können.

Die meisten Werkzeuge sind jedoch auf eine Programmiersprache wie Java, C# oder Ruby ausgerichtet. Daher ist es nötig, sich Gedanken zu machen, wie man mit möglichst wenig Aufwand die Geschäftsprozesse wie alle anderen Komponenten in dem Projekt handhaben und in die Build-Umgebung integrieren kann.

Beispielprojekt

In unserem aktuellen Projekt standen wir schnell vor der Herausforderung, ein komplexes Softwareprojekt zur Prozessintegration von mehreren Hundert Partnersystemen effizient zu entwickeln und mit hoher Qualität in die Produktion zu überführen. Der Prozessteil dieses Projekts besteht aktuell aus:

Daneben gibt es noch weitere Java-Webanwendungen und -Webservices, die aber klassische Java-Komponenten und somit aus Maven- und Jenkins-Sicht nicht interessant sind. Im Folgenden wollen wir demonstrieren, wie das komplette Build und Deployment in diesem Projekt mittels Apache Maven und Jenkins automatisiert werden konnte.

Build-Automatisierung mit Apache Maven

Im ersten Schritt musste das komplette Projekt automatisiert erstellt und paketiert werden. Da neben den ausführbaren Prozessen ausschließlich Java-Komponenten entwickelt wurden, fiel die Wahl für das Buildsystem auf Apache Maven [1].

Damit wollten wir standardisierte Builds und Deployments etablieren, die nicht abhängig vom Entwickler sind, sondern – egal von wo, von wem und zu welchem Zeitpunkt – einheitlich gemacht werden. Neben den Java-Projekten gibt es im Wesentlichen zwei Maven-Modultypen: Module für WSDLs und solche für die Prozesse.

Die WSDLs werden zum einen Teil zentral in einem separaten Subversion Repository verwaltet und von dort ausgecheckt. Diese WSDLs sind extern für Partnersysteme sichtbar und unterliegen daher einem separaten Review- und Freigabeprozess. Der andere Teil beschreibt interne Services, die ohne Freigabe für die ausschließlich interne Benutzung entwickelt werden. Diese WSDLs liegen im Projekt-Subversion direkt als Maven-Module vor.

Aufbau der zu erstellenden Pakete

Es gibt ja einige Möglichkeiten, wie man Java-Projekte strukturieren, konfigurieren, bauen und zuletzt auch verteilen (deploy) kann. Wir haben uns für Maven entschieden. Im Team war genügend Know-how vorhanden, und man kann mit Maven mit der gleichen Projektkonfiguration arbeiten wie auf dem Build- Server. Uns ist bewusst, dass Maven-Builds nicht den schnellsten Durchlauf haben. Aber dies nehmen wir gerne in Kauf, wenn die Projekte auf allen Umgebungen inkl. der IDE gleich konfigurierbar sind sowie alle Projektbeteiligten das Build-Werkzeug kennen.

WSDL-Pakete

Für die für den Informationsaustausch bestimmten Schemas und WSDLs haben wir zur allgemeinen Verwendung für die BPEL- und Java-Projekte eine eigene Projektstruktur aufgebaut. Dies erlaubt uns:

Alle unsere Projektpaketgruppen fassen wir in einem Basis-Projekt zusammen, damit wir allgemeine, für alle Pakete gültige Erstellungskonfigurationen definieren können. Dies erlaubt uns in den eigentlichen Subpaketen mit einer minimalen Konfiguration auszukommen, um die JAXB-Klassen und auch das eigentliche Paket zu erstellen. Die daraus entstehende Struktur ist in Abb. 1 gezeigt. Die in Tabelle 1 dargestellten Pakete werden zu JARs zusammengebaut und im zentralen Maven-Repository zur Verfügung gestellt, damit BPEL- und Java-Projekte diese in ihren Abhängigkeiten aufnehmen und aus dem Artefakt entnehmen können, was sie brauchen – Klassen, Schemas oder WSDLs.

Tabelle 1: Beispiele für Projektmodule
Paket Beschreibung
schemas Das Basispaket: Enthält die für alle Subpakete gültigen Konfigurationen
schemas.service Beispiel einer Schnittstellenbeschreibung eines Webservices, enthält die Schemas und die WSDLs
schemas.bpel Beispiel einer Schnittstellenbeschreibung eines BPEL-Prozesses
schemas.ui Beispiel einer Schnittstellenbeschreibung eines BPEL-Prozesses, welcher nur im User-Interface verwendet wird
Abbildung 1: Modulstruktur

Im übergeordneten Projekt Schemas werden alle Plug-ins konfiguriert (JAX-WS für die Generierung von Java-Code für die Webservice-Schnittstellen, XML- Validierung für alle enthaltenen XML-Dateien) sowie die Einstellungen für die WSDL- und XSD-Paketierung definiert, so dass diese aus den Ressourcen mitpaketiert werden. Das pom.xml kann in dem Repository zu diesem Artikel heruntergeladen werden [2].

Durch die globalen Definitionen in dem Parentprojekt ist das POM des Pakets schemas.service sehr kurz. Dies ist insbesondere wichtig, da es viele solcher Projekte gibt und somit unnötige Arbeit vermieden wird (Listing 1).

<project [...]> <modelVersion>4.0.0</modelVersion> <parent> <groupId>mygroupid</groupId> <artifactId>schemas</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>schemas.services</artifactId> <version>0.0.11-SNAPSHOT</version> <packaging>jar</packaging> <name>schema.services</name> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxws-maven-plugin</artifactId> <executions> <execution> <phase>process-resources</phase> <goals> <goal>wsimport</goal> </goals> <configuration> <verbose>true</verbose> <extension>true</extension> <wsdlDirectory>src/main/wsdl/Internal</wsdlDirectory> <wsdlFiles> <wsdlFile>Services.wsdl</wsdlFile> </wsdlFiles> <wsdlLocation>/*</wsdlLocation> <sourceDestDir> ${basedir}/target/generated-sources/jaxws </sourceDestDir> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> </plugin> </plugins> </build> </project>

BPEL-Pakete

BPEL-Projekte in eine Struktur zu bringen, die mit den gleichen oder möglichst ähnlichen Verfahren zu bauen und zu verteilen sind wie all die anderen, „normalen“ Java-Pakete, gestaltete sich dagegen aufwändiger.

Es gibt in Maven leider kein „packaging bpel“. Somit mussten wir eine Lösung finden, das Projekt in Maven so zu beschreiben, dass es mit dem ActiveVOS- Designer (Eclipse) umgehen konnte und die BPEL-Projekte auch auf dem Build- Server gebaut und automatisch in die ActiveVOS-Engine verteilt werden konnten. Die von uns gewählte Struktur ist in Abb. 2 gezeigt.

Abbildung 2: Maven-Struktur für BPEL-Projekte

Auch hier verwenden wir ein kleines Maven-Projekt, um mehrere Prozess- Projekte in einem Projekt zusammenfassen zu können. Neben den Modulen enthält es die Maven-Profile, die wir weiter unten beschreiben werden. Wir erlauben uns hier, nicht auf alle Maven-Details einzugehen, sondern konzentrieren uns auf die Elemente, die wir für den Maven-basierenden Bau von Prozessen verwenden.

ActiveVOS bietet die Möglichkeit, die Prozesse mit Ant zu bauen und auch zu verteilen. Damit wir das build.xml nicht in jedes einzelne Prozess-Paket von Hand kopieren mussten, bauten wir ein kleines Maven-Resource-Paket, das zu einem JAR gebaut wird (Listing 2).

<project [...]>     <modelVersion>4.0.0</modelVersion>     <parent>         <groupId>mygroupid</groupId>         <artifactId>process</artifactId>         <version>1.2.09-SNAPSHOT</version>     </parent>     <artifactId>process.builder</artifactId>     <packaging>jar</packaging>     <name>process.builder</name>     <description> Module contains additional scripts to build and deploy a process </description>     <build>         <resources>             <resource>                 <directory>src/scripts</directory>                 <includes>                     <include>**/build.xml</include>                 </includes>             </resource>                   </resources>     </build> </project>

Damit der ActiveVOS Ant Build auch wirklich in Maven funktioniert, muss im Maven-Dependency-Management das maven-ant-plugin [3] richtig konfiguriert werden (Listing 3).

<properties> <maven-antrun-plugin.version>1.6</maven-antrun-plugin.version> <activevos.version>9.0.0</activevos.version> <ant.version>1.8.2</ant.version> <ant-nodeps.version>1.8.1</ant-nodeps.version> <commons-net.version>3.0.1</commons-net.version> <commons-discovery.version>0.5</commons-discovery.version> <commons-logging.version>1.1.1</commons-logging.version> <axis.version>1.4</axis.version> <wsdl4j.version>1.6.2</wsdl4j.version> <axis-wsdl4j.version>1.5.1</axis-wsdl4j.version> <spring.javax-activation.version>1.1.1</spring.javax-activation.version> </properties>

Darüber hinaus sind neben dem Maven-Ant-Plugin noch die Abhängigkeiten auf die ActiveVOS-Bibliotheken zu definieren. Wir wrappen das vom ActiveVOS Designer erstellte Ant-Script mit einem eigenen, welches die gesamte Konfiguration vornimmt. Dieses ist ebenfalls im Repository zu diesem Artikel erhältlich.

Paket process.proc1

Dadurch, dass die Schemas und WSDLs als JARs im zentralen Maven-Repository verfügbar sind und für das Erstellen das Ressourcen-Projekt process.builder auch als JAR im Maven-Repository vorhanden ist, können wir mit dem eigentlichen Prozess-Projekt beginnen.

Prozesse funktionieren ohne die Umsysteme nicht wirklich, daher muss in einem BPEL-Projekt erst sichergestellt werden, dass alle notwendigen Schemas und WSDLs verfügbar sind. In unserem Fall sind diese Dateien in unseren WSDL-Paketen in unserem zentralen Maven-Repository verfügbar und müssen nur noch kopiert, entpackt und die enthaltenen Schemas und WSDLs an einen vorgegeben Platz in der Projektstruktur kopiert werden.

Dies kann mit dem Maven-Plugin maven-dependency-plugin ziemlich einfach realisiert werden. Man muss sich nur Gedanken machen, wohin die Ressourcen kopiert werden sollen. Für temporäre Dateien ist in einem Maven-Projekt das Verzeichnis target der richtige Ort. Der ganze Inhalt im target- Verzeichnis kann mit dem Maven-Goal clean gelöscht und danach z.B. mit compile und anderen Maven-Goals wieder initialisiert werden.

Daher kopieren wir nun die im JAR vorhandenen Dateien aus dem Verzeichnis wsdl in das lokale Projektverzeichnis target/wsdl. Dieses Verzeichnis kann nun im BPEL-Prozess relativ referenziert werden. Außerdem dürfen wir den bereits oben genannten process.builder mit dem entsprechenden build.xml für den eigentlichen Prozessbau und dem Prozess- Installationsschritt vergessen.

Damit für die Maven-Dependency klar ersichtlich ist, dass das Projekt process.proc1 vom schemas.service abhängig ist, sollte man noch die entsprechende Dependency im POM angeben. Da die Abhängigkeit nicht in dem Prozess mitpaketiert werden muss, geben wir für den scope provided an (Listing 4).

<dependencies> <dependency> <groupId>mygroupid</groupId> <artifactId>schemas.service</artifactId> <version>0.0.1-SNAPSHOT</version> <scope>provided</scope> </dependency> <dependency> <groupId>mygroupid</groupId> <artifactId>process.builder</artifactId> <version>0.0.1-SNAPSHOT</version> <scope>provided</scope> </dependency> </dependencies>
Weitere Informationen zu Modellierungsumgebungen

Hinweis für die Modellierungsumgebungen

Beim Initialisieren der Entwicklungsumgebung, von neuen Teilprojekten oder einem Clean-Checkout muss eines beachtet werden: Nach dem ersten Checkout und vor dem Öffnen des ActiveVOS-Designers (oder anderen Prozessmodellierungsumgebungen) muss zuerst dafür gesorgt werden, dass alle notwendigen WSDLs und Schemas im target-Verzeichnis vorhanden sind.

Dazu kann mit dem Maven-Goal compile dafür gesorgt werden, dass die Maven-Phase generate-sources ausgeführt wird. Maven führt dann im obigen Beispiel das Goal unpack des maven-dependency-plugin aus und kopiert die Dateien.

Wie die Dateien genau kopiert werden, ist in Abb. 3 gezeigt. In den Projekten, in denen Schemas (und die genauso aufgebauten Datentransformationsprojekte) gespeichert werden, liegen die Dateien ausschließlich im src-Bereich. Auch Abhängigkeiten wie z.B. gemeinsam genutzte XML-Schemas werden in den src-Baum kopiert. Dies erlaubt es, in den Editoren korrekte, relative Referenzen zu setzen, verlangt aber, dass man diszipliniert die kopierten Dateien in der Versionsverwaltung seiner Wahl ignoriert. Beim Build werden alle benötigten Dateien in target/generated-sources kopiert und von dort paketiert, so dass das Maven-Artefakt auch alle Abhängigkeiten bereits besitzt. Somit müssen andere Projekte nur eine Abhängigkeit auf ein Projekt setzen und nicht selbst alle transitiven Abhängigkeiten verwalten. Unserer Erfahrung nach ist es immens wichtig, dass die relativen Verweise funktionieren, weil sonst viele Tools nicht einsetzbar sind oder erst aufwändig mit XML-Schema-Katalogen konfiguriert werden müssen, sofern das Werkzeug solche überhaupt unterstützt.

In den BPEL-Projekten werden alle benötigten Dateien in das target- Verzeichnis kopiert und aus dem BPEL-Prozess relativ referenziert. Beim Paketieren werden alle benötigten Dateien aus dem src- und dem target-Zweig in die Deploymentfile kopiert.

Abbildung 3: Ressourcen-Verwaltung innerhalb der Prozessprojekte

Hat man den Prozess im ActiveVOS-Designer erstellt, kann dieser nun auch über Maven gebaut und auch auf der ActiveVOS-Instanz installiert (verteilt) werden. Dazu verwenden wir das maven-ant-plugin, das im Maven-Plugin- Management bereits soweit vorkonfiguriert wurde, dass nur noch der eigentliche Aufruf des build.xmls konfiguriert werden muss (Listing 5).

<plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <id>run-package</id> <phase>package</phase> <goals> <goal>run</goal> </goals> <configuration> <target> <ant antfile="target/bin/build.xml" target="package" inheritAll="true" inheritRefs="true"> <property name="processname" value="proc1" /> </ant> </target> </configuration> </execution> </executions> </plugin>

Da es in Maven keinen Paket-Typ für die ActiveVOS BPRs gibt, haben wir uns mit einem kleinen Plugin build-helper-maven-plugin [4] beholfen, um im Maven-Projekt nicht nur das Pseudo-JAR zu bauen und zu paktieren und ins Maven Repository zu stellen, sondern auch das eigentliche BPR (Listing 6).

<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <executions> <execution> <id>attach-artifacts</id> <phase>package</phase> <goals> <goal>attach-artifact</goal> </goals> <configuration> <artifacts> <artifact> <file>${project.build.directory}/proc1.bpr</file> <type>bpr</type> </artifact> </artifacts> </configuration> </execution> </executions> </plugin>

Prozess-Deployment

Nun fehlt nur noch das Deployment. Das heißt, wir bauen den Prozess automatisch zusammen und wollen ihn auch gleich in einer lokalen oder auf einer entfernten ActiveVOS-Instanz verteilen (deploy). Dazu verwenden wir auch wieder unser oben erwähntes Ant-Script. Damit wir aber ein lokales und ein entferntes Deployment unterscheiden können, fügen wir in unserem POM zwei weitere Profile ein, wie in Listing 7 gezeigt. Nun kann mit der Angabe des Maven-Profils und dem Maven-Goal install der gebaute Prozess auf die richtige ActiveVOS Instanz installiert werden: mvn clean install -Pdev.

<profile> <id>dev</id> <properties> <activevos.deploy> http://remotehost:8080/active-bpel/services/ActiveBpelDeployBPR </activevos.deploy> <activevos.username>myuser</activevos.username> <activevos.password>mypassword</activevos.password> </properties> <build> <pluginManagement> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <id>run-deploy</id> <phase>install</phase> <goals> <goal>run</goal> </goals> <configuration> <target> <ant antfile="${project.build.directory}/bin/build.xml" target="deploy" inheritAll="true" inheritRefs="true"> <property name="processname" value="${process.name}" /> <property name="archive.deploypath" value="${activevos.deploy}" /> <property name="archive.username" value="${activevos.username}" /> <property name="archive.password" value="${activevos.password}" /> </ant> </target> </configuration> </execution> </executions> </plugin> </plugins> </pluginManagement> </build> </profile>

Zentraler Build mit Jenkins und Staging

Durch die Wahl von Maven kann nun dieselbe Projektkonfiguration für den Nightly Build, der zentral auf einem Development-Server ausgeführt wird, implementiert werden. Es können hier die gleichen Maven-Goals verwendet werden wie auf dem lokalen PC des Entwicklers. Je nachdem, wie die eigene Entwicklungsumgebung aussieht, können die unterschiedlichen Environments im Maven-Projekt durch Profile unterschieden werden. Wie im vorherigen Abschnitt beschrieben, verwenden wir zwei Profile:

Während der Nightly Build mindestens tagesaktuelle Deployments auf der Integrationsumgebung zur Verfügung stellt, wird von den Administratoren auf Anforderung auf das Test- und das Produktionssystem deployt.

Der Release-Build wird ebenfalls über Jenkins gesteuert und führt neben den üblichen Artifact-Releases noch ein Staging für den Betrieb ein. Die Schnittstelle zum Betrieb sind dabei spezielle Verzeichnisse, in denen fertig paketierte Deployment-Einheiten zur Verfügung gestellt werden. Dies umfasst die WAR-Archive sowie die BPRs für die Geschäftsprozesse. Zusätzlich werden aber auch für alle Server die Einstellungen als Textdateien exportiert. Diese können vom Betrieb mittels Scripts auf die Test- und Produktionsinstanzen angewendet werden. Somit ist sichergestellt, dass alle Einstellungen korrekt übernommen werden. Damit die BPRs richtig paketiert werden können, muss das Maven-POM noch etwas erweitert werden, damit:

Das Kopieren in die Staging-Verzeichnisse wurde durch Kopieraktionen gelöst, die mittels eines eingebetteten Apache Ant Copy Tasks arbeiten. Selbstverständlich releasen wir vor dem Staging alle Projekte unter Verwendung des maven-scm-plugin. Um den Rahmen des Artikels nicht zu sprengen, verzichten wir hier auf die genauen Details.

Um die Deployment-Pakete für alle Staging-Umgebungen verwenden zu können, haben wir die URN-Mappings auf dem ActiveVOS-Server genutzt, die es erlauben, die Prozesse mit logischen Endpunkten zu paketieren, die dann durch eine Serverkonfiguration auf physische Endpunkte abgebildet wird. Dieser „Mini-ESB“ erlaubt es auf einfache Art und Weise, dass das gleiche Paket für Unit-Tests mit gemockten Services bis hin zum produktiven Einsatz genutzt werden kann, die Konfiguration serverseitig geschieht.

Lessons Learned

Auch wenn wir anfangs Probleme hatten, wie wir die Paketierung am besten lösen, so haben wir nun eine pragmatische Lösung gefunden. Dabei haben wir die Integration der WSDL-Dateien, die verschiedene Schemas aus unterschiedlichen Standards und die Maven-Integration der Geschäftsprozesse gelöst, so dass mittels einen einzigen Maven-Builds alle Softwarekomponenten kompiliert und paketiert werden. Die durch automatisierte Builds und Nightly Builds gewonne Sicherheit ist sowohl qualitativ als auch subjektiv für die Entwickler wichtig.

Was in Java-Projekten mittlerweile eine Selbstverständlichkeit ist, lässt sich mit ein wenig Arbeit auch für andere Artefakte erreichen. Die Erleichterung, auch in Stresssituationen auf Knopfdruck das Projekt bauen und deployen zu können, vermeidet Fehler; gerade im Vergleich zu anderen Projekten, wo die Geschäftsprozesse direkt aus der Entwicklungsumgebung auf Produktionsserver deployt werden, was über kurz oder lang zu einem Versionschaos und schwer nachzuvollziehenden Fehlern führt.

Daneben sind die integrierten Tests, auf die wir im Rahmen des Artikels nicht weiter eingehen konnten, ein Teil der Qualitätssicherungsstrategie. Hier sei auf [5] verwiesen, wo BPELUnit beschrieben wird, das ebenfalls über Maven-Unterstützung von Haus aus verfügt.

Referenzen

  1. Apache Maven, http://maven.apache.org/, Stand: 25.11.2012.  ↩

  2. Repository zum Artikel: https://github.com/dluebke/article-prozesse-vom-fliessband, Stand: 25.11.2012.  ↩

  3. Maven AntRun Plug–in: >http://maven.apache.org/plugins/maven–antrun–plugin/>, Stand: 25.11.2012.  ↩

  4. Build Helper Maven Plug–in: https://www.mojohaus.org/build-helper-maven-plugin/, Stand: 25.11.2012.  ↩

  5. „Testobjekt: Geschäftsprozess. Geschäftsagilität durch Tests sichern“. Daniel Lübke, Tammo van Lessen, Java Magazin 05/2012.  ↩