Keep informed?
Subscribe for our newsletter now!

Ein kleiner jBPM 4 Showcase

Wie versprochen möchte ich pünktlich zum Release der Version 4 der Open Source Process Engine JBoss jBPM am Freitag, den 10.07.2009, gleich einen kleinen Showcase berschreiben. Diesen Showcase habe ich auch bei meinem Vortrag auf dem Java Forum Stuttgart gezeigt und er wird auch nochmals genauer in einem bald erscheinenden JavaMagazin-Artikel erläutert. Gebaut habe ich ihn mal zwischendruch mit dem so genannten Candidate Relase.

Konkret geht es um einen kleinen Shop, der Designertaschen herstellt. Der Prozess dahinter soll nun mit jBPM automtatisiert werden.

An dieser Stelle möchte ich mich kurz fassen und lediglich  Showcase und Quellcode dazu vorstellen. Eine detailliertere Beschreibung folgt wie gesagt im JavaMagazin.

Also steigen wir sofort ein, folgender Prozess wurde ausgetüftelt:

Es ist zu sehen, dass jBPM 4 nun auch mit den BPMN-Shapes arbeitet. Auch kann man bereits einige Activity-Typen (=Knotentypen) erkennen, wie zum Beispiel menschliche Interaktion, Wartezustände oder auch “Serviceaufrufe” als Referenz auf Java-Methoden.

Dahinter liegt natürlich ein Prozess als XML-Datei:

<process name="Bestellung" xmlns="http://jbpm.org/4.0/jpdl">
   <start g="118,152,48,48" name="start1">
      <transition to="Bestellung_pruefen"/>
   </start>
   <task candidate-groups="Lager" g="191,149,109,52" name="Bestellung_pruefen">
      <transition g="267,103:-3,27" name="Problem aufgetreten" to="Alternativvorschlag_erarbeiten" />
      <transition g="268,236:0,-25" name="Auftrag OK" to="Bestellung_buchen"/>
   </task>
   <task candidate-groups="Designer" g="289,77,174,52" name="Alternativvorschlag_erarbeiten">
      <transition to="Kunden_informieren"/>
   </task>
   <java class="com.camunda.training.jbpm.service.MockService" g="482,79,119,52" method="informCustomer" name="Kunden_informieren">
		<arg><object expr="#{order.customer}"/></arg>
		<arg><object expr="#{problem}"/></arg>
		<arg><object expr="#{message}"/></arg>
		<arg><object expr="#{order.orderedItem}"/></arg>
		<arg><object expr="#{execution.id}"/></arg>
      <transition to="Auf_Entscheidung_warten"/>
   </java>
   <state g="625,80,150,52" name="Auf_Entscheidung_warten">
      <transition to="Stornierung?"/>
   </state>
   <decision g="804,84,48,48" name="Stornierung?">
      <transition g="828,43;245,43:247,-19" name="Alternativvorschlag bestellen" to="Bestellung_pruefen">
          <condition expr="#{orderChanged}"/>
      </transition>
      <transition g="-26,-18" name="Stornierung" to="cancel"/>
   </decision>
   <java class="com.camunda.training.jbpm.service.MockService" g="329,210,122,52" method="bookOrder" name="Bestellung_buchen">
   		<arg><object expr="#{order}"/></arg>
      <transition to="Ware_produzieren"/>
   </java>
   <task candidate-groups="Arbeiter" g="486,212,113,52" name="Ware_produzieren">
      <transition to="Warten_auf_Versand"/>
   </task>
   <state g="640,213,121,52" name="Warten_auf_Versand">
      <transition to="end"/>
   </state>
   <end g="886,216,48,48" name="end"/>
   <end-cancel g="884,85,48,48" name="cancel"/>
</process>

Die Beispielanwendung

Um eine Betsellung aufzugeben, also eine Prozessinstanz zu starten, wurde ein kleiner PHP-Shop implementiert. Dabei habe ich Quercus verwendet, so dass ich PGP-Seiten direkt auf dem JBoss deployen kann und in PHP auch Java-Code einbetten kann. Warum? Einfach weil es sich cool anhörteund ich es auch mal kurz ausprobieren wollte ;-). Obenist die resultierende Bestellseite abgebildet, die mir unser Studi Christian dankenswerter Weise fix mal aufgehübscht hat.

