Schnittstellen
Einführung
Mit Hilfe dieses Dienstes können Bestände aus einem Dateisystem importiert werden. Die zu importierenden Bestände werden aufbereitet und der stock-API zugeführt. Ein Reporting des Importerfolges wird dauerhaft in der Tabelle task_log festgehalten.
Technische Details zur Funktionsweise des File-System-Watchers
Der Namespace werner-backend.crosscutting.interface.file-system-watch dient dazu, ein Verzeichnis zu überwachen und neue Dateien, die in dieses Verzeichnis abgelegt werden, zu verarbeiten. Nachfolgend sind die Hauptfunktionen und der Ablauf des Watchers aus der Sicht eines technischen Nutzers beschrieben:
1. Überwachung des Verzeichnisses
Der Watcher überwacht kontinuierlich ein angegebenes Verzeichnis (path-to-watch) auf das Auftreten neuer Dateien, die einem bestimmten Muster entsprechen (files-to-watch-regex-pattern). Sobald eine neue Datei erkannt wird, wird diese in eine Liste der Kandidaten-Dateien aufgenommen.
2. Überprüfung der Dateistabilität
Nachdem eine Datei als Kandidat erkannt wurde, überwacht der Watcher für eine festgelegte Zeitspanne (expected-time-of-file-being-of-constant-size), ob sich die Dateigröße ändert. Dies stellt sicher, dass die Datei vollständig geschrieben wurde und stabil ist, bevor mit der Verarbeitung begonnen wird.
3. Verschieben der Datei
Sobald die Datei als stabil erkannt wurde, wird sie in ein temporäres data-Verzeichnis innerhalb des definierten Verzeichnisses (path-to-copy-to) verschoben. Diese Verschiebung stellt sicher, dass die Originaldatei nicht weiter verändert wird, während sie verarbeitet wird.
4. Verarbeiten der Datei
Nach dem Verschieben in das data-Verzeichnis wird die Datei von einer benutzerdefinierten Lambda-Funktion (lambda) verarbeitet. Diese Funktion kann beliebige Aufgaben ausführen, wie z.B. das Parsen der Datei, das Extrahieren von Daten und das Übergeben dieser Daten an andere Systemkomponenten.
5. Abschluss der Verarbeitung
Nach erfolgreicher Verarbeitung wird die Datei in das save-Verzeichnis verschoben. Falls bei der Verarbeitung Fehler auftreten, wird die Datei stattdessen in das failure-Verzeichnis verschoben. Dies erleichtert die Fehlersuche und das erneute Verarbeiten fehlerhafter Dateien.
6. Beenden des Watchers
Der Watcher kann durch einen Aufruf der zurückgegebenen Lambda-Funktion (fn [] (reset! stop true)) gestoppt werden. Dies beendet die Überwachung des Verzeichnisses und alle damit verbundenen Hintergrundprozesse.
Zusammenfassung der Aufgaben:
- Überwachen eines Verzeichnisses: Der Watcher wartet auf neue Dateien in einem festgelegten Verzeichnis.
- Überprüfen der Dateistabilität: Der Watcher stellt sicher, dass Dateien vollständig geschrieben sind, bevor sie verarbeitet werden.
- Verschieben und Verarbeiten der Datei: Dateien werden in ein temporäres Verzeichnis verschoben und dort von einer benutzerdefinierten Funktion verarbeitet.
- Speichern oder Fehlerbehandlung: Verarbeitete Dateien werden entweder gespeichert oder bei Fehlern in ein Fehlerverzeichnis verschoben.
Durch diese Schritte stellt der File-System-Watcher sicher, dass Dateien zuverlässig und geordnet verarbeitet werden können, ohne dass es zu Inkonsistenzen oder Datenverlusten kommt.
Konfiguration
1. Die Konfiguration mittels .edn-Datei
Die Konfiguration des Dienstes erfolgt über eine .edn-Datei, welche verschiedene Spezifikationen enthält, die definieren, wie die Bestände importiert werden sollen. Jede Spezifikation in der .edn-Datei beschreibt eine bestimmte Importaufgabe, einschließlich des zu überwachenden Verzeichnisses, des CSV-Formats und der zu importierenden Datenfelder.
Der Dienst verwendet diese Konfigurationen, um Dateisystem-Überwachungen (File Watchers) einzurichten, die auf bestimmte Muster in Dateinamen achten und die Dateien entsprechend den gegebenen Spezifikationen verarbeiten. Die Ergebnisse des Importvorgangs, einschließlich Erfolg oder Fehler, werden in der task_log-Tabelle protokolliert.
2. Beispiel einer .edn-Spezifikation
Hier ist ein Beispiel einer .edn-Konfiguration, die zwei unterschiedliche Importaufgaben definiert:
{:server/jetty {:handler #ig/ref :werner/app :port 8080}
:werner/router {}
:werner/app {:jdbc-url #ig/ref :db/postgres :router #ig/ref :werner/router}
:werner/walkable-parser {:jdbc-url #ig/ref :db/postgres}
;; Dont need to set this here, werner-backend uses the docker container configuration
:db/postgres {}
:domain/job {:werner/app #ig/ref :werner/app}
:domain/device {:werner/app #ig/ref :werner/app}
:tasks/import_stocks_from_filesystem {
:db/postgres #ig/ref :db/postgres
:specs [{
:separator ","
:quote \"
:encoding "UTF-8"
:locale "de_CH" ;; Beispiel-LOCALE für die Schweiz (Deutsch)
:job_name "import books initially"
:columns [["PID" :hostsystem_reference :string]
["Barcode" :barcode :string]
["Call Number" :call_no :string]
["Title" :ident :string]
["Author" :author :string]
["Publication Date" :year_of_publication :string]]
:invariants {"article/ident" "Buch", :dy 30}
:path-to-watch "/tmp/cds-job-import"
:path-to-copy-to "/tmp/werner/interface/unibas-stock-import"
:files-to-watch-regex "\\._initial.*\\.csv"}
{
:job_name "import book updates"
:locale "en_US" ;; Beispiel-LOCALE für die Vereinigten Staaten
:columns [["PID" :hostsystem_reference :string]
["Barcode" :barcode :string]
["Call Number" :call_no :string]
["Title" :ident :string]
["Author" :author :string]
["Publication Date" :year_of_publication :string]]
:invariants {"article/ident" "Buch", :dy 30}
:path-to-watch "/tmp/cds-job-import"
:path-to-copy-to "/tmp/werner/interface/unibas-stock-import"
:files-to-watch-regex "\\._update.*\\.csv"}]}}
3. Elemente der Spezifikation
Die Spezifikationen in der .edn-Datei bestehen aus mehreren Schlüsseln, die die Konfiguration des Importprozesses steuern. Hier sind die wichtigsten Elemente der Spezifikation in einer Tabelle erläutert:
| Element | Beschreibung | Beispielwert |
|---|---|---|
:separator | Das Zeichen, das als Trennzeichen für die CSV-Spalten verwendet wird. | "," |
:quote | Das Zeichen, das als Anführungszeichen für CSV-Werte verwendet wird, wenn sie ein Trennzeichen enthalten oder mit Leerzeichen beginnen/enden. | "\"" |
:encoding | Die Zeichenkodierung, die zum Lesen der CSV-Dateien verwendet wird. | "UTF-8" |
:locale | Das Locale, das für die Konvertierung von Zahlen und Datumswerten verwendet wird. | "de_CH" |
:job_name | Der Name des Importauftrags. Dieser Name wird verwendet, um den Job in Protokollen und Berichten zu identifizieren. | "import books initially" |
:columns | Eine Liste von Spalten-Spezifikationen. Jede Spezifikation enthält den CSV-Spaltennamen, den Zielschlüssel und den Typ, in den der Wert konvertiert wird. | [["PID" :hostsystem_reference :string]] |
:invariants | Eine Map von festen Werten, die während des Imports auf jede Zeile angewendet werden. Diese Werte werden in die Struktur eingefügt, bevor sie an die API gesendet werden. | {"article/ident" "Buch", :dy 30} |
:path-to-watch | Der Pfad zu dem Verzeichnis, das überwacht wird. | "/tmp/cds-job-import" |
:path-to-copy-to | Der Pfad zu dem Verzeichnis, in das verarbeitete Dateien verschoben werden. | "/tmp/werner/interface/unibas-stock-import" |
:files-to-watch-regex | Ein regulärer Ausdruck, der bestimmt, welche Dateien im Verzeichnis überwacht und verarbeitet werden. | "\\._initial.*\\.csv" |
Strukturen
1. Datenbankstruktur von stock
Die folgende Tabelle zeigt die Struktur der stock-Tabelle, die für den Import verwendet wird:
| Feld | Typ | Beschreibung | Wertebereich |
|---|---|---|---|
id | integer | Eindeutiger Bezeichner für den Bestandsartikel. Dieser Wert wird automatisch inkrementiert. | integer |
created_at | timestamp with time zone | Zeitstempel, wann der Bestand erstellt wurde. Wird automatisch vom System gesetzt. | timestamp |
updated_at | timestamp with time zone | Zeitstempel, wann der Bestand zuletzt aktualisiert wurde. | timestamp |
archived | timestamp with time zone | Zeitstempel, wann der Bestand archiviert wurde. Wird gesetzt, wenn der Artikel gelöscht wird. | timestamp |
barcode | character varying(250) | Barcode, der dem Bestandsartikel zugeordnet ist. | Zeichenkette bis zu 250 Zeichen |
article_id | integer | Primärschlüssel des Artikels, der mit diesem Bestandsartikel verbunden ist. | integer |
hostsystem_reference | character varying(250) | Referenzbezeichner, der im Hostsystem verwendet wird. | Zeichenkette bis zu 250 Zeichen |
latitude | integer | Breitengrad für die Geolokalisierung des Bestandsartikels. | integer |
longitude | integer | Längengrad für die Geolokalisierung des Bestandsartikels. | integer |
net_weight | numeric(10,5) | Gewicht des Bestandsartikels in Kilogramm. Dieser Wert ist eine Dezimalzahl mit fester Genauigkeit (numeric(10,5)). | Dezimalzahl |
net_volume | numeric(10,5) | Volumen des Bestandsartikels in Kubikmetern. Dieser Wert ist eine Dezimalzahl mit fester Genauigkeit (numeric(10,5)). | Dezimalzahl |
dx | numeric(10,5) | Länge des Bestandsartikels in Zentimetern. | Dezimalzahl |
dy | numeric(10,5) | Breite des Bestandsartikels in Zentimetern. | Dezimalzahl |
dz | numeric(10,5) | Höhe des Bestandsartikels in Zentimetern. | Dezimalzahl |
current_stock_location_id | integer | Bezeichner für den aktuellen Standort des Bestandsartikels im Lager. | integer |
locking_reason_id | integer | Bezeichner für den Grund, warum der Bestand gesperrt ist (z.B. reserviert, beschädigt). | integer |
author | character varying(250) | Autor des Buches (falls zutreffend). | Zeichenkette bis zu 250 Zeichen |
imprint | character varying(250) | Untertitel des Buches (falls zutreffend). | Zeichenkette bis zu 250 Zeichen |
title | text | Titel des Buches oder Bestandsartikels. | Text |
call_no | character varying(100) | Signatur des Buches, auch bekannt als call number. | Zeichenkette bis zu 100 Zeichen |
year_of_publication | character varying(100) | Veröffentlichungsjahr des Buches oder Bestandsartikels. | Zeichenkette bis zu 100 Zeichen |
2. Requeststruktur
Die folgende Tabelle beschreibt die Struktur des Requests für die stock-API:
| Feld | Beschreibung | Wertebereich |
|---|---|---|
id | Eindeutiger Bezeichner für den Bestandsartikel. Dieser Wert wird automatisch inkrementiert. | integer |
created_at | Zeitstempel, wann der Bestand erstellt wurde. Wird automatisch vom System gesetzt. | timestamp |
updated_at | Zeitstempel, wann der Bestand zuletzt aktualisiert wurde. | timestamp |
archived | Zeitstempel, wann der Bestand archiviert wurde. Wird gesetzt, wenn der Artikel gelöscht wird. | timestamp |
net_weight | Gewicht des Bestandsartikels in Kilogramm. Dieser Wert wird als Dezimalzahl mit bis zu 5 Nachkommastellen dargestellt. | Dezimalzahl |
net_volume | Volumen des Bestandsartikels in Kubikmetern. Dieser Wert wird als Dezimalzahl mit bis zu 5 Nachkommastellen dargestellt. | Dezimalzahl |
dx | Länge des Bestandsartikels in Zentimetern. Dieser Wert wird als Dezimalzahl mit fester Genauigkeit verarbeitet. | Dezimalzahl |
dy | Breite des Bestandsartikels in Zentimetern. Dieser Wert wird als Dezimalzahl mit fester Genauigkeit verarbeitet. | Dezimalzahl |
dz | Höhe des Bestandsartikels in Zentimetern. Dieser Wert wird als Dezimalzahl mit fester Genauigkeit verarbeitet. | Dezimalzahl |
current_stock_location_id | Bezeichner für den aktuellen Standort des Bestandsartikels im Lager. | integer |
locking_reason_id | Bezeichner für den Grund, warum der Bestand gesperrt ist (z.B. reserviert, beschädigt). | integer |
article_id | Primärschlüssel des Artikels, der mit diesem Bestandsartikel verbunden ist. | integer |
article/ident | Bezeichner des Artikels, der mit diesem Bestandsartikel verbunden ist. Dieser Wert wird nur verwendet, wenn article_id fehlt. | Zeichenkette |
article/hostsystem_reference | Referenz des Artikels im Hostsystem. Dieser Wert wird nur verwendet, wenn article_id fehlt und muss eindeutig sein. | Zeichenkette |
latitude | Breitengrad für die Geolokalisierung des Bestandsartikels. | Dezimalzahl |
longitude | Längengrad für die Geolokalisierung des Bestandsartikels. | Dezimalzahl |
barcode | Barcode, der dem Bestandsartikel zugeordnet ist. | Zeichenkette |
author | Autor des Buches (falls zutreffend). | Zeichenkette |
hostsystem_reference | Referenzbezeichner, der im Hostsystem verwendet wird. | Zeichenkette |
imprint | Untertitel des Buches (falls zutreffend). | Zeichenkette |
title | Titel des Buches oder Bestandsartikels. | Text |
call_no | Signatur des Buches, auch bekannt als call number. | Zeichenkette |
year_of_publication | Veröffentlichungsjahr des Buches oder Bestandsartikels. | Zeichenkette |
:_toDelete | Gibt an, ob der Bestandsartikel archiviert werden soll. Dieser Wert wird nicht in der Datenbank gespeichert, sondern als transient betrachtet. | boolean |
Beispiel-Request
{
"updateKey": "hostsystem_reference",
"stocks": [
{
"hostsystem_reference": "12345",
"barcode": "A1001389689",
"call_no": "UBH BS 143:35",
"title": "Baltische Bibliographie 2000",
"author": "",
"year_of_publication": "2005"
}
]
}