Upload der BA ZIP Dateien hinzugefügt
This commit is contained in:
@@ -15,7 +15,9 @@
|
|||||||
"WebFetch(domain:walidhajeri.hashnode.dev)",
|
"WebFetch(domain:walidhajeri.hashnode.dev)",
|
||||||
"Bash(find \"C:\\\\\\\\src\\\\\\\\Galabau\\\\\\\\glb-spielwiese\\\\\\\\automaton\" -name \"FileProcessingPipeline.java\")",
|
"Bash(find \"C:\\\\\\\\src\\\\\\\\Galabau\\\\\\\\glb-spielwiese\\\\\\\\automaton\" -name \"FileProcessingPipeline.java\")",
|
||||||
"PowerShell(Get-ChildItem -Path \"C:\\\\src\\\\Galabau\\\\glb-spielwiese\\\\quarkus-automaton\\\\src\\\\main\\\\java\" -Recurse | Where-Object { !$_.PSIsContainer } | Select-Object FullName)",
|
"PowerShell(Get-ChildItem -Path \"C:\\\\src\\\\Galabau\\\\glb-spielwiese\\\\quarkus-automaton\\\\src\\\\main\\\\java\" -Recurse | Where-Object { !$_.PSIsContainer } | Select-Object FullName)",
|
||||||
"PowerShell(cmd /c \"dir /s /b C:\\\\src\\\\Galabau\\\\glb-spielwiese\\\\quarkus-automaton\\\\src\\\\main\\\\java\")"
|
"PowerShell(cmd /c \"dir /s /b C:\\\\src\\\\Galabau\\\\glb-spielwiese\\\\quarkus-automaton\\\\src\\\\main\\\\java\")",
|
||||||
|
"Bash(Get-ChildItem -Path \"C:\\\\src\\\\Galabau\\\\glb-spielwiese\" -Directory)",
|
||||||
|
"Bash(Select-Object Name)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,16 +16,22 @@ public interface OciConfig {
|
|||||||
String bucket();
|
String bucket();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Root-Prefix für alle Objekte im Bucket, z.B. {@code mandant_42/}.
|
* Root-Prefix für alle Objekte im Bucket, z.B. {@code testmandant-42/}.
|
||||||
* Muss mit {@code /} enden.
|
* Muss mit {@code /} enden.
|
||||||
*/
|
*/
|
||||||
String tenantPrefix();
|
String tenantPrefix();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prefix für eingehende Dateien unterhalb von {@code tenantPrefix},
|
* Gemeinsamer Basis-Prefix für alle BA-Eingangs-Pfade unterhalb von {@code tenantPrefix},
|
||||||
* z.B. {@code eingang/}. Muss mit {@code /} enden.
|
* z.B. {@code BA/Eingang/}. Muss mit {@code /} enden.
|
||||||
*/
|
*/
|
||||||
String incomingKorrespondenzenPrefix();
|
String baBasePrefix();
|
||||||
|
|
||||||
|
/** Konfiguration für die BA-Korrespondenzen-Pipeline. */
|
||||||
|
Korrespondenzen korrespondenzen();
|
||||||
|
|
||||||
|
/** Konfiguration für die BA-Aufrechnungen-Pipeline. */
|
||||||
|
Aufrechnungen aufrechnungen();
|
||||||
|
|
||||||
/** OCI Tenancy OCID. Aus Env-Var {@code OCI_TENANCY_ID}. */
|
/** OCI Tenancy OCID. Aus Env-Var {@code OCI_TENANCY_ID}. */
|
||||||
String tenancyId();
|
String tenancyId();
|
||||||
@@ -49,4 +55,32 @@ public interface OciConfig {
|
|||||||
* Muss mit der APEX Automation und dem ORDS-Package abgestimmt sein.
|
* Muss mit der APEX Automation und dem ORDS-Package abgestimmt sein.
|
||||||
*/
|
*/
|
||||||
String markerFilenameDbProcessing();
|
String markerFilenameDbProcessing();
|
||||||
|
|
||||||
|
interface Korrespondenzen {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix für eingehende Korrespondenz-Dateien relativ zu {@code baBasePrefix},
|
||||||
|
* z.B. {@code Import/BA-Korrespondenzen/}. Muss mit {@code /} enden.
|
||||||
|
* Vollständiger Pfad: {@code tenantPrefix + baBasePrefix + incomingPrefix}.
|
||||||
|
*/
|
||||||
|
String incomingPrefix();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix für archivierte ZIP-Originaldateien relativ zu {@code baBasePrefix},
|
||||||
|
* z.B. {@code BA-Korrespondenzen ZIP-Dateien}. Kein abschließendes {@code /} —
|
||||||
|
* das aktuelle Jahr wird zur Laufzeit angehängt: {@code <prefix> <yyyy>/}.
|
||||||
|
* Vollständiger Pfad: {@code tenantPrefix + baBasePrefix + archivePrefix + " 2026/"}.
|
||||||
|
*/
|
||||||
|
String archivePrefix();
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Aufrechnungen {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix für eingehende Aufrechnungs-Dateien relativ zu {@code baBasePrefix},
|
||||||
|
* z.B. {@code Import/Aufrechnungen/}. Muss mit {@code /} enden.
|
||||||
|
* Vollständiger Pfad: {@code tenantPrefix + baBasePrefix + incomingPrefix}.
|
||||||
|
*/
|
||||||
|
String incomingPrefix();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.time.Year;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,38 +80,56 @@ public class OciUploadService {
|
|||||||
Log.infof("OCI-Upload: %d Datei(en) für '%s'", files.size(), context.zipNameWithoutExt);
|
Log.infof("OCI-Upload: %d Datei(en) für '%s'", files.size(), context.zipNameWithoutExt);
|
||||||
|
|
||||||
for (FileEntry entry : files) {
|
for (FileEntry entry : files) {
|
||||||
String key = buildKey(context.zipNameWithoutExt, entry.relativePath);
|
String key = buildKorrespondenzenKey(context.zipNameWithoutExt, entry.relativePath);
|
||||||
entry.ociKey = key;
|
entry.ociKey = key;
|
||||||
putFile(key, context.localExtractDir.resolve(entry.relativePath), entry.fileSize);
|
putFile(key, context.localExtractDir.resolve(entry.relativePath), entry.fileSize);
|
||||||
Log.infof("Datei hochgeladen: %s (%d Bytes)", key, entry.fileSize);
|
Log.infof("Datei hochgeladen: %s (%d Bytes)", key, entry.fileSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.infof("OCI-Upload Dateien abgeschlossen: %d Datei(en) in '%s'",
|
Log.infof("OCI-Upload Dateien abgeschlossen: %d Datei(en) in '%s'",
|
||||||
files.size(), buildPrefix(context.zipNameWithoutExt));
|
files.size(), buildKorrespondenzenPrefix(context.zipNameWithoutExt));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setzt den Marker in OCI — signalisiert der DB-Verarbeitung, dass der Batch vollständig ist.
|
* Setzt den Marker in OCI — signalisiert der DB-Verarbeitung, dass der Batch vollständig ist.
|
||||||
* Wird erst nach dem SFTP-Rename zu {@code .processed} aufgerufen, damit Marker und
|
* Wird erst nach dem SFTP-Delete aufgerufen, damit Marker und
|
||||||
* SFTP-Zustand immer konsistent sind: Marker vorhanden ↔ ZIP bereits als verarbeitet markiert.
|
* SFTP-Zustand immer konsistent sind: Marker vorhanden ↔ ZIP bereits vom SFTP gelöscht.
|
||||||
*
|
*
|
||||||
* @param context enthält den Ziel-Prefix für den Marker-Key
|
* @param context enthält den Ziel-Prefix für den Marker-Key
|
||||||
* @throws OciException bei Verbindungs- oder Upload-Fehlern
|
* @throws OciException bei Verbindungs- oder Upload-Fehlern
|
||||||
*/
|
*/
|
||||||
public void uploadMarker(ProcessingContext context) throws OciException {
|
public void uploadMarker(ProcessingContext context) throws OciException {
|
||||||
String markerKey = buildKey(context.zipNameWithoutExt, config.markerFilenameDbProcessing());
|
String markerKey = buildKorrespondenzenKey(context.zipNameWithoutExt, config.markerFilenameDbProcessing());
|
||||||
Log.infof("Lade Marker hoch: '%s'", markerKey);
|
Log.infof("Lade Marker hoch: '%s'", markerKey);
|
||||||
putMarker(markerKey);
|
putMarker(markerKey);
|
||||||
context.markerUploaded = true;
|
context.markerUploaded = true;
|
||||||
Log.infof("Marker hochgeladen: '%s'", markerKey);
|
Log.infof("Marker hochgeladen: '%s'", markerKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildPrefix(String zipNameWithoutExt) {
|
/**
|
||||||
return config.tenantPrefix() + config.incomingKorrespondenzenPrefix() + zipNameWithoutExt + "/";
|
* Lädt die Original-ZIP-Datei in den Archivordner in OCI hoch.
|
||||||
|
* Ziel-Key: {@code tenantPrefix + baBasePrefix + archivePrefix + " <Jahr>/" + zipFilename}
|
||||||
|
*
|
||||||
|
* @param context enthält den lokalen ZIP-Pfad und den Dateinamen
|
||||||
|
* @throws OciException bei Verbindungs- oder Upload-Fehlern
|
||||||
|
* @throws IOException bei Problemen beim Lesen der lokalen ZIP-Datei
|
||||||
|
*/
|
||||||
|
public void uploadZipFile(ProcessingContext context) throws OciException, IOException {
|
||||||
|
String yearFolder = config.korrespondenzen().archivePrefix() + " " + Year.now().getValue() + "/";
|
||||||
|
String key = config.tenantPrefix() + config.baBasePrefix() + yearFolder + context.zipFilename;
|
||||||
|
long fileSize = Files.size(context.localZipPath);
|
||||||
|
Log.infof("Lade ZIP-Archiv hoch: '%s' (%d Bytes)", key, fileSize);
|
||||||
|
putFile(key, context.localZipPath, fileSize);
|
||||||
|
Log.infof("ZIP-Archiv hochgeladen: '%s'", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildKey(String zipNameWithoutExt, String relativePath) {
|
private String buildKorrespondenzenPrefix(String zipNameWithoutExt) {
|
||||||
return buildPrefix(zipNameWithoutExt) + relativePath;
|
return config.tenantPrefix() + config.baBasePrefix()
|
||||||
|
+ config.korrespondenzen().incomingPrefix() + zipNameWithoutExt + "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildKorrespondenzenKey(String zipNameWithoutExt, String relativePath) {
|
||||||
|
return buildKorrespondenzenPrefix(zipNameWithoutExt) + relativePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putFile(String key, Path localFile, long fileSize) throws OciException {
|
private void putFile(String key, Path localFile, long fileSize) throws OciException {
|
||||||
|
|||||||
@@ -130,6 +130,11 @@ public class FileProcessingPipeline {
|
|||||||
Log.infof("ZIP '%s' heruntergeladen (%d Bytes)", zipFilename,
|
Log.infof("ZIP '%s' heruntergeladen (%d Bytes)", zipFilename,
|
||||||
Files.size(context.localZipPath));
|
Files.size(context.localZipPath));
|
||||||
|
|
||||||
|
// --- OCI ZIP-Archiv ---
|
||||||
|
MDC.put("step", "oci-zip-archive");
|
||||||
|
Log.info("Starte ZIP-Upload in OCI");
|
||||||
|
ociUploadService.uploadZipFile(context);
|
||||||
|
|
||||||
// --- Entpacken ---
|
// --- Entpacken ---
|
||||||
MDC.put("step", "zip-extract");
|
MDC.put("step", "zip-extract");
|
||||||
zipExtractionService.extract(context);
|
zipExtractionService.extract(context);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ galabau.sftp.password=${GALABAU_SFTP_PASSWORD:}
|
|||||||
# Fingerprint auf host: ssh-keyscan <host> | ssh-keygen -lf -
|
# Fingerprint auf host: ssh-keyscan <host> | ssh-keygen -lf -
|
||||||
galabau.sftp.host-key-fingerprint=${GALABAU_SFTP_HOST_KEY_FINGERPRINT:SHA256:xyz}
|
galabau.sftp.host-key-fingerprint=${GALABAU_SFTP_HOST_KEY_FINGERPRINT:SHA256:xyz}
|
||||||
# Verzeichnis auf dem SFTP-Server, in dem der Lieferant ZIP-Dateien ablegt
|
# Verzeichnis auf dem SFTP-Server, in dem der Lieferant ZIP-Dateien ablegt
|
||||||
galabau.sftp.remote-path=${GALABAU_SFTP_REMOTE_PATH:/bundesagenturfuerarbeit/austausch/dev/galaeingang}
|
galabau.sftp.remote-path=${GALABAU_SFTP_REMOTE_PATH:/bundesagenturfuerarbeit/austausch/sck-dev/galaeingang}
|
||||||
# Temporäres lokales Verzeichnis für Download + Entpacken — wird nach jeder ZIP bereinigt
|
# Temporäres lokales Verzeichnis für Download + Entpacken — wird nach jeder ZIP bereinigt
|
||||||
galabau.sftp.local-work-dir=/tmp/sftp-work
|
galabau.sftp.local-work-dir=/tmp/sftp-work
|
||||||
# galabau.sftp.private-key-path=/etc/secrets/sftp-key
|
# galabau.sftp.private-key-path=/etc/secrets/sftp-key
|
||||||
@@ -27,8 +27,14 @@ galabau.oci.region=${OCI_REGION}
|
|||||||
galabau.oci.bucket=${OCI_BUCKET}
|
galabau.oci.bucket=${OCI_BUCKET}
|
||||||
# Root-Prefix im Bucket, muss mit / enden
|
# Root-Prefix im Bucket, muss mit / enden
|
||||||
galabau.oci.tenant-prefix=${OCI_TENANT_PREFIX:testmandant-42/}
|
galabau.oci.tenant-prefix=${OCI_TENANT_PREFIX:testmandant-42/}
|
||||||
# Eingangs-Prefix unterhalb von tenant-prefix, muss mit / enden
|
# Gemeinsamer Basis-Prefix für alle BA-Eingangs-Pfade, muss mit / enden
|
||||||
galabau.oci.incoming-korrespondenzen-prefix=${OCI_INCOMING_FILES_PATH:BA/Eingang/Import/BA-Korrespondenzen/}
|
galabau.oci.ba-base-prefix=${OCI_BA_BASE_PREFIX:BA/Eingang/}
|
||||||
|
# BA-Korrespondenzen: Eingangs-Prefix relativ zu ba-base-prefix, muss mit / enden
|
||||||
|
galabau.oci.korrespondenzen.incoming-prefix=${OCI_KORRESPONDENZEN_INCOMING_PREFIX:Import/BA-Korrespondenzen/}
|
||||||
|
# BA-Korrespondenzen: Archiv-Prefix relativ zu ba-base-prefix — Jahr wird zur Laufzeit angehängt
|
||||||
|
galabau.oci.korrespondenzen.archive-prefix=${OCI_KORRESPONDENZEN_ARCHIVE_PREFIX:BA-Korrespondenzen ZIP-Dateien}
|
||||||
|
# BA-Aufrechnungen: Eingangs-Prefix relativ zu ba-base-prefix, muss mit / enden
|
||||||
|
galabau.oci.aufrechnungen.incoming-prefix=${OCI_AUFRECHNUNGEN_INCOMING_PREFIX:Import/Aufrechnungen/}
|
||||||
galabau.oci.tenancy-id=${OCI_TENANCY_ID}
|
galabau.oci.tenancy-id=${OCI_TENANCY_ID}
|
||||||
galabau.oci.user-id=${OCI_USER_ID}
|
galabau.oci.user-id=${OCI_USER_ID}
|
||||||
galabau.oci.fingerprint=${OCI_FINGERPRINT}
|
galabau.oci.fingerprint=${OCI_FINGERPRINT}
|
||||||
|
|||||||
Reference in New Issue
Block a user