Klickt man auf den Bestellbutton wird dabei folgender Code ausfgeführt, zugegeben eine etwas unschöne Mischung aus Java und PHP, aber für einen schnellen Prototypen denke ich ganz nett. Quercus beherrscht es nämlich, Java-Code direkt einzubetten, eigentlich wird sogar der gesammte PHP-Code in Java-Bytecode übersetzt.

import org.jbpm.api.Configuration;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.ProcessEngine;
import java.util.HashMap;
import com.camunda.training.jbpm.domain.Customer;
import com.camunda.training.jbpm.domain.Order;

$conf = new Configuration();

$processEngine = $conf->buildProcessEngine();
$executionService = $processEngine->getExecutionService();

$order = new Order();
$order->setOrderedItem( $_GET['orderedItem'] );
$order->setPrice(99.95);
$order->setCustomer(new Customer());
$order->getCustomer()->setName( $_GET['customer_name'] );
$order->getCustomer()->setEmail( $_GET['customer_email'] );
$order->getCustomer()->setAddress( $_GET['customer_address'] );

$variables = new HashMap();
$variables->put("order", $order);

// start process instance
$pi = $executionService->startProcessInstanceByKey("Bestellung", $variables);

Mehr ist nicht notwendig. Man kann auch sehen, dass in diesem Fall die Bestellung als Java-Objekt als Prozessvariablen übergeben wird. Die entstandene Prozessinstanz kann man sich über die in jBPM 4 mitgelieferte Webcoonsole (Google WebToolkit) auch gleich anschauen, sogat grafisch mit Markierung, wo im Prozessablauf sich die Instanz aktuell befindet:

Die aktive Aufgabe “Bestellung_pruefen” ist in diesem Fall ein Human Task, also wird eine Aufgabe in der so genannten Task Liste erstellt. Im Showcase wird sie zuerst der Gruppe “Lager” zugerodnet (siehe candidate-group Attribut im XML) und erscheint auf der Gruppen Task Liste. Von dort muss sich dier User die Aufgabe zuerst “ziehen” (claim). To claim heißt in diesem Fall, dass ich mir die Aufgabe hole. Damit verschwindet sie von der Gruppenliste und wandert in meine persönliche Task Liste.

Dort kann dann auch ein Formular geöffnet werden um die Aufgabe zu bearbeiten. Aktuell ist das Formular in der Webconsole ein Freemarker-Template, wobei der Dateiname dem Activtiy-Namen entsprechen muss. Dies ist übrigens der Grund, warum im Showcase die Aktivitätsnamen mit Unterstrichen und ohne Umlaute arbeiten ;-) Dies soll allerdings in Zukunft verbessert werden, so dass für eine Aktivität konfiguriert werden kann, welches Formular verwendet wird. Dies ermöglicht es dann auch, das gleiche Formular für verschiedene Aufgaben zu verwenden. Der folgende Screenshot verdeutlicht dies:

Nehmen wir den einfachen Fall an, benötigte Rohwaren sind im Lager und die Tasche kann folglich produziert werden, dann würde der Lager-Sachbearbeiter hier auf “Auftrag OK” klicken. Damit wird der Prozess den “unteren” Weg weiter laufen und in “Ware_produzieren” ankommen. Dort würde nun der Designer die Aufgabe in seine Workliste bekommen. Dies habe ich mir als Screenshot an dieser Stelle gespart.

Ist die Ware produziert, muss sie versendet werden. Mit vielen Kunden hatten wir schon die Diskussion, ob dies ein Task oder ein einfacher Wartezustand ist. Ich denke, es kommt darauf an, wie man arbeitet. Soll tatsächlich ein Mitarbeiter auf Grund der fertig gestellten Tasche aktiv loslaufen, diese abholen und verschicken, dann wäre es eine astreine Aufgabe. denn wir müssen dies dem Mitarbeiter ja über seine Aufgabenliste mitteilen.

