Ein­füh­rung

Infor­ma­tica ist der Markt­füh­rer unter den Anbie­tern von Daten­in­te­gra­ti­ons­soft­ware und viele Unter­neh­men ver­trauen beim Extra­hie­ren, Trans­fe­rie­ren und Laden von Daten der Werk­zeug­pa­lette, die Infor­ma­tica bie­tet. Im ent­spre­chen­den Gart­ner-Qua­dran­ten haben Sie seit vie­len Jah­ren die Spit­zen­po­si­tion inne.

Die Mög­lich­kei­ten der Ver­si­ons­kon­trolle, die Infor­ma­tica Power­Cen­ter [1] zum Nachverfolgen/Rückabwickeln von Ent­wick­lungs­schrit­ten inner­halb eines Repo­si­to­ries oder zum Deployen von Ände­run­gen in z.B. Test- oder Pro­duk­ti­ons­um­ge­bun­gen bie­tet, sind jedoch etwas unhand­lich. Wenn man in Infor­ma­tica Power­Cen­ter die Ver­sio­nie­rung nutzt, dann führt dies dazu, dass von jedem Objekt (map­pings, tar­gets, sources etc.) jede Ver­sion gespei­chert wird und sich ledig­lich der object sta­tus ändert. Dar­ge­stellt wird nur das jeweils aktive Objekt und wenn man ein nicht akti­ves Objekt wie­der akti­vie­ren möchte, dann muss man sei­nen Sta­tus wie­der auf Active set­zen. Dies führt dann aber zu Namens­kon­flik­ten, wenn die zuvor aktive Ver­sion des Objekts nicht zuerst auf Delete gesetzt oder umbe­nannt wurde. Die­ses Vor­ge­hen bedeu­tet auch, dass jede ein­ge­checkte Ver­sion kom­plett gespei­chert wird. Diese Art der Ver­sio­nie­rung bedarf natür­lich ungleich mehr Spei­cher­platz und War­tungs­auf­wand, da nicht mehr benö­tigte Ver­sio­nen gelöscht wer­den müs­sen. Dau­er­haf­tes Löschen wird von Infor­ma­tica als Purge bezeich­net, in Abgren­zung zum Delete, wodurch eine Ver­sion nur inak­ti­viert wird. Eine ein­mal gelöschte Ver­sion eines Objek­tes ist dann aber auch dau­er­haft verloren.

Die Ver­sio­nie­rungs­lö­sung von Infor­ma­tica Power­Cen­ter erlaubt grund­sätz­lich auch das Ver­tei­len von Ent­wick­lungs­schrit­ten auf z.B. eine Inte­gra­ti­ons-/Test-/Pro­duk­ti­ons­um­ge­bung über soge­nannte Deploy­ment Groups. Die Nut­zung von dyna­mi­schen Deploy­ment Groups ermög­licht es dem Nut­zer auf Grund­lage einer Query die Objekte zusam­men­zu­stel­len, die von der Deploy­ment Group erfasst wer­den sol­len. Dyna­misch bedeu­tet hier­bei, dass die Query zum Zeit­punkt des Deploy­ments aus­ge­führt wird und die Grund­lage für das Deploy­ment bil­det. Aller­dings gilt es hier­bei genau auf die Abhän­gig­kei­ten von Child und Parent Objek­ten zu ach­ten. Für die Extrak­tion von ver­sio­nier­ten Objek­ten müs­sen zusätz­lich Labels ver­wen­det wer­den, um die kor­rekte Ver­sion zu iden­ti­fi­zie­ren. Dies kann zu Pro­ble­men füh­ren, da die Label, die zur Iden­ti­fi­zie­rung von ver­sio­nier­ten Parent und Child Objek­ten ver­wen­det wer­den, ihre Syn­chro­ni­zi­tät ver­lie­ren kön­nen. [2] Im Ide­al­fall kann jedoch auf diese Weise vom Ent­wick­lungs­re­po­si­tory per Query eine Deploy­ment Group erstellt und extra­hiert wer­den, die sich dann auf einer ande­ren Umge­bung wie­der ein­bin­den lässt.

Zusam­men­fas­send lässt sich sagen, dass die Ver­sio­nie­rung von Infor­ma­tica auf jeden Fall res­sour­cen­in­ten­siv ist und zudem ein hohes Maß an Dis­zi­plin beim Ver­wal­ten der Abhän­gig­kei­ten und Namens­ge­bun­gen bzw. der Labels erfordert.

