Error handling verbessert und OCI Verbindungsaufbau Problem behoben
This commit is contained in:
@@ -110,7 +110,7 @@ quarkus-automaton/
|
||||
| `sftp-download` | `SftpService` | SSHJ | Lädt ZIP in lokales Arbeitsverzeichnis |
|
||||
| `zip-extract` | `ZipExtractionService` | Apache Commons Compress | Entpackt ZIP, preserviert Ordnerstruktur |
|
||||
| `oci-upload` | `OciUploadService` | OCI SDK | Lädt Dateien + Marker zu OCI Object Storage |
|
||||
| `sftp-rename` | `SftpService` | SSHJ | Remote-Rename zu `.processed` oder `.error` |
|
||||
| `sftp-rename` | `SftpService` | SSHJ | Remote-Rename zu `.processed` (bei Erfolg) oder `.error` (nur bei ungültiger ZIP) |
|
||||
| `ords-notify` | `OrdsNotificationService` | MicroProfile REST Client | Ruft ORDS-Endpunkt auf |
|
||||
| `cleanup` | `FileProcessingPipeline` | pure Java | Löscht lokale Arbeitsdateien (ZIP + entpackte Dateien) |
|
||||
|
||||
@@ -244,14 +244,14 @@ n8n fire-and-forget-Verhalten.
|
||||
|
||||
### Fehlerklassen
|
||||
|
||||
| Fehler | Typ | Retry | Verhalten |
|
||||
| Fehler | Typ | Umbenennung | Verhalten |
|
||||
|---|---|---|---|
|
||||
| SFTP-Verbindung fehlgeschlagen | transient | nein | Nächster APEX-Lauf (1h) versucht es |
|
||||
| ZIP beschädigt | persistent | nein | ZIP auf SFTP umbenennen zu `.error`, Log |
|
||||
| OCI-Verbindung fehlgeschlagen (z.B. 503) | transient | ja (exponential backoff) | @Retry |
|
||||
| OCI-Upload einer Datei schlägt fehl | persistent | nein | SFTP-Rename zu `.error`, Log — bereits hochgeladene OCI-Dateien bleiben (idempotent) |
|
||||
| ORDS-Aufruf schlägt fehl | transient | ja (2-3x) | Marker liegt vor → APEX Automation schlägt beim nächsten Lauf ein |
|
||||
| Allgemein technischer Fehler | fallabhängig | siehe SmallRye Fault Tolerance | Exception-Log |
|
||||
| SFTP-Verbindung / Download fehlgeschlagen | transient | keine | Datei bleibt auf SFTP — nächster APEX-Lauf (1h) versucht es |
|
||||
| ZIP beschädigt / ungültig | persistent | → `.error` | Datei ist defekt, manuelle Prüfung nötig |
|
||||
| OCI-Verbindung fehlgeschlagen | transient | keine | Datei bleibt auf SFTP — nächster Lauf versucht erneut (OCI PUT idempotent) |
|
||||
| SFTP-Rename zu `.processed` fehlgeschlagen | transient | keine | ORDS wurde noch nicht aufgerufen (kommt danach) — kein Doppelimport; nächster Lauf wiederholt den Schritt |
|
||||
| ORDS-Aufruf schlägt fehl | transient | keine (`.processed` bereits gesetzt) | Marker liegt in OCI vor — APEX Automation findet ihn beim nächsten Lauf |
|
||||
| Unerwarteter Laufzeitfehler | fallabhängig | keine | Exception wird geloggt, Datei bleibt auf SFTP |
|
||||
|
||||
### Retry-Strategie (SmallRye Fault Tolerance)
|
||||
|
||||
@@ -309,17 +309,23 @@ Credentials, Fehlerbehandlung).
|
||||
Pipeline.processAll():
|
||||
1. SftpService.listZipFiles() → ["export_2026-04-08.zip", ...]
|
||||
2. für jede ZIP:
|
||||
a. SftpService.download(zip) → lokale Datei
|
||||
b. ZipExtractionService.extract() → ProcessingContext mit FileEntry-Liste
|
||||
c. OciUploadService.upload() → Dateien + Marker in OCI
|
||||
d. SftpService.renameRemote(.processed oder .error)
|
||||
e. OrdsNotificationService.notify()
|
||||
a. SftpService.download(zip) → lokale Datei
|
||||
b. ZipExtractionService.extract() → ProcessingContext mit FileEntry-Liste
|
||||
↳ ZipException → Rename zu .error, Abbruch
|
||||
c. OciUploadService.uploadFiles() → Dateien in OCI (noch kein Marker)
|
||||
d. SftpService.renameRemote(.processed)
|
||||
e. OciUploadService.uploadMarker() → Marker in OCI (erst nach Rename — siehe Invariante)
|
||||
f. OrdsNotificationService.notify()
|
||||
f. cleanup: lokale ZIP + Entpack-Verzeichnis löschen ← immer, auch bei Fehler
|
||||
```
|
||||
|
||||
**Cleanup (Schritt f) läuft immer** — in einem `finally`-Block — damit kein Disk-Vollaufen
|
||||
bei Fehlern oder großen ZIPs.
|
||||
|
||||
**Umbenennung zu `.error`** erfolgt ausschließlich bei `ZipException` (defekte/ungültige Datei).
|
||||
Bei Infrastrukturfehlern (SFTP, OCI, ORDS) bleibt die Datei unverändert auf dem SFTP und wird
|
||||
beim nächsten Lauf automatisch erneut verarbeitet.
|
||||
|
||||
---
|
||||
|
||||
## OCI-Authentifizierung (SimpleAuthenticationDetailsProvider)
|
||||
@@ -343,11 +349,13 @@ public class OciUploadService {
|
||||
.tenantId(config.tenancyId())
|
||||
.userId(config.userId())
|
||||
.fingerprint(config.fingerprint())
|
||||
.region(Region.fromRegionId(config.region()))
|
||||
.privateKeySupplier(new FilePrivateKeySupplier(config.privateKeyPath()))
|
||||
.privateKeySupplier(() -> Files.newInputStream(Path.of(config.privateKeyPath())))
|
||||
.build();
|
||||
|
||||
this.client = ObjectStorageClient.builder().build(auth);
|
||||
// Endpoint explizit setzen — verhindert blockierenden HTTP-Discovery-Call im SDK
|
||||
client = ObjectStorageClient.builder()
|
||||
.endpoint("https://objectstorage." + config.region() + ".oraclecloud.com")
|
||||
.build(auth);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -452,6 +460,12 @@ public class ProcessIncomingRequest {
|
||||
<artifactId>oci-java-sdk-objectstorage</artifactId>
|
||||
<version>3.44.0</version>
|
||||
</dependency>
|
||||
<!-- HTTP-Provider für OCI SDK (jersey3 = Jakarta EE 9+, kompatibel mit Quarkus) -->
|
||||
<dependency>
|
||||
<groupId>com.oracle.oci.sdk</groupId>
|
||||
<artifactId>oci-java-sdk-common-httpclient-jersey3</artifactId>
|
||||
<version>3.44.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- ZIP -->
|
||||
<dependency>
|
||||
|
||||
Reference in New Issue
Block a user