diff --git a/pom.xml b/pom.xml index a64a944..76d56ba 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ dropwizard-application-errors - 2.0.1-SNAPSHOT + 2.1.0-SNAPSHOT jar ${project.groupId}:${project.artifactId} @@ -51,7 +51,7 @@ pom import - + org.kiwiproject kiwi @@ -80,6 +80,16 @@ dropwizard-jdbi3 + + io.dropwizard + dropwizard-validation + + + + jakarta.validation + jakarta.validation-api + + org.kiwiproject kiwi @@ -90,7 +100,7 @@ metrics-healthchecks-severity ${metrics-healthchecks-severity.version} - + org.slf4j slf4j-api @@ -150,7 +160,7 @@ kiwi-test test - + ch.qos.logback logback-classic diff --git a/src/main/java/org/kiwiproject/dropwizard/error/config/CleanupConfig.java b/src/main/java/org/kiwiproject/dropwizard/error/config/CleanupConfig.java index bdcdc30..ce56370 100644 --- a/src/main/java/org/kiwiproject/dropwizard/error/config/CleanupConfig.java +++ b/src/main/java/org/kiwiproject/dropwizard/error/config/CleanupConfig.java @@ -1,9 +1,15 @@ package org.kiwiproject.dropwizard.error.config; import io.dropwizard.util.Duration; +import io.dropwizard.validation.MinDuration; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + import lombok.Getter; import lombok.Setter; +import java.util.concurrent.TimeUnit; + /** * Configuration class used to set up the {@link org.kiwiproject.dropwizard.error.job.CleanupApplicationErrorsJob} */ @@ -25,31 +31,41 @@ public enum CleanupStrategy { /** * The strategy to use for what to clean up. Defaults to {@link CleanupStrategy#ALL_ERRORS}. */ + @NotNull private CleanupStrategy cleanupStrategy = CleanupStrategy.ALL_ERRORS; /** - * The duration that a resolved error will live before being deleted. + * The duration that a resolved error will live before being deleted. Defaults to 14 days. */ + @NotNull + @MinDuration(value = 1, unit = TimeUnit.MINUTES) private Duration resolvedErrorExpiration = Duration.days(14); /** - * The duration that an unresolved error will live before being deleted. + * The duration that an unresolved error will live before being deleted. Defaults to 60 days. */ + @NotNull + @MinDuration(value = 1, unit = TimeUnit.MINUTES) private Duration unresolvedErrorExpiration = Duration.days(60); /** * The name to give the scheduled job for cleaning up errors. Defaults to {@code Application-Errors-Cleanup-Job-%d} * which will result in thread names like {@code Application-Errors-Cleanup-Job-1}. */ + @NotBlank private String cleanupJobName = "Application-Errors-Cleanup-Job-%d"; /** * Initial delay before the cleanup job runs. Defaults to 1 minute. */ + @NotNull + @MinDuration(value = 1, unit = TimeUnit.MINUTES) private Duration initialJobDelay = Duration.minutes(1); /** * Interval that the cleanup job will run. Defaults to once a day. */ + @NotNull + @MinDuration(value = 1, unit = TimeUnit.MINUTES) private Duration jobInterval = Duration.days(1); } diff --git a/src/test/java/org/kiwiproject/dropwizard/error/config/CleanupConfigTest.java b/src/test/java/org/kiwiproject/dropwizard/error/config/CleanupConfigTest.java index b907d9f..ea8f85d 100644 --- a/src/test/java/org/kiwiproject/dropwizard/error/config/CleanupConfigTest.java +++ b/src/test/java/org/kiwiproject/dropwizard/error/config/CleanupConfigTest.java @@ -3,18 +3,84 @@ import static org.assertj.core.api.Assertions.assertThat; import io.dropwizard.util.Duration; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.kiwiproject.test.validation.ValidationTestHelper.assertNoViolations; +import static org.kiwiproject.test.validation.ValidationTestHelper.assertOnePropertyViolation; + +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.kiwiproject.reflect.KiwiReflection; @DisplayName("CleanupConfig") class CleanupConfigTest { + private CleanupConfig config; + + @BeforeEach + void setUp() { + config = new CleanupConfig(); + } + @Test void shouldHaveDefaults() { var config = new CleanupConfig(); - assertThat(config.getCleanupStrategy()).isEqualTo(CleanupConfig.CleanupStrategy.ALL_ERRORS); - assertThat(config.getResolvedErrorExpiration()).isEqualTo(Duration.days(14)); - assertThat(config.getUnresolvedErrorExpiration()).isEqualTo(Duration.days(60)); + assertAll( + () -> assertThat(config.getCleanupStrategy()).isEqualTo(CleanupConfig.CleanupStrategy.ALL_ERRORS), + () -> assertThat(config.getResolvedErrorExpiration()).isEqualTo(Duration.days(14)), + () -> assertThat(config.getUnresolvedErrorExpiration()).isEqualTo(Duration.days(60)), + () -> assertThat(config.getCleanupJobName()).isEqualTo("Application-Errors-Cleanup-Job-%d"), + () -> assertThat(config.getInitialJobDelay()).isEqualTo(Duration.minutes(1)), + () -> assertThat(config.getJobInterval()).isEqualTo(Duration.days(1)) + ); + } + + @Test + void shouldValidateRequiredFields() { + KiwiReflection.invokeMutatorMethodsWithNull(config); + + assertAll( + () -> assertOnePropertyViolation(config, "cleanupStrategy"), + () -> assertOnePropertyViolation(config, "resolvedErrorExpiration"), + () -> assertOnePropertyViolation(config, "unresolvedErrorExpiration"), + () -> assertOnePropertyViolation(config, "cleanupJobName"), + () -> assertOnePropertyViolation(config, "initialJobDelay"), + () -> assertOnePropertyViolation(config, "jobInterval") + ); + } + + @ParameterizedTest + @ValueSource(longs = {60, 61, 90, 120}) + void shouldPassValidationWhenDurationsAreAtOrAboveTheMinimumAllowed(long seconds) { + var duration = Duration.seconds(seconds); + + config.setResolvedErrorExpiration(duration); + config.setUnresolvedErrorExpiration(duration); + config.setInitialJobDelay(duration); + config.setJobInterval(duration); + + assertNoViolations(config); + } + + @ParameterizedTest + @ValueSource(longs = {0, 1, 30, 59}) + void shouldValidateMinimumDurations(long seconds) { + var duration = Duration.seconds(seconds); + + config.setResolvedErrorExpiration(duration); + config.setUnresolvedErrorExpiration(duration); + config.setInitialJobDelay(duration); + config.setJobInterval(duration); + + assertAll( + () -> assertOnePropertyViolation(config, "resolvedErrorExpiration"), + () -> assertOnePropertyViolation(config, "unresolvedErrorExpiration"), + () -> assertOnePropertyViolation(config, "initialJobDelay"), + () -> assertOnePropertyViolation(config, "jobInterval") + ); } }