diff --git a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/GuiSchedulerTab.java b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/GuiSchedulerTab.java index ab68fd4..9651bfe 100644 --- a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/GuiSchedulerTab.java +++ b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/GuiSchedulerTab.java @@ -40,9 +40,6 @@ import javafx.scene.layout.VBox; * *
- * Alle übrigen Inhalte der Datei bleiben unverändert. Existiert der Key - * noch nicht, wird er am Ende der Datei ergänzt. - * - * @param enabled neuer Wert für {@code scheduler.enabled} - * @throws SchedulerSettingsWriteException wenn der Schreibvorgang fehlschlägt - */ - @Override - public void saveEnabled(boolean enabled) throws SchedulerSettingsWriteException { - updateProperty(KEY_ENABLED, String.valueOf(enabled)); + return new SchedulerSettings(intervalSeconds); } /** @@ -229,13 +213,6 @@ public class FileChannelConfigurationAccessAdapter // Hilfsmethoden: Parsen // ------------------------------------------------------------------------- - private boolean parseEnabled(String raw) { - if (raw == null || raw.isBlank()) { - return SchedulerSettings.DEFAULT_ENABLED; - } - return Boolean.parseBoolean(raw.trim()); - } - private int parseInterval(String raw) { if (raw == null || raw.isBlank()) { return SchedulerSettings.DEFAULT_INTERVAL_SECONDS; diff --git a/pdf-umbenenner-adapter-in-scheduler/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/scheduler/FileChannelConfigurationAccessAdapterTest.java b/pdf-umbenenner-adapter-in-scheduler/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/scheduler/FileChannelConfigurationAccessAdapterTest.java index 3965c26..64b73c4 100644 --- a/pdf-umbenenner-adapter-in-scheduler/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/scheduler/FileChannelConfigurationAccessAdapterTest.java +++ b/pdf-umbenenner-adapter-in-scheduler/src/test/java/de/gecheckt/pdf/umbenenner/adapter/in/scheduler/FileChannelConfigurationAccessAdapterTest.java @@ -16,22 +16,12 @@ import org.junit.jupiter.api.io.TempDir; import de.gecheckt.pdf.umbenenner.application.port.out.ConfigurationFileLockException; import de.gecheckt.pdf.umbenenner.application.port.out.SchedulerSettings; -import de.gecheckt.pdf.umbenenner.application.port.out.SchedulerSettingsWriteException; /** * Unit-Tests für {@link FileChannelConfigurationAccessAdapter}. - *
- * Deckt das Lock-Protokoll (Erwerb, Freigabe, Idempotenz), die Settings-Lese- - * und Schreiblogik sowie die format-erhaltenden Zeileneigenschaften ab. - * Alle Tests arbeiten auf einer temporären {@code .properties}-Datei im - * JUnit-eigenen {@code @TempDir}. */ class FileChannelConfigurationAccessAdapterTest { - // ========================================================================= - // Lock-Protokoll - // ========================================================================= - @Test void isLocked_returnsFalseBeforeAnyAcquire(@TempDir Path tempDir) throws IOException { Path config = createConfigFile(tempDir, ""); @@ -115,10 +105,6 @@ class FileChannelConfigurationAccessAdapterTest { .isInstanceOf(ConfigurationFileLockException.class); } - // ========================================================================= - // loadSettings - // ========================================================================= - @Test void loadSettings_returnsDefaultsWhenKeysAreMissing(@TempDir Path tempDir) throws IOException { Path config = createConfigFile(tempDir, "source.folder=S:\\source\n"); @@ -127,27 +113,25 @@ class FileChannelConfigurationAccessAdapterTest { SchedulerSettings settings = adapter.loadSettings(); - assertThat(settings.enabled()).isEqualTo(SchedulerSettings.DEFAULT_ENABLED); assertThat(settings.intervalSeconds()).isEqualTo(SchedulerSettings.DEFAULT_INTERVAL_SECONDS); } @Test void loadSettings_returnsConfiguredValues(@TempDir Path tempDir) throws IOException { - String content = "scheduler.enabled=true\nscheduler.interval.seconds=300\n"; + String content = "scheduler.interval.seconds=300\n"; Path config = createConfigFile(tempDir, content); FileChannelConfigurationAccessAdapter adapter = new FileChannelConfigurationAccessAdapter(config); SchedulerSettings settings = adapter.loadSettings(); - assertThat(settings.enabled()).isTrue(); assertThat(settings.intervalSeconds()).isEqualTo(300); } @Test void loadSettings_returnsDefaultIntervalForNonNumericValue(@TempDir Path tempDir) throws IOException { - String content = "scheduler.enabled=false\nscheduler.interval.seconds=not-a-number\n"; + String content = "scheduler.interval.seconds=not-a-number\n"; Path config = createConfigFile(tempDir, content); FileChannelConfigurationAccessAdapter adapter = new FileChannelConfigurationAccessAdapter(config); @@ -157,19 +141,6 @@ class FileChannelConfigurationAccessAdapterTest { assertThat(settings.intervalSeconds()).isEqualTo(SchedulerSettings.DEFAULT_INTERVAL_SECONDS); } - @Test - void loadSettings_returnsDefaultEnabledForBlankValue(@TempDir Path tempDir) - throws IOException { - String content = "scheduler.enabled=\nscheduler.interval.seconds=180\n"; - Path config = createConfigFile(tempDir, content); - FileChannelConfigurationAccessAdapter adapter = - new FileChannelConfigurationAccessAdapter(config); - - SchedulerSettings settings = adapter.loadSettings(); - - assertThat(settings.enabled()).isEqualTo(SchedulerSettings.DEFAULT_ENABLED); - } - @Test void loadSettings_returnsDefaultsWhenFileIsEmpty(@TempDir Path tempDir) throws IOException { Path config = createConfigFile(tempDir, ""); @@ -181,78 +152,10 @@ class FileChannelConfigurationAccessAdapterTest { assertThat(settings).isEqualTo(SchedulerSettings.defaults()); } - // ========================================================================= - // saveEnabled - // ========================================================================= - - @Test - void saveEnabled_updatesExistingKeyAndPreservesOtherLines(@TempDir Path tempDir) - throws IOException { - String initial = "source.folder=/opt/source\nscheduler.enabled=false\ntarget.folder=/opt/target\n"; - Path config = createConfigFile(tempDir, initial); - FileChannelConfigurationAccessAdapter adapter = - new FileChannelConfigurationAccessAdapter(config); - - adapter.saveEnabled(true); - - Properties props = loadProperties(config); - assertThat(props.getProperty("scheduler.enabled")).isEqualTo("true"); - assertThat(props.getProperty("source.folder")).isEqualTo("/opt/source"); - assertThat(props.getProperty("target.folder")).isEqualTo("/opt/target"); - } - - @Test - void saveEnabled_appendsKeyWhenMissing(@TempDir Path tempDir) throws IOException { - String initial = "source.folder=/opt/source\n"; - Path config = createConfigFile(tempDir, initial); - FileChannelConfigurationAccessAdapter adapter = - new FileChannelConfigurationAccessAdapter(config); - - adapter.saveEnabled(true); - - Properties props = loadProperties(config); - assertThat(props.getProperty("scheduler.enabled")).isEqualTo("true"); - assertThat(props.getProperty("source.folder")).isEqualTo("/opt/source"); - } - - @Test - void saveEnabled_writesCorrectlyThroughChannelWhenLocked(@TempDir Path tempDir) - throws IOException { - String initial = "scheduler.enabled=false\n"; - Path config = createConfigFile(tempDir, initial); - FileChannelConfigurationAccessAdapter adapter = - new FileChannelConfigurationAccessAdapter(config); - - adapter.acquireLock(); - try { - adapter.saveEnabled(true); - } finally { - adapter.releaseLock(); - } - - Properties props = loadProperties(config); - assertThat(props.getProperty("scheduler.enabled")).isEqualTo("true"); - } - - @Test - void saveEnabled_throwsSchedulerSettingsWriteException_whenFileDoesNotExist( - @TempDir Path tempDir) { - Path nonExistent = tempDir.resolve("missing.properties"); - FileChannelConfigurationAccessAdapter adapter = - new FileChannelConfigurationAccessAdapter(nonExistent); - - assertThatThrownBy(() -> adapter.saveEnabled(true)) - .isInstanceOf(SchedulerSettingsWriteException.class); - } - - // ========================================================================= - // saveIntervalSeconds - // ========================================================================= - @Test void saveIntervalSeconds_updatesExistingKeyAndPreservesOtherLines(@TempDir Path tempDir) throws IOException { - String initial = "scheduler.interval.seconds=180\nscheduler.enabled=false\n"; + String initial = "source.folder=/opt/source\nscheduler.interval.seconds=180\ntarget.folder=/opt/target\n"; Path config = createConfigFile(tempDir, initial); FileChannelConfigurationAccessAdapter adapter = new FileChannelConfigurationAccessAdapter(config); @@ -261,12 +164,13 @@ class FileChannelConfigurationAccessAdapterTest { Properties props = loadProperties(config); assertThat(props.getProperty("scheduler.interval.seconds")).isEqualTo("300"); - assertThat(props.getProperty("scheduler.enabled")).isEqualTo("false"); + assertThat(props.getProperty("source.folder")).isEqualTo("/opt/source"); + assertThat(props.getProperty("target.folder")).isEqualTo("/opt/target"); } @Test void saveIntervalSeconds_appendsKeyWhenMissing(@TempDir Path tempDir) throws IOException { - String initial = "scheduler.enabled=true\n"; + String initial = "source.folder=/opt/source\n"; Path config = createConfigFile(tempDir, initial); FileChannelConfigurationAccessAdapter adapter = new FileChannelConfigurationAccessAdapter(config); @@ -275,47 +179,58 @@ class FileChannelConfigurationAccessAdapterTest { Properties props = loadProperties(config); assertThat(props.getProperty("scheduler.interval.seconds")).isEqualTo("240"); - assertThat(props.getProperty("scheduler.enabled")).isEqualTo("true"); - } - - // ========================================================================= - // Zeilenenden-Erhaltung - // ========================================================================= - - @Test - void saveEnabled_preservesCrlfLineEndings(@TempDir Path tempDir) throws IOException { - String initial = "scheduler.enabled=false\r\nother.key=value\r\n"; - Path config = createConfigFileBinary(tempDir, initial.getBytes(StandardCharsets.UTF_8)); - FileChannelConfigurationAccessAdapter adapter = - new FileChannelConfigurationAccessAdapter(config); - - adapter.saveEnabled(true); - - byte[] resultBytes = Files.readAllBytes(config); - String result = new String(resultBytes, StandardCharsets.UTF_8); - assertThat(result).contains("scheduler.enabled=true\r\n"); - assertThat(result).contains("other.key=value\r\n"); + assertThat(props.getProperty("source.folder")).isEqualTo("/opt/source"); } @Test - void saveEnabled_preservesLfLineEndings(@TempDir Path tempDir) throws IOException { - String initial = "scheduler.enabled=false\nother.key=value\n"; + void saveIntervalSeconds_writesCorrectlyThroughChannelWhenLocked(@TempDir Path tempDir) + throws IOException { + String initial = "scheduler.interval.seconds=180\n"; Path config = createConfigFile(tempDir, initial); FileChannelConfigurationAccessAdapter adapter = new FileChannelConfigurationAccessAdapter(config); - adapter.saveEnabled(true); + adapter.acquireLock(); + try { + adapter.saveIntervalSeconds(300); + } finally { + adapter.releaseLock(); + } + + Properties props = loadProperties(config); + assertThat(props.getProperty("scheduler.interval.seconds")).isEqualTo("300"); + } + + @Test + void saveIntervalSeconds_preservesCrlfLineEndings(@TempDir Path tempDir) throws IOException { + String initial = "scheduler.interval.seconds=180\r\nother.key=value\r\n"; + Path config = createConfigFileBinary(tempDir, initial.getBytes(StandardCharsets.UTF_8)); + FileChannelConfigurationAccessAdapter adapter = + new FileChannelConfigurationAccessAdapter(config); + + adapter.saveIntervalSeconds(300); + + byte[] resultBytes = Files.readAllBytes(config); + String result = new String(resultBytes, StandardCharsets.UTF_8); + assertThat(result).contains("scheduler.interval.seconds=300\r\n"); + assertThat(result).contains("other.key=value\r\n"); + } + + @Test + void saveIntervalSeconds_preservesLfLineEndings(@TempDir Path tempDir) throws IOException { + String initial = "scheduler.interval.seconds=180\nother.key=value\n"; + Path config = createConfigFile(tempDir, initial); + FileChannelConfigurationAccessAdapter adapter = + new FileChannelConfigurationAccessAdapter(config); + + adapter.saveIntervalSeconds(300); String result = Files.readString(config, StandardCharsets.UTF_8); - assertThat(result).contains("scheduler.enabled=true\n"); + assertThat(result).contains("scheduler.interval.seconds=300\n"); assertThat(result).contains("other.key=value\n"); assertThat(result).doesNotContain("\r\n"); } - // ========================================================================= - // Hilfsmethoden - // ========================================================================= - private static Path createConfigFile(Path tempDir, String content) throws IOException { Path config = tempDir.resolve("test.properties"); Files.writeString(config, content, StandardCharsets.UTF_8); diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/in/SchedulerControlUseCase.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/in/SchedulerControlUseCase.java index ac33c2f..b542beb 100644 --- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/in/SchedulerControlUseCase.java +++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/in/SchedulerControlUseCase.java @@ -25,7 +25,6 @@ public interface SchedulerControlUseCase { * folgende Sequenz gestartet: *
- * Wird vom Scheduler-Tab aufgerufen, wenn der Benutzer den fehlgeschlagenen - * Autostart dauerhaft deaktivieren möchte. Sicher aufzurufen wenn der Scheduler - * gestoppt ist. - *
- * Muss auf einem Hintergrund-Thread aufgerufen werden. - */ - void disableAutostart(); } diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/in/SchedulerStartException.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/in/SchedulerStartException.java index 6b7bbe6..b0368db 100644 --- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/in/SchedulerStartException.java +++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/in/SchedulerStartException.java @@ -3,9 +3,8 @@ package de.gecheckt.pdf.umbenenner.application.port.in; /** * Wird geworfen, wenn der Start des automatischen Schedulers fehlschlägt. *
- * Mögliche Ursachen sind: Fehler beim Erwerb des Konfigurations-Datei-Locks, - * Fehler beim Persistieren von {@code scheduler.enabled=true} oder - * technische Fehler beim Starten des Scheduler-Adapters. + * Mögliche Ursachen sind: Fehler beim Erwerb des Konfigurations-Datei-Locks + * oder technische Fehler beim Starten des Scheduler-Adapters. *
* Diese Ausnahme ist ungeprüft (extends {@link RuntimeException}) und
* wird in der Callchain bis zum GUI-Layer weitergeleitet, der eine
diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/in/SchedulerStatus.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/in/SchedulerStatus.java
index 1f65eac..54c42e8 100644
--- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/in/SchedulerStatus.java
+++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/in/SchedulerStatus.java
@@ -26,16 +26,13 @@ import de.gecheckt.pdf.umbenenner.application.port.out.RunSummary;
* @param lastError letzte aufgetretene deutsche Fehlermeldung;
* wird bei erfolgreichem Lauf gelöscht,
* bei {@code SkippedBusy} unverändert gelassen
- * @param autostartFailed {@code true}, wenn ein konfigurierter Autostart
- * beim Programmstart fehlgeschlagen ist
*/
public record SchedulerStatus(
SchedulerState state,
Optional
- * Zustand ist {@link SchedulerState#STOPPED}, alle optionalen Felder
- * sind leer und {@code autostartFailed} ist {@code false}.
+ * Zustand ist {@link SchedulerState#STOPPED} und alle optionalen Felder
+ * sind leer.
*
* @return initialer Scheduler-Status
*/
@@ -73,8 +70,7 @@ public record SchedulerStatus(
Optional.empty(),
Optional.empty(),
Optional.empty(),
- Optional.empty(),
- false
+ Optional.empty()
);
}
}
diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/out/SchedulerSettings.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/out/SchedulerSettings.java
index 2263659..135e3f5 100644
--- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/out/SchedulerSettings.java
+++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/out/SchedulerSettings.java
@@ -3,23 +3,16 @@ package de.gecheckt.pdf.umbenenner.application.port.out;
/**
* Persistierte Scheduler-Einstellungen aus der {@code .properties}-Datei.
*
- * Dieses DTO repräsentiert die beiden Scheduler-Properties
- * {@code scheduler.enabled} und {@code scheduler.interval.seconds},
- * wie sie aus der Konfigurationsdatei gelesen werden. Es wird von
- * {@link SchedulerSettingsPort#loadSettings()} zurückgegeben und
- * dient als Eingabe für die Autostart-Entscheidung und die
- * Scheduler-Tab-Anzeige.
+ * Dieses DTO repräsentiert die Scheduler-Property
+ * {@code scheduler.interval.seconds}, wie sie aus der Konfigurationsdatei
+ * gelesen wird. Es wird von {@link SchedulerSettingsPort#loadSettings()}
+ * zurückgegeben und dient als Eingabe für die Scheduler-Tab-Anzeige.
*
- * @param enabled {@code true}, wenn der Scheduler beim nächsten
- * Programmstart automatisch gestartet werden soll
* @param intervalSeconds konfigurierte Wartezeit in Sekunden zwischen
* Läufen; entspricht dem gelesenen Rohwert
* ohne weitere Validierung
*/
-public record SchedulerSettings(boolean enabled, int intervalSeconds) {
-
- /** Standardwert für {@code scheduler.enabled}, wenn der Key fehlt oder leer ist. */
- public static final boolean DEFAULT_ENABLED = false;
+public record SchedulerSettings(int intervalSeconds) {
/** Standardwert für {@code scheduler.interval.seconds}, wenn der Key fehlt oder leer ist. */
public static final int DEFAULT_INTERVAL_SECONDS = 180;
@@ -27,9 +20,9 @@ public record SchedulerSettings(boolean enabled, int intervalSeconds) {
/**
* Erzeugt eine {@code SchedulerSettings}-Instanz mit Standardwerten.
*
- * @return Instanz mit {@code enabled=false} und {@code intervalSeconds=180}
+ * @return Instanz mit {@code intervalSeconds=180}
*/
public static SchedulerSettings defaults() {
- return new SchedulerSettings(DEFAULT_ENABLED, DEFAULT_INTERVAL_SECONDS);
+ return new SchedulerSettings(DEFAULT_INTERVAL_SECONDS);
}
}
diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/out/SchedulerSettingsPort.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/out/SchedulerSettingsPort.java
index 5ce60ff..82a731b 100644
--- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/out/SchedulerSettingsPort.java
+++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/out/SchedulerSettingsPort.java
@@ -4,9 +4,8 @@ package de.gecheckt.pdf.umbenenner.application.port.out;
* Outbound-Port zum Lesen und Schreiben der Scheduler-Einstellungen
* in der {@code .properties}-Konfigurationsdatei.
*
- * Schreiboperationen aktualisieren ausschließlich die beiden
- * Scheduler-Keys ({@code scheduler.enabled} und
- * {@code scheduler.interval.seconds}). Alle übrigen Zeilen, Kommentare
+ * Schreiboperationen aktualisieren ausschließlich den Scheduler-Key
+ * {@code scheduler.interval.seconds}. Alle übrigen Zeilen, Kommentare
* und unbekannten Properties bleiben unverändert erhalten.
*
* Schreibvorgänge sind atomar: Sie erfolgen über eine temporäre Datei,
@@ -33,17 +32,6 @@ public interface SchedulerSettingsPort {
*/
SchedulerSettings loadSettings();
- /**
- * Schreibt den Wert von {@code scheduler.enabled} in die
- * Konfigurationsdatei.
- *
- * Alle übrigen Inhalte der Datei bleiben unverändert.
- *
- * @param enabled neuer Wert für {@code scheduler.enabled}
- * @throws SchedulerSettingsWriteException wenn der Schreibvorgang fehlschlägt
- */
- void saveEnabled(boolean enabled) throws SchedulerSettingsWriteException;
-
/**
* Schreibt den Wert von {@code scheduler.interval.seconds} in die
* Konfigurationsdatei.
diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultSchedulerControlUseCase.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultSchedulerControlUseCase.java
index 0d279a3..fc31475 100644
--- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultSchedulerControlUseCase.java
+++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/usecase/DefaultSchedulerControlUseCase.java
@@ -28,7 +28,7 @@ import java.util.concurrent.atomic.AtomicReference;
* Dieser Use Case:
*
- * Wird von der Bootstrap-Schicht aufgerufen, wenn ein konfigurierter Autostart
- * beim Programmstart fehlgeschlagen ist. Alle übrigen Statusfelder bleiben erhalten;
- * lediglich {@link SchedulerStatus#autostartFailed()} wird auf {@code true} gesetzt.
- *
- * Diese Methode darf nur aufgerufen werden, wenn der Scheduler noch gestoppt ist
- * (unmittelbar nach einem fehlgeschlagenen {@link #start()}).
- */
- public void markAutostartFailed() {
- statusRef.updateAndGet(s -> new SchedulerStatus(
- s.state(), s.lastRunEndedAt(), s.lastRunSummary(),
- s.nextTickAt(), s.lastError(), true));
- logger.warn("Scheduler-Status: Autostart als fehlgeschlagen markiert.");
- }
-
// -------------------------------------------------------------------------
// Tick-Wrapper (package-private für Testbarkeit)
// -------------------------------------------------------------------------
@@ -265,8 +222,7 @@ public class DefaultSchedulerControlUseCase implements SchedulerControlUseCase {
*
* Package-private, damit Unit-Tests den Tick-Wrapper direkt aufrufen können
* ohne den Scheduler-Executor zu starten.
@@ -315,11 +271,9 @@ public class DefaultSchedulerControlUseCase implements SchedulerControlUseCase {
lastRunEndedAt,
lastRunSummary,
nextTickAt,
- lastError,
- afterBatch.autostartFailed()));
+ lastError));
if (stopping) {
- tryPersistDisabled();
lockPort.releaseLock();
logger.info("Scheduler gestoppt nach Abschluss des laufenden Batches.");
}
@@ -331,14 +285,6 @@ public class DefaultSchedulerControlUseCase implements SchedulerControlUseCase {
// Hilfsmethoden
// -------------------------------------------------------------------------
- private void tryPersistDisabled() {
- try {
- settingsPort.saveEnabled(false);
- } catch (Exception e) {
- logger.warn("Fehler beim Zurücksetzen von scheduler.enabled auf false.", e);
- }
- }
-
private static SchedulerStatus withState(
SchedulerStatus base, SchedulerState state, Optional
- * Teststrategien:
- *
* Erzeugt {@link FileChannelConfigurationAccessAdapter}, {@link ScheduledExecutorServiceSchedulerAdapter}
* und {@link DefaultSchedulerControlUseCase} und speichert den Use Case in
- * {@link #guiSchedulerUseCase}. Ist in der Konfiguration {@code scheduler.enabled=true}
- * gesetzt, wird der Scheduler sofort gestartet (Autostart).
+ * {@link #guiSchedulerUseCase}. Der Scheduler wird beim Programmstart
+ * niemals automatisch gestartet; der Benutzer startet ihn ausschließlich
+ * bewusst über den Start-Button im Scheduler-Tab.
*
* Schlägt die Initialisierung fehl, wird {@link #guiSchedulerUseCase} auf
* {@link Optional#empty()} gesetzt und der Fehler als Warnung geloggt.
@@ -1119,16 +1119,6 @@ public class BootstrapRunner {
DefaultSchedulerControlUseCase schedulerUseCase = new DefaultSchedulerControlUseCase(
schedulerAdapter, configAccessAdapter, configAccessAdapter, batchRunTrigger);
guiSchedulerUseCase = Optional.of(schedulerUseCase);
-
- if (configAccessAdapter.loadSettings().enabled()) {
- try {
- schedulerUseCase.start();
- LOG.info("Scheduler: Autostart aktiviert gemäß Konfiguration.");
- } catch (SchedulerStartException e) {
- LOG.warn("Scheduler: Autostart fehlgeschlagen: {}", e.getMessage());
- schedulerUseCase.markAutostartFailed();
- }
- }
} catch (Exception e) {
LOG.warn("Scheduler: Initialisierung fehlgeschlagen – Scheduler nicht verfügbar: {}",
e.getMessage(), e);
*
- * Im Fall {@link SchedulerState#STOPPED} werden außerdem {@code enabled=false}
- * persistiert und der OS-Lock freigegeben.
+ * Im Fall {@link SchedulerState#STOPPED} wird außerdem der OS-Lock freigegeben.
*
- *
*/
@ExtendWith(MockitoExtension.class)
class DefaultSchedulerControlUseCaseTest {
@@ -62,13 +49,9 @@ class DefaultSchedulerControlUseCaseTest {
@BeforeEach
void setUp() {
- when(settingsPort.loadSettings()).thenReturn(new SchedulerSettings(false, 180));
+ when(settingsPort.loadSettings()).thenReturn(new SchedulerSettings(180));
}
- // =========================================================================
- // Initialer Zustand
- // =========================================================================
-
@Test
void getStatus_returnsInitialStatusOnCreation() {
DefaultSchedulerControlUseCase useCase = createUseCase();
@@ -80,15 +63,13 @@ class DefaultSchedulerControlUseCaseTest {
assertThat(status.lastRunSummary()).isEmpty();
assertThat(status.nextTickAt()).isEmpty();
assertThat(status.lastError()).isEmpty();
- assertThat(status.autostartFailed()).isFalse();
}
@Test
void constructor_loadsSettingsIntervalSeconds() {
- when(settingsPort.loadSettings()).thenReturn(new SchedulerSettings(false, 300));
+ when(settingsPort.loadSettings()).thenReturn(new SchedulerSettings(300));
DefaultSchedulerControlUseCase useCase = createUseCase();
- // Verify interval is 300 by starting and checking the SchedulerConfig passed to schedulerPort
useCase.start();
ArgumentCaptor