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:

ElementBeschreibungBeispielwert
:separatorDas Zeichen, das als Trennzeichen für die CSV-Spalten verwendet wird.","
:quoteDas Zeichen, das als Anführungszeichen für CSV-Werte verwendet wird, wenn sie ein Trennzeichen enthalten oder mit Leerzeichen beginnen/enden."\""
:encodingDie Zeichenkodierung, die zum Lesen der CSV-Dateien verwendet wird."UTF-8"
:localeDas Locale, das für die Konvertierung von Zahlen und Datumswerten verwendet wird."de_CH"
:job_nameDer Name des Importauftrags. Dieser Name wird verwendet, um den Job in Protokollen und Berichten zu identifizieren."import books initially"
:columnsEine 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]]
:invariantsEine 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-watchDer Pfad zu dem Verzeichnis, das überwacht wird."/tmp/cds-job-import"
:path-to-copy-toDer Pfad zu dem Verzeichnis, in das verarbeitete Dateien verschoben werden."/tmp/werner/interface/unibas-stock-import"
:files-to-watch-regexEin 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:

FeldTypBeschreibungWertebereich
idintegerEindeutiger Bezeichner für den Bestandsartikel. Dieser Wert wird automatisch inkrementiert.integer
created_attimestamp with time zoneZeitstempel, wann der Bestand erstellt wurde. Wird automatisch vom System gesetzt.timestamp
updated_attimestamp with time zoneZeitstempel, wann der Bestand zuletzt aktualisiert wurde.timestamp
archivedtimestamp with time zoneZeitstempel, wann der Bestand archiviert wurde. Wird gesetzt, wenn der Artikel gelöscht wird.timestamp
barcodecharacter varying(250)Barcode, der dem Bestandsartikel zugeordnet ist.Zeichenkette bis zu 250 Zeichen
article_idintegerPrimärschlüssel des Artikels, der mit diesem Bestandsartikel verbunden ist.integer
hostsystem_referencecharacter varying(250)Referenzbezeichner, der im Hostsystem verwendet wird.Zeichenkette bis zu 250 Zeichen
latitudeintegerBreitengrad für die Geolokalisierung des Bestandsartikels.integer
longitudeintegerLängengrad für die Geolokalisierung des Bestandsartikels.integer
net_weightnumeric(10,5)Gewicht des Bestandsartikels in Kilogramm. Dieser Wert ist eine Dezimalzahl mit fester Genauigkeit (numeric(10,5)).Dezimalzahl
net_volumenumeric(10,5)Volumen des Bestandsartikels in Kubikmetern. Dieser Wert ist eine Dezimalzahl mit fester Genauigkeit (numeric(10,5)).Dezimalzahl
dxnumeric(10,5)Länge des Bestandsartikels in Zentimetern.Dezimalzahl
dynumeric(10,5)Breite des Bestandsartikels in Zentimetern.Dezimalzahl
dznumeric(10,5)Höhe des Bestandsartikels in Zentimetern.Dezimalzahl
current_stock_location_idintegerBezeichner für den aktuellen Standort des Bestandsartikels im Lager.integer
locking_reason_idintegerBezeichner für den Grund, warum der Bestand gesperrt ist (z.B. reserviert, beschädigt).integer
authorcharacter varying(250)Autor des Buches (falls zutreffend).Zeichenkette bis zu 250 Zeichen
imprintcharacter varying(250)Untertitel des Buches (falls zutreffend).Zeichenkette bis zu 250 Zeichen
titletextTitel des Buches oder Bestandsartikels.Text
call_nocharacter varying(100)Signatur des Buches, auch bekannt als call number.Zeichenkette bis zu 100 Zeichen
year_of_publicationcharacter 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:

FeldBeschreibungWertebereich
idEindeutiger Bezeichner für den Bestandsartikel. Dieser Wert wird automatisch inkrementiert.integer
created_atZeitstempel, wann der Bestand erstellt wurde. Wird automatisch vom System gesetzt.timestamp
updated_atZeitstempel, wann der Bestand zuletzt aktualisiert wurde.timestamp
archivedZeitstempel, wann der Bestand archiviert wurde. Wird gesetzt, wenn der Artikel gelöscht wird.timestamp
net_weightGewicht des Bestandsartikels in Kilogramm. Dieser Wert wird als Dezimalzahl mit bis zu 5 Nachkommastellen dargestellt.Dezimalzahl
net_volumeVolumen des Bestandsartikels in Kubikmetern. Dieser Wert wird als Dezimalzahl mit bis zu 5 Nachkommastellen dargestellt.Dezimalzahl
dxLänge des Bestandsartikels in Zentimetern. Dieser Wert wird als Dezimalzahl mit fester Genauigkeit verarbeitet.Dezimalzahl
dyBreite des Bestandsartikels in Zentimetern. Dieser Wert wird als Dezimalzahl mit fester Genauigkeit verarbeitet.Dezimalzahl
dzHöhe des Bestandsartikels in Zentimetern. Dieser Wert wird als Dezimalzahl mit fester Genauigkeit verarbeitet.Dezimalzahl
current_stock_location_idBezeichner für den aktuellen Standort des Bestandsartikels im Lager.integer
locking_reason_idBezeichner für den Grund, warum der Bestand gesperrt ist (z.B. reserviert, beschädigt).integer
article_idPrimärschlüssel des Artikels, der mit diesem Bestandsartikel verbunden ist.integer
article/identBezeichner des Artikels, der mit diesem Bestandsartikel verbunden ist. Dieser Wert wird nur verwendet, wenn article_id fehlt.Zeichenkette
article/hostsystem_referenceReferenz des Artikels im Hostsystem. Dieser Wert wird nur verwendet, wenn article_id fehlt und muss eindeutig sein.Zeichenkette
latitudeBreitengrad für die Geolokalisierung des Bestandsartikels.Dezimalzahl
longitudeLängengrad für die Geolokalisierung des Bestandsartikels.Dezimalzahl
barcodeBarcode, der dem Bestandsartikel zugeordnet ist.Zeichenkette
authorAutor des Buches (falls zutreffend).Zeichenkette
hostsystem_referenceReferenzbezeichner, der im Hostsystem verwendet wird.Zeichenkette
imprintUntertitel des Buches (falls zutreffend).Zeichenkette
titleTitel des Buches oder Bestandsartikels.Text
call_noSignatur des Buches, auch bekannt als call number.Zeichenkette
year_of_publicationVeröffentlichungsjahr des Buches oder Bestandsartikels.Zeichenkette
:_toDeleteGibt 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"
    }
  ]
}
Previous
Rücklagern von Büchern