In diesem Teil der Mule ESB Reihe widme ich mich der Integration von Mainframe Programmen in den Mule Enterprise Service Bus. Hierzu verwende ich die Open Source Erweiterung LegStar for Mule ESB der Firma LegSem . Mit dieser lassen sich in COBOL oder PL/I geschriebene CICS Programme in Mule einbinden. Diese Einbindung kann bidirektional erfolgen: Sowohl Mule Flows können Mainframe Programme aufrufen als auch Mainframe Programme Mule Flows. Dies ist ein großer Vorteil gegenüber anderen Technologien um CICS Programme in die Java Welt zu integrieren – z.B. dem IBM CICS Transaction Gateway (CTG) . Ganz abgesehen davon, dass Mule natürlich nicht auf die Java Welt beschränkt ist.
LegStar for Mule ESB
LegStar for Mule ESB oder kurz Legs4Mule besteht aus vier Bestandteilen:
LegStar Eclipse Plugin
Mit einem Eclipse Plugin kann man alle benötigten LegStar Artefakte basierend auf Eingaben in Wizards generieren.
LegStar Transformer
Mittels LegStar Transformern werden die Nutzdaten zwischen der fachlichen Anwendung und dem Mainframe transformiert.
Die Transformer erwarten die fachlichen Daten in Form von XML oder als Java Objekte (Befüllung der generierten Java-Klassen) und wandeln diese in einen Binärstrom entsprechend der Copysatzstruktur des CICS Programms.
LegStar Transports
LegStar Transports übermitteln den zuvor erzeugten Binärstrom zum Mainframe. Es stehen Transports für die Übertragung der Daten per IBM WebSphere MQ , Sockets und HTTP zur Verfügung.
MQ und HTTP können in beide Richtungen verwendet werden. Über Sockets kann Mule ein CICS Programm aufrufen aber nicht umgekehrt.
LegStar Mainframe Komponenten
Wenn HTTP oder Sockets als Transportprotokoll verwendet wird, müssen auf Mainframe Seite LegStar C/370 Programme installiert werden.
Im Falle von HTTP klinkt sich dieses LegStar Programm in den CICS Web Support ein und wird bei eintreffenden HTTP Requests aufgerufen und linkt zum Zielprogramm.
Bei der Verwendung von WebSphere MQ sorgt dieses selbst für den Aufruf des CICS Zielprogramms und es ist keine LegStar Installation auf Mainframe Seite notwendig.
Tutorial
Aber nun zu einem praktischen Beispiel in dem ich aus Mule ein CICS Programm per HTTP aufrufen werde.
Das Beispiel besteht aus drei Bausteinen:
- Einem Client – der Einfachheit halber nutze ich einen JUnit Test.
- Einer Mule App aus Inbound und Outbound Endpoint: Der Inbound Edpoint kann beliebig gewählt werden. Ich wähle den simplem VM Endpoint. Das könnte aber genauso gut ein HTTP, Web Service oder JMS Endpoint sein. Der Outbound Endpoint in Richtung Mainframe setzt sich aus einem Legstar Transformer und Endpoint zusammen.
- Auf Mainframe Seite nimmt der CICS Web Support den HTTP Call entgegen, übergibt an LegStar und dieses linkt wiederum zum CICS Programm.
Hinweis zu LegStar Mainframe Komponenten
Auf die Installation der LegStar Mainframe Komponente und Einrichtung des CICS Web Support gehe ich nicht ein, da dies den Umfang des Blogbeitrags sprengen würde.
Eine Anleitung befindet sich unter:
LegStar HTTP Transport http://www.legsem.com/legstar/legstar-transport/legstar-chttprt/index.html
Eclipse Plugin installieren
Bevor wir richtig loslegen können, müssen wir zuerst das Eclipse Plugin installieren, das alle benötigten Legs4Mule Komponenten mitliefert. Dieses lässt sich sowohl in Mule Studio installieren als auch in einem “puren” Eclipse. Ich gehe in Folgendem von Mule Studio 3.3.1 aus.
Wir installieren von der Update Site http://www.legsem.com/legstar/mule/eclipse/update
das Plugin mit dem Namen “LegStar Mule Component Generator”
(“Help” -> “Install New Software …” -> “Add” Update Site -> Plugin auswählen -> “Next” … )
Copysatz der Partnersuche
Als Beispiel möchte ich einen Partner aus einem Partnersystem auf dem Mainframe lesen. Der stark vereinfachte Copysatz des COBOL Programms sieht wie folgt aus:
101 DFHCOMMAREA. 2 /**************************************************************** 00000100 3 * COPY-STRECKE PARTNER1 00000200 4 *---------------------------------------------------------------- 00000300 5 * Ein- Ausgabebereich der Schnittstelle zur Partnersuche 00000400 6 * Länge: 70 00000500 7 ******************************************************************00000600 8 00000700 9 03 PARTNER-NR PIC X(10). 00000800 10 * *** 10 stellige Partnernummer 00000900 11 03 NAME PIC X(30). 00001000 12 * *** Nachname des Partners 00001100 13 03 VORNAME PIC X(30). 00001200 14 * *** Vorname des Partner 00001300
partnersuche.cpy
Dieser Copysatz dient sowohl der Ein- als auch Ausgabe. Mittels einer PARTNER-NR wird der Partner identifiziert/gesucht und in Form von NAME und VORNAME vom Partnersystem geliefert.
Separate Copysätze für Ein- und Ausgabe sind ebenfalls möglich. Die nachfolgenden Schritte (XML Schema und Transfomer Generierung) müssen dann jeweils zweimal durchgeführt werden . Bei einer weitergehenden Aufteilung z.B. falls die Ausgabe aus mehreren Copysatz-Dateien besteht, empfiehlt es sich diese vor der Nutzung mit LegStar zu einer Datei zusammen zu fassen.
Falls das Mainframe Programm in PL/I geschrieben ist, muss der Copysatz zu allererst ins COBOL Format gewandelt werden. Hierzu stellt LegStar folgenden Konverter zur Verfügung:
legstar-pli2cob – Translates PL/I structures to COBOL structures https://code.google.com/p/legstar-pli2cob/
Download des Copysatzes
Der Copysatz kann bei GitHub heruntergeladen werden:
https://raw.github.com/codecentric/legstar-beispiel/master/partnersuche/partnersuche.cpy
Oder das gesamte Beispiel – die Commits entsprechen den Schritten des Beitrags:
https://github.com/codecentric/legstar-beispiel
XML Schema der Mainframe Schnittstelle generieren
Aus unserem Copysatz lassen wir LegStar ein XML Schema generieren, das die Schnittstelle unseres Mainframe Programms beschreibt und Ausgangspunkt für die Transformation zwischen Java oder XML und dem Mainframe Binärstroms ist (Grundlage für den LegStar Transformer).
Wir legen dazu in Mule Studio ein Mule Projekt inklusive Mule Flow an und kopieren den Copysatz partnersuche.cpy in dieses. Über den Button “LegStar new structures mapping…” in der Eclipse Buttonleiste starten wir den passenden LegStar Wizard. Wir geben der Schema Datei einen passenden Namen und bestimmen den Namespace.
Im zweiten Dialog des Wizards wählen wir unsere Copysatz Datei partnersuche.cpy aus und starten die Generierung mit “Finish”. Im Hintergrund erzeugt LegStar ein ANT-Skript mit der eigentlichen Logik und führt dieses aus (dieses Verfahren werden wir auch in den folgenden Schritten beobachten).
Nach erfolgter Generierung können wir im Eclipse XML Schema Editor prüfen, ob das Schema der Mainframe Schnittstelle entspricht.
LegStar Transformer generieren
Nun kommen wir zur zentralen Komponente unserer Mainframe Integration. Wir selektieren das gerade erzeugte XML Schema und wählen aus dem Kontextmenü “LegStar” – “Generate Transformers…”. Im sich öffnenden Dialog müssen wir nur das oberste Element des Copysatzes die Dfhcommarea auswählen und mit “Finish” die Generierung starten.
Ergebnis sind zwei Java Packages mit mehreren Klassen. Die wichtigste davon ist die Klasse de.codecentric.partnersuche.Dfhcommarea – unsere Schnittstelle zu unserem Mainframe Programm. In dieser finden wir die Eingabe String partnerNr und die Ausgaben String name und String vorname.
1@XmlElement(required = true) 2@CobolElement(cobolName = "PARTNER-NR", type = CobolType.ALPHANUMERIC_ITEM, 3 levelNumber = 3, picture = "X(10)", srceLine = 9) 4protected String partnerNr;
Ausschnitt aus Dfhcommarea
Die Variablen verfügen sowohl über eine Annotation vom Typ @XmlElement als auch @CobolElement.
Erstere wird verwendet, wenn wir LegStar ein XML Dokument als Input übergeben – aus dem XML wird die Java Klasse befüllt. Genauer gesagt, erfolgt mittels JAXB ein Marshalling bzw. Unmarshalling.
Zweitere sagt LegStar wie es aus der gefüllten Java Klasse einen COBOL Binärstrom erzeugen soll.
Die eigentlichen Transformer sind folgende Klassen im bind Package
- DfhcommareaJavaToHostTransformer Java >> Copysatz
- DfhcommareaHostToJavaTransformer Copysatz >> Java
- DfhcommareaXmlToHostTransformer XML >> Copysatz
- DfhcommareaHostToXmlTransformer Copysatz >> XML
Operations Mapping anlegen
Jetzt müssen wir LegStar mitteilen, welche Operationen wir auf dem Mainframen aufrufen wollen. Dazu erstellen wir ein Mapping der Operationen. Jede Operation hat einen Namen und definiert welches Mainframe Programm aufgerufen wird und welcher Copysatz als Ein- und Ausgabe dient bzw. welche JAXB Klasse – das ist der Link zu den erzeugten Transformern.
Wir drücken dazu den zweiten Legstar Button in der Eclipse Button Leiste: “LegStar new operations mapping….”. Im Wizard geben wir der Mapping Datei einen Namen und “Finish”.
Im “Operations mapping editor” definieren wir eine Operation/Mapping und nutzen unsere JAXB-Klasse de.codecentric.partnersuche.Dfhcommarea als Ein- und Ausgabe.
Der Name der Operation kann frei gewählt werden. Unser aufzurufendes CICS Programm hat den Namen PARTNER1.
Wenn unsere Operation fertiggestellt ist, speichern wir das Mapping über den normalen Speicher-Befehl.
Mule Mainframe Adapter generieren
Nachdem wir jetzt noch komplett in der LegStar Welt waren, kommt jetzt endlich Mule ins Spiel. Über den “Generate” Button im “Operations mapping editor” können wir sowohl einen Mule Mainframe Adapter als auch einen Mule Mainframe Proxy erzeugen.
- Der Adapter dient zum Aufruf von Mainframe Programmen aus einer Mule App heraus.
- Den Proxy benötigen wir für die Gegenrichtung – Mainframe ruft Mule.
Ich zeige im folgenden die Erzeugung des Adapters. Dazu klicken wir auf “Generate” und wählen den “Mule Mainframe Adapter Generator”.
Jetzt sind wir nur noch einen Dialog von einer ausführbaren Mule Applikation entfernt. Dieser Dialog hat es allerdings in sich.
In diesem wird folgendes festgelegt:
- Mainframe character set: Mit welchem Encoding arbeitet der Mainframe. Dieses sollte bei den Mainframe Administratoren erfragt werden.
- Client to Adapter payload: Hier können wir entscheiden, ob unsere Mule Anwendung die fachlichen Daten in XML Form – entsprechend des generierten XML Schemas – oder eine befüllte Instanz der Klasse de.codecentric.partner.partner.Dfhcommarea liefern möchte. Wir gehen den Java Weg.
- Adapter to Mainframe transport: Für die Kommunikation zum Mainframe können drei Protokolle verwendet werden: HTTP, WebSpere MQ und Sockets. Wir verwenden den HTTP Transport.
- (Mainframe HTTP) settings: Dieser Block des Dialogs hängt von dem verwendeten Kommunikationsprotokoll (Transport) ab. Im Falle von HTTP ist hier der Host und Port des CICS Web Support anzugeben. Der Pfad zeigt auf die installierten LegStar Mainframe Komponenten (Das C/370 Programm LSWEBBIN ).
- 1. Hinweis: Im Pfad versteckt sich auch die Transaktion unter der das Mainframe Programm aufgerufen wird! CWBA ist eine Standardtransaktion des CICS Web Support.
- 2. Hinweis: In der aktuellen Version des LegStar Eclipse Plugins (3.1.0) werden die Authentifizierungsdaten (User ID, Password) vom Plugin ignoriert. Ich zeige später wie diese direkt im Mule Flow eingetragen werden.
Das Ergebnis ist der Mule Flow (mule-config.xml ) und zwei Mule Transformer
(DfhcommareaToHostMuleTransformer , HostToDfhcommareaMuleTransformer ) die wiederum die generierten LegStar Transformer nutzen.
Übersicht der erzeugten Artefakte
Um nicht den Überblick über die vielen erzeugten Artefakte zu verlieren, eine kleine Übersicht:
Mule Studio + LegStar Eclipse Plugin
Das LegStar Plugin ist für ein “pures” Eclipse plus Mule Standalone 3.1.2 erstellt worden und daher leider nicht vollständig kompatibel zu Mule Studio 3.3.1.
Damit unser generierter Mule Flow in Mule Studio lauffähig ist, müssen wir zwei Änderungen vornehmen:
1. mule-config.xml in partnersuche.xml kopieren
Den Inhalt (XML) des generierten Mule Flows (conf/mule-config.xml) kopieren wir in den von Mule Studio angelegten Flow (src/main/app/partnersuche.xml).
Den conf-Ordner können wir anschließend löschen.
2. Mule 3.1.2 Bibliotheken entfernen
Das LegStar Plugin hat zwei Mule 3.1.2 Bibliotheken zum Classpath unseres Projektes hinzugefügt (mule-core-3.1.2.jar und mule-transport-http-3.1.2.jar). Da sich diese mit den ebenfalls im Classpath befindlichen Mule 3.3.1 Bibliotheken beißen, müssen wir die alten Bibliotheken aus dem Classpath entfernen.
Wir rufen dazu die “Properties” unseres Eclipse Projekts auf und entfernen unter “Java Build Path” -> “Libraries” den “LegStar Mule library container”. Anschließend fügen wir über “Add External JARs…” folgende vier Bibliotheken aus dem Eclipse Plugins Verzeichnis (MuleStudio/plugins/com.legstar.eclipse.plugin.mulegen_3.1.0/lib) wieder hinzu:
- legstar-mule-generator-3.1.0.jar
- legstar-mule-generator-3.1.0-javadoc.jar
- legstar-mule-transport-3.1.0.jar
- legstar-mule-transport-3.1.0-javadoc.jar
Mule Flow
Der Mule Flow sieht jetzt (nach zusätzlichen kosmetischen Änderungen) wie folgt aus:
1<!-- Transform serialized java objects to mainframe data --> 2<legstar:java-to-host-transformer 3 name="suchePartnerJavaToHost" hostCharset="IBM01141" 4 class="de.codecentric.partnersuche.cixs.DfhcommareaToHostMuleTransformer" /> 5 6<!-- Transform mainframe data to serialized java objects --> 7<legstar:host-to-java-transformer 8 name="suchePartnerHostToJava" hostCharset="IBM01141" 9 class="de.codecentric.partnersuche.cixs.HostToDfhcommareaMuleTransformer" /> 10 11<!-- Wrap mainframe data in a LegStar request for mainframe program execution --> 12<legstar:host-to-legstar-transformer 13 name="suchePartnerHostToLegStar" hostCharset="IBM01141"> 14 <legstar:host-program name="PARTNER1" 15 maxDataLength="70"> 16 </legstar:host-program> 17</legstar:host-to-legstar-transformer> 18 19<!-- Unwrap LegStar response to mainframe program execution --> 20<legstar:legstar-to-host-transformer 21 name="suchePartnerLegStarToHost" /> 22 23<http:endpoint name="suchePartnerClientEndpoint" 24 exchange-pattern="request-response" 25 address="http://localhost:3280/suchePartner" 26 doc:name="HTTP"> 27 <byte-array-to-object-transformer 28 name="byte-array-to-object-transformer" /> 29</http:endpoint> 30 31<legstar:endpoint name="mainframeRequestEndpoint" 32 exchange-pattern="request-response" 33 address="legstar://mainframe:4081/CICS/CWBA/LSWEBBIN" /> 34 35<flow name="suchePartnerAdapter" doc:name="suchePartnerAdapter"> 36 <inbound-endpoint ref="suchePartnerClientEndpoint" 37 doc:name="HTTP Endpoint" exchange-pattern="request-response" /> 38 <outbound-endpoint ref="mainframeRequestEndpoint" 39 transformer-refs="suchePartnerJavaToHost suchePartnerHostToLegStar" 40 responseTransformer-refs="suchePartnerLegStarToHost suchePartnerHostToJava" 41 doc:name="LegStar Endpoint" exchange-pattern="request-response" /> 42</flow>
partnersuche.xml Der Flow an sich besteht aus zwei Endpoints. Ein HTTP Inbound Endpoint nimmt das serialisierte Java Objekt (Dfhcommarea) entgegen und der LegStar Outbound Endpoint schickt den Copysatz zum Mainframe. Damit diese Endpoints ihre Arbeit verrichten können, sind jeweils eine Eingangs- und Ausgangs-Adresse (address) konfiguriert.
Die Transformationen zwischen Java und Copysatz (und vice versa) sind in den Transformer-Referenzen (transformer-refs, responseTransformer-refs) versteckt.
- legstar:java-to-host-transformer, legstar:host-to-java-transformer: Diese im letzten Schritt generierten Mule Transformer nutzen die LegStar Transfomer um aus der Dfhcommarea einen Bytestrom entsprechend des Copysatzes zu erzeugen und vice versa. Konfiguriert ist jeweils das im Wizard angegebene Mainframe Encoding.
- legstar:host-to-legstar-transformer, legstar:legstar-to-host-transformer: Diese zwei Mule Transfomer aus der LegStar Distribution erweitern den Copysatz um LegStar spezifische Properties. Die LegStar Mainframe Komponente erfährt in diesen Properties welches Zielprogramm es aufzurufen hat (name=“PARTNER1″) und die Maximallänge des Copysatzes (maxDataLength=“70″) – beides ebenfalls Informationen aus dem Wizard.
CICS Web Support Authentifizierung
Bei der Einrichtung der CICS Web Support muss man sich entscheiden, ob und wie der CICS Web Zugang und somit der Zugriff über LegStar auf die CICS Programme geschützt werden soll. Falls BASIC konfiguriert wird, nutzt CICS eine HTTP basic authentication.
Wie bereits erwähnt, läuft die Angabe der User ID und des Passworts im Wizard leider ins Leere. Wir müssen User ID und Passwort im legstar:endpoint im address Parameter angeben:
1<legstar:endpoint name="mainframeRequestEndpoint" 2 exchange-pattern="request-response" 3 address="legstar://userid:passwort@mainframe:4081/CICS/CWBA/LSWEBBIN" />
Alternativ kann der LegStar Endpoint (outbound:endpoint und legstar:endpoint) durch einen “normalen” HTTP Outbound Endpoint ersetzt werden:
1<http:outbound-endpoint 2 transformer-refs="suchePartnerJavaToHost suchePartnerHostToLegStar" 3 responseTransformer-refs="suchePartnerLegStarToHost suchePartnerHostToJava" 4 doc:name="LegStar Endpoint" exchange-pattern="request-response" 5 host="mainframe" port="4081" path="CICS/CWBA/LSWEBBIN" 6 mimeType="application/octet-stream" 7 user="userid" password="passwort" />
Dies ist die auch die richtige Wahl, falls die Kommunikation zum CICS Web Support per HTTPS geschützt wird – der LegStar Endpoint unterstützt in der aktuellen Version kein HTTPS.
Hinweis: Bei Verwendung des HTTP Outbound Endpoints muss der mimeType angegeben werden (application/octet-stream).
Testen der Mule Applikation
Nach den vorhergehenden „Korrekturen“ an unserer Mule Applikation bzgl. Mule Studio und der Authentifizierung ist diese vollständig und wir sind fast am Ende des Tutorials angelangt. Natürlich muss die Korrektheit der Applikation noch getestet werden. Zumindest zeige ich wie ein solcher Test aussehen kann, falls der passende Mainframe zur Verfügung steht.
Verwendung eines VM Inbound Endpoints
Um die Mule Applikation leichter testen zu können, ersetzen wir den HTTP Inbound Endpoint (inbound-endpoint und http:endpoint) durch einen VM Inbound Endpoint.
1<vm:inbound-endpoint exchange-pattern="request-response" 2 path="partnersuche" doc:name="VM Endpoint" />
JUnit Test
Unser Unit-Test sieht dann wie folgt aus:
1public class PartnersucheTest extends FunctionalTestCase {
2
3 @Test
4 public void test() throws MuleException {
5
6 Dfhcommarea dfhcommarea = new ObjectFactory().createDfhcommarea();
7 dfhcommarea.setPartnerNr("1234567890");
8
9 MuleMessage muleMessage = muleContext.getClient().send(
10 "vm://partnersuche", dfhcommarea, null);
11
12 Object payload = muleMessage.getPayload();
13 Assert.assertTrue("Payload ist keine Dfhcommarea",
14 payload instanceof Dfhcommarea);
15
16 dfhcommarea = (Dfhcommarea) payload;
17 Assert.assertEquals("Max", dfhcommarea.getVorname());
18 Assert.assertEquals("Mustermann", dfhcommarea.getName());
19 }
20
21 @Override
22 protected String getConfigResources() {
23 return "src/main/app/partnersuche.xml";
24 }
25}
PartnersucheTest.java
Wir erben vom FunctionalTestCase, der im Hintergrund eine Mule Instanz hochfährt.
In der Testmethode füllen wir die Dfhcommarea mit einer Partnernummer, schicken sie an den VM Endpoint und die Payload der Antwort-Message ist wiederum eine Dfhcommarea mit Name und Vorname des gesuchten Partners.
Hinweis:
Damit der Unit-Test korrekt funktioniert, muss Log4j konfiguriert werden. Dazu kann folgende log4j.xml in src/test/resources kopiert werden: https://raw.github.com/codecentric/legstar-beispiel/master/partnersuche/src/test/resources/log4j.xml
Weitere Teile dieser Artikelserie
- Was ist ein ESB und wofür kann man ihn nutzen?
- Tutorial “Enterprise Service Bus mit Mule ESB”: Hello World/Bus
- Tutorial “Enterprise Service Bus mit Mule ESB”: MuleMessage und Java-Komponenten
- Tutorial „Enterprise Service Bus mit Mule ESB“: Nachrichten mit Java transformieren
- Tutorial „Enterprise Service Bus mit Mule ESB“: Integration von CICS Programmen
- Tutorial “Enterprise Service Bus mit Mule ESB”: Transport, Connector, Endpoint: Ein paar Grundlagen…
- Tutorial “Enterprise Service Bus mit Mule ESB”: Performance und Threads
- Tutorial “Enterprise Service Bus mit Mule ESB”: Steuerung und Kontrolle per JMX
- Veröffentlichen von Informationen zu Mule Applikationen im Maven-Umfeld
- Tutorial “Enterprise Service Bus mit Mule ESB”: Exceptions und Email
Weitere Beiträge
von Andreas Fritz
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog-Autor*in
Andreas Fritz
Senior IT Consultant / Senior IT Architect
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.