JSR 208 – Java Business Integration: Java meets SOA

Highway to SOA

Daniel Adelhardt und Armin Wallrab

Dieser Artikel durchleuchtet einerseits die Konzepte und Architektur von Java Business Integration (JBI), stellt aber auch dar, welche Motivation hinter JBI steht und welche Problemstellungen sich damit lösen lassen.

Wenn es um die hohe Kunst geht, Applikationen und Prozesse unternehmensweit zu integrieren, ist in letzter Zeit immer häufiger der Begriff SOA in aller Munde. Viele Unternehmen stehen derzeit vor der Frage, auf welche Art und Weise sie in Zukunft ihre heterogene Applikationslandschaft integrieren und betreiben wollen. In der Vergangenheit wurden häufig Ansätze der klassischen Enterprise Application Integration (EAI) verfolgt. Viele dieser Integrationsvorhaben hatten jedoch – wenn überhaupt – nur fragwürdigen Erfolg. Häufig scheiterten EAI-Projekte an exorbitant hohen Kosten, schlechter Skalierbarkeit, hoher Komplexität und unflexibler Technik. Nicht zuletzt musste man sich in den meisten Fällen an einen Hersteller mit durchweg proprietärer Technik binden, da für Produkte in diesem Umfeld kaum Industriestandards existieren. Mittlerweile haben sich neue, innovativere Konzepte wie z.B. der Enterprise Service Bus (ESB) entwickelt. Diese eignen sich wesentlich besser als technische Grundlage für SOAs, trotzdem bleibt auch hier an einigen wichtigen Stellen das Problem fehlender Standards und mangelnder Erweiterbarkeit haften.
Im Bereich Java steht für die Entwicklung von Diensten und Anwendungen mit der Java Enterprise Edition (Java EE) seit einigen Jahren ein standardisiertes, weit verbreitetes und allgemein akzeptiertes Konzept zur Verfügung. Wenn man jedoch lose gekoppelte Systeme nicht nur technisch, sondern semantisch zu höherwertigen Geschäftsprozessen komponieren will, so muss dies in der Regel ausimplementiert werden. Es fehlen in Java einfach die geeigneten Mechanismen. JBI tritt an, diese Mängel zu beseitigen. Basierend auf Best Practices wird im JSR 208 ein Framework definiert, mit dem man den systematischen Aufbau einer SOA mit Java-Unterstützung bewältigen kann.

Architekturdiagramm eines JBI-Containers
Java Business Integration-Architektur

Die JBI-Spezifikation definiert als Grundgerüst ein Komponenten-Framework, das auf dem Konzept eines Containers aufbaut, der über definierte Plug-in-Schnittstellen erweitert werden kann. Diese Plug-in-Komponenten sind in der Regel selbst wieder Container und können Dienste und Business-Logik bereitstellen sowie Protokolle und Bindings integrieren. Die Spezifikation umfasst nicht nur, wie diese Komponenten miteinander kollaborieren, sondern auch deren Packaging, das Deployment von Artefakten in eine Komponente und das Management sämtlicher Bestand- teile einer JBI-Umgebung. Wesentliche Bausteine einer JBI-Umgebung sind die folgenden:

  • Der JBI-Container hostet die Plug-in-Komponenten und den Normalized Message Router. Analog zu einem EJB-Container stellt er über APIs einige wichtige Einrichtungen bereit, die von den Komponenten verwendet werden könen (z.B. ClassLoader, Logger, MBeanServer etc.). Zentrale Aufgabe des JBI-Containers ist jedoch sicherlich die Bereitstellung des Management-Interface über JMX. Auf Management-Eingriffe (z.B. Stoppen einer Komponente) muss der JBI-Container geeignet reagieren und die Anforderung an die entsprechenden Callback Interfaces der referenzierten Komponente weiterleiten.
  • Der Normalized Message Router (NMR) übernimmt die Rolle eines Mediators zwischen Plug-in-Komponenten. Plug-in-Komponenten kommunizieren in JBI nie direkt miteinander, sondern immer über den NMR und sind somit technisch entkoppelt. Die wichtigsten Aufgaben des NMR sind das implizite und explizite Routing von Nachrichten zwischen einzelnen Komponenten.
  • Service Engines (SE) sind Plug-in-Komponenten, die Dienste oder Business-Logik bereitstellen. Beispiele für SEs sind Process Engines (BPEL4WS), Rules Engines, XSLT-Prozessoren, Content-based Router oder auch EJB-Container. Service Engines beschreiben und registrieren ihre Schnittstellen mithilfe des in WSDL 2.0 definierten Abstract Service Model beim NMR.
  • Binding Components (BC) sind ebenfalls Plug-in-Komponenten und bilden die Schnittstellen einer JBI-Umgebung zur Außenwelt. Hauptaufgabe von BCs ist die Umwandlung von Protokollen und Bindings in das normalisierte Nachrichtenformat, das in JBI zur Kommunikation verwendet wird. Beispiele für Protokolle, die eine BC abbilden können, sind: SOAP/HTTP, XML/JMS, JCA oder EDI. Jedoch können auch beliebige Legacy-Protokolle über Entwicklung und Integration einer geeigneten Binding-Komponente integriert werden.
  • Service Units sind spezielle Deployment-Artefakte für eine JBI-Komponente und daher logischerweise für den JBI-Container transparent. Im Falle von BCs bestehen SUs üblicherweise aus Konfigurationsinformationen, z.B. Host/Port, Send-/Receive-Queue. Beispiele: XSLT Stylesheets in einen XSLT-Prozessor, BPEL Process Definitions in eine Process Engine. Allein die entsprechende Komponente muss wissen, was mit der SU anzufangen ist.
  • Das Management Interface von JBI-Container, Komponenten und deren Artefakten ist in JBI nicht nur standardisiert, sondern sogar auf standardisiertem Wege erweiterbar. JBI definiert zum Beispiel Management-Hooks für Lebenszyklus und Installation/Deinstallation von Komponenten.
