Ein­lei­tung

In die­sem Blog­bei­trag wird dar­ge­stellt, wie Tal­end Jobs (Tal­end Data Inte­gra­tion (DI)) in ein exter­nes Java-Pro­jekt ein­ge­bun­den wer­den kön­nen. In vie­len Pro­jek­ten gibt es die Anfor­de­rung Daten aus ver­schie­de­nen Quel­len zu laden, mit­ein­an­der zu kom­bi­nie­ren und zu trans­for­mie­ren. Auch wenn es nahe­liegt eine Imple­men­tie­rung direkt in der jewei­li­gen Pro­gram­mier­spra­che des Pro­jekts vor­zu­neh­men, bie­ten gra­phi­sche ETL-Anwen­dun­gen einige Vor­teile, wel­che den Ent­wick­lungs-Pro­zess deut­lich ein­fa­cher gestal­ten und den Auf­wand redu­zie­ren kön­nen. Von den gän­gi­gen ETL-Tools inte­griert sich Tal­end DI am bes­ten in Java-Pro­jekte, da sich direkt aus dem Tal­end Stu­dio Cli­ent JAR-Dateien bauen las­sen, wel­che direkt in Tal­end-fremde Java-Pro­jekte inte­griert wer­den kön­nen. Ein Grund für die Inte­gra­tion eines Tal­end-Jobs in ein exter­nes Java-Pro­jekt kann es sein, dass man Ergeb­nisse als Rest-Ser­vice anbie­ten oder aus dem Java-Pro­jekt direkt ETL-Stre­cken aus­füh­ren möchte. 

Auch wenn Tal­end DI haupt­säch­lich als stand-alone Daten­in­te­gra­ti­ons-Tool kon­zi­piert ist, wel­ches übli­cher­weise (vor allem in der Enter­prise-Ver­sion) sei­nen Ein­satz­zweck im Data Ware­house oder Data Lake fin­det, bie­tet bereits die Open-Source Ver­sion (Tal­end Open Stu­dio) ein mäch­ti­ges Werk­zeug zur Ent­wick­lung von Daten­ver­ar­bei­tungs­stre­cken, die sich in pro­duk­ti­ven Java-Umge­bun­gen nut­zen lassen. 

Auf ein gra­phi­sches Werk­zeug zur Ent­wick­lung von kom­ple­xen ETL-Pro­zes­sen zu set­zen, kann einige Vor­teile brin­gen. Tal­end DI bie­tet viele spe­zi­fi­sche Kom­po­nen­ten, die in der Ent­wick­lung genutzt wer­den kön­nen und so viele Anwen­dungs­sze­na­rien abbil­den. Dazu kommt eine große Com­mu­nity, die wei­tere Kom­po­nen­ten für spe­zi­fi­schere Auf­ga­ben bereit­stellt. So las­sen sich Tal­end-Jobs über­all nutz­ten, wo man mit Code-basier­ten Pro­zes­sen an Gren­zen stößt. Tal­end DI bie­tet die Mög­lich­keit über­sicht­li­che Jobs zu desi­gnen, die mit eta­blier­ten Pro­zes­sen sehr gut wart­bar sind und eine ein­fa­che Feh­ler­ana­lyse bie­ten, wel­che sich bei in Code geschrie­be­nen ETL-Jobs oft­mals schwie­rig erweist. 

Design des Talend-Jobs