Wird aber hingegen die Tasche auf eine Palette gelegt und der Versand verschickt diese gesammelt am Nachmittag, dann finde ich ist es aus Sicht des Prozesses ein Wartezustand. Denn wir warten auf das externe Ereignis, dass der erfolgreiche Versand gemeldet wird. Um den Versand zurück zu melden haben wir also nicht die Task Liste als Oberfläche sondern einen eigenen Mechanismus. Im Idealfall würde die Software des Logistikers (DHL o.ä.) diese Rückmeldung automatisch ausgeben und wir könnten es elektronisch importieren. Im Showcase habe ich aber einfach eine simple Oberfläche gebastelt, die alle Prozesse im Zustand “Warten_auf_Versand” ausgibt, so dass versendete Pakete einfach quittiert werden können:

Die ausgewählten Prozessinstanzen werden dann weiter getriggert und in unserem Fall wird der Bestellprozess beendet.

Historische Prozessinstanzen

Vor allem für die Umsteiger von jBPM 3 sei an dieser Stelle erwähnt, dass die neue Version anders tickt. Wird eine Prozessinstanz beendet so wird sie aus der Tabelle der aktiven Instanzen gelöscht und komplett in History-Tabellen verschoben. Dies löst das alte Problem, dass die jBPM-tabellen rasant voll werden, wenn viele Prozesse gestartet werden. Das würde bei unserem Taschen-Designer sicher kein Problem (sonst wäre er glaube ich sehr reich ;-)), kann aber in großen Umgebungen durchaus spannend werden.

Fazit & Download

Der Blog-Post hat jetzt nicht die Hintergründe und Neuerungen in jBPM 4 erläutert. Dafür bitte ich, sich bis zum Erscheinen des JavaMagazin-Artikels zu gedulden. Ziel war es, einen einfachen Showcase kurz darzustellen. Ich hoffe, dass ich dies erreichen konnte.

jBPM 4 selbst ist eine sehr interessante Weiterentwicklung der bekannten Open Source Process Engine, die sich in einigen Punkten bedeutend weiter entwickelt hat (Stichworte: Process Virtual Machine (PVM), API, BPMN). Allerdings muss man auch anmerken, dass aktuell noch nicht alle Features der 3er Version unterstützt werden. Auch muss sich die Stabilität in größeren Umgebungen noch bewären, da die Engine eben ganz frisch ist und nunmal eine Neuentwicklung darstellt (Code aus jBPM 3 wurde kaum wieder verwendet da die interne Architektur stark umgebaut wurde). Man sollte der neuen Version also noch ein paar Monate Zeit geben alle Features nachzuziehen und Kinderkrankheiten zu beseitigen.

Nichtsdestotrotz ist die Dokumentation jetzt schon sehr gut und auch die Test-Suite sehr umfangreich. Erstmals sind beispielsweise auch gute Tests zu Concurrency-Problemen und ähnliches enthalten. Die neue Version ist also auf jeden Fall cool und wird ganz sicher noch spannend! An Feedback und Meinungen sind wir natürlich dabei auch immer interessiert.

Der Showcase zum Runterladen findet sich hier:jbpm4-showcase. Es muss lediglich die build.xml mit dem richtigen JBoss-Pfad angepasst werden. Auch muss natürlich quercus installiert werden, damit die PHP-Seiten funktionieren. Okay, das ist vielleicht ein bisschen uncool an der Lösung, sorry! Trotzdem viel Spaß beim ausprobieren.

Und sollte ich irgendwann keine Lust mehr haben auf die Informatik hab ich somit auch gleich schon mal ein Ausweichgeschäft :-)

Bernd Rücker

About Bernd Rücker, CEO

Bernd Rücker is co-founder and CEO of camunda. But he is also software developer, trainer and consultant who was activley contributing to the Open Source Workflow engines jBPM 3 and Activiti before starting camunda BPM. He has profound experience in BPM projects and Java Enterprise. He worked with Process Engines and BPM for over 10 years in countless real-life projects. He is author of several books, numerous articles and regular speaker on conferences.

Already read?

Why BPMN is not enough

Decision Model and Notation (DMN) – the new Business Rules Standard. An introduction by example.

Free: Camunda BPM Online Training

CMMN – The BPMN for Case Management?

New Whitepaper: The Zero-Code BPM Myth

6 Responses

Leave a reply