1
0

Optimierung: Anwendungskonfiguration auf Minimalbedarf zugeschnitten

This commit is contained in:
2026-04-05 09:45:31 +02:00
parent 7764a50308
commit 3657b0c3de
8 changed files with 103 additions and 146 deletions

View File

@@ -0,0 +1,20 @@
package de.gecheckt.pdf.umbenenner.application.config;
/**
* Minimal runtime configuration for the application layer.
* <p>
* Contains only the application-level runtime parameters that are needed during
* batch document processing. Technical infrastructure configuration (paths, API keys,
* persistence parameters, etc.) is kept in the bootstrap layer.
* <p>
* This intentionally small contract ensures the application layer depends only on
* the configuration values it actually uses, following hexagonal architecture principles.
*/
public record RuntimeConfiguration(
/**
* Maximum number of pages a document can have to be processed.
* Documents exceeding this limit are rejected during pre-checks.
*/
int maxPages
)
{ }

View File

@@ -1,6 +1,6 @@
package de.gecheckt.pdf.umbenenner.application.service;
import de.gecheckt.pdf.umbenenner.application.config.StartConfiguration;
import de.gecheckt.pdf.umbenenner.application.config.RuntimeConfiguration;
import de.gecheckt.pdf.umbenenner.domain.model.DocumentProcessingOutcome;
import de.gecheckt.pdf.umbenenner.domain.model.PreCheckFailed;
import de.gecheckt.pdf.umbenenner.domain.model.PreCheckFailureReason;
@@ -48,23 +48,23 @@ public class DocumentProcessingService {
*
* @param candidate the document candidate to process
* @param extractionResult the result from PDF extraction (from {@link de.gecheckt.pdf.umbenenner.application.port.out.PdfTextExtractionPort})
* @param configuration the startup configuration (used for pre-check validation)
* @param runtimeConfig the runtime configuration (used for pre-check validation)
* @return the complete processing outcome (implementing {@link DocumentProcessingOutcome})
* @throws NullPointerException if any parameter is null
*/
public static DocumentProcessingOutcome processDocument(
SourceDocumentCandidate candidate,
PdfExtractionResult extractionResult,
StartConfiguration configuration) {
RuntimeConfiguration runtimeConfig) {
Objects.requireNonNull(candidate, "candidate must not be null");
Objects.requireNonNull(extractionResult, "extractionResult must not be null");
Objects.requireNonNull(configuration, "configuration must not be null");
Objects.requireNonNull(runtimeConfig, "runtimeConfig must not be null");
return switch (extractionResult) {
case PdfExtractionSuccess success ->
// Extraction succeeded: evaluate pre-checks
PreCheckEvaluator.evaluate(candidate, success, configuration);
PreCheckEvaluator.evaluate(candidate, success, runtimeConfig);
case PdfExtractionContentError contentError ->
// PDF content not extractable: classify as pre-check failed (deterministic content error)

View File

@@ -1,6 +1,6 @@
package de.gecheckt.pdf.umbenenner.application.service;
import de.gecheckt.pdf.umbenenner.application.config.StartConfiguration;
import de.gecheckt.pdf.umbenenner.application.config.RuntimeConfiguration;
import de.gecheckt.pdf.umbenenner.domain.model.DocumentProcessingOutcome;
import de.gecheckt.pdf.umbenenner.domain.model.PreCheckFailureReason;
import de.gecheckt.pdf.umbenenner.domain.model.PreCheckFailed;
@@ -44,18 +44,18 @@ public class PreCheckEvaluator {
*
* @param candidate the source document metadata
* @param extraction the successfully extracted PDF content
* @param configuration the startup configuration (used for maxPages limit)
* @param runtimeConfig the runtime configuration (used for maxPages limit)
* @return the pre-check outcome: passed or failed with reason (both implement {@link DocumentProcessingOutcome})
* @throws NullPointerException if any parameter is null
*/
public static DocumentProcessingOutcome evaluate(
SourceDocumentCandidate candidate,
PdfExtractionSuccess extraction,
StartConfiguration configuration) {
RuntimeConfiguration runtimeConfig) {
Objects.requireNonNull(candidate, "candidate must not be null");
Objects.requireNonNull(extraction, "extraction must not be null");
Objects.requireNonNull(configuration, "configuration must not be null");
Objects.requireNonNull(runtimeConfig, "runtimeConfig must not be null");
// Pre-check 1: Verify document has usable text
if (!hasUsableText(extraction.extractedText())) {
@@ -66,7 +66,7 @@ public class PreCheckEvaluator {
}
// Pre-check 2: Verify document page count does not exceed configured limit
if (extraction.pageCount().exceedsLimit(configuration.maxPages())) {
if (extraction.pageCount().exceedsLimit(runtimeConfig.maxPages())) {
return new PreCheckFailed(
candidate,
PreCheckFailureReason.PAGE_LIMIT_EXCEEDED

View File

@@ -1,6 +1,6 @@
package de.gecheckt.pdf.umbenenner.application.usecase;
import de.gecheckt.pdf.umbenenner.application.config.StartConfiguration;
import de.gecheckt.pdf.umbenenner.application.config.RuntimeConfiguration;
import de.gecheckt.pdf.umbenenner.application.port.in.BatchRunOutcome;
import de.gecheckt.pdf.umbenenner.application.port.in.BatchRunProcessingUseCase;
import de.gecheckt.pdf.umbenenner.application.port.out.FingerprintPort;
@@ -77,7 +77,7 @@ import java.util.Objects;
*/
public class DefaultBatchRunProcessingUseCase implements BatchRunProcessingUseCase {
private final StartConfiguration configuration;
private final RuntimeConfiguration runtimeConfiguration;
private final RunLockPort runLockPort;
private final SourceDocumentCandidatesPort sourceDocumentCandidatesPort;
private final PdfTextExtractionPort pdfTextExtractionPort;
@@ -86,13 +86,13 @@ public class DefaultBatchRunProcessingUseCase implements BatchRunProcessingUseCa
private final ProcessingLogger logger;
/**
* Creates the batch use case with the already-loaded startup configuration and all
* required ports for the flow.
* Creates the batch use case with the runtime configuration and all required ports for the flow.
* <p>
* The configuration is loaded and validated by Bootstrap before use case creation;
* the use case receives the result directly and does not re-read the properties file.
* The runtime configuration contains only the application-level settings needed
* during batch processing. Technical infrastructure configuration (paths, persistence,
* API details, etc.) is managed by Bootstrap.
*
* @param configuration the validated startup configuration; must not be null
* @param runtimeConfiguration the runtime configuration containing application-level settings; must not be null
* @param runLockPort for exclusive run locking; must not be null
* @param sourceDocumentCandidatesPort for loading PDF candidates from the source folder;
* must not be null
@@ -106,14 +106,14 @@ public class DefaultBatchRunProcessingUseCase implements BatchRunProcessingUseCa
* @throws NullPointerException if any parameter is null
*/
public DefaultBatchRunProcessingUseCase(
StartConfiguration configuration,
RuntimeConfiguration runtimeConfiguration,
RunLockPort runLockPort,
SourceDocumentCandidatesPort sourceDocumentCandidatesPort,
PdfTextExtractionPort pdfTextExtractionPort,
FingerprintPort fingerprintPort,
DocumentProcessingCoordinator documentProcessingCoordinator,
ProcessingLogger logger) {
this.configuration = Objects.requireNonNull(configuration, "configuration must not be null");
this.runtimeConfiguration = Objects.requireNonNull(runtimeConfiguration, "runtimeConfiguration must not be null");
this.runLockPort = Objects.requireNonNull(runLockPort, "runLockPort must not be null");
this.sourceDocumentCandidatesPort = Objects.requireNonNull(
sourceDocumentCandidatesPort, "sourceDocumentCandidatesPort must not be null");
@@ -142,8 +142,6 @@ public class DefaultBatchRunProcessingUseCase implements BatchRunProcessingUseCa
return BatchRunOutcome.LOCK_UNAVAILABLE;
}
logger.debug("Configuration in use: source={}, target={}",
configuration.sourceFolder(), configuration.targetFolder());
logger.info("Batch run started. RunId: {}, Start: {}",
context.runId(), context.startInstant());
@@ -301,7 +299,7 @@ public class DefaultBatchRunProcessingUseCase implements BatchRunProcessingUseCa
logExtractionResult(candidate, extractionResult);
DocumentProcessingOutcome outcome =
DocumentProcessingService.processDocument(candidate, extractionResult, configuration);
DocumentProcessingService.processDocument(candidate, extractionResult, runtimeConfiguration);
logProcessingOutcome(candidate, outcome);