Für einen Tal­end-Job, den man in ein Java-Pro­jekt ein­bin­den möchte, gibt es keine beson­de­ren Vor­aus­set­zun­gen. Es soll­ten die Richt­li­nien für gutes Design ange­wen­det wer­den, die auch für den Ein­satz von Tal­end DI als stand-alone-Anwen­dung gel­ten. Ziel sollte es sein, den Job über­sicht­lich zu hal­ten und so viel Logik wie mög­lich im Java-Backend abzu­bil­den. Diese kann dann über Aus­prä­gun­gen von Kon­text-Varia­blen an den Tal­end-Job über­ge­ben wer­den. Dafür bie­tet es sich an eine eigene Java-Klasse zu imple­men­tie­ren, wel­che diese Logik bereit­stellt. Auch soll­ten alle Kon­stan­ten in das externe Java-Pro­jekt aus­ge­la­gert wer­den, um die War­tung und Ände­run­gen an dem Job so ein­fach wie mög­lich zu gestal­ten. Anpas­sun­gen im Java-Code kön­nen schnel­ler durch­ge­führt wer­den als Ände­run­gen an dem Talend-Job. 

Als Bei­spiel dient ein simp­ler Job (ETL_RUNNER), der zufäl­lig erzeugte Test­da­ten in eine Daten­bank schreibt. Die Anzahl der Kon­text-Para­me­ter ist überschaubar: 

  • num­berO­fIn­pu­tRows = Anzahl der Daten­sätze die erzeugt wer­den sollen
  • tar­getDBHost = Host der Zieldatenbank
  • tar­getDB­Port = Port der Zieldatenbank
  • tar­getDBU­ser = Benut­zer der Zieldatenbank
  • tar­get­Schema = Schema der Zieldatenbank
  • tar­getTable = Tabelle der Zieldatenbank

Diese Kon­text-Para­me­ter sol­len über den Java-Code gesteu­ert wer­den, sodass der Tal­end-Job in unter­schied­li­chen Aus­füh­rungs­um­ge­bun­gen lau­fen kann. 

Baut man den Job nun mit Hilfe von Tal­end Stu­dio, kann man alle Haken abwäh­len. Der Auf­ruf soll direkt aus der gene­rier­ten JAR-Datei erfol­gen und alle Kon­text-Para­me­ter wer­den aus der exter­nen Java-Klasse übergeben. 

Abbil­dung 1: Build-Dia­log des Tal­end Jobs

Das Java-Pro­jekt in die­sem Bei­spiel ent­hält zwei Pakete: 

  • saracus.talend.wrapper: Hier liegt der Java-Code
  • saracus.talend.repository: Hier wird der ent­packte Tal­end-Code abgelegt

Ein­bin­den des Jobs in das Java-Projekt

Sobald der Tal­end-Job gebaut wor­den ist, kön­nen die erzeug­ten JAR-Dateien dem Build-Path des Java-Pro­jekts hin­zu­ge­fügt wer­den. Dann kön­nen diese bei der Aus­füh­rung des Java-Codes berück­sich­tigt wer­den. Die Liste der JAR-Dateien für die­ses Bei­spiel sieht fol­gen­er­ma­ßen aus: 

Abbil­dung 2: Build-Path des exter­nen Java-Projektes

Hier sind der Tal­end-Job „ETL_RUNNER“ und alle benö­tig­ten Abhän­gig­kei­ten ent­hal­ten, sodass der Job direkt aus dem exter­nen Code auf­ge­ru­fen wer­den kann. In Pro­jek­ten, in denen die Builds auto­ma­ti­siert gestar­tet wer­den, kön­nen aus den JAR-Dateien Abhän­gig­kei­ten erzeugt wer­den aus denen sich dann mit Build-Tools wie Apa­che Maven oder Gradle fer­tige Anwen­dun­gen erzeu­gen lassen. 

Die Kon­text Para­me­ter kön­nen bei dem Auf­ruf des Tal­end-Jobs als String-Array über­ge­ben wer­den, wobei fol­gende Form ein­ge­hal­ten wer­den muss: 

–context_param {context_name}={context_ausprägung} 

In der fol­gen­den Bei­spiel-Klasse wer­den die Aus­prä­gun­gen der benö­tig­ten Kon­text-Para­me­ter sta­tisch übergeben: 

package saracus.talend.wrapper; 

import java.util.ArrayList; 

