refactor(import): make import directory @Value-configurable
The hardcoded `static final String IMPORT_DIR = "/import"` was the only non-`@Value` configurable input in MassImportService — every column index next to it is wired through `app.import.col.*`. Lifts the contract from infrastructure (compose bind mount) into application config (`app.import.dir`), with `/import` as the default so the existing bind-mount path keeps working. Addresses review feedback from Markus and Felix on #526. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -99,7 +99,9 @@ public class MassImportService {
|
|||||||
@Value("${app.import.col.transcription:13}")
|
@Value("${app.import.col.transcription:13}")
|
||||||
private int colTranscription;
|
private int colTranscription;
|
||||||
|
|
||||||
private static final String IMPORT_DIR = "/import";
|
@Value("${app.import.dir:/import}")
|
||||||
|
private String importDir;
|
||||||
|
|
||||||
private static final DateTimeFormatter GERMAN_DATE = DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.GERMAN);
|
private static final DateTimeFormatter GERMAN_DATE = DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.GERMAN);
|
||||||
|
|
||||||
// ODS XML namespaces
|
// ODS XML namespaces
|
||||||
@@ -129,7 +131,7 @@ public class MassImportService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private File findSpreadsheetFile() throws IOException {
|
private File findSpreadsheetFile() throws IOException {
|
||||||
try (Stream<Path> files = Files.list(Paths.get(IMPORT_DIR))) {
|
try (Stream<Path> files = Files.list(Paths.get(importDir))) {
|
||||||
return files
|
return files
|
||||||
.filter(p -> {
|
.filter(p -> {
|
||||||
String name = p.toString().toLowerCase();
|
String name = p.toString().toLowerCase();
|
||||||
@@ -137,7 +139,7 @@ public class MassImportService {
|
|||||||
})
|
})
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseThrow(() -> new RuntimeException(
|
.orElseThrow(() -> new RuntimeException(
|
||||||
"Keine Tabellendatei (.ods/.xlsx/.xls) in " + IMPORT_DIR + " gefunden!"))
|
"Keine Tabellendatei (.ods/.xlsx/.xls) in " + importDir + " gefunden!"))
|
||||||
.toFile();
|
.toFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -378,7 +380,7 @@ public class MassImportService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Optional<File> findFileRecursive(String filename) {
|
private Optional<File> findFileRecursive(String filename) {
|
||||||
try (Stream<Path> walk = Files.walk(Paths.get(IMPORT_DIR))) {
|
try (Stream<Path> walk = Files.walk(Paths.get(importDir))) {
|
||||||
return walk.filter(p -> !Files.isDirectory(p))
|
return walk.filter(p -> !Files.isDirectory(p))
|
||||||
.filter(p -> p.getFileName().toString().equals(filename))
|
.filter(p -> p.getFileName().toString().equals(filename))
|
||||||
.map(Path::toFile)
|
.map(Path::toFile)
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ class MassImportServiceTest {
|
|||||||
void setUp() {
|
void setUp() {
|
||||||
service = new MassImportService(documentService, personService, tagService, s3Client, thumbnailAsyncRunner);
|
service = new MassImportService(documentService, personService, tagService, s3Client, thumbnailAsyncRunner);
|
||||||
ReflectionTestUtils.setField(service, "bucketName", "test-bucket");
|
ReflectionTestUtils.setField(service, "bucketName", "test-bucket");
|
||||||
|
ReflectionTestUtils.setField(service, "importDir", "/import");
|
||||||
ReflectionTestUtils.setField(service, "colIndex", 0);
|
ReflectionTestUtils.setField(service, "colIndex", 0);
|
||||||
ReflectionTestUtils.setField(service, "colBox", 1);
|
ReflectionTestUtils.setField(service, "colBox", 1);
|
||||||
ReflectionTestUtils.setField(service, "colFolder", 2);
|
ReflectionTestUtils.setField(service, "colFolder", 2);
|
||||||
@@ -79,6 +80,19 @@ class MassImportServiceTest {
|
|||||||
assertThat(service.getStatus().state()).isEqualTo(MassImportService.State.FAILED);
|
assertThat(service.getStatus().state()).isEqualTo(MassImportService.State.FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void runImportAsync_readsFromConfiguredImportDir(@TempDir Path tempDir) {
|
||||||
|
// Empty temp dir → findSpreadsheetFile throws "no spreadsheet" with the
|
||||||
|
// configured path in the message. Proves the field, not a constant,
|
||||||
|
// drives the lookup.
|
||||||
|
ReflectionTestUtils.setField(service, "importDir", tempDir.toString());
|
||||||
|
|
||||||
|
service.runImportAsync();
|
||||||
|
|
||||||
|
assertThat(service.getStatus().state()).isEqualTo(MassImportService.State.FAILED);
|
||||||
|
assertThat(service.getStatus().message()).contains(tempDir.toString());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void runImportAsync_throwsConflict_whenAlreadyRunning() {
|
void runImportAsync_throwsConflict_whenAlreadyRunning() {
|
||||||
MassImportService.ImportStatus running = new MassImportService.ImportStatus(
|
MassImportService.ImportStatus running = new MassImportService.ImportStatus(
|
||||||
|
|||||||
Reference in New Issue
Block a user