WSDL und JBI
Für die Beschreibung von Interaktionen zwischen Komponenten in JBI wird auf den WSDL 2.0-Standard zurückgegriffen. WSDL definiert eine Operation als einen Austausch von Nachrichten zwischen Service Provider und Service Consumer – basierend auf einem Message Exchange Pattern, das beide verstehen. Mehrere solcher Operations bilden ein Interface, das wiederum von einem oder mehreren Services implementiert werden kann. Jeder Service hat seinerseits wieder einen oder mehrere Endpoints, über die die Aufrufe erfolgen. Um einen solchen Service zu nutzen, initiiert also ein Consumer einen Message Exchange mit einer bestimmten Operation. Der Consumer kennt dabei in JBI allerdings nur das entsprechende Interface, nicht jedoch den wirklichen Endpoint und somit sind Provider und Consumer voneinander entkoppelt. Es ist also durchaus möglich, dass mehrere Services das Interface implementieren und dann z.B. abhängig von Quality-of-Service-Kriterien zu einem bestimmten Endpoint geroutet wird.
Normalized Messages und Message Exchanges

Alle Nachrichten, die der Normalized Message Router verarbeitet, müssen in einem Standardformat vorliegen. JBI definiert dazu das Konzept der Normalized Messages (NM):

  • Die Payload enthält die eigentlichen Nutzdaten gemäß der in WSDL 2.0 beschriebenen Interface Operation Message Definition – es handelt sich also nicht um ein kanonisches Format. Für eine Komponente stehen diese Nutzdaten in Form einer XML TRaX Source (d.h. DOM, SAX oder Stream) zur Verfügung und können dementsprechend mit dem JAX-P API verarbeitet werden.
  • Metadaten repräsentieren kontextspezifische Message Properties, die typischerweise während der Verarbeitung der Nachricht entstanden sind. Dabei handelt es sich z.B. um Security Tokens, Transaktionsinformationen oder einfach komponentenspezifische Daten, die mit einem Name-Value-Paar in den Metadaten abgelegt sind. Normalerweise legen hier BCs ihre Connection- und Transportinformationen ab.