Infor­ma­tica bie­tet zwar die Mög­lich­keit über einen wei­te­ren Ser­vice, das soge­nannte Model Repo­si­tory, Git anzu­bin­den, bzw. die Objekte des Model Repo­si­to­ries zusätz­lich in einem loka­len oder auch glo­ba­len Git Repo­si­tory abzu­le­gen, jedoch ist hier­bei nicht vor­ge­se­hen, eigene Ent­wick­lungs­zweige zu erstel­len und ser­ver­über­grei­fend Ände­run­gen an Objek­ten zu ver­wal­ten und zu ver­tei­len. Zudem benö­tigt jedes Repo­si­tory sein eige­nes Model Repo­si­tory, wel­ches wie­derum jeweils ein eige­nes Git Repo­si­tory anbin­det. Git dient hier eher zur Ver­wal­tung einer zusätz­li­chen Siche­rungs­ko­pie und zum Sper­ren von Objek­ten des Model Repo­si­to­ries, da ver­hin­dert wer­den kann, dass meh­rere Ent­wick­ler gleich­zei­tig an einem Objekt arbei­ten.[3]

Die Alter­na­tive

Eine alter­na­tive Mög­lich­keit der Ver­sio­nie­rung von Infor­ma­tica-Repo­si­tory-Objek­ten soll im Fol­gen­den vor­ge­stellt und erläu­tert werden.

Grund­le­gend lässt sich jedes Objekt in einem Infor­ma­tica Repo­si­tory als XML-Datei expor­tie­ren. Es ist also nahe­lie­gend, eine Ver­sio­nie­rung der XML-Dateien vor­zu­neh­men, die zuvor aus einem Repo­si­tory expor­tiert wurden.

Die benö­tig­ten Pro­gramme sind alle in Python ent­wi­ckelt und nut­zen im Wesent­li­chen das Infor­ma­tica Befehls­zei­len­pro­gramm pmrep [4], wel­ches grund­le­gende Funk­tio­na­li­tä­ten im Umgang mit den Repo­si­to­ries bereit­stellt. So las­sen sich z.B. Objekte auf­lis­ten, als XML-Datei expor­tie­ren, Ord­ner erstel­len oder löschen, Ver­bin­dun­gen zu Repo­si­to­ries her­stel­len, etc.

Die eigent­li­che Her­aus­for­de­rung für die Ent­wick­lung einer sinn­vol­len Ver­sio­nie­rungs­lö­sung ist der Umgang mit den XML-Dateien, die expor­tiert wer­den. Dazu muss man sich zunächst die Struk­tur der expor­tier­ten XML-Dateien ver­ge­gen­wär­ti­gen und ver­ste­hen, wel­che Infor­ma­tio­nen auf wel­che Weise in den XML-Expor­ten steckt.

Gehen wir von einem Repo­si­tory „Beispiel_Repository“ aus. Neh­men wir nun an, dass an einem Map­ping gear­bei­tet wurde, wel­ches in einem Work­flow zur Anwen­dung kommt. Wenn ein Export die­ses Work­flows durch­ge­führt wird, dann wer­den, je nach Export­ein­stel­lun­gen, die unter­schied­lichs­ten Trans­for­ma­tio­nen, Sources, Tar­gets, Map­pings, Mapp­lets, etc. im XML zusam­men­ge­fasst. Unter der Annahme, dass die betrof­fe­nen Objekte in den Repo­si­tory-Ord­nern „SPAM“, „EGGS“und „BACON“ gespei­chert sind, könnte ein XML-Export eine Struk­tur wie in Abbil­dung 1 dar­ge­stellt auf­zei­gen. Der Export besteht aus Ele­men­ten, die zur all­ge­mei­nen Beschrei­bung des Repo­si­to­ries die­nen und aus Ele­men­ten, die die betrof­fe­nen Repo­si­tory-Ord­ner und deren Inhalt darstellen.

Es wird sofort ersicht­lich, dass es nicht sinn­voll wäre, die­sen XML-Export zu ver­sio­nie­ren, da die Infor­ma­tion zum einen repo­si­to­ry­spe­zi­fisch ist und zum ande­ren die Ele­mente des XMLs diverse Objekt­in­for­ma­tio­nen aus unter­schied­lichs­ten Repo­si­tory-Ord­nern erfas­sen und deren Rei­hen­folge von dem expor­tier­ten Work­flow selbst abhängt. Das bedeu­tet, dass in einem ande­ren Export die glei­che Source Defi­ni­tion, die in dem Bei­spiel-Export im Fol­der „BACON“ ent­hal­ten ist, erfasst sein kann. Somit wäre die Infor­ma­tion über ein und die­selbe Source in zwei ver­schie­de­nen XML-Expor­ten vor­han­den. Diese XML-Exporte wären dann auf jeden Fall unter­schied­lich und damit auch für ein Ver­sio­nie­rungs­tool, wie z.B. git. Das die Source Defi­ni­tion in bei­den Expor­ten exakt gleich sein kann und sich somit zwi­schen den bei­den Expor­ten die Source Defi­ni­tion nicht geän­dert hat, wäre damit nicht erfassbar.

