Inspiriert durch eine Anfrage in der Apache OFBiz User Mailingliste (Mailthread siehe Setting OFBiz with Enterprise Service Bus) stelle ich hier kurz vor, wie sich mit den OFBiz Bordmitteln eine Enterprise Service Bus (ESB) Systemintegration über den Java Message Service (JMS) erreichen lässt.

In komplexeren Szenarien, insbesondere wenn Apache OFBiz als E-Commerce-Plattform eingesetzt wird, ist häufig eine Integration in die bestehende Systemlandschaft notwendig. Stammdaten wie Artikeldaten, Debitoren und Konditionen sollen aus dem ERP System an OFBiz gesendet werden und Bestellungen werden an das ERP System übergeben.

Wenn diese Daten zwischen den Systemen transformiert und aufbereitet oder an verschiedene Systeme verteilt werden sollen, lohnt sich der Einsatz eines Enterprise Service Bus (ESB) als Middleware zur Datenverteilung und -aufbereitung.

Ein ESB wie Apache ServiceMix und der EAI Komponente Apache Camel beherrscht verschiedene Technologien zur Anbindung und Verteilung (Routing) der Daten und ist meist nachrichtenbasiert aufgebaut. Neben den dateibasierten Endpoints (File, FTP) oder REST (http, https) wird der Nachrichtentransport häufig über den Java Message Service (JMS) realisiert.

Apache OFBiz JMS Anbindung

OFBiz verwendet diese Technologie intern, um seinen Entity Cache über mehrere Serverinstanzen hinweg synchron zu halten. Dabei werden bei einer Cache Änderung die anderen Serverinstanzen per JMS über diese Änderung informiert und können so Ihren eigenen Cache entsprechend warten und synchron halten. Der Anspruch hier sind Performance und Stabilität.

Die grundsätzliche Anbindung von OFBiz an JMS in beide Richtungen besteht also bereits. Die grundlegenden Einstellungen für JMS/ActiveMQ in OFBiz werden in der jndi.properties vorgenommen:

java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=tcp://127.0.0.1:61616
# register some queues in JNDI using the form
# queue.[jndiName] = [physicalName]
queue.ofbizServiceInbound = ofbizServiceInbound
queue.ofbizServiceOutbound = ofbizServiceOutbound

Nun horcht OFBiz auf die konfigurierten Queues.

Um aus OFBiz heraus einen entfernten Service per JMS anzusprechen, wird zunächst eine entsprechende JMS Service Engine Konfiguration in der serviceengine.xml konfiguriert:

<jms-service name="outputChannel" send-mode="all">
   <server jndi-server-name="default" jndi-name="ConnectionFactory" 
           topic-queue="ofbizServiceOutbound" type="queue" 
           username="xxx" password="xxx" listen="false"/>;
</jms-service>

Der OFBiz Service zum Aufruf eines entfernten Service oder Senden einer Nachricht per JMS wird in der services.xml des entsprechenden Moduls konfiguriert:

<service name="dummyCallEaiService" engine="jms" 
         location="outputChannel" invoke="dummyService">
   <description>Send a JMS message to an EAI queue</description>
   <attribute name="parameter" type="String" mode="IN" optional="false" allow-html="any" />
</service>

Die wichtigsten Konfigurationselemente sind

engine="jms"

Teilt OFBiz mit, dass der Serviceaufruf über die JMS Service Engine anstatt der Standard Service Engine laufen soll. Es wird eine JMS Message an die konfigurierte Queue gesendet anstatt eine OFBiz Service aufzurufen.

location="outputChannel"

Spezifiziert die Queue, an welche die Nachricht gesendet werden soll (siehe Konfiguration oben).

invoke="dummyService"

Gibt den Namen des entfernten Service an, der aufgerufen werden soll oder dient als Kennzeichen für den Nachrichteninhalt, um im ESB entscheiden zu können, wie mit dieser Nachricht verfahren werden soll.

Um einen OFBiz Service vom ESB aus per JMS ansprechen zu können, ist folgende Konfiguration notwendig:

serviceengine.xml

<!-- Konfiguration des Eingangskanals zum Aufruf von via JMS -->
<jms-service name="inputChannel" send-mode="none">
   <server jndi-server-name="default" jndi-name="ConnectionFactory" 
           topic-queue="ofbizServiceInbound" type="queue" 
           username="xxx" password="xxx" listen="true"/>
</jms-service>

Um einen OFBiz Service vom ESB über JMS anzusprechen, muss nur eine Service Context Map in eine JMS Nachricht geschrieben und an die Queue gesendet werden. In OFBiz ist dann keine weitere Logik zur Interpretation der Nachricht mehr notwendig.

Die beschriebene Lösung lässt sich sehr schön mit Apache Camel und Apache ServiceMix realisieren. Eine einfache Route zum Senden einer Nachricht an OFBiz kann dann so aussehen:

Um die Verarbeitung innerhalb des ESB Message Routing etwas zu erleichtern kann man sich einen einfachen Processor schreiben, der die eigentlichen Nutzdaten einer Nachricht nimmt und diese in eine OFBiz Service Context Map einpackt. Dies dann ggf. in einem der nächsten Blog Posts…