public class TalendContext { 
    public String[] getContextParameters() {		 
        ArrayList<String> params = new ArrayList<String>(); 
        params.add("--context_param numberOfInputRows=" + noInputRows);
        params.add("--context_param targetDBHost=" + "xx.xx.xxx.xxx"); 
        params.add("--context_param targetDBPort=" + port); 
        params.add("--context_param targetDBUser=" + "dbUser"); 
        params.add("--context_param targetSchema=" + "schemaName"); 
        params.add("--context_param targetTable=" + "tableName"); 
        return params.stream().toArray(String[]::new); 
    } 
} 

In pro­duk­ti­ven Pro­jek­ten kön­nen die Aus­prä­gun­gen dyna­misch, je nach Umge­bung in denen der ETL-Job aus­ge­führt wer­den soll, erzeugt werden. 

Die Klasse, die den Tal­end-Job auf­ruft und aus­führt, erzeugt dann ein Tal­end­Con­text-Objekt und gibt die­ses an den Auf­ruf des Tal­end-Jobs weiter: 

package saracus.talend.wrapper;

import etlrepository.etl_runner_0_1.ETL_RUNNER; 

public class TalendWrapper { 
    public static void main(String[] args) {	 
        
        ETL_RUNNER etl = new ETL_RUNNER(); 
        TalendContext context = new TalendContext(); 
        etl.runJobInTOS(context.getContextParameters()); 
    } 
} 

So lässt sich der Tal­end-Job mit einem Varia­blen-Kon­text aus Java direkt aufrufen. 

Hier wird die Methode run­Job­In­TOS zum Aus­füh­ren des Tal­end-Jobs genutzt, wel­che direkt aus der erzeug­ten Jar-Datei stammt. Tal­end bie­tet zwei Metho­den, um Jobs aus gene­rier­ten JAR-Dateien auszuführen: 

  • run­Job­In­TOS: Akzep­tiert ein String-Array als Kon­text-Para­me­ter und führt den Job aus 
  • run­Job: Ist eine Wrap­per-Methode für run­Job­In­TOS und gibt einen bes­ser les­ba­ren Feh­ler­code zurück 

Wei­tere Metho­den des Tal­end-Jobs geben den Aus­füh­rungs-Kon­text (get­Con­text()), den Feh­ler­code (error­Code()), ent­spre­chende Pro­cess iden­ti­fier (pid(), father­Pid(), root­Pid()), den Start­zeit­punkt (start­Time()) oder den aktu­el­len Sta­tus des Jobs (sta­tus()) zurück. 

Beson­der­hei­ten von Tal­end in Java-Projekten 

Aus dem Ein­bin­den eines Tal­end-Jobs in ein Java-Pro­jekt las­sen sich einige Ein­schrän­kun­gen der Open-Source Vari­ante von Tal­end auf­wie­gen. Vor allem der große Nach­teil, dass die Sche­du­ling-Funk­tion des Tal­end-Admi­nis­tra­tion-Cen­ter (TAC) nicht zur Ver­fü­gung steht fällt nicht ins Gewicht. Denn in einem exis­tie­ren­den Java-Pro­jekt müs­sen andere Werk­zeuge zum Ein­satz kom­men, um die Aus­füh­rungs­pla­nung zu übernehmen. 

Für die Feh­ler­ana­lyse und das Log­ging des Tal­end-Jobs muss nach Art des Pro­jek­tes ent­schie­den wer­den, ob mit den Stan­dard-Kom­po­nen­ten gear­bei­tet wird, die Logs und Feh­ler in Tal­end DI doku­men­tie­ren. Diese Kom­po­nen­ten kön­nen ihre Infor­ma­tio­nen dann ent­we­der in Dateien oder eine Daten­bank schrei­ben. Ein ande­rer Ansatz, wel­cher sich am bes­ten in die übli­che Infrastruktur von Java-Pro­jek­ten ein­fügt, ist es über tJava-Kom­po­nen­ten direkt Log4j-Nach­rich­ten zu erzeu­gen. Diese inte­grie­ren sich erfah­rungs­ge­mäß am bes­ten in Log-Manage­ment Anwen­dun­gen. Da sich Log4j-Nach­rich­ten bes­ser fin­den las­sen als die Logs, die durch die Tal­end-Kom­po­nen­ten erzeugt wer­den, da diese über die glei­chen Fil­ter wie die Logs der eigent­li­chen Java-Anwen­dung gefun­den wer­den können.