+-------------------------------------------------------------------------------+
| Exemplarischer und gekürzter Auszug eines XML-Exports. Bis auf die Namen der  |   
| Folder sind alle Attribute der einzelnen Elemente entfernt worden, um die     |
| Struktur des XML-Exports zu veranschaulichen                                  |
+-------------------------------------------------------------------------------+

<?xml version="1.0" encoding="UTF-8"?>
<DOCTYPE POWERMART SYSTEM "powrmart.dtd">
<POWERMART CREATION_DATE="12/10/2020 14:44:29" REPOSITORY_VERION="123.456">
<REPOSITORY NAME="Beispiel_Repository" VERSION="123" CODEPAGE="UTF-8" DATATYPE="Oracle">

<FOLDER NAME="SPAM">
    <TARGET>
        <TARGETFIELD/>
    </TARGET>
    <TRANSFORMATION>
        <TRANSFORMFIELD/>
        ...
        <TABLEATTRIBUTE/>
        ...
    </TRANSFORMATION>
    <MAPPING>
        <TRANSFORMATION>
            <TRANSFORMFIELD/>
            ...
            <TABLEATTRIBUTE/>
            ...
        </TRANSFORMATION>
        <INSTANCE/>
        <CONNECTOR/>
        <TARGETLOADORDER/>
        <MAPPINGVARIABLE/>
    </MAPPING>
    <SHORTCUT/>
</FOLDER>

<FOLDER NAME="EGGS">
    <TARGET>
        <TARGETFIELD/>
    </TARGET>
    <TRANSFORMATION>
        <TRANSFORMFIELD/>
        ...
        <TABLEATTRIBUTE/>
        ...
    </TRANSFORMATION>
    <MAPPLET>
        <TRANSFORMATION>
            <TRANSFORMFIELD/>
            ...
            <TABLEATTRIBUTE/>
            ...
        </TRANSFORMATION>
        <INSTANCE/>
        <CONNECTOR/>
        <TARGETLOADORDER/>
        <MAPPINGVARIABLE/>
    </MAPPLET>
</FOLDER>

<FOLDER NAME="BACON">
    <SOURCE>
        <SOURCEFIELD/>
    </SOURCE>
</FOLDER>

</REPOSITORY>
</POWERMART>

Sequen­zie­ren und Sortieren

Im Kern ist also das Pro­blem der XML-Exporte, dass ein Export diverse Infor­ma­tio­nen des Repo­si­to­rys zusam­men­ge­fasst dar­stellt. An die­ser Stelle kann jedoch ein­ge­grif­fen wer­den und Hilfs­pro­gramme kön­nen ent­wi­ckelt wer­den, die die Exporte sequen­zie­ren, sor­tie­ren und in geeig­ne­ter Weise als XML-Bau­steine abspeichern.

Eine sinn­volle Ord­ner­struk­tur, in der die sequen­zier­ten und sor­tier­ten XML-Dateien abge­legt wer­den und die dann auch mit git ver­sio­niert wer­den kann, ori­en­tiert sich an der Ord­ner­struk­tur des Repo­si­to­rys. Das heißt, man benö­tigt, wenn in unse­rem Bei­spiel das Repo­si­tory zusätz­lich zu den Ord­nern „SPAM“, „EGGS“ und „BACON“, die Ord­ner „SAUSAGE“und „BEANS“ ent­hält, ein zu ver­sio­nie­ren­des Ver­zeich­nis – nen­nen wir es „ETL_Repo“, mit den Unter­ord­nern „SPAM“, „EGGS“, „BACON, „SAUSAGE“ und „BEANS“. Jeder Ord­ner beinhal­tet wie­derum die Struk­tu­ren des Infor­ma­tica Repo­si­to­rys, also jeweils einen Ord­ner für z.B. Work­flows, Trans­for­ma­ti­ons, Tar­gets, Sources, Short­cuts, Mapp­lets, Map­pings usw.