Die (optionalen) Attachments, die mit der NM ausgetauscht werden sollen, können in beliebigem – also auch binärem – Format vorliegen. Die Bearbeitung dieser Anhänge erfolgt in den Komponenten über Data Handler aus dem Java Activation Framework.
Komponenten verwenden zur Kommunikation mit dem NMR einen vom Container bereitgestellten DeliveryChannel als Kommunikations-Pipe und müssen vor der Übergabe einer Nachricht ihre Daten normalisieren. Umgekehrt müssen Messages, die vom NMR kommen, zur Weiterverarbeitung in einer Komponente häufig erst denormalisiert werden.
Reihenfolge und Anzahl der ausgetauschten Nachrichten innerhalb einer Interaktion werden in JBI anhand der WSDL 2.0 Message Exchange Patterns (MEP) definiert. Eine Request/Response-Interaktion ist also z.B. durch ein InOut-MEP genau beschrieben. In JBI ist ein Standardkatalog von vier MEPs (In-Only, Robust-In-Only, In-Out, In-Optional-Out) spezifiziert, die jede Implementierung unterstützen muss. Alle an einer Konversation beteiligten NMs werden zusammen mit Metadaten für den Nachrichtenaustausch in einem MessageExchange-Container-Objekt zusammengefasst. Abbildung 2 zeigt den vereinfachten Ablauf der Kommunikation zwischen einem externen SOAP/ HTTP Client mit einem JBI-Container.

Kommunikation mit externen Services
  • Ein externer Client sendet einen SOAP Request per HTTP an die SOAP/HTTP Binding-Komponente. Der Aufruf enthält Protokoll- und Binding-spezifische Informationen in HTTP-Transport- und SOAP Header sowie die eigentliche zu transportierende Payload „encoded“ im SOAP Body. Die JBI-Spezifikation bezeichnet diese Nachrichten auch als Bound Messages, um zu kennzeichnen, dass es sich um protokoll- bzw. transportspezifische Formate handelt.
  • Die BC nimmt den SOAP Request entgegen und normalisiert die Nachricht, d.h., sie erzeugt zuerst eine InOut-MessageExchange und über dieses als Factory eine NM. Im NM-Objekt werden die dekodierten Nutzdaten in der Payload-Sektion und HTTP/SOAP-spezifische Informationen in der Metadaten-Sektion abgelegt. Optional können der NM bzw. der ME noch weitere Metadaten wie Security Principal, Transaktionsinformationen oder BC-spezifische Daten übergeben werden. Attachments der SOAP Message werden der NM als Attachment angehängt.
  • Die Nachricht wird dann letztendlich als InOut-ME-Objekt (mit der darin enthaltenen NM) über den DeliveryChannel der BC an den NMR zur Weiterverarbeitung geschickt. Der NMR routet das InOut-ME-Objekt an den DeliveryChannel der richtigen SE. Wie in JBI das Routing erfolgt, lässt sich über den Interface- bzw. den Service-Namen oder über die Konfiguration steuern.
  • Die SE akzeptiert den InOut-ME, denormalisiert die In-Message und ruft eine ServiceUnit zur Verarbeitung auf. Das Ergebnis wird zu einer neuen NM normalisiert und als Out-Message in den InOut-ME verpackt. Das InOut-ME-Objekt wird über den DeliveryChannel an den NMR geschickt, der dann zurück zur BC routet. Die BC denormalisiert die Out-Message und erzeugt eine SOAP Response. Diese wird über das HTTP-Protokoll an den aufrufenden Client zurückgeschickt.
Service Engines und Binding Components

SEs und BCs sind logisch und technisch gesehen identisch, eigentlich hat die Unterscheidung nur pragmatische Gründe. Während SEs dafür gedacht sind, Träger der Business-Logik zu sein (z.B. in Form einer BPEL Engine oder eines EJB-Containers), ist es die Aufgabe der BCs, die Kommunikation mit der Außenwelt über Protokolle und Bindings zu ermöglichen. Die Kommunikation geht dabei natürlich in beide Richtungen, das bedeutet:

  • Eine BC kann als Proxy für einen externen Client arbeiten, der einen Dienst einer SE nutzen möchte. Die BC fungiert in diesem Fall als Remote Service Provider Proxy.
  • Eine BC kann auch als Proxy für eine SE arbeiten, die selbst einen externen Dienst aufrufen möchte. Die BC arbeitet dann als Remote Service Consumer Proxy.
  • Wenn man das Beispiel der BPEL Engine aufgreift, wird deutlich, dass diese sowohl als Service Provider als auch als Service Consumer arbeitet. Wird ein BPEL-Prozess von außen gestartet, fungiert sie als Provider – ruft sie in jedoch ihrem Prozessablauf einen anderen Dienst auf, so wird sie zum Consumer.