Des Wei­te­ren ist die feh­lende Inte­gra­tion eines Ver­si­ons­ver­wal­tungs­tools nicht wei­ter dra­ma­tisch, da sich die Tal­end-Repo­si­to­ries im Gan­zen mit allen mög­li­chen Ver­si­ons­ver­wal­tungs-Werk­zeu­gen ver­sio­nie­ren las­sen. Dazu muss aller­dings für jeden ETL-Pro­zess ein eige­nes Repo­si­tory in das Java-Pro­jekt inte­griert wer­den, um eine par­al­lele Bear­bei­tung zu ermög­li­chen, da Merge-Kon­flikte nicht inner­halb des Stu­dios gelöst wer­den können. 

Nach­teile des Ein­sat­zes eines exter­nen ETL-Werkzeuges

Die Funk­ti­ons­weise der ETL-Stre­cken lässt sich mit Inte­gra­ti­ons-Test bzw. End-to-End-Tests, bei denen alle rele­van­ten Inputs gemockt wer­den und ein vor­her defi­nier­tes Ergeb­nis geprüft wird, tes­ten. Der Ein­satz von Unit-Test, um klei­nere Ein­hei­ten inner­halb der Jobs zu tes­ten, ist aller­dings nicht mög­lich und kann bei kom­ple­xen Pro­zes­sen ein Pro­blem dar­stel­len, da nicht alle ein­zel­nen Kom­po­nen­ten getes­tet wer­den kön­nen. Hier muss indi­vi­du­ell ent­schie­den wer­den, ob der Vor­teil ein gra­phi­sches Ent­wick­lungs-Werk­zeug nut­zen zu kön­nen durch den Nach­teil keine voll­stän­dige Test­ab­de­ckung zu errei­chen auf­ge­ho­ben wird.

Wei­ter­hin wer­den durch den Ein­satz von Tal­end neue Fähig­kei­ten im Team benö­tigt. Diese müs­sen ent­we­der neu auf­ge­baut oder durch neue Ent­wick­ler erbracht wer­den. Hier kann nicht pau­schal beur­teilt wer­den, ob diese zusätz­li­chen Kos­ten durch die ent­ste­hen­den Vor­teile auf­ge­wo­gen werden. 

Fazit

Wenn das not­wen­dige Know­how bereit­ge­stellt wer­den kann und der Ver­zicht auf Unit-Tests mög­lich ist, bie­tet Tal­end DI ein mäch­ti­ges gra­phi­sches Werk­zeug kom­plexe ETL-Pro­zesse in einem exter­nen Java-Pro­jekt umzu­set­zen. Es gibt eine große Com­mu­nity, die viele frei kon­fi­gu­rier­bare Kom­po­nen­ten bereit­stellt. Diese ver­ein­fa­chen den Ent­wick­lungs-Pro­zess deut­lich und unter­stüt­zen alle gän­gi­gen Tech­no­lo­gien und erfül­len alle Anfor­de­run­gen an ETL-Pro­zesse. Dabei inte­griert sich Tal­end DI sehr gut in vor­han­dene Java-Infrastruktur und bie­tet (fast) alle Frei­hei­ten, die man auch mit einer Code basier­ten Imple­men­tie­rung von ETL-Stre­cken errei­chen kann. 

Erfah­ren Sie hier mehr über Lösun­gen im Bereich Data Manage­ment oder besu­chen Sie eines unse­rer kos­ten­lo­sen Web­i­nare.