Upload der BA ZIP Dateien hinzugefügt

This commit is contained in:
2026-05-13 16:17:03 +02:00
parent a099d28113
commit c74e49e11b
5 changed files with 83 additions and 17 deletions

View File

@@ -16,16 +16,22 @@ public interface OciConfig {
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.
*/
String tenantPrefix();
/**
* Prefix für eingehende Dateien unterhalb von {@code tenantPrefix},
* z.B. {@code eingang/}. Muss mit {@code /} enden.
* Gemeinsamer Basis-Prefix für alle BA-Eingangs-Pfade unterhalb von {@code tenantPrefix},
* 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}. */
String tenancyId();
@@ -49,4 +55,32 @@ public interface OciConfig {
* Muss mit der APEX Automation und dem ORDS-Package abgestimmt sein.
*/
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();
}
}

View File

@@ -19,6 +19,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Year;
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);
for (FileEntry entry : files) {
String key = buildKey(context.zipNameWithoutExt, entry.relativePath);
String key = buildKorrespondenzenKey(context.zipNameWithoutExt, entry.relativePath);
entry.ociKey = key;
putFile(key, context.localExtractDir.resolve(entry.relativePath), entry.fileSize);
Log.infof("Datei hochgeladen: %s (%d Bytes)", key, entry.fileSize);
}
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.
* Wird erst nach dem SFTP-Rename zu {@code .processed} aufgerufen, damit Marker und
* SFTP-Zustand immer konsistent sind: Marker vorhanden ↔ ZIP bereits als verarbeitet markiert.
* Wird erst nach dem SFTP-Delete aufgerufen, damit Marker und
* 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
* @throws OciException bei Verbindungs- oder Upload-Fehlern
*/
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);
putMarker(markerKey);
context.markerUploaded = true;
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) {
return buildPrefix(zipNameWithoutExt) + relativePath;
private String buildKorrespondenzenPrefix(String zipNameWithoutExt) {
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 {

View File

@@ -130,6 +130,11 @@ public class FileProcessingPipeline {
Log.infof("ZIP '%s' heruntergeladen (%d Bytes)", zipFilename,
Files.size(context.localZipPath));
// --- OCI ZIP-Archiv ---
MDC.put("step", "oci-zip-archive");
Log.info("Starte ZIP-Upload in OCI");
ociUploadService.uploadZipFile(context);
// --- Entpacken ---
MDC.put("step", "zip-extract");
zipExtractionService.extract(context);