diff --git a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/adapters/RawCloudProcess.java b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/adapters/RawCloudProcess.java index 4bd4b83775..931f528b75 100644 --- a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/adapters/RawCloudProcess.java +++ b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/adapters/RawCloudProcess.java @@ -23,11 +23,13 @@ public CloudProcess derive() { Integer healthCheckTimeout = null; String healthCheckHttpEndpoint = null; Integer healthCheckInvocationTimeout = null; + Integer healthCheckInterval = null; if (healthCheck.getData() != null) { Data healthCheckData = healthCheck.getData(); healthCheckTimeout = healthCheckData.getTimeout(); healthCheckInvocationTimeout = healthCheckData.getInvocationTimeout(); healthCheckHttpEndpoint = healthCheckData.getEndpoint(); + healthCheckInterval = healthCheckData.getInterval(); } Integer readinessHealthCheckInvocationTimeout = null; String readinessHealthCheckHttpEndpoint = null; @@ -49,6 +51,7 @@ public CloudProcess derive() { .healthCheckHttpEndpoint(healthCheckHttpEndpoint) .healthCheckTimeout(healthCheckTimeout) .healthCheckInvocationTimeout(healthCheckInvocationTimeout) + .healthCheckInterval(healthCheckInterval) .readinessHealthCheckType(readinessHealthCheckType.getType() .getValue()) .readinessHealthCheckHttpEndpoint(readinessHealthCheckHttpEndpoint) diff --git a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/domain/CloudProcess.java b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/domain/CloudProcess.java index 86df6003a7..ef141ae3fe 100644 --- a/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/domain/CloudProcess.java +++ b/multiapps-controller-client/src/main/java/org/cloudfoundry/multiapps/controller/client/facade/domain/CloudProcess.java @@ -29,6 +29,9 @@ public abstract class CloudProcess extends CloudEntity implements Derivable> parametersList) { Integer healthCheckInvocationTimeout = (Integer) PropertiesUtil.getPropertyValue(parametersList, SupportedParameters.HEALTH_CHECK_INVOCATION_TIMEOUT, null); + Integer healthCheckInterval = (Integer) PropertiesUtil.getPropertyValue(parametersList, + SupportedParameters.HEALTH_CHECK_INTERVAL, null); String healthCheckType = (String) PropertiesUtil.getPropertyValue(parametersList, SupportedParameters.HEALTH_CHECK_TYPE, null); String healthCheckHttpEndpoint = (String) PropertiesUtil.getPropertyValue(parametersList, SupportedParameters.HEALTH_CHECK_HTTP_ENDPOINT, @@ -67,6 +69,7 @@ public Staging parse(List> parametersList) { .stackName(stackName) .healthCheckTimeout(healthCheckTimeout) .invocationTimeout(healthCheckInvocationTimeout) + .healthCheckInterval(healthCheckInterval) .healthCheckType(healthCheckType) .healthCheckHttpEndpoint(healthCheckHttpEndpoint) .readinessHealthCheckType(readinessHealthCheckType) diff --git a/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/parser/StagingParametersParserTest.java b/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/parser/StagingParametersParserTest.java index 98677fc307..10176c6b64 100644 --- a/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/parser/StagingParametersParserTest.java +++ b/multiapps-controller-core/src/test/java/org/cloudfoundry/multiapps/controller/core/parser/StagingParametersParserTest.java @@ -21,6 +21,7 @@ import static org.cloudfoundry.multiapps.controller.core.model.SupportedParameters.BUILDPACK; import static org.cloudfoundry.multiapps.controller.core.model.SupportedParameters.BUILDPACKS; import static org.cloudfoundry.multiapps.controller.core.model.SupportedParameters.DOCKER; +import static org.cloudfoundry.multiapps.controller.core.model.SupportedParameters.HEALTH_CHECK_INTERVAL; import static org.cloudfoundry.multiapps.controller.core.model.SupportedParameters.LIFECYCLE; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -138,6 +139,24 @@ void testValidateWithAllParametersMissing() { assertNull(staging.getDockerInfo()); } + @Test + void testHealthCheckIntervalIsParsedWhenProvided() { + parametersList.add(mapOf(HEALTH_CHECK_INTERVAL, 45)); + + Staging staging = parser.parse(parametersList); + + assertNotNull(staging); + assertEquals(Integer.valueOf(45), staging.getHealthCheckInterval()); + } + + @Test + void testHealthCheckIntervalDefaultsToNullWhenMissing() { + Staging staging = parser.parse(parametersList); + + assertNotNull(staging); + assertNull(staging.getHealthCheckInterval()); + } + private static Map mapOf(String key, Object value) { return Collections.singletonMap(key, value); } diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/util/AdditionalModuleParametersReporter.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/util/AdditionalModuleParametersReporter.java index 1d2cff63be..02700b5d59 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/util/AdditionalModuleParametersReporter.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/util/AdditionalModuleParametersReporter.java @@ -40,6 +40,18 @@ public void reportUsageOfAdditionalParameters(Module module) { readinessHealthCheckInvocationTimeout, readinessHealthCheckInterval, buildpacks.toString(), module.getType()); } + String healthCheckType = (String) module.getParameters() + .get(SupportedParameters.HEALTH_CHECK_TYPE); + String healthCheckHttpEndpoint = (String) module.getParameters() + .get(SupportedParameters.HEALTH_CHECK_HTTP_ENDPOINT); + Integer healthCheckInvocationTimeout = (Integer) module.getParameters() + .get(SupportedParameters.HEALTH_CHECK_INVOCATION_TIMEOUT); + Integer healthCheckInterval = (Integer) module.getParameters() + .get(SupportedParameters.HEALTH_CHECK_INTERVAL); + if (healthCheckType != null) { + reportUsageOfHealthCheckParameters(mtaId, correlationId, healthCheckType, healthCheckHttpEndpoint, healthCheckInvocationTimeout, + healthCheckInterval, buildpacks.toString(), module.getType()); + } } // this method is being observed by Dynatrace, be careful if you change it @@ -51,4 +63,13 @@ private void reportUsageOfReadinessHealthCheckParameters(String mtaId, String co mtaId, correlationId, readinessHealthCheckType, readinessHealthCheckHttpEndpoint, readinessHealthCheckInvocationTimeout, readinessHealthCheckInterval, buildpacks, moduleType)); } + + // this method is being observed by Dynatrace, be careful if you change it + private void reportUsageOfHealthCheckParameters(String mtaId, String correlationId, String healthCheckType, + String healthCheckHttpEndpoint, Integer healthCheckInvocationTimeout, + Integer healthCheckInterval, String buildpacks, String moduleType) { + LOGGER.info(MessageFormat.format("MTA with ID \"{0}\" associated with operation ID \"{1}\" uses health check parameters: type=\"{2}\", httpEndpoint=\"{3}\", invocationTimeout=\"{4}\", interval=\"{5}\", buildpacks=\"{6}\", moduleType=\"{7}\"", + mtaId, correlationId, healthCheckType, healthCheckHttpEndpoint, healthCheckInvocationTimeout, + healthCheckInterval, buildpacks, moduleType)); + } } diff --git a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/util/AdditionalModuleParametersReporterTest.java b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/util/AdditionalModuleParametersReporterTest.java new file mode 100644 index 0000000000..fd9e6d4aa3 --- /dev/null +++ b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/util/AdditionalModuleParametersReporterTest.java @@ -0,0 +1,124 @@ +package org.cloudfoundry.multiapps.controller.process.util; + +import java.util.HashMap; +import java.util.Map; + +import org.cloudfoundry.multiapps.controller.core.model.SupportedParameters; +import org.cloudfoundry.multiapps.controller.process.steps.ProcessContext; +import org.cloudfoundry.multiapps.controller.process.variables.Variables; +import org.cloudfoundry.multiapps.mta.model.DeploymentDescriptor; +import org.cloudfoundry.multiapps.mta.model.Module; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class AdditionalModuleParametersReporterTest { + + private static final String MTA_ID = "test-mta"; + private static final String CORRELATION_ID = "corr-1"; + private static final String MODULE_TYPE = "java.tomee"; + private static final String HTTP = "http"; + private static final String ENDPOINT = "/health"; + private static final Integer INVOCATION_TIMEOUT = 5; + private static final Integer INTERVAL = 30; + + @Mock + private ProcessContext context; + + private AdditionalModuleParametersReporter reporter; + private AutoCloseable mockitoCloseable; + + @BeforeEach + void setUp() { + mockitoCloseable = MockitoAnnotations.openMocks(this); + DeploymentDescriptor descriptor = DeploymentDescriptor.createV3() + .setId(MTA_ID); + when(context.getRequiredVariable(Variables.DEPLOYMENT_DESCRIPTOR)).thenReturn(descriptor); + when(context.getRequiredVariable(Variables.CORRELATION_ID)).thenReturn(CORRELATION_ID); + reporter = new AdditionalModuleParametersReporter(context); + } + + @AfterEach + void tearDown() throws Exception { + mockitoCloseable.close(); + } + + @Test + void testReportEntersHealthCheckBranchWhenHealthCheckTypeIsPresent() { + Module module = buildModuleWithHealthCheck(HTTP, INTERVAL); + + assertDoesNotThrow(() -> reporter.reportUsageOfAdditionalParameters(module)); + + verify(context).getRequiredVariable(Variables.DEPLOYMENT_DESCRIPTOR); + verify(context).getRequiredVariable(Variables.CORRELATION_ID); + } + + private static Module buildModuleWithHealthCheck(String type, Integer interval) { + Map params = new HashMap<>(); + params.put(SupportedParameters.HEALTH_CHECK_TYPE, type); + params.put(SupportedParameters.HEALTH_CHECK_HTTP_ENDPOINT, ENDPOINT); + params.put(SupportedParameters.HEALTH_CHECK_INVOCATION_TIMEOUT, INVOCATION_TIMEOUT); + if (interval != null) { + params.put(SupportedParameters.HEALTH_CHECK_INTERVAL, interval); + } + return Module.createV3() + .setName("m") + .setType(MODULE_TYPE) + .setParameters(params); + } + + @Test + void testReportToleratesNullHealthCheckInterval() { + Module module = buildModuleWithHealthCheck(HTTP, null); + + assertDoesNotThrow(() -> reporter.reportUsageOfAdditionalParameters(module)); + } + + @Test + void testReportSkipsHealthCheckBranchWhenHealthCheckTypeIsMissing() { + Map params = new HashMap<>(); + params.put(SupportedParameters.HEALTH_CHECK_INTERVAL, INTERVAL); + Module module = Module.createV3() + .setName("m") + .setType(MODULE_TYPE) + .setParameters(params); + + assertDoesNotThrow(() -> reporter.reportUsageOfAdditionalParameters(module)); + } + + @Test + void testReportHandlesBothHealthCheckBranchesWithoutThrowing() { + Map params = new HashMap<>(); + params.put(SupportedParameters.HEALTH_CHECK_TYPE, HTTP); + params.put(SupportedParameters.HEALTH_CHECK_HTTP_ENDPOINT, ENDPOINT); + params.put(SupportedParameters.HEALTH_CHECK_INVOCATION_TIMEOUT, INVOCATION_TIMEOUT); + params.put(SupportedParameters.HEALTH_CHECK_INTERVAL, INTERVAL); + params.put(SupportedParameters.READINESS_HEALTH_CHECK_TYPE, HTTP); + params.put(SupportedParameters.READINESS_HEALTH_CHECK_HTTP_ENDPOINT, ENDPOINT); + params.put(SupportedParameters.READINESS_HEALTH_CHECK_INVOCATION_TIMEOUT, INVOCATION_TIMEOUT); + params.put(SupportedParameters.READINESS_HEALTH_CHECK_INTERVAL, INTERVAL); + Module module = Module.createV3() + .setName("m") + .setType(MODULE_TYPE) + .setParameters(params); + + assertDoesNotThrow(() -> reporter.reportUsageOfAdditionalParameters(module)); + } + + @Test + void testReportToleratesEmptyParameterMap() { + Module module = Module.createV3() + .setName("m") + .setType(MODULE_TYPE) + .setParameters(new HashMap<>()); + + assertDoesNotThrow(() -> reporter.reportUsageOfAdditionalParameters(module)); + } + +}