Jede JBI-Implementierung muss laut Spezifikation mindestens eine SOAP BC mitliefern, die WS-I Basic Profile 1.1-kompatibel ist. Für die Einbindung einer Komponente in eine JBI-Umgebung müssen einige Java-Interfaces implementiert werden, welche der JBI-Container verwendet, wenn über das Management-Interface bestimmte Operationen initiiert worden sind:

  • Das Bootstrap-Interface ist ein Callback-Interface, das vom JBI-Container während der Installation einer Komponente verwendet wird. Der JBI-Container entpackt und persistiert die Komponte zwar selbstständig, trotzdem muss er die Methode onInstall() aufrufen, damit die Komponente bei der Installation spezifische Setup-Tasks durchführen kann.
  • Das ComponentLifeCycle-Interface enthält Callbacks der Komponente, mit denen der JBI-Container den Lebenszyklus der Komponente steuert. Die Komponente kann dann auf Start/Stopp-Situationen geeignet reagieren. So wird der Komponente beim Aufruf von init() ein Kontextobjekt übergeben, das sie sich natürlich speichern sollte und über das sie auf Ressourcen des Containers zugreifen kann (z.B. auf den ihr zugeordneten DeliveryChannel). Beim Aufruf von start() sollte die Komponente dann ihre ServiceUnits initialisieren, die korrespondierenden Endpoints aktivieren und (mindestens) einen Thread starten, der auf dem DeliveryChannel auf Nachrichten wartet.
  • Über das Component-Interface erfolgen ebenfalls zur Laufzeit Interaktionen zwischen Komponente und JBI-Container. So erhält der JBI-Container Zugriff auf den ComponentLifeCycle, den ServiceUnitManager oder per Aufruf von getExtensionMBean() die von der Komponente implementierten Management-Erweiterungen.
  • ServiceUnitManager ist das Interface der Komponente, mit dem der Deployment, Undeploment und Lebenszyklus der SUs gesteuert wird. Das Entpacken und Persistieren einer SU wird zwar wieder von der JBI-Umgebung selbstständig durchgeführt, zusätzliche Aufgaben (etwa eine Konsistenzprüfung des Deployments) kann der ServiceUnitManger beim Aufruf von deploy() erledigen. Analog zum ComponentLifeCylce-Interface gibt es auch hier wieder Methoden, die beim Starten oder Beenden einer SU durch den JBI-Container aufgerufen werden.
JBI-Management

In der Java EE-Spezifikation war zwar von Beginn an das Thema Packaging definiert, jedoch wurden Konzepte für standardisiertes Deployment, Management und Monitoring erst sehr spät (mit J2EE 1.4) aufgenommen und leider auch nur sehr rudimentär adressiert. Die JBI-Spezifikation hingegen sieht diese Themen als zentralen Bestandteil der Architektur vor und berücksichtigt deshalb sehr weit reichende Unterstützung für operative Aufgabenstellungen. Im Detail spezifiziert JBI folgende Aspekte:

  • Packaging von JBI-Komponenten (SE/ BC) sowie standardisierte JBI-Deployment-Deskriptoren (META-INF/jbi.xml)
  • Installation von JBI-Komponenten in einen laufenden JBI-Container über die InstallationServiceMBean und InstallerMBean
  • Deployment von den Service Assemblies (Komposition aus mehreren zusammengehörenden Service Units) in Service Engines und Binding Components über die DeploymentServiceMBean
  • Extension Hooks, mit den JBI-Komponenten eigene MBeans registrieren
  • Starten/Stoppen von Komponenten und zusammengehörenden Services (Composite Assemblies)
  • Management der JBI-Infrastruktur per Ant Scripting. Der Support für Ant ist verpflichtend für jede JBI-Implementierung. Die Spezifikation definiert z.B. Ant-Tasks für das Deployment/Undeployment, Komponenteninstallation/-deinstallation und Start/Stopp von Komponenten. Damit lässt sich eine JBI-Umgebung vollständig und standardisiert „skripten“
Fazit

