Error handling verbessert und OCI Verbindungsaufbau Problem behoben
This commit is contained in:
@@ -38,7 +38,6 @@ public class OciUploadService {
|
||||
.tenantId(config.tenancyId())
|
||||
.userId(config.userId())
|
||||
.fingerprint(config.fingerprint())
|
||||
.region(com.oracle.bmc.Region.fromRegionId(config.region()))
|
||||
.privateKeySupplier(() -> {
|
||||
try {
|
||||
return Files.newInputStream(Path.of(config.privateKeyPath()));
|
||||
@@ -48,22 +47,23 @@ public class OciUploadService {
|
||||
}
|
||||
})
|
||||
.build();
|
||||
|
||||
Log.info("Authentifizierung...");
|
||||
this.client = ObjectStorageClient.builder().build(auth);
|
||||
Log.info("Auhtentifizierung...");
|
||||
client = ObjectStorageClient.builder()
|
||||
.endpoint("https://objectstorage." + config.region() + ".oraclecloud.com")
|
||||
.build(auth);
|
||||
Log.infof("OCI ObjectStorage-Client initialisiert (Region: %s, Bucket: %s)", config.region(), config.bucket());
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt alle Dateien aus {@code context.extractedFiles} sowie den Marker in OCI hoch.
|
||||
* Dateien mit {@code isMarker = true} werden übersprungen — der Marker wird separat
|
||||
* am Ende hochgeladen, um sicherzustellen dass er erst nach allen Dateien erscheint.
|
||||
* Lädt alle Nutzdateien aus {@code context.extractedFiles} in OCI hoch — ohne Marker.
|
||||
* Der Marker wird erst nach dem SFTP-Rename zu {@code .processed} gesetzt (siehe
|
||||
* {@link #uploadMarker}), damit APEX Automation den Batch nie verarbeitet bevor die
|
||||
* ZIP-Datei auf dem SFTP als verarbeitet markiert ist.
|
||||
*
|
||||
* @param context enthält die Liste der hochzuladenden Dateien und den Ziel-Prefix
|
||||
* @throws OciException bei Verbindungs- oder Upload-Fehlern
|
||||
*/
|
||||
public void upload(ProcessingContext context) throws OciException {
|
||||
Log.info("OCI Upload gestartet.");
|
||||
public void uploadFiles(ProcessingContext context) throws OciException {
|
||||
List<FileEntry> files = context.extractedFiles.stream()
|
||||
.filter(e -> !e.isMarker)
|
||||
.toList();
|
||||
@@ -77,13 +77,24 @@ public class OciUploadService {
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @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());
|
||||
Log.infof("Lade Marker hoch: '%s'", markerKey);
|
||||
uploadMarker(markerKey);
|
||||
|
||||
putMarker(markerKey);
|
||||
context.markerUploaded = true;
|
||||
Log.infof("OCI-Upload abgeschlossen: %d Datei(en) + Marker in '%s'",
|
||||
files.size(), buildPrefix(context.zipNameWithoutExt));
|
||||
Log.infof("Marker hochgeladen: '%s'", markerKey);
|
||||
}
|
||||
|
||||
private String buildPrefix(String zipNameWithoutExt) {
|
||||
@@ -108,7 +119,7 @@ public class OciUploadService {
|
||||
}
|
||||
}
|
||||
|
||||
private void uploadMarker(String key) throws OciException {
|
||||
private void putMarker(String key) throws OciException {
|
||||
try (InputStream is = InputStream.nullInputStream()) {
|
||||
client.putObject(PutObjectRequest.builder()
|
||||
.namespaceName(config.namespace())
|
||||
|
||||
@@ -69,6 +69,8 @@ public class FileProcessingPipeline {
|
||||
executor.submit(() -> {
|
||||
try {
|
||||
processAll();
|
||||
} catch (Exception e) {
|
||||
Log.errorf(e, "Unerwarteter Fehler im Pipeline-Lauf");
|
||||
} finally {
|
||||
isRunning.set(false);
|
||||
}
|
||||
@@ -91,6 +93,7 @@ public class FileProcessingPipeline {
|
||||
|
||||
if (zipFiles.isEmpty()) {
|
||||
Log.info("Keine neuen ZIP-Dateien auf dem SFTP-Server gefunden");
|
||||
Log.info("Pipeline-Lauf abgeschlossen");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -122,17 +125,24 @@ public class FileProcessingPipeline {
|
||||
Log.infof("ZIP '%s' entpackt: %d Datei(en)", zipFilename,
|
||||
context.extractedFiles.size());
|
||||
|
||||
// --- OCI Upload ---
|
||||
// --- OCI Upload (Dateien, noch kein Marker) ---
|
||||
MDC.put("step", "oci-upload");
|
||||
context.status = ProcessingStatus.PARTIALLY_UPLOADED;
|
||||
Log.info("Starte OCI-Upload");
|
||||
ociUploadService.upload(context);
|
||||
context.status = ProcessingStatus.MARKER_UPLOADED;
|
||||
ociUploadService.uploadFiles(context);
|
||||
|
||||
// --- SFTP Rename → .processed ---
|
||||
// Erst nach erfolgreichem Datei-Upload — Marker kommt danach,
|
||||
// damit Marker-Präsenz in OCI ↔ ZIP bereits .processed auf SFTP.
|
||||
MDC.put("step", "sftp-rename");
|
||||
sftpService.renameFile(zipFilename, zipFilename + ".processed");
|
||||
|
||||
// --- OCI Marker ---
|
||||
// Signalisiert der DB-Verarbeitung, dass der Batch vollständig hochgeladen ist.
|
||||
MDC.put("step", "oci-marker");
|
||||
ociUploadService.uploadMarker(context);
|
||||
context.status = ProcessingStatus.MARKER_UPLOADED;
|
||||
|
||||
// --- ORDS Notify ---
|
||||
MDC.put("step", "ords-notify");
|
||||
ordsNotificationService.triggerDbProcessing(context);
|
||||
@@ -140,14 +150,19 @@ public class FileProcessingPipeline {
|
||||
context.status = ProcessingStatus.ORDS_NOTIFIED;
|
||||
Log.infof("Verarbeitung erfolgreich abgeschlossen: '%s'", zipFilename);
|
||||
|
||||
} catch (SftpException | ZipException | OciException | OrdsException e) {
|
||||
Log.errorf(e, "Verarbeitung von '%s' fehlgeschlagen: %s", zipFilename, e.getMessage());
|
||||
} catch (ZipException e) {
|
||||
Log.errorf(e, "Ungültige ZIP-Datei '%s' — wird zu .error umbenannt", zipFilename);
|
||||
context.status = ProcessingStatus.FAILED;
|
||||
tryRenameToError(zipFilename);
|
||||
} catch (SftpException | OciException | OrdsException e) {
|
||||
Log.errorf(e, "Verarbeitung von '%s' fehlgeschlagen (Infrastruktur): %s", zipFilename, e.getMessage());
|
||||
context.status = ProcessingStatus.FAILED;
|
||||
} catch (IOException e) {
|
||||
Log.errorf(e, "I/O-Fehler bei der Verarbeitung von '%s'", zipFilename);
|
||||
context.status = ProcessingStatus.FAILED;
|
||||
tryRenameToError(zipFilename);
|
||||
} catch (RuntimeException e) {
|
||||
Log.errorf(e, "Unerwarteter Laufzeitfehler bei der Verarbeitung von '%s'", zipFilename);
|
||||
context.status = ProcessingStatus.FAILED;
|
||||
} finally {
|
||||
postProcessingCleanup(context);
|
||||
long durationSeconds = Duration.between(context.startTime, LocalDateTime.now()).toSeconds();
|
||||
|
||||
Reference in New Issue
Block a user