From 9eca51b62ef6f69788d5af3a11ffd3191965cf65 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Fri, 22 Oct 2021 11:44:37 +0200 Subject: add deadline into HSM-Facade Health-Check that fails this test if HSM-Facade does not responde --- .../actuator/HsmFacadeProviderHealthCheck.java | 74 ++++++++++++++++++---- ...deProviderHealthCheckNoKeyStoreFactoryTest.java | 3 + .../actuator/HsmFacadeProviderHealthCheckTest.java | 2 +- .../credentials/KeyOperationPerformanceTest.java | 1 + 4 files changed, 65 insertions(+), 15 deletions(-) diff --git a/eaaf-springboot-utils/src/main/java/at/gv/egiz/eaaf/utils/springboot/actuator/HsmFacadeProviderHealthCheck.java b/eaaf-springboot-utils/src/main/java/at/gv/egiz/eaaf/utils/springboot/actuator/HsmFacadeProviderHealthCheck.java index d2406552..3b2e3fe7 100644 --- a/eaaf-springboot-utils/src/main/java/at/gv/egiz/eaaf/utils/springboot/actuator/HsmFacadeProviderHealthCheck.java +++ b/eaaf-springboot-utils/src/main/java/at/gv/egiz/eaaf/utils/springboot/actuator/HsmFacadeProviderHealthCheck.java @@ -1,10 +1,17 @@ package at.gv.egiz.eaaf.utils.springboot.actuator; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Service; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory.HsmFacadeStatus; import lombok.extern.slf4j.Slf4j; @@ -19,27 +26,27 @@ import lombok.extern.slf4j.Slf4j; @Service("HsmFacadeProvider") public class HsmFacadeProviderHealthCheck implements HealthIndicator { + private static final String CONFIG_PROP_HEALTHCHECK_DEADLINE = "security.hsmfacade.healthcheck.deadline"; + private static final int DEFAULT_HEALTHCHECK_DEADLINE = 10; + @Autowired(required = false) EaafKeyStoreFactory factory; - + @Autowired(required = false) IConfiguration basicConfig; + @Override public Health health() { if (factory != null && factory.isHsmFacadeInitialized()) { + int deadline = getIntegerFromConfig(CONFIG_PROP_HEALTHCHECK_DEADLINE, DEFAULT_HEALTHCHECK_DEADLINE); + CompletableFuture asynchTestOperation = new CompletableFuture<>(); + Executors.newCachedThreadPool().submit(() -> runHsmTest(asynchTestOperation)); try { - HsmFacadeStatus status = factory.checkHsmFacadeStatus(); - log.trace("Current HSM-Facade status: {}", status); - if (HsmFacadeStatus.UP.equals(status)) { - return Health.up().build(); - - } else if (HsmFacadeStatus.DOWN.equals(status)) { - return Health.down().build(); - - } + return asynchTestOperation.get(deadline, TimeUnit.SECONDS); - } catch (Exception e) { - log.warn("HSM-Facaden Health-Check has an error", e); - return Health.down(e).build(); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + log.warn("Receive no respose from Health-Check after {} seconds.", deadline, e); + return Health.outOfService().withException(e).build(); - } + } + } else { log.trace("No {} or HSM-Facade is not initialized. Skipping healthCheck ...", @@ -51,4 +58,43 @@ public class HsmFacadeProviderHealthCheck implements HealthIndicator { } + private void runHsmTest(CompletableFuture completableFuture) { + try { + HsmFacadeStatus status = factory.checkHsmFacadeStatus(); + log.trace("Current HSM-Facade status: {}", status); + if (HsmFacadeStatus.UP.equals(status)) { + completableFuture.complete(Health.up().build()); + + } else if (HsmFacadeStatus.DOWN.equals(status)) { + completableFuture.complete(Health.down().build()); + + } + + } catch (Exception e) { + log.warn("HSM-Facaden Health-Check has an error", e); + completableFuture.complete(Health.down(e).build()); + + } + + } + + private int getIntegerFromConfig(String key, int defaultValue) { + if (basicConfig == null) { + log.info("Using default-value: {} for Config. Property: {}", defaultValue, key); + return defaultValue; + + } else { + String value = basicConfig.getBasicConfiguration(key, String.valueOf(defaultValue)); + try { + return Integer.parseInt(value); + + } catch (NumberFormatException e) { + log.warn("Config. Property: {} with value: {} is NO valid Integer", key, value, e); + log.info("Using default-value: {} for Config. Property: {}", defaultValue, key); + return defaultValue; + + } + } + } + } diff --git a/eaaf-springboot-utils/src/test/java/at/gv/egiz/eaaf/utils/springboot/test/actuator/HsmFacadeProviderHealthCheckNoKeyStoreFactoryTest.java b/eaaf-springboot-utils/src/test/java/at/gv/egiz/eaaf/utils/springboot/test/actuator/HsmFacadeProviderHealthCheckNoKeyStoreFactoryTest.java index 92c88544..9d3c0d02 100644 --- a/eaaf-springboot-utils/src/test/java/at/gv/egiz/eaaf/utils/springboot/test/actuator/HsmFacadeProviderHealthCheckNoKeyStoreFactoryTest.java +++ b/eaaf-springboot-utils/src/test/java/at/gv/egiz/eaaf/utils/springboot/test/actuator/HsmFacadeProviderHealthCheckNoKeyStoreFactoryTest.java @@ -8,6 +8,8 @@ import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.Status; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -16,6 +18,7 @@ import at.gv.egiz.eaaf.utils.springboot.actuator.HsmFacadeProviderHealthCheck; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/spring/test_spring_actuator.xml") +@DirtiesContext(classMode = ClassMode.BEFORE_CLASS) public class HsmFacadeProviderHealthCheckNoKeyStoreFactoryTest { @Mock diff --git a/eaaf-springboot-utils/src/test/java/at/gv/egiz/eaaf/utils/springboot/test/actuator/HsmFacadeProviderHealthCheckTest.java b/eaaf-springboot-utils/src/test/java/at/gv/egiz/eaaf/utils/springboot/test/actuator/HsmFacadeProviderHealthCheckTest.java index 29feee5e..d6bdf26a 100644 --- a/eaaf-springboot-utils/src/test/java/at/gv/egiz/eaaf/utils/springboot/test/actuator/HsmFacadeProviderHealthCheckTest.java +++ b/eaaf-springboot-utils/src/test/java/at/gv/egiz/eaaf/utils/springboot/test/actuator/HsmFacadeProviderHealthCheckTest.java @@ -88,7 +88,7 @@ public class HsmFacadeProviderHealthCheckTest { Health status = check.health(); //validate result - Assert.assertEquals("wrong statusCode", Status.UNKNOWN.getCode(), status.getStatus().getCode()); + Assert.assertEquals("wrong statusCode", Status.OUT_OF_SERVICE.getCode(), status.getStatus().getCode()); } diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/KeyOperationPerformanceTest.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/KeyOperationPerformanceTest.java index c907301d..90d878b9 100644 --- a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/KeyOperationPerformanceTest.java +++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/KeyOperationPerformanceTest.java @@ -31,6 +31,7 @@ import at.gv.egiz.eaaf.core.impl.data.Pair; import at.gv.egiz.eaaf.core.test.dummy.DummyAuthConfigMap; import lombok.extern.slf4j.Slf4j; +@Ignore @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/spring/test_eaaf_pvp_lazy.beans.xml") @DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD) -- cgit v1.2.3