diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PostfachProperties.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PostfachProperties.java index 0329d8cf6471c54815aae43bea6d60121aff4a87..2ed0945651f869e878ded29ce296be72bf7a0994 100644 --- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PostfachProperties.java +++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PostfachProperties.java @@ -3,6 +3,9 @@ package de.ozgcloud.nachrichten.postfach.osiv2.config; import java.util.List; import jakarta.annotation.Nullable; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -32,10 +35,16 @@ public class Osi2PostfachProperties { public static class AuthConfiguration { public static final String PREFIX = Osi2PostfachProperties.PREFIX + ".auth"; + @NotBlank private String clientId; + @NotBlank private String clientSecret; - private List<String> scope; + @NotNull + @Valid + private List<@NotBlank String> scope; + @NotBlank private String tokenUri; + @NotBlank private String resource; } @@ -46,8 +55,11 @@ public class Osi2PostfachProperties { public static class ApiConfiguration { public static final String PREFIX = Osi2PostfachProperties.PREFIX + ".api"; + @NotBlank private String url; + @NotBlank private String tenant; + @NotBlank private String nameIdentifier; } @@ -64,7 +76,9 @@ public class Osi2PostfachProperties { private boolean enabled; + @NotBlank private String host; + @NotNull private Integer port; @Nullable diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PropertiesValidator.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PropertiesValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..19f24545ca18f1bc3a5e2a8e8525187a9014630e --- /dev/null +++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PropertiesValidator.java @@ -0,0 +1,47 @@ +package de.ozgcloud.nachrichten.postfach.osiv2.config; + +import java.util.Set; + +import javax.annotation.PostConstruct; + +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validator; + +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.nachrichten.postfach.osiv2.ServiceIfOsi2Enabled; +import lombok.RequiredArgsConstructor; + +@ServiceIfOsi2Enabled +@RequiredArgsConstructor +public class Osi2PropertiesValidator { + + private final Osi2PostfachProperties.AuthConfiguration authConfiguration; + private final Osi2PostfachProperties.ApiConfiguration apiConfiguration; + private final Osi2PostfachProperties.ProxyConfiguration proxyConfiguration; + private final Validator validator; + + @PostConstruct + public void validateConfiguration() { + validateConfiguration(authConfiguration); + validateConfiguration(apiConfiguration); + if (proxyConfiguration.isEnabled()) { + validateConfiguration(proxyConfiguration); + } + } + + private <T> void validateConfiguration(T configuration) { + var violations = validator.validate(configuration); + if (!violations.isEmpty()) { + throw new TechnicalException( + "%s is invalid: %s".formatted(configuration.getClass().getSimpleName(), formatConstraintValidation(violations))); + } + } + + private <T> String formatConstraintValidation(Set<ConstraintViolation<T>> constraints) { + return constraints.stream() + .map(violation -> String.format("%s: %s", violation.getPropertyPath(), violation.getMessage())) + .reduce((a, b) -> a + ", " + b) + .orElse(""); + } +} + diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java index 5f29cedb5c7d84a587da178e0eabb13684190437..989ae00cba9f3caa4f564fc9ac37b77e323a6efa 100644 --- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java +++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java @@ -15,8 +15,8 @@ import de.ozgcloud.nachrichten.postfach.osiv2.exception.Osi2UploadException; import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MessageExchangeApi; import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.QuarantineApi; import de.ozgcloud.nachrichten.postfach.osiv2.model.FileChunkInfo; -import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Message; import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Attachment; +import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2Message; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; @@ -64,7 +64,6 @@ public class PostfachApiFacadeService { return responseMapper.toMessage(messageReply); } - public void deleteMessage(final String messageId) { messageExchangeApi.deleteMessage(UUID.fromString(messageId)); } diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java index cf4e57286e4fcbe210aab9ade1eeeebbdf71761c..1460c960f3dd143541ffb9459ce94cdcecbae9ab 100644 --- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java +++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteServiceITCase.java @@ -12,9 +12,7 @@ import java.util.function.Function; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; @@ -48,7 +46,6 @@ import lombok.SneakyThrows; @TestPropertySource(properties = { "ozgcloud.osiv2.proxy.enabled=false", }) -@ExtendWith(MockitoExtension.class) class OsiPostfachRemoteServiceITCase { @RegisterExtension diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PropertiesValidatorTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PropertiesValidatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0a22469b89e5199d5331ba920bee60cf51a84ed6 --- /dev/null +++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/config/Osi2PropertiesValidatorTest.java @@ -0,0 +1,142 @@ +package de.ozgcloud.nachrichten.postfach.osiv2.config; + +import static org.assertj.core.api.Assertions.*; + +import java.util.List; +import java.util.stream.Stream; + +import jakarta.validation.Validation; +import jakarta.validation.Validator; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import de.ozgcloud.common.errorhandling.TechnicalException; + +class Osi2PropertiesValidatorTest { + + private static final Validator VALIDATOR; + + static { + try (var factory = Validation.buildDefaultValidatorFactory()) { + VALIDATOR = factory.getValidator(); + } + } + + @DisplayName("validate configuration") + @Nested + class TestValidateConfiguration { + + @DisplayName("should return if is valid") + @Test + void shouldReturnIfIsValid() { + var validator = new Osi2PropertiesValidator( + createAuthConfiguration(), + createApiConfiguration(), + createProxyConfiguration(), + VALIDATOR + ); + + assertThatCode(validator::validateConfiguration).doesNotThrowAnyException(); + } + + @DisplayName("should return if is valid with disabled proxy") + @Test + void shouldReturnIfIsValidWithDisabledProxy() { + var validator = new Osi2PropertiesValidator( + createAuthConfiguration(), + createApiConfiguration(), + createDisabledProxyConfiguration(), + VALIDATOR + ); + + assertThatCode(validator::validateConfiguration).doesNotThrowAnyException(); + } + + static Stream<Arguments> invalidValidatorConfigurations() { + return Stream.of( + Arguments.of( + new Osi2PostfachProperties.AuthConfiguration(), + createApiConfiguration(), + createProxyConfiguration() + ), + Arguments.of( + createAuthConfiguration(), + new Osi2PostfachProperties.ApiConfiguration(), + createProxyConfiguration() + ), + Arguments.of( + createAuthConfiguration(), + createApiConfiguration(), + createInvalidProxyConfiguration() + ) + ); + } + + @DisplayName("should throw exception if is invalid") + @ParameterizedTest + @MethodSource("invalidValidatorConfigurations") + void shouldThrowExceptionIfIsInvalid( + Osi2PostfachProperties.AuthConfiguration authConfiguration, + Osi2PostfachProperties.ApiConfiguration apiConfiguration, + Osi2PostfachProperties.ProxyConfiguration proxyConfiguration + ) { + var validator = new Osi2PropertiesValidator( + authConfiguration, + apiConfiguration, + proxyConfiguration, + VALIDATOR + ); + + assertThatThrownBy(validator::validateConfiguration) + .isInstanceOf(TechnicalException.class) + .hasMessageContaining("is invalid"); + } + + private static Osi2PostfachProperties.ApiConfiguration createApiConfiguration() { + var conf = new Osi2PostfachProperties.ApiConfiguration(); + conf.setUrl("http://localhost:8080"); + conf.setTenant("tenant"); + conf.setNameIdentifier("abc"); + return conf; + } + + private static Osi2PostfachProperties.AuthConfiguration createAuthConfiguration() { + var conf = new Osi2PostfachProperties.AuthConfiguration(); + conf.setClientId("clientId"); + conf.setClientSecret("clientSecret"); + conf.setScope(List.of("scope")); + conf.setTokenUri("http://localhost:8081"); + conf.setResource("resource"); + return conf; + } + + private static Osi2PostfachProperties.ProxyConfiguration createProxyConfiguration() { + var conf = new Osi2PostfachProperties.ProxyConfiguration(); + conf.setEnabled(true); + conf.setHost("localhost"); + conf.setPort(8080); + return conf; + } + + private static Osi2PostfachProperties.ProxyConfiguration createDisabledProxyConfiguration() { + var conf = new Osi2PostfachProperties.ProxyConfiguration(); + conf.setEnabled(false); + return conf; + } + + private static Osi2PostfachProperties.ProxyConfiguration createInvalidProxyConfiguration() { + var conf = new Osi2PostfachProperties.ProxyConfiguration(); + conf.setEnabled(true); + conf.setHost("localhost"); + conf.setPort(null); + return conf; + } + + } + +} \ No newline at end of file