Wenn nun mit den Hilfs­pro­gram­men ein XML-Export eines Work­flows, des gan­zen Ord­ners, oder des gesam­ten Repo­si­to­rys ange­sto­ßen wird, so wird der eigent­li­che Export direkt sequen­ziert und sor­tiert auf die ein­zel­nen Ord­ner auf­ge­teilt. In Abbil­dung 2 ist dies gra­fisch für das Bei­spiel aus Abbil­dung 1 verdeutlicht.

Serverübergreifende Versionskontrolle Bild2
Abbil­dung 2 Ord­ner­struk­tur und gra­fi­sche Dar­stel­lung der XML-Sortierung

Die­ses Vor­ge­hen sorgt dafür, dass bei einem Export unter­schied­lichs­ter Ele­mente immer nur dann im ver­sio­nier­ten Ord­ner (ETL_Repo) eine Ände­rung erfasst wird, wenn sich auch tat­säch­lich inhalt­lich etwas an den expor­tier­ten Ele­men­ten geän­dert hat. Eine Beson­der­heit stel­len die Attri­bute der „Fol­der“- und „Repository“-Elemente, die in Abbil­dung 2 magen­ta­far­ben mar­kiert sind, dar. Diese Infor­ma­tio­nen gehö­ren in der ver­sio­nier­ten Ord­ner­struk­tur in den jewei­li­gen Ord­ner und kön­nen z.B. sehr gut als JSON-Datei erfasst werden.

Ein wei­te­rer Vor­teil die­ser Art der Ver­sio­nie­rung und Aufbereitung der XMLs ist die Fle­xi­bi­li­tät, die sich ergibt, wenn Ände­run­gen auf andere Repo­si­to­ries auf ande­ren Ser­vern über­tra­gen wer­den sol­len. In Ergän­zung zu einem Export-Pro­gramm, wel­ches direkt sequen­ziert und sor­tiert, benö­tigt man natür­lich auch ein Import-Pro­gramm, wel­ches die Infor­ma­tio­nen in dem git Repo­si­tory „ETL_Repo“ wie­der in das eigent­li­che Infor­ma­tica Repo­si­tory lädt. Hier spielt die JSON-Datei „repository_info.json“ eine wich­tige Rolle. In die­sem JSON ist der Name des expor­tier­ten Repo­si­to­rys ent­hal­ten. Wenn man an die­ser Stelle mit Platz­hal­tern arbei­tet, ermög­licht dies, den Repo­si­tory-Namen, der bei einem Import genutzt wer­den soll, in einer con­fig Datei auf dem jewei­li­gen Ser­ver abzu­le­gen und dyna­misch bei einem Import in die XML-Datei ein­zu­bauen. Auf diese Weise las­sen sich Ände­run­gen an einem Repo­si­tory, die auf einer Ent­wick­lungs­um­ge­bung gemacht wur­den, sehr kom­for­ta­bel in eine Test- oder Pro­duk­ti­ons­um­ge­bung ein­spie­len. Ebenso erhöht die­ses Vor­ge­hen die Fle­xi­bi­li­tät der Ent­wick­ler, da man z.B. auf zwei ver­schie­de­nen Ent­wick­lungs­ser­vern und Repo­si­to­ries arbei­ten kann und seine jewei­li­gen Ände­run­gen in einem eige­nen Zweig des git-Repo­si­to­rys ver­wal­ten kann.

Fazit

Infor­ma­tica Repo­si­to­ries kön­nen auf sinn­volle Weise ver­sio­niert wer­den. Um dies zu rea­li­sie­ren, muss ein­ma­lig ein erhöh­ten Pro­gram­mier­auf­wand betrie­ben wer­den, da geeig­nete Hilfs­pro­gramme erstellt wer­den müs­sen. Die Vor­teile lie­gen jedoch auf der Hand. Zum einen kann so auf die unter Umstän­den immense Ver­grö­ße­rung der Repo­si­tory-Daten­bank ver­zich­tet wer­den, da nicht jede Ände­rung gespei­chert wird, son­dern mit git die tat­säch­li­chen Ände­run­gen nach­ver­folgt und rück­ab­ge­wi­ckelt wer­den kön­nen und das volle Poten­zial von der Ent­wick­lung auf eige­nen Zwei­gen genutzt wer­den kann. Zum ande­ren erhöht das Vor­ge­hen die Fle­xi­bi­li­tät bei der Ent­wick­lung, da man Ände­run­gen auf unter­schied­lichste Repo­si­to­ries auf ver­schie­de­nen Ser­vern ver­tei­len kann.

1. Die Aus­sa­gen bezie­hen sich auf die Infor­ma­tica Power­Cen­ter Ver­sio­nen 10.2.0 bis 10.4.1