122 lines
4.9 KiB
Java
122 lines
4.9 KiB
Java
package de.galabau.dateieingang.oci;
|
|
|
|
import com.oracle.bmc.auth.SimpleAuthenticationDetailsProvider;
|
|
import com.oracle.bmc.objectstorage.ObjectStorage;
|
|
import com.oracle.bmc.objectstorage.ObjectStorageClient;
|
|
import com.oracle.bmc.objectstorage.requests.PutObjectRequest;
|
|
import de.galabau.dateieingang.config.OciConfig;
|
|
import de.galabau.dateieingang.exception.OciException;
|
|
import de.galabau.dateieingang.model.FileEntry;
|
|
import de.galabau.dateieingang.model.ProcessingContext;
|
|
import io.quarkus.logging.Log;
|
|
import jakarta.annotation.PostConstruct;
|
|
import jakarta.enterprise.context.ApplicationScoped;
|
|
import jakarta.inject.Inject;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Lädt die entpackten Dateien und den Marker in OCI Object Storage hoch.
|
|
* Authentifizierung via OCI HTTP Signature V1 (entspricht APEX Web Credential vom Typ OCI).
|
|
*/
|
|
@ApplicationScoped
|
|
public class OciUploadService {
|
|
|
|
@Inject
|
|
OciConfig config;
|
|
|
|
private ObjectStorage client;
|
|
|
|
@PostConstruct
|
|
void init() {
|
|
SimpleAuthenticationDetailsProvider auth = SimpleAuthenticationDetailsProvider.builder()
|
|
.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()));
|
|
} catch (IOException e) {
|
|
throw new RuntimeException("OCI Private Key nicht lesbar: "
|
|
+ config.privateKeyPath(), e);
|
|
}
|
|
})
|
|
.build();
|
|
|
|
this.client = ObjectStorageClient.builder().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.
|
|
*
|
|
* @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 {
|
|
List<FileEntry> files = context.extractedFiles.stream()
|
|
.filter(e -> !e.isMarker)
|
|
.toList();
|
|
|
|
Log.infof("OCI-Upload gestartet: %d Datei(en) für '%s'", files.size(), context.zipNameWithoutExt);
|
|
|
|
for (FileEntry entry : files) {
|
|
String key = buildKey(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);
|
|
}
|
|
|
|
String markerKey = buildKey(context.zipNameWithoutExt, config.markerFilenameDbProcessing());
|
|
Log.infof("Lade Marker hoch: '%s'", markerKey);
|
|
uploadMarker(markerKey);
|
|
|
|
context.markerUploaded = true;
|
|
Log.infof("OCI-Upload abgeschlossen: %d Datei(en) + Marker in '%s'",
|
|
files.size(), buildPrefix(context.zipNameWithoutExt));
|
|
}
|
|
|
|
private String buildPrefix(String zipNameWithoutExt) {
|
|
return config.tenantPrefix() + config.incomingPrefix() + zipNameWithoutExt + "/";
|
|
}
|
|
|
|
private String buildKey(String zipNameWithoutExt, String relativePath) {
|
|
return buildPrefix(zipNameWithoutExt) + relativePath;
|
|
}
|
|
|
|
private void putFile(String key, Path localFile, long fileSize) throws OciException {
|
|
try (InputStream is = Files.newInputStream(localFile)) {
|
|
client.putObject(PutObjectRequest.builder()
|
|
.namespaceName(config.namespace())
|
|
.bucketName(config.bucket())
|
|
.objectName(key)
|
|
.putObjectBody(is)
|
|
.contentLength(fileSize)
|
|
.build());
|
|
} catch (Exception e) {
|
|
throw new OciException("OCI-Upload fehlgeschlagen für '" + key + "'", e);
|
|
}
|
|
}
|
|
|
|
private void uploadMarker(String key) throws OciException {
|
|
try (InputStream is = InputStream.nullInputStream()) {
|
|
client.putObject(PutObjectRequest.builder()
|
|
.namespaceName(config.namespace())
|
|
.bucketName(config.bucket())
|
|
.objectName(key)
|
|
.putObjectBody(is)
|
|
.contentLength(0L)
|
|
.build());
|
|
} catch (Exception e) {
|
|
throw new OciException("OCI-Upload Marker fehlgeschlagen für '" + key + "'", e);
|
|
}
|
|
}
|
|
}
|