diff --git a/CHANGELOG.md b/CHANGELOG.md index 9335746d06..644f75c377 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Usage: ./scripts/extract-changelog-for-version.sh 1.3.37 5 ``` ### 1.9.0-SNAPSHOT +* Fix #443: Add health check enricher for SmallRye Health * Fix #777: `k8s:build` with Dockerfile throws `Connection reset by peer` error on old docker daemons * Fix #1137: Add support to add `.resources` in initContainer generated by VolumePermissionEnricher * Fix #1156: `k8s:build`/`k8sBuild` tries to access Kubernetes Cluster diff --git a/gradle-plugin/kubernetes/pom.xml b/gradle-plugin/kubernetes/pom.xml index 7369bdc53f..f3f521b7f0 100644 --- a/gradle-plugin/kubernetes/pom.xml +++ b/gradle-plugin/kubernetes/pom.xml @@ -121,6 +121,11 @@ jkube-kit-wildfly-jar ${jkube.kit.version} + + org.eclipse.jkube + jkube-kit-smallrye + ${jkube.kit.version} + org.eclipse.jkube jkube-kit-profiles diff --git a/gradle-plugin/kubernetes/src/main/resources/META-INF/jkube/profiles-default.yml b/gradle-plugin/kubernetes/src/main/resources/META-INF/jkube/profiles-default.yml index 9a2df3f2a8..9be0beb708 100644 --- a/gradle-plugin/kubernetes/src/main/resources/META-INF/jkube/profiles-default.yml +++ b/gradle-plugin/kubernetes/src/main/resources/META-INF/jkube/profiles-default.yml @@ -60,6 +60,7 @@ - jkube-healthcheck-webapp - jkube-healthcheck-micronaut - jkube-healthcheck-openliberty + - jkube-healthcheck-smallrye - jkube-prometheus - jkube-service-discovery diff --git a/gradle-plugin/openshift/src/main/resources/META-INF/jkube/profiles-default.yml b/gradle-plugin/openshift/src/main/resources/META-INF/jkube/profiles-default.yml index c9e3faf4d6..f65df7360c 100644 --- a/gradle-plugin/openshift/src/main/resources/META-INF/jkube/profiles-default.yml +++ b/gradle-plugin/openshift/src/main/resources/META-INF/jkube/profiles-default.yml @@ -55,6 +55,7 @@ - jkube-healthcheck-webapp - jkube-healthcheck-micronaut - jkube-healthcheck-openliberty + - jkube-healthcheck-smallrye # DeploymentConfigEnricher converts Deployment into DeploymentConfig - jkube-openshift-deploymentconfig diff --git a/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/JKubeProjectUtil.java b/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/JKubeProjectUtil.java index 1c3191e2f6..c96cd0b994 100644 --- a/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/JKubeProjectUtil.java +++ b/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/JKubeProjectUtil.java @@ -77,20 +77,22 @@ public static boolean hasDependency(JavaProject jkubeProject, String groupId, St return getDependency(jkubeProject, groupId, artifactId) != null; } + public static boolean hasTransitiveDependency(JavaProject javaProject, String groupId, String artifactId) { + return getTransitiveDependency(javaProject, groupId, artifactId) != null; + } + public static boolean hasDependencyWithGroupId(JavaProject project, String groupId) { return Optional.ofNullable(project).map(JavaProject::getDependencies) .map(deps -> deps.stream().anyMatch(dep -> Objects.equals(dep.getGroupId(), groupId))) .orElse(false); } + public static Dependency getTransitiveDependency(JavaProject javaProject, String groupId, String artifactId) { + return getDependencyByGroupArtifact(javaProject.getDependenciesWithTransitive(), groupId, artifactId); + } + public static Dependency getDependency(JavaProject jkubeProject, String groupId, String artifactId) { - List dependencyList = jkubeProject.getDependencies(); - if (dependencyList != null) { - return iterateOverListWithCondition(dependencyList, dependency -> - Objects.equals(dependency.getGroupId(), groupId) && Objects.equals(dependency.getArtifactId(), artifactId)) - .orElse(null); - } - return null; + return getDependencyByGroupArtifact(jkubeProject.getDependencies(), groupId, artifactId); } /** @@ -198,4 +200,13 @@ public static File resolveArtifact(JavaProject project, String groupId, String a } return artifact; } + + private static Dependency getDependencyByGroupArtifact(List dependencyList, String groupId, String artifactId) { + if (dependencyList != null) { + return iterateOverListWithCondition(dependencyList, dependency -> + Objects.equals(dependency.getGroupId(), groupId) && Objects.equals(dependency.getArtifactId(), artifactId)) + .orElse(null); + } + return null; + } } diff --git a/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/MicroprofileHealthUtil.java b/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/MicroprofileHealthUtil.java index ed5d7b1333..19468c53c4 100644 --- a/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/MicroprofileHealthUtil.java +++ b/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/MicroprofileHealthUtil.java @@ -19,7 +19,8 @@ import static org.eclipse.jkube.kit.common.util.SemanticVersionUtil.isVersionAtLeast; public class MicroprofileHealthUtil { - private static final String MICROPROFILE_HEALTH_DEPENDENCY = "microprofile-health"; + private static final String MICROPROFILE_HEALTH_DEPENDENCY = "microprofile-health-api"; + private static final String MICROPROFILE_HEALTH_GROUP = "org.eclipse.microprofile.health"; private static final String MICROPROFILE_DEPENDENCY = "microprofile"; private static final String MICROPROFILE_GROUP = "org.eclipse.microprofile"; private static final int MICROPROFILE_HEALTH_SUPPORTED_VERSION_MAJOR = 3; @@ -31,19 +32,19 @@ public class MicroprofileHealthUtil { private MicroprofileHealthUtil() { } public static boolean hasMicroProfileHealthDependency(JavaProject javaProject) { - return JKubeProjectUtil.hasDependency(javaProject, MICROPROFILE_GROUP , MICROPROFILE_HEALTH_DEPENDENCY); + return JKubeProjectUtil.hasTransitiveDependency(javaProject, MICROPROFILE_HEALTH_GROUP , MICROPROFILE_HEALTH_DEPENDENCY); } public static boolean hasMicroProfileDependency(JavaProject javaProject) { - return JKubeProjectUtil.hasDependency(javaProject, MICROPROFILE_GROUP , MICROPROFILE_DEPENDENCY); + return JKubeProjectUtil.hasTransitiveDependency(javaProject, MICROPROFILE_GROUP , MICROPROFILE_DEPENDENCY); } public static boolean isStartupEndpointSupported(JavaProject javaProject) { String microProfileHealthVersion; if (hasMicroProfileDependency(javaProject)) { - microProfileHealthVersion = getMicroProfileVersionFromArtifactId(javaProject, MICROPROFILE_DEPENDENCY); + microProfileHealthVersion = getMicroProfileVersionFromArtifactId(javaProject, MICROPROFILE_GROUP, MICROPROFILE_DEPENDENCY); } else if (hasMicroProfileHealthDependency(javaProject)) { - microProfileHealthVersion = getMicroProfileVersionFromArtifactId(javaProject, MICROPROFILE_HEALTH_DEPENDENCY); + microProfileHealthVersion = getMicroProfileVersionFromArtifactId(javaProject, MICROPROFILE_HEALTH_GROUP, MICROPROFILE_HEALTH_DEPENDENCY); } else { return false; } @@ -51,8 +52,8 @@ public static boolean isStartupEndpointSupported(JavaProject javaProject) { return isVersionAtLeast(MICROPROFILE_HEALTH_SUPPORTED_VERSION_MAJOR, MICROPROFILE_HEALTH_SUPPORTED_VERSION_MINOR, microProfileHealthVersion); } - private static String getMicroProfileVersionFromArtifactId(JavaProject javaProject, String artifactId) { - Dependency microProfileDep = JKubeProjectUtil.getDependency(javaProject, MICROPROFILE_GROUP, artifactId); + private static String getMicroProfileVersionFromArtifactId(JavaProject javaProject, String groupId, String artifactId) { + Dependency microProfileDep = JKubeProjectUtil.getTransitiveDependency(javaProject, groupId, artifactId); if (microProfileDep != null) { return microProfileDep.getVersion(); } diff --git a/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/JKubeProjectUtilTest.java b/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/JKubeProjectUtilTest.java index e1a6d756c3..2d06f443cb 100644 --- a/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/JKubeProjectUtilTest.java +++ b/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/JKubeProjectUtilTest.java @@ -21,6 +21,7 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; +import java.util.Collections; import java.util.Properties; import static org.assertj.core.api.Assertions.assertThat; @@ -71,6 +72,33 @@ void hasDependencyWithGroupIdWithNoDependency() { assertThat(result).isFalse(); } + @Test + void hasTransitiveDependency_whenGroupArtifactMatchesInProvidedDeps_shouldReturnTrue() { + // Given + final JavaProject project = mock(JavaProject.class); + when(project.getDependenciesWithTransitive()).thenReturn(Collections.singletonList( + Dependency.builder().groupId("org.example").artifactId("artifact").version("1.3.37").build() + )); + + // When + final boolean result = JKubeProjectUtil.hasTransitiveDependency(project, "org.example", "artifact"); + + // Then + assertThat(result).isTrue(); + } + + @Test + void hasTransitiveDependency_whenGroupArtifactNoMatchInProvidedDeps_shouldReturnTrue() { + // Given + final JavaProject project = mock(JavaProject.class); + + // When + final boolean result = JKubeProjectUtil.hasTransitiveDependency(project, "org.example", "artifact"); + + // Then + assertThat(result).isFalse(); + } + @Test void getFinalOutputArtifact_withNothingProvided_returnsNull() { // Given diff --git a/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/MicroprofileHealthUtilTest.java b/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/MicroprofileHealthUtilTest.java index d88d5d9b46..d5d57f0c0a 100644 --- a/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/MicroprofileHealthUtilTest.java +++ b/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/MicroprofileHealthUtilTest.java @@ -17,6 +17,8 @@ import org.eclipse.jkube.kit.common.JavaProject; import org.junit.jupiter.api.Test; +import java.util.Collections; + import static org.assertj.core.api.AssertionsForClassTypes.assertThat; class MicroprofileHealthUtilTest { @@ -47,7 +49,7 @@ void hasMicroProfileDependency_withMicroProfile_shouldReturnTrue() { @Test void hasMicroProfileHealthDependency_withMicroProfileHealth_shouldReturnTrue() { // Given - JavaProject javaProject = createNewJavaProjectDependency("org.eclipse.microprofile", "microprofile-health", "5.0"); + JavaProject javaProject = createNewJavaProjectDependency("org.eclipse.microprofile.health", "microprofile-health-api", "5.0"); // When boolean result = MicroprofileHealthUtil.hasMicroProfileHealthDependency(javaProject); @@ -95,7 +97,7 @@ void isStartupEndpointSupported_withMicroprofileAfter3_1_shouldReturnTrue() { @Test void isStartupEndpointSupported_withMicroprofileHealthAfter3_1_shouldReturnTrue() { // Given - JavaProject javaProject = createNewJavaProjectDependency("org.eclipse.microprofile", "microprofile-health", "5.0"); + JavaProject javaProject = createNewJavaProjectDependency("org.eclipse.microprofile.health", "microprofile-health-api", "5.0"); // When boolean result = MicroprofileHealthUtil.isStartupEndpointSupported(javaProject); @@ -105,10 +107,10 @@ void isStartupEndpointSupported_withMicroprofileHealthAfter3_1_shouldReturnTrue( } private JavaProject createNewJavaProjectDependency(String groupId, String artifactId, String version) { - return JavaProject.builder().dependency(Dependency.builder() + return JavaProject.builder().dependenciesWithTransitive(Collections.singletonList(Dependency.builder() .groupId(groupId) .artifactId(artifactId) .version(version) - .build()).build(); + .build())).build(); } } diff --git a/jkube-kit/jkube-kit-openliberty/src/test/java/org/eclipse/jkube/openliberty/enricher/OpenLibertyHealthCheckEnricherTest.java b/jkube-kit/jkube-kit-openliberty/src/test/java/org/eclipse/jkube/openliberty/enricher/OpenLibertyHealthCheckEnricherTest.java index 8ae1fe3c1f..fd2d1785c1 100644 --- a/jkube-kit/jkube-kit-openliberty/src/test/java/org/eclipse/jkube/openliberty/enricher/OpenLibertyHealthCheckEnricherTest.java +++ b/jkube-kit/jkube-kit-openliberty/src/test/java/org/eclipse/jkube/openliberty/enricher/OpenLibertyHealthCheckEnricherTest.java @@ -182,7 +182,7 @@ void create_withMicroprofileEnabledAndEnricherConfiguration_shouldProbesAsConfig } private void withMicroprofileDependency(String microProfileVersion) { - when(javaProject.getDependencies()).thenReturn(Collections.singletonList(Dependency.builder() + when(javaProject.getDependenciesWithTransitive()).thenReturn(Collections.singletonList(Dependency.builder() .groupId("org.eclipse.microprofile") .artifactId("microprofile") .version(microProfileVersion) diff --git a/jkube-kit/jkube-kit-smallrye/pom.xml b/jkube-kit/jkube-kit-smallrye/pom.xml new file mode 100644 index 0000000000..cfc415e7c1 --- /dev/null +++ b/jkube-kit/jkube-kit-smallrye/pom.xml @@ -0,0 +1,51 @@ + + + + + jkube-kit-parent + org.eclipse.jkube + 1.9.0-SNAPSHOT + ../parent/pom.xml + + 4.0.0 + jkube-kit-smallrye + JKube Kit :: SmallRye + + + org.eclipse.jkube + jkube-kit-enricher-specific + + + org.projectlombok + lombok + + + org.junit.jupiter + junit-jupiter-engine + + + org.assertj + assertj-core + + + org.mockito + mockito-core + + + \ No newline at end of file diff --git a/jkube-kit/jkube-kit-smallrye/src/main/java/org/eclipse/jkube/smallrye/SmallRyeUtils.java b/jkube-kit/jkube-kit-smallrye/src/main/java/org/eclipse/jkube/smallrye/SmallRyeUtils.java new file mode 100644 index 0000000000..1998f45518 --- /dev/null +++ b/jkube-kit/jkube-kit-smallrye/src/main/java/org/eclipse/jkube/smallrye/SmallRyeUtils.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2019 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at: + * + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.jkube.smallrye; + +import org.eclipse.jkube.kit.common.JavaProject; +import org.eclipse.jkube.kit.common.util.JKubeProjectUtil; + +public class SmallRyeUtils { + private static final String SMALLRYE_GROUPID = "io.smallrye"; + private static final String SMALLRYE_HEALTH_ARTIFACTID = "smallrye-health"; + + private SmallRyeUtils() { } + + public static boolean hasSmallRyeDependency(JavaProject javaProject) { + return JKubeProjectUtil.hasDependency(javaProject, SMALLRYE_GROUPID , SMALLRYE_HEALTH_ARTIFACTID); + } +} \ No newline at end of file diff --git a/jkube-kit/jkube-kit-smallrye/src/main/java/org/eclipse/jkube/smallrye/enricher/SmallRyeHealthCheckEnricher.java b/jkube-kit/jkube-kit-smallrye/src/main/java/org/eclipse/jkube/smallrye/enricher/SmallRyeHealthCheckEnricher.java new file mode 100644 index 0000000000..6e77d9a7eb --- /dev/null +++ b/jkube-kit/jkube-kit-smallrye/src/main/java/org/eclipse/jkube/smallrye/enricher/SmallRyeHealthCheckEnricher.java @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2019 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at: + * + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.jkube.smallrye.enricher; + +import io.fabric8.kubernetes.api.model.Probe; +import io.fabric8.kubernetes.api.model.ProbeBuilder; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.eclipse.jkube.kit.common.Configs; +import org.eclipse.jkube.kit.enricher.api.JKubeEnricherContext; +import org.eclipse.jkube.kit.enricher.specific.AbstractHealthCheckEnricher; + +import static org.eclipse.jkube.kit.common.Configs.asInteger; +import static org.eclipse.jkube.kit.common.util.MicroprofileHealthUtil.DEFAULT_LIVENESS_PATH; +import static org.eclipse.jkube.kit.common.util.MicroprofileHealthUtil.DEFAULT_READINESS_PATH; +import static org.eclipse.jkube.kit.common.util.MicroprofileHealthUtil.DEFAULT_STARTUP_PATH; +import static org.eclipse.jkube.kit.common.util.MicroprofileHealthUtil.isStartupEndpointSupported; +import static org.eclipse.jkube.smallrye.SmallRyeUtils.hasSmallRyeDependency; + +public class SmallRyeHealthCheckEnricher extends AbstractHealthCheckEnricher { + + public SmallRyeHealthCheckEnricher(JKubeEnricherContext buildContext) { + super(buildContext, "jkube-healthcheck-smallrye"); + } + + @AllArgsConstructor + private enum Config implements Configs.Config { + + SCHEME("scheme", "HTTP"), + PORT("port", "8080"), + LIVENESS_FAILURE_THRESHOLD("livenessFailureThreshold", "3"), + LIVENESS_SUCCESS_THRESHOLD("livenessSuccessThreshold", "1"), + LIVENESS_INITIAL_DELAY("livenessInitialDelay", "0"), + LIVENESS_PERIOD_SECONDS("livenessPeriodSeconds", "10"), + LIVENESS_PATH("livenessPath", DEFAULT_LIVENESS_PATH), + READINESS_FAILURE_THRESHOLD("readinessFailureThreshold", "3"), + READINESS_SUCCESS_THRESHOLD("readinessSuccessThreshold", "1"), + READINESS_INITIAL_DELAY("readinessInitialDelay", "0"), + READINESS_PERIOD_SECONDS("readinessPeriodSeconds", "10"), + READINESS_PATH("readinessPath", DEFAULT_READINESS_PATH), + STARTUP_FAILURE_THRESHOLD("startupFailureThreshold", "3"), + STARTUP_SUCCESS_THRESHOLD("startupSuccessThreshold", "1"), + STARTUP_INITIAL_DELAY("startupInitialDelay", "0"), + STARTUP_PERIOD_SECONDS("startupPeriodSeconds", "10"), + STARTUP_PATH("startupPath", DEFAULT_STARTUP_PATH); + + @Getter + protected String key; + @Getter + protected String defaultValue; + } + + @Override + protected Probe getReadinessProbe() { + return discoverSmallRyeHealthCheck(getConfig(Config.READINESS_PATH), getConfigAsInt(Config.READINESS_INITIAL_DELAY), getConfigAsInt(Config.READINESS_FAILURE_THRESHOLD), getConfigAsInt(Config.READINESS_SUCCESS_THRESHOLD), getConfigAsInt(Config.READINESS_PERIOD_SECONDS)); + } + + @Override + protected Probe getLivenessProbe() { + return discoverSmallRyeHealthCheck(getConfig(Config.LIVENESS_PATH), getConfigAsInt(Config.LIVENESS_INITIAL_DELAY), getConfigAsInt(Config.LIVENESS_FAILURE_THRESHOLD), getConfigAsInt(Config.LIVENESS_SUCCESS_THRESHOLD), getConfigAsInt(Config.LIVENESS_PERIOD_SECONDS)); + } + + @Override + protected Probe getStartupProbe() { + if (isStartupEndpointSupported(getContext().getProject())) { + return discoverSmallRyeHealthCheck(getConfig(Config.STARTUP_PATH), getConfigAsInt(Config.STARTUP_INITIAL_DELAY), getConfigAsInt(Config.STARTUP_FAILURE_THRESHOLD), getConfigAsInt(Config.STARTUP_SUCCESS_THRESHOLD), getConfigAsInt(Config.STARTUP_PERIOD_SECONDS)); + } + return null; + } + + private Probe discoverSmallRyeHealthCheck(String path, int initialDelay, int failureThreshold, int successThreshold, int periodSeconds) { + if (hasSmallRyeDependency(getContext().getProject())) { + return new ProbeBuilder() + .withNewHttpGet() + .withNewPort(asInteger(getConfig(Config.PORT))) + .withPath(path) + .withScheme(getConfig(Config.SCHEME)) + .endHttpGet() + .withFailureThreshold(failureThreshold) + .withSuccessThreshold(successThreshold) + .withInitialDelaySeconds(initialDelay) + .withPeriodSeconds(periodSeconds) + .build(); + } + return null; + } + + private int getConfigAsInt(Configs.Config key) { + return Integer.parseInt(getConfig(key)); + } +} diff --git a/jkube-kit/jkube-kit-smallrye/src/main/resources/META-INF/jkube/enricher-default b/jkube-kit/jkube-kit-smallrye/src/main/resources/META-INF/jkube/enricher-default new file mode 100644 index 0000000000..d2dfb9ceba --- /dev/null +++ b/jkube-kit/jkube-kit-smallrye/src/main/resources/META-INF/jkube/enricher-default @@ -0,0 +1,2 @@ +# Healthcheck Enricher +org.eclipse.jkube.smallrye.enricher.SmallRyeHealthCheckEnricher \ No newline at end of file diff --git a/jkube-kit/jkube-kit-smallrye/src/test/java/org/eclipse/jkube/smallrye/SmallRyeUtilsTest.java b/jkube-kit/jkube-kit-smallrye/src/test/java/org/eclipse/jkube/smallrye/SmallRyeUtilsTest.java new file mode 100644 index 0000000000..b96802ddb4 --- /dev/null +++ b/jkube-kit/jkube-kit-smallrye/src/test/java/org/eclipse/jkube/smallrye/SmallRyeUtilsTest.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2019 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at: + * + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.jkube.smallrye; + +import org.eclipse.jkube.kit.common.Dependency; +import org.eclipse.jkube.kit.common.JavaProject; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class SmallRyeUtilsTest { + private JavaProject javaProject; + + @BeforeEach + public void setUp() { + javaProject = mock(JavaProject.class); + } + + @Test + void hasSmallRyeDependency_whenNoSmallRyeFound_thenReturnFalse() { + // Given + mockDependencies(Collections.emptyList()); + + // When + boolean result = SmallRyeUtils.hasSmallRyeDependency(javaProject); + + // Then + assertThat(result).isFalse(); + } + + @Test + void hasSmallRyeDependency_whenSmallRyeFound_thenReturnTrue() { + // Given + mockDependencies(Collections.singletonList(Dependency.builder() + .groupId("io.smallrye") + .artifactId("smallrye-health") + .build())); + + // When + boolean result = SmallRyeUtils.hasSmallRyeDependency(javaProject); + + // Then + assertThat(result).isTrue(); + } + + private void mockDependencies(List dependencyList) { + when(javaProject.getDependencies()).thenReturn(dependencyList); + } +} diff --git a/jkube-kit/jkube-kit-smallrye/src/test/java/org/eclipse/jkube/smallrye/enricher/SmallRyeHealthCheckEnricherTest.java b/jkube-kit/jkube-kit-smallrye/src/test/java/org/eclipse/jkube/smallrye/enricher/SmallRyeHealthCheckEnricherTest.java new file mode 100644 index 0000000000..39c30f42a1 --- /dev/null +++ b/jkube-kit/jkube-kit-smallrye/src/test/java/org/eclipse/jkube/smallrye/enricher/SmallRyeHealthCheckEnricherTest.java @@ -0,0 +1,202 @@ +/** + * Copyright (c) 2019 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at: + * + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.jkube.smallrye.enricher; + +import io.fabric8.kubernetes.api.model.Container; +import io.fabric8.kubernetes.api.model.KubernetesListBuilder; +import io.fabric8.kubernetes.api.model.Probe; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder; +import org.eclipse.jkube.kit.common.Dependency; +import org.eclipse.jkube.kit.common.JavaProject; +import org.eclipse.jkube.kit.config.resource.PlatformMode; +import org.eclipse.jkube.kit.config.resource.ProcessorConfig; +import org.eclipse.jkube.kit.enricher.api.JKubeEnricherContext; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.Collections; +import java.util.Properties; +import java.util.function.Supplier; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.mockito.Answers.RETURNS_DEEP_STUBS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class SmallRyeHealthCheckEnricherTest { + private JKubeEnricherContext context; + private JavaProject javaProject; + private Properties properties; + private KubernetesListBuilder klb; + + @BeforeEach + void setup() { + properties = new Properties(); + ProcessorConfig processorConfig = new ProcessorConfig(); + klb = new KubernetesListBuilder(); + klb.addToItems(new DeploymentBuilder() + .editOrNewSpec() + .editOrNewTemplate() + .editOrNewMetadata() + .withName("template-name") + .endMetadata() + .editOrNewSpec() + .addNewContainer() + .withImage("container/image") + .endContainer() + .endSpec() + .endTemplate() + .endSpec() + .build()); + + context = mock(JKubeEnricherContext.class, RETURNS_DEEP_STUBS); + javaProject = mock(JavaProject.class, RETURNS_DEEP_STUBS); + when(context.getProject()).thenReturn(javaProject); + when(context.getProperties()).thenReturn(properties); + when(context.getConfiguration().getProcessorConfig()).thenReturn(processorConfig); + when(javaProject.getProperties()).thenReturn(properties); + when(javaProject.getBaseDirectory()).thenReturn(new File("/tmp/ignore")); + when(javaProject.getOutputDirectory()).thenReturn(new File("/tmp/ignore")); + } + + @Test + void create_withNoSmallRyeDependency_shouldNotAddProbes() { + // Given + SmallRyeHealthCheckEnricher smallRyeHealthCheckEnricher = new SmallRyeHealthCheckEnricher(context); + + // When + smallRyeHealthCheckEnricher.create(PlatformMode.kubernetes, klb); + + // Then + assertNoProbesAdded(); + } + + @Test + void create_withSmallRyeDependency_shouldAddProbes() { + // Given + withSmallRyeDependency(); + withMicroprofileHealthTransitiveDependency("3.1"); + SmallRyeHealthCheckEnricher smallRyeHealthCheckEnricher = new SmallRyeHealthCheckEnricher(context); + // When + smallRyeHealthCheckEnricher.create(PlatformMode.kubernetes, klb); + // Then + assertProbesAdded("HTTP", "/health/live", "HTTP", "/health/ready", "HTTP", "/health/started"); + } + + @Test + void create_withSmallRyeDependencyAndOldMicroprofileHealthTransitiveDependency_shouldOnlyAddLivenessReadinessProbes() { + // Given + withSmallRyeDependency(); + withMicroprofileHealthTransitiveDependency("2.2"); + SmallRyeHealthCheckEnricher smallRyeHealthCheckEnricher = new SmallRyeHealthCheckEnricher(context); + // When + smallRyeHealthCheckEnricher.create(PlatformMode.kubernetes, klb); + // Then + assertProbesAdded("HTTP", "/health/live", "HTTP", "/health/ready", null, null); + assertThat(getFirstContainerFromDeployment()) + .extracting(Container::getStartupProbe) + .isNull(); + } + + @Test + void create_withMicroprofileHealthAndSmallRyeWithEnricherConfiguration_shouldProbesAsConfigured() { + // Given + withSmallRyeDependency(); + withMicroprofileHealthTransitiveDependency("3.1"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.scheme", "HTTPS"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.port", "8080"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.livenessPath", "/custom/health/live"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.livenessFailureThreshold", "5"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.livenessSuccessThreshold", "5"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.livenessInitialDelay", "5"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.livenessPeriodSeconds", "5"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.readinessPath", "/custom/health/ready"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.readinessFailureThreshold", "5"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.readinessSuccessThreshold", "5"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.readinessInitialDelay", "5"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.readinessPeriodSeconds", "5"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.startupPath", "/custom/health/startup"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.startupFailureThreshold", "5"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.startupSuccessThreshold", "5"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.startupInitialDelay", "5"); + properties.put("jkube.enricher.jkube-healthcheck-smallrye.startupPeriodSeconds", "5"); + SmallRyeHealthCheckEnricher smallRyeHealthCheckEnricher = new SmallRyeHealthCheckEnricher(context); + // When + smallRyeHealthCheckEnricher.create(PlatformMode.kubernetes, klb); + // Then + assertProbesAdded("HTTPS", "/custom/health/live", "HTTPS", "/custom/health/ready", "HTTPS", "/custom/health/startup"); + assertThat(getFirstContainerFromDeployment()) + .hasFieldOrPropertyWithValue("livenessProbe.failureThreshold", 5) + .hasFieldOrPropertyWithValue("livenessProbe.successThreshold", 5) + .hasFieldOrPropertyWithValue("livenessProbe.initialDelaySeconds", 5) + .hasFieldOrPropertyWithValue("livenessProbe.periodSeconds", 5) + .hasFieldOrPropertyWithValue("livenessProbe.httpGet.port.IntVal", 8080) + .hasFieldOrPropertyWithValue("readinessProbe.failureThreshold", 5) + .hasFieldOrPropertyWithValue("readinessProbe.successThreshold", 5) + .hasFieldOrPropertyWithValue("readinessProbe.initialDelaySeconds", 5) + .hasFieldOrPropertyWithValue("readinessProbe.periodSeconds", 5) + .hasFieldOrPropertyWithValue("readinessProbe.httpGet.port.IntVal", 8080) + .hasFieldOrPropertyWithValue("startupProbe.failureThreshold", 5) + .hasFieldOrPropertyWithValue("startupProbe.successThreshold", 5) + .hasFieldOrPropertyWithValue("startupProbe.initialDelaySeconds", 5) + .hasFieldOrPropertyWithValue("startupProbe.periodSeconds", 5) + .hasFieldOrPropertyWithValue("startupProbe.httpGet.port.IntVal", 8080); + } + + private void withMicroprofileHealthTransitiveDependency(String microProfileVersion) { + when(javaProject.getDependenciesWithTransitive()).thenReturn(Collections.singletonList(Dependency.builder() + .groupId("org.eclipse.microprofile.health") + .artifactId("microprofile-health-api") + .version(microProfileVersion) + .build())); + } + + private void withSmallRyeDependency() { + when(javaProject.getDependencies()).thenReturn(Collections.singletonList(Dependency.builder() + .groupId("io.smallrye") + .artifactId("smallrye-health") + .build())); + } + + + private void assertProbesAdded(String livenessScheme, String livenessPath, String readyScheme, String readyPath, String startedScheme, String startedPath) { + Container container = getFirstContainerFromDeployment(); + assertProbe(container::getLivenessProbe, livenessScheme, livenessPath); + assertProbe(container::getReadinessProbe, readyScheme, readyPath); + assertProbe(container::getStartupProbe, startedScheme, startedPath); + } + + private void assertNoProbesAdded() { + Container container = getFirstContainerFromDeployment(); + assertThat(container.getLivenessProbe()).isNull(); + assertThat(container.getReadinessProbe()).isNull(); + assertThat(container.getStartupProbe()).isNull(); + } + + private void assertProbe(Supplier probeSupplier, String scheme, String path) { + if (scheme != null && path != null) { + assertThat(probeSupplier.get()) + .hasFieldOrPropertyWithValue("httpGet.scheme", scheme) + .hasFieldOrPropertyWithValue("httpGet.path", path); + } + } + + private Container getFirstContainerFromDeployment() { + Deployment deployment = (Deployment) klb.buildFirstItem(); + assertThat(deployment.getSpec().getTemplate().getSpec().getContainers()).hasSize(1); + return deployment.getSpec().getTemplate().getSpec().getContainers().get(0); + } +} diff --git a/jkube-kit/pom.xml b/jkube-kit/pom.xml index 5f9112980a..cc52107307 100644 --- a/jkube-kit/pom.xml +++ b/jkube-kit/pom.xml @@ -60,6 +60,7 @@ jkube-kit-micronaut jkube-kit-openliberty jkube-kit-wildfly-jar + jkube-kit-smallrye diff --git a/kubernetes-maven-plugin/plugin/pom.xml b/kubernetes-maven-plugin/plugin/pom.xml index 8dc5e438ab..9ce1743f47 100644 --- a/kubernetes-maven-plugin/plugin/pom.xml +++ b/kubernetes-maven-plugin/plugin/pom.xml @@ -125,6 +125,12 @@ ${jkube.kit.version} + + org.eclipse.jkube + jkube-kit-smallrye + ${jkube.kit.version} + + org.eclipse.jkube jkube-kit-profiles diff --git a/kubernetes-maven-plugin/plugin/src/main/resources/META-INF/jkube/profiles-default.yml b/kubernetes-maven-plugin/plugin/src/main/resources/META-INF/jkube/profiles-default.yml index 86626f7190..c8f3e62c27 100644 --- a/kubernetes-maven-plugin/plugin/src/main/resources/META-INF/jkube/profiles-default.yml +++ b/kubernetes-maven-plugin/plugin/src/main/resources/META-INF/jkube/profiles-default.yml @@ -60,6 +60,7 @@ - jkube-healthcheck-webapp - jkube-healthcheck-micronaut - jkube-healthcheck-openliberty + - jkube-healthcheck-smallrye - jkube-prometheus - jkube-service-discovery diff --git a/openshift-maven-plugin/plugin/src/main/resources/META-INF/jkube/profiles-default.yml b/openshift-maven-plugin/plugin/src/main/resources/META-INF/jkube/profiles-default.yml index 882b5ea3d7..f4fd08fc5c 100644 --- a/openshift-maven-plugin/plugin/src/main/resources/META-INF/jkube/profiles-default.yml +++ b/openshift-maven-plugin/plugin/src/main/resources/META-INF/jkube/profiles-default.yml @@ -55,6 +55,7 @@ - jkube-healthcheck-webapp - jkube-healthcheck-micronaut - jkube-healthcheck-openliberty + - jkube-healthcheck-smallrye # DeploymentConfigEnricher converts Deployment into DeploymentConfig - jkube-openshift-deploymentconfig