Für wen ist nun die Java Business Integration-Spezifikation relevant? JBI richtet sich nicht an „klassische“ Java EE-Entwickler, die z.B. Business-Logik in Form von Java EE-Komponenten entwickeln. In erster Linie ist JBI für Hersteller von Integrationsplattformen bzw. Erweiterungen interessant, die auf einer offenen Architektur aufbauen wollen. Kerngedanke der JBI-Initiative ist es ein Ökosystem für Hersteller und Entwickler von offenen Integrationslösungen und Plug-in-Komponenten zu etablieren. Unter diesem Gesichtspunkt muss der JBI-Spezifikation auch die größte Bedeutung beigemessen werden: Standardisierung eines Marktes, der bislang von proprietären Lösungen dominiert ist. Wer bereits heute JBI als Grundlage seiner SOA-Architektur verwenden möchte, hat dazu verschiedene Möglichkeiten. Die JBI-Referenzimplementierung wird als Open-Source-Projekt open-esb weiterentwickelt. Hier wird das Ziel verfolgt, eine produktionstaugliche JBI-Implementierung zu entwickeln, die direkt für eigene Integrationsprojekte genutzt und mit kommerziellen oder Open-Source-Plug-ins erweitert werden kann. Darüber hinaus gibt es bereits einige andere Open-Source-Projekte, die JBI nutzen. Beispiele sind ServiceMix , Celtix und Mule. Einige Firmen haben ebenfalls bereits kommerzielle Produkte angekündigt, mit denen Anfang 2006 zu rechnen ist.

SOA und JBI
Einige immer wiederkehrende technische Anwendungsmuster wie das sog. ACDC-Prinzip (Asynchronous, Conversational, Document-centric) sind charakteristisch für SOAs. Das ACDC-Prinzip dient als Ziel und Grundlage für viele andere Spezifikationen wie JAXWS 2.0, SOAP 1.2 und WSDL 2.0. Auch die JBI-Spezifikation verwendet bei der Definition von Architektur und Framework die gleichen Konzepte. So ist z.B. das Ablaufmodell bei JBI durchweg Event-getrieben und Komponenten nehmen im Framework definierte Rollen ein (Service Provider, Service Consumer).
JBI arbeitet zusätzlich mit dokumentzentrischen Nachrichten und den in WSDL 2.0 spezifizierten Message Exchange Patterns. Zum Nachrichtenaustausch spezifiziert JBI übrigens ein „Pull-Modell“, d.h., der Empfänger einer Nachricht muss diese explizit abholen. Service Provider und Service Consumer arbeiten also nie im gleichen Thread. Die einzelnen Komponenten sind somit technisch entkoppelt, aber auf semantischer Ebene integriert. Klare Trennung zwischen Implementierung (Endpoint) und Schnittstelle (Interface) sowie Trennung von Business-Logik (SEs) und dem Zugriff über Protokolle (BCs) sind durch die zugrunde liegende Architektur vorgegeben.

Natürlich wird es nicht bei der JBI-Spezifikation Version 1.0 bleiben. Punkte, die bereits jetzt für zukünftige Versionen identifiziert wurden, sind z.B. Work-Manager-Konzepte für Thread-Management in Komponenten, langlebige und persistente MessageExchanges, Erweiterung der Security-Konzepte, Message Handler (Interceptors) sowie die horizontale Skalierung von JBI-Containern. Insbesondere der Aspekt Verteilung von JBI-Containern zum Zweck der Skalierung und Hoch- verfügbarkeit – und damit der Aufbau von Enterprise Service Bus-(ESB-)Architekturen – wird ein Differenzierungsmerkmal kommerzieller Produkte werden. Zu wünschen ist auch, dass die Integration bzw. Koexistenz mit Java EE besser definiert wird. JBI verfolgt das Ziel, leichtgewichtige Integrationslösungen zu ermöglichen, und sieht deshalb keine explizite Abhängigkeit von Java EE vor. Softwareherstellern, die einen eigenen JBI-Container entwickeln, ist es jedoch freigestellt, für ihre Implementierung auf einem Application Server aufzubauen.


Links & Literatur

  1. Java Business Integration
  2. WSDL 2.0
Daniel Adelhardt und Armin Wallrab arbeiten als Java-Architekten mit dem Fokus auf Java EE und SOA bei Sun Microsystems in München.
Geschrieben von
Daniel Adelhardt und Armin Wallrab
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.