package de.galabau.dateieingang.api; import de.galabau.dateieingang.config.ApplicationConfig; import de.galabau.dateieingang.pipeline.FileProcessingPipeline; import io.quarkus.logging.Log; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import java.util.Map; /** * REST-Endpunkt für den Dateieingang-Trigger. * Wird von der APEX Automation stündlich per HTTP POST aufgerufen (fire & forget). */ @Path("/api/process-incoming") @ApplicationScoped public class FileProcessingResource { @Inject ApplicationConfig config; @Inject FileProcessingPipeline pipeline; /** * Nimmt einen Trigger von der APEX Automation entgegen und startet die Pipeline asynchron. * Gibt sofort {@code 202 Accepted} zurück — Fehler in der Pipeline landen im Log. * * @param apiKey API-Key aus dem Header {@code X-Api-Key} * @return 202 bei erfolgreichem Start, 401 bei fehlendem/falschem Key, 409 wenn Pipeline läuft */ @POST @Produces(MediaType.APPLICATION_JSON) public Response triggerProcessing(@HeaderParam("X-Api-Key") String apiKey) { if (apiKey == null || !config.api().key().equals(apiKey)) { Log.warn("Trigger abgelehnt — ungültiger oder fehlender API-Key"); return Response.status(Response.Status.UNAUTHORIZED).build(); } boolean started = pipeline.tryProcessAllAsync(); if (!started) { return Response.status(409) .entity(Map.of("message", "Pipeline läuft bereits")) .build(); } Log.info("Pipeline-Trigger akzeptiert, Verarbeitung startet im Hintergrund"); return Response.accepted() .entity(Map.of("message", "Pipeline gestartet")) .build(); } }