sascha@4111: FLYS-AFT:
sascha@4111: """""""""
sascha@4110: 
sascha@4111: Der FLYS-AFT-ETL-Prozessor aktualisiert eine FLYS-Datenbank mithilfe
tom@8679: eines DIPS-XML-Exports und einer AFT-Datenbank in Bezug auf Pegel und
sascha@4111: Abflusstafeln.
sascha@4111: 
sascha@4111: Vorbedingungen:
sascha@4111: ---------------
sascha@4111: 
sascha@4111:     * Es existiert ein DIPS-XML-Export unter einen erreichbaren Pfad
sascha@4111:       im Dateisystem.
sascha@4111: 
sascha@4111:     * Es existiert eine AFT-Datenbank mit bekannten Credentials.
sascha@4111: 
sascha@4111:     * Es existiert eine FLYS-Datenbank mit bekannten Credentials.
sascha@4111: 
sascha@4113: Bau:
sascha@4113: ----
tom@8834:    * Maven (>= 2) sollte installiert sein und im Pfad liegen.
sascha@4113: 
sascha@4113:      $ mvn --version
sascha@4113:      Sollte Versionsinformationen ausgeben.
sascha@4113: 
tom@9719:    * Für den Oracle-kompatiblen Bau kann dann folgendes
sascha@4113:      aufgerufen werden:
sascha@4113: 
tom@8835:      $ mvn -f pom-oracle.xml clean package assembly:single
sascha@4113: 
tom@8835:      Das Archiv target/river-etl-1.0-SNAPSHOT-bin.tar.gz kann dann an den Ort
tom@8835:      der Installation verschoben und schließlich entpackt werden:
tom@8835: 
tom@8835:      $ tar xzf river-etl-1.0-SNAPSHOT-bin.tar.gz
sascha@4113: 
sascha@4113:    * Folgendes führt das fertige Programm dann aus:
sascha@4113: 
tom@8835:      $ river-etl-1.0-SNAPSHOT/bin/run.sh
sascha@4113: 
sascha@4111: Konfiguration:
sascha@4111: --------------
sascha@4111: 
tom@8834: Zur Konfiguration wird eine Konfigurations-Datei benötigt. Diese wird
tom@8834: standardmäßig im aktuellen Arbeitsverzeichnis unter dem Namen 'config.xml'
sascha@4111: gesucht. Der Pfad zu dieser Datei kann allerdings auch mit der
sascha@4111: System-Property config.file gesetzt werden.
sascha@4111: Dies geschieht über den Kommandozeilenparameter "-Dconfig.file=/pfad/zur/config.xml"
tom@8837: im Start-Skript bin/run.sh oder als Parameter zu diesem Skript.
tom@9726: Als zweiter Parameter kann eine log4j-Konfigurations-Datei gegeben werden.
sascha@4111: 
sascha@4111: Die Konfigurationsdatei hat folgende Struktur:
sascha@4111: 
aheinecke@4943:  1 <?xml version="1.0" encoding="UTF-8"?>
aheinecke@4943:  2 <sync>
aheinecke@4943:  3   <!-- If modified send messages -->
aheinecke@4943:  4   <notifications>
aheinecke@4943:  5     <notifaction url="http://example.com">
aheinecke@4943:  6       <caches>
aheinecke@4943:  7         <cache name="my-cache"/>
aheinecke@4943:  8       </caches>
aheinecke@4943:  9     </notifaction>
aheinecke@4943: 10   </notifications>
aheinecke@4943: 11   <!-- The path to the DiPs file -->
aheinecke@4943: 12   <dips>
aheinecke@4943: 13     <file>/the/path/to/the/dips/file</file>
aheinecke@4943: 14     <repair>/the/path/to/the/xslt/to/repair/dips</repair>
aheinecke@4943: 15   </dips>
aheinecke@4943: 16   <!-- The FLYS side -->
aheinecke@4943: 17   <side name="flys">
aheinecke@4943: 18     <db>
aheinecke@4943: 19       <driver>oracle.jdbc.OracleDriver</driver>
aheinecke@4943: 20       <user>flys</user>
aheinecke@4943: 21       <password>flys</password>
aheinecke@4943: 22       <url>jdbc:oracle:thin:@//localhost:1521/XE</url>
aheinecke@4943: 23     </db>
aheinecke@4943: 24   </side>
aheinecke@4943: 25   <!-- The AFT side -->
aheinecke@4943: 26   <side name="aft">
aheinecke@4943: 27     <db>
aheinecke@4943: 28       <driver>oracle.jdbc.OracleDriver</driver>
aheinecke@4943: 29       <user>aft</user>
aheinecke@4943: 30       <password>aft</password>
aheinecke@4943: 31       <url>jdbc:oracle:thin:@//localhost:1521/XE</url>
aheinecke@4943: 32       <execute-login>
aheinecke@4943: 33         <statement>ALTER SESSION SET CURRENT_SCHEMA=AFT</statement>
aheinecke@4943: 34       </execute-login>
aheinecke@4943: 35     </db>
aheinecke@4943: 36   </side>
aheinecke@4943: 37 </sync>
sascha@4111: 
sascha@4111: Sie besteht aus vier Bereichen:
sascha@4111: 
sascha@4111:   * DIPS:
sascha@4111:     Zeile 13: Pfad zur XML-Datei mit dem DIPS-Export
sascha@4111:     Zeile 14: Pfad zur Reparatur-XSL-Transformation (s.u.).
sascha@4111:                Dieser ist optional.
sascha@4111:   * FLYS:
sascha@4111:     Zeile 19: JDBC-Treiber für den Zugriff auf die FLYS-Datenbank
sascha@4111:     Zeile 20: DB-Nutzername
sascha@4111:     Zeile 21: Connection-URL zur FLYS-Datenbank
sascha@4111: 
sascha@4111:   * AFT:
sascha@4111:     Zeile 28: JDBC-Treiber für den Zugriff auf die AFT-Datenbank
sascha@4111:     Zeile 29: DB-Nutzername
sascha@4111:     Zeile 30: Connection-URL zur AFT-Datenbank
sascha@4111: 
aheinecke@4943:   * Schemata:
aheinecke@4943:     Zeile 32-34: Schema in welches die Daten geschrieben werden sollen.
aheinecke@4943: 
sascha@4111:   * Benachrichtigungen:
sascha@4111:     Zeile    5: URL des Web-Service, der benachrichtigt werden soll.
sascha@4111:     Zeile 6-18: Die Nachricht, die an den Web-Service verschickt werden soll.
aheinecke@4943: 
sascha@4111: Funktionsweise:
sascha@4111: ---------------
sascha@4111: 
sascha@4111:     Als erstes wird die DIPS-Datei geladen. Ist angegeben, dass
sascha@4111:     eine Reparatur-XSL-Transformation auf diese angewendet werden
tom@8679:     soll, wird diese ebenfalls geladen und auf das DIPS-Dokument
teichmann@5857:     angewandt.
sascha@4111: 
sascha@4111:     !!! Hinweis: Unter doc/repair.xsl findet sich eine Beispiel-Transformation,
tom@8679:     !!! die mithilfe von doc/pegelstationen.xml für die Flüsse
sascha@4111:     !!! Saar, Mosel und Elbe die Pegelnummern der FLYS-Pegel
tom@8679:     !!! auf die Pegelnummern von Pegel-Online anpasst.
sascha@4111: 
tom@8679:     Die so vor-behandelten DIPS-Daten werden mit der AFT-Datenbank
tom@7818:     verbunden. Verbindungspunkt ist hierbei die Pegelnummer
tom@7818:     ("NUMMER" in DIPS, "MESSSTELLE.MESSSTELLE_NR" in AFT), die
sascha@4111:     in beiden Systemen gleich sein muss.
sascha@4111: 
sascha@4111:     Wurde für einzelne Pegel die Verbindung zwischen AFT und DIPS
sascha@4111:     erfolgreich hergestellt, wird versucht mit der entsprechenden
tom@7818:     Pegelnummer auch eine Verbindung zu FLYS herzustellen.
sascha@4111: 
sascha@4111:     Werden Pegel in AFT und DIPS gefunden, die sich nicht in FLYS befinden,
tom@8679:     werden diese in FLYS angelegt (mit Station "STATIONIERUNG",
tom@7818:     Pegelnullpunkt "PNP" und Einzugsgebietsgröße
tom@7818:     "EINZUGSGEBIET_AEO" aus DIPS) und mit den Abflusstafeln aus AFT
sascha@4111:     gefüllt.
sascha@4111: 
tom@8766:     Werden Pegel in AFT, DIPS und FLYS gefunden, so werden die Abflusstafeln
sascha@4111:     in FLYS mithilfe von AFT aktualisiert. Die Verbindung der Abflusstafeln
sascha@4111:     wird über deren Bezeichner hergestellt:
sascha@4111: 
sascha@4111:        AFT:  "ABFLUSSTAFEL.ABFLUSSTAFEL_BEZ"
tom@8679:        FLYS: "discharge_tables.description"
sascha@4111: 
sascha@4111:     Für alle vorhandenen Paare von AFT/FLYS-Abflusstafeln werden
sascha@4111:     die W/Q-Werte abgeglichen und FLYS entsprechend aktualisiert.
sascha@4111:     Abflusstafeln, die in FLYS noch nicht vorhanden sind, werden
sascha@4111:     in FLYS übernommen.
sascha@4111: 
tom@8766:     Um Inkonsistenzen in FLYS zu vermeiden, müssen zusätzlich bestimmte
tom@8766:     Bedingungen erfüllt sein, damit der Abgleich korrekt stattfinden kann.
tom@7818:     So muss etwa der Name des Gewässers in DIPS ("GEWAESSER") auch im Namen des
tom@8679:     Gewässers in FLYS ("rivers.name") enthalten sein, sowie der Pegel an einer
tom@8679:     für das Gewässer gültigen Station ("STATIONIERUNG" in DIPS) liegen.
tom@7818:     Die im Folgenden dokumentierten
aheinecke@7349:     Fehlermeldungen geben über derartige Probleme Auskunft.
aheinecke@7349: 
sascha@4111:     Wenn es nach dem Abgleich der AFT- und FLYS-DB eine Veränderung
sascha@4111:     in FLYS gegeben hat, können an konfigurierbare Web-Dienste
sascha@4111:     Nachrichten verschickt werden, dass sich Daten geändert haben.
tom@8679:     Die FLYS-Applikation selbst besitzt einen Dienst, der aufgerufen
tom@8766:     werden kann, um dessen interne Caches zu invalidieren.
sascha@4111:     Dies vermeidet Dateninkonsistenzen.
sascha@4110: 
sascha@4110: Fehlermeldungen:
sascha@4110: ================
sascha@4110: 
tom@8679: Während die Synchronisationsprozesses können verschiedene Fehler
sascha@4111: auftreten.
sascha@4111: 
sascha@4110: Allgemein:
sascha@4110: ----------
sascha@4110: 
sascha@4110: SYNC: syncing failed.
sascha@4110: 
tom@8679:     Während der Synchronisation ist ein Fehler aufgetreten. Details
sascha@4110:     finden sich in der Regel oberhalb dieser Fehlermeldung.
sascha@4110: 
sascha@4110: REPAIR: Cannot open DIPS repair XSLT file.
teichmann@5857: 
sascha@4110:     Die zur Reparatur angegebene XSL-Transformation konnte nicht geladen
sascha@4110:     werden.
sascha@4110: 
sascha@4110: REPAIR: Fixing DIPS failed.
sascha@4110: 
sascha@4110:     Die Anwendung der XSL-Transformation zur Reparatur der DIPS-Daten
tom@8679:     ist fehlgeschlagen. Details hierzu sollten sich oberhalb dieser
sascha@4110:     Fehlermeldung zu finden sein.
sascha@4110: 
sascha@4110: Benachrichtigung:
sascha@4110: -----------------
sascha@4110: 
sascha@4110: NOTIFY: Invalid URL '<URL>'. Ignored.
sascha@4110: 
sascha@4110:     Die zur Benachrichtigung angegebene URL ist nicht valide und
sascha@4110:     wird daher ignoriert.
sascha@4110: 
sascha@4110: NOTIFY: '<URL>' is not an HTTP(S) connection.
sascha@4110: 
tom@8679:     Die zur Benachrichtigung angegebene URL öffnet keine
sascha@4110:     HTTP- bzw. HTTPS-Verbindung.
sascha@4110: 
sascha@4110: NOTIFY: Sending message to '<URL>' failed.
sascha@4110: 
sascha@4110:     Der Versand der Benachrichtigung an die URL ist fehlgeschlagen.
sascha@4110: 
sascha@4110: DIPS:
sascha@4110: -----
sascha@4110: 
sascha@4110: DIPS: MESSSTELLE '<NAME>' not found in DIPS. Gauge number used for lookup: <NUMMER>
sascha@4110: 
sascha@4110:     Es wurde vergeblich versucht, mithilfe einer AFT-Pegelnummer in DIPS
sascha@4110:     ein entsprechendes Gegenstück zu finden.
sascha@4110: 
sascha@4110: DIPS: MESSSTELLE '<NAME>' is assigned to river '<FLUSS1>'. Needs to be on '<FLUSS2>'.
sascha@4110: 
sascha@4110:     Aus Sicht von AFT wird Messstelle <NAME> an <FLUSS2> erwartet.
sascha@4110:     DIPS ordnet sie aber <FLUSS1> zu.
sascha@4110: 
sascha@4110: DIPS: Gauge '<PEGEL>' has no datum. Ignored.
sascha@4110: 
sascha@4110:     Der DIPS-Pegel <PEGEL> hat keinen PNP und kann deshalb nicht
sascha@4110:     importiert werden.
sascha@4110: 
sascha@4110: DIPS: Setting AEO of gauge '<NAME>' to zero.
sascha@4110: 
sascha@4110:     Der AEO-Wert ist bei dem DIPS-Pegel <NAME> nicht gesetzt und
sascha@4110:     wird mit Null angenommen.
sascha@4110: 
sascha@4110: DIPS: Setting station of gauge '<NAME>' to zero.
sascha@4110: 
sascha@4110:     Der DIPS-Pegel '<NAME>' hat keine zugeordnete Stationierung und
sascha@4110:     es wird angenommen, dass dieser an km 0 liegt.
sascha@4110: 
sascha@4110: DIPS: Station of gauge '<NAME>' is zero.
sascha@4110: 
sascha@4110:     Im Regelfall ist ein Stationierung an km 0 ein Datenfehler.
sascha@4110: 
sascha@4110: DIPS: Cannot find '<DATEINAME>'.
sascha@4110: 
sascha@4110:     Der Pfad zum XML-Dokument mit den DIPS-Daten konnte nicht gefunden
sascha@4110:     werden.
sascha@4110: 
sascha@4110: DIPS: Cannot load DIPS document.
tom@8679: 
sascha@4110:     Das XML-Dokument mit den DIPS-Daten konnte nicht geladen werden.
sascha@4110: 
sascha@4110: DIPS: '<NAME2>' collides with '<NAME1>' on gauge number <NUMMER>.
sascha@4110: 
sascha@4110:     In DIPS gibt es zwei Pegel mit NAME1 und NAME2, die dieselbe Pegelnummer
sascha@4110:     haben.
sascha@4110: 
sascha@4110: DIPS: Gauge '<NAME>' has invalid gauge number '<NUMBER>'.
sascha@4110: 
sascha@4110:     Der DIPS-Pegel Name hat eine Pegelnummer <NUMMER>, die sich nicht
tom@8679:     in einen 64bit-Integer verwandeln lässt.
sascha@4110: 
aheinecke@7217: DIPS: Skipping Gauge: '<NAME>' because it is at Station: <pos> and the
aheinecke@7217: river is limited to: <fromkm> - <tokm>
aheinecke@7217: 
aheinecke@7217:     Der DIPS Pegel wurde nicht eingelesen da seine Stationierung
aheinecke@7217:     nicht mit den Fluss Kilometern in FLYS übereinstimmt. In einer
tom@8679:     darauf folgenden Meldung wird geloggt das dieser Pegel nicht in
aheinecke@7217:     DIPS vorhanden ist (da er nicht eingelesen wurde).
aheinecke@7217: 
sascha@4110: AFT:
sascha@4110: ----
sascha@4110: 
sascha@4110: AFT: ABFLUSSTAFEL_NR = <NUMMER>: <GUELTIG_VON> > <GUELTIG_BIS>. -> swap
sascha@4110: 
sascha@4110:     Eine AFT-Abflusstafel hat vertauschte GUELTIG_VON- und GUELTIG_BIS-Werte.
sascha@4110:     Diese werden implizit in die zeitlich richtige Reihenfolge gebracht.
sascha@4110: 
sascha@4110: FLYS/AFT: Value duplication w=<W> q=<Q>. -> ignore.
sascha@4110: 
sascha@4110:     Beim Laden einer Abflusstafel wurden ein W/Q-Duplikat entdeckt
sascha@4110:     und ignoriert.
sascha@4110: 
sascha@4110: AFT: Invalid MESSSTELLE_NR for MESSSTELLE '<NAME>':
sascha@4110: 
sascha@4110:     Die Messtellen-Nummer für die Messtelle <NAME> ist ungültig.
sascha@4110:     Erwartet wird ein String, der sich in einen 64bit-Integer umwandeln lässt.
sascha@4110: 
sascha@4110: AFT: Found discharge table '<BESCHREIBUNG>' with same description. -> ignore.
sascha@4110: 
sascha@4110:     In AFT wurde eine Abflusstafel gefunden, die die gleiche Bezeichnung
sascha@4110:     trägt wie eine andere, die demselben Pegel zugeordnet ist. Somit
sascha@4110:     ist keine eindeutige Zuordnung möglich.
sascha@4110: 
sascha@4110: FLYS:
sascha@4110: -----
sascha@4110: 
sascha@4110: FLYS: Found discharge table '<BESCHREIBUNG>' with same description. -> ignore
sascha@4110: 
sascha@4110:     In FLYS wurde eine Abflusstafel gefunden, die die gleiche Bezeichnung
sascha@4110:     trägt wie eine andere, die demselben Pegel zugeordnet ist. Somit
sascha@4110:     ist keine eindeutige Zuordnung möglich.
sascha@4110: 
sascha@4110: FLYS: Gauge '<PEGEL>' has no official number. Ignored.
sascha@4110: 
tom@8679:     Der Pegel <PEGEL> in FLYS hat keinen Pegelnummer und wird deshalb
sascha@4110:     nicht in Betracht gezogen.
sascha@4110: 
sascha@4110: FLYS: Gauge '<PEGEL>' number is not found in AFT/DIPS.
sascha@4110: 
sascha@4110:     Der Pegel <PEGEL> hat eine Pegelnummer, die aber nicht in AFT/DIPS
sascha@4110:     zu finden ist.
sascha@4110: 
sascha@4110: FLYS: discharge table <ID> has no description. Ignored.
sascha@4110: 
sascha@4110:     Die Abflusstafel in FLYS hat keine Beschreibung. Diese wird
sascha@4110:     allerdings zum Abgleich mit DIPS/AFT benötigt.
sascha@4110: 
sascha@4110: FLYS: Found discharge table '<BESCHREIBUNG>' with same description. -> ignore
sascha@4110: 
sascha@4110:     In FLYS wurde eine Abflusstafel gefunden, die die gleiche Bezeichnung
sascha@4110:     trägt wie eine andere, die demselben Pegel zugeordnet ist. Somit
sascha@4110:     ist keine eindeutige Zuordnung möglich.
sascha@4110: 
sascha@4110: FLYS: Gauge '<PEGEL>' has no official number. Ignored.
sascha@4110: 
tom@8679:     Der Pegel <PEGEL> in FLYS hat keinen Pegelnummer und wird deshalb
sascha@4110:     nicht in Betracht gezogen.
sascha@4110: 
sascha@4110: FLYS: Gauge '<PEGEL>' number is not found in AFT/DIPS.
sascha@4110: 
sascha@4110:     Der Pegel <PEGEL> hat eine Pegelnummer, die aber nicht in AFT/DIPS
sascha@4110:     zu finden ist.
sascha@4110: 
sascha@4110: FLYS: discharge table <ID> has no description. Ignored.
sascha@4110: 
sascha@4110:     Die Abflusstafel in FLYS hat keine Beschreibung. Diese wird
sascha@4110:     allerdings zum Abgleich mit DIPS/AFT benötigt.