diff --git a/config/config-mp/src/main/java/io/helidon/config/mp/DeprecatedMpConfig.java b/config/config-mp/src/main/java/io/helidon/config/mp/DeprecatedMpConfig.java new file mode 100644 index 00000000000..f20978cb7df --- /dev/null +++ b/config/config-mp/src/main/java/io/helidon/config/mp/DeprecatedMpConfig.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.helidon.config.mp; + +import java.util.Optional; +import java.util.logging.Logger; + +import org.eclipse.microprofile.config.Config; + +/** + * A utility class to handle MicroProfile configuration properties that should no longer be used. + *
+ * For one major release, the property is retrieved through this class, to warn about the usage. + * In next major release, the deprecated property is removed (as is use of this class). + *
+ * This class is closely patterned after {@code io.helidon.config.DeprecatedConfig} and works whether the MP config object
+ * is proxied by CDI or not. That other class can be used in conjunction with
+ * {@link io.helidon.config.mp.MpConfig#toHelidonConfig(org.eclipse.microprofile.config.Config)} for MP
+ * config objects that are not injected but that does work for MP config objects proxied by CDI. This one does work for
+ * those use cases.
+ */
+public final class DeprecatedMpConfig {
+ private static final Logger LOGGER = Logger.getLogger(DeprecatedMpConfig.class.getName());
+
+ private DeprecatedMpConfig() {
+ }
+
+ /**
+ * Get a value from config, attempting to read both the keys.
+ * Warning is logged if either the current key is not defined, or both the keys are defined.
+ *
+ * @param config configuration instance
+ * @param type type of the retrieved value
+ * @param currentKey key that should be used
+ * @param deprecatedKey key that should not be used
+ * @param
* By default, this health check has a threshold of 100%, meaning that it will never fail the threshold check.
* Also, by default, it will check the root path {@code /}. These defaults can be modified using the
- * {@value CONFIG_KEY_PATH} property (default {@value DEFAULT_PATH}), and the {@value CONFIG_KEY_THRESHOLD_PERCENT}
+ * {@value CURRENT_CONFIG_KEY_PATH} property (default {@value DEFAULT_PATH}), and the
+ * {@value CURRENT_CONFIG_KEY_THRESHOLD_PERCENT}
* property (default {@value DEFAULT_THRESHOLD}, virtually 100). The threshold should be set to a percent, such as 50 for 50% or
* 99 for 99%. If disk usage
* exceeds this threshold, then the health check will fail.
@@ -69,7 +70,7 @@ public class DiskSpaceHealthCheck implements HealthCheck {
* directory as application path), use
* {@link io.helidon.health.checks.DiskSpaceHealthCheck.Builder#path(java.nio.file.Path)}.
* When running within a MicroProfile server, you can configure path using a configuration key
- * {@value #CONFIG_KEY_PATH}
+ * {@value #CURRENT_CONFIG_KEY_PATH}
* Defaults to {@value}
*/
public static final String DEFAULT_PATH = ".";
@@ -82,19 +83,34 @@ public class DiskSpaceHealthCheck implements HealthCheck {
static final String CONFIG_KEY_DISKSPACE_PREFIX = "diskSpace";
static final String CONFIG_KEY_PATH_SUFFIX = "path";
- static final String CONFIG_KEY_THRESHOLD_PERCENT_SUFFIX = "thresholdPercent";
-
/**
* Full configuration key for path, when configured through MicroProfile config.
+ *
+ * @deprecated The value will change to {@value CURRENT_CONFIG_KEY_PATH} in a future release
*/
- public static final String CONFIG_KEY_PATH = HealthChecks.CONFIG_KEY_HEALTH_PREFIX
+ @Deprecated(since = "3.2.11")
+ public static final String CONFIG_KEY_PATH = HealthChecks.DEPRECATED_CONFIG_KEY_BUILT_IN_HEALTH_CHECKS_PREFIX
+ "." + CONFIG_KEY_DISKSPACE_PREFIX
+ "." + CONFIG_KEY_PATH_SUFFIX;
-
+ static final String CONFIG_KEY_THRESHOLD_PERCENT_SUFFIX = "thresholdPercent";
/**
* Full configuration key for threshold percent, when configured through Microprofile config.
+ *
+ * @deprecated The value will change to {@value CURRENT_CONFIG_KEY_THRESHOLD_PERCENT} in future release
*/
- public static final String CONFIG_KEY_THRESHOLD_PERCENT = HealthChecks.CONFIG_KEY_HEALTH_PREFIX
+ @Deprecated(since = "3.2.11")
+ public static final String CONFIG_KEY_THRESHOLD_PERCENT = HealthChecks.DEPRECATED_CONFIG_KEY_BUILT_IN_HEALTH_CHECKS_PREFIX
+ + "." + CONFIG_KEY_DISKSPACE_PREFIX
+ + "." + CONFIG_KEY_THRESHOLD_PERCENT_SUFFIX;
+
+ // The following two constants are used in the Javadoc to nudge users toward using the config key prefix "health.checks"
+ // rather than the obsolete "helidon.health". Because the original public constants above have always referred to the
+ // now-deprecated config prefixes, those values are unchanged to preserve backward compatibility.
+ private static final String CURRENT_CONFIG_KEY_PATH = HealthChecks.CONFIG_KEY_BUILT_IN_HEALTH_CHECKS_PREFIX
+ + "." + CONFIG_KEY_DISKSPACE_PREFIX
+ + "." + CONFIG_KEY_PATH_SUFFIX;
+
+ private static final String CURRENT_CONFIG_KEY_THRESHOLD_PERCENT = HealthChecks.CONFIG_KEY_BUILT_IN_HEALTH_CHECKS_PREFIX
+ "." + CONFIG_KEY_DISKSPACE_PREFIX
+ "." + CONFIG_KEY_THRESHOLD_PERCENT_SUFFIX;
@@ -114,16 +130,8 @@ public class DiskSpaceHealthCheck implements HealthCheck {
}
@Inject
- DiskSpaceHealthCheck(
- @ConfigProperty(name = CONFIG_KEY_PATH, defaultValue = DEFAULT_PATH) File path,
- @ConfigProperty(name = CONFIG_KEY_THRESHOLD_PERCENT, defaultValue = "99.999") double thresholdPercent
- ) {
- try {
- this.fileStore = Files.getFileStore(path.toPath());
- } catch (IOException e) {
- throw new HealthCheckException("Failed to obtain file store for path " + path.getAbsolutePath(), e);
- }
- this.thresholdPercent = thresholdPercent;
+ DiskSpaceHealthCheck(org.eclipse.microprofile.config.Config mpConfig) {
+ this(builder().update(applyConfig(mpConfig)));
}
private DiskSpaceHealthCheck(Builder builder) {
@@ -174,6 +182,29 @@ public static DiskSpaceHealthCheck create() {
return builder().build();
}
+ private static Consumer
@@ -62,8 +61,18 @@ public class HeapMemoryHealthCheck implements HealthCheck {
/**
* Config property key for heap memory threshold.
+ *
+ * @deprecated The value will change to {@value #CURRENT_CONFIG_KEY_THRESHOLD_PERCENT} in a future release
*/
- public static final String CONFIG_KEY_THRESHOLD_PERCENT = HealthChecks.CONFIG_KEY_HEALTH_PREFIX
+ @Deprecated(since = "3.2.11")
+ public static final String CONFIG_KEY_THRESHOLD_PERCENT = HealthChecks.DEPRECATED_CONFIG_KEY_BUILT_IN_HEALTH_CHECKS_PREFIX
+ + "." + CONFIG_KEY_HEAP_PREFIX
+ + "." + CONFIG_KEY_THRESHOLD_PERCENT_SUFFIX;
+
+ // The following constant is used in the Javadoc to nudge users toward using the current config key prefix "health.checks"
+ // rather than the deprecated "helidon.health". The public constant above has always used the now-deprecated prefix so that
+ // value is unchanged to preserve backward compatibility.
+ private static final String CURRENT_CONFIG_KEY_THRESHOLD_PERCENT = HealthChecks.CONFIG_KEY_BUILT_IN_HEALTH_CHECKS_PREFIX
+ "." + CONFIG_KEY_HEAP_PREFIX
+ "." + CONFIG_KEY_THRESHOLD_PERCENT_SUFFIX;
@@ -72,11 +81,18 @@ public class HeapMemoryHealthCheck implements HealthCheck {
// this will be ignored if not within CDI
@Inject
- HeapMemoryHealthCheck(
- Runtime runtime,
- @ConfigProperty(name = CONFIG_KEY_THRESHOLD_PERCENT, defaultValue = "98") double threshold) {
- this.thresholdPercent = threshold;
+ HeapMemoryHealthCheck(Runtime runtime, org.eclipse.microprofile.config.Config mpConfig) {
+ // Cannot use
+ this(runtime, DeprecatedMpConfig.getConfigValue(mpConfig,
+ Double.class,
+ thresholdPercentKey(HealthChecks.CONFIG_KEY_BUILT_IN_HEALTH_CHECKS_PREFIX),
+ thresholdPercentKey(HealthChecks.DEPRECATED_CONFIG_KEY_BUILT_IN_HEALTH_CHECKS_PREFIX))
+ .orElse(DEFAULT_THRESHOLD));
+ }
+
+ HeapMemoryHealthCheck(Runtime runtime, double thresholdPercent) {
this.rt = runtime;
+ this.thresholdPercent = thresholdPercent;
}
private HeapMemoryHealthCheck(Builder builder) {
@@ -104,6 +120,12 @@ public static HeapMemoryHealthCheck create() {
return builder().build();
}
+ private static String thresholdPercentKey(String prefix) {
+ return prefix + "."
+ + CONFIG_KEY_HEAP_PREFIX + "."
+ + CONFIG_KEY_THRESHOLD_PERCENT_SUFFIX;
+ }
+
@Override
public HealthCheckResponse call() {
//Formatter ensures that returned delimiter will be always the same
@@ -174,7 +196,7 @@ public Builder thresholdPercent(double threshold) {
* @param config {@code Config} node for heap memory
* @return updated builder instance
*/
- public Builder config(Config config) {
+ public Builder config(io.helidon.config.Config config) {
config.get(CONFIG_KEY_THRESHOLD_PERCENT_SUFFIX)
.asDouble()
.ifPresent(this::thresholdPercent);
diff --git a/health/health-checks/src/main/java/module-info.java b/health/health-checks/src/main/java/module-info.java
index bc7a53253fc..575bc592b33 100644
--- a/health/health-checks/src/main/java/module-info.java
+++ b/health/health-checks/src/main/java/module-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2021 Oracle and/or its affiliates.
+ * Copyright (c) 2018, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
requires io.helidon.common;
requires io.helidon.config;
+ requires io.helidon.config.mp;
requires io.helidon.health;
requires io.helidon.health.common;
requires static microprofile.config.api;
diff --git a/health/health-checks/src/test/java/io/helidon/health/checks/ConfigTest.java b/health/health-checks/src/test/java/io/helidon/health/checks/ConfigTest.java
index ff7d1054ced..39015adb15c 100644
--- a/health/health-checks/src/test/java/io/helidon/health/checks/ConfigTest.java
+++ b/health/health-checks/src/test/java/io/helidon/health/checks/ConfigTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates.
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
import io.helidon.common.http.MediaType;
import io.helidon.config.Config;
import io.helidon.config.ConfigSources;
+import io.helidon.config.DeprecatedConfig;
import io.helidon.health.HealthSupport;
import io.helidon.media.jsonp.JsonpSupport;
import io.helidon.webclient.WebClient;
@@ -69,7 +70,7 @@ static void shutdownServer(WebServer server) {
@Test
void bothFail() throws InterruptedException, ExecutionException, TimeoutException {
- JsonObject health = runWithConfig("bothFail", Http.Status.SERVICE_UNAVAILABLE_503.code());
+ JsonObject health = runWithConfig("bothFailWithDeprecatedPrefix.helidon.health", Http.Status.SERVICE_UNAVAILABLE_503.code());
JsonObject diskSpace = getLivenessCheck(health, "diskSpace");
assertThat("Disk space liveness return data", diskSpace, is(notNullValue()));
@@ -83,7 +84,7 @@ void bothFail() throws InterruptedException, ExecutionException, TimeoutExceptio
@Test
void bothPass() throws InterruptedException, ExecutionException, TimeoutException {
- JsonObject health = runWithConfig("bothPass", Http.Status.OK_200.code());
+ JsonObject health = runWithConfig("bothPassWithDeprecatedPrefix.helidon.health", Http.Status.OK_200.code());
JsonObject diskSpace = getLivenessCheck(health, "diskSpace");
assertThat("Disk space liveness return data", diskSpace, is(notNullValue()));
@@ -95,10 +96,25 @@ void bothPass() throws InterruptedException, ExecutionException, TimeoutExceptio
assertThat("Heap memory liveness check status", heapMemory.getString("status"), is("UP"));
}
+ @Test
+ void testWithoutHelidonPrefix() throws ExecutionException, InterruptedException, TimeoutException {
+ JsonObject health = runWithConfig("bothFailWithoutDeprecatedHelidonPrefix.health.checks",
+ Http.Status.SERVICE_UNAVAILABLE_503.code());
+ JsonObject diskSpace = getLivenessCheck(health, "diskSpace");
+
+ assertThat("Disk space liveness return data", diskSpace, is(notNullValue()));
+ assertThat("Disk space liveness check status", diskSpace.getString("status"), is("DOWN"));
+
+ JsonObject heapMemory = getLivenessCheck(health, "heapMemory");
+
+ assertThat("Heap memory liveness return data", heapMemory, is(notNullValue()));
+ assertThat("Heap memory liveness check status", heapMemory.getString("status"), is("DOWN"));
+ }
+
private JsonObject runWithConfig(String configKey, int expectedStatus) throws InterruptedException, ExecutionException,
TimeoutException {
HealthSupport healthSupport = HealthSupport.builder()
- .addLiveness(HealthChecks.healthChecks(testConfig.get(configKey + ".helidon.health")))
+ .addLiveness(HealthChecks.healthChecks(testConfig.get(configKey)))
.build();
WebServer webServer = null;
try {
diff --git a/health/health-checks/src/test/resources/testConfig.yaml b/health/health-checks/src/test/resources/testConfig.yaml
index b32513a91d4..46847147070 100644
--- a/health/health-checks/src/test/resources/testConfig.yaml
+++ b/health/health-checks/src/test/resources/testConfig.yaml
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2021 Oracle and/or its affiliates.
+# Copyright (c) 2021, 2024 Oracle and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,17 +13,25 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-bothFail:
+bothFailWithDeprecatedPrefix:
helidon:
health:
diskSpace:
thresholdPercent: 0.0
heapMemory:
thresholdPercent: 0.0
-bothPass:
+bothPassWithDeprecatedPrefix:
helidon:
health:
diskSpace:
thresholdPercent: 98.1
heapMemory:
- thresholdPercent: 98.1
\ No newline at end of file
+ thresholdPercent: 98.1
+# Following are set to zero to avoid the defaults and force a DOWN state the test can easily detect.
+bothFailWithoutDeprecatedHelidonPrefix:
+ health:
+ checks:
+ diskSpace:
+ thresholdPercent: 0.0
+ heapMemory:
+ thresholdPercent: 0.0
\ No newline at end of file
diff --git a/microprofile/health/pom.xml b/microprofile/health/pom.xml
index 198e85c53ea..e3355347e1b 100644
--- a/microprofile/health/pom.xml
+++ b/microprofile/health/pom.xml
@@ -60,6 +60,11 @@
+ * We specify 0 values to force the statuses to DOWN. The default config settings cause the checks to return UP, so if we
+ * detect DOWN statuses we know the config has been found and applied correctly.
+ */
+@HelidonTest
+@AddConfig(key = "health.checks.diskSpace.thresholdPercent", value = "0.0")
+@AddConfig(key = "health.checks.heapMemory.thresholdPercent", value = "0.0")
+class TestConfigPrefix {
+
+ @Inject
+ private WebTarget webTarget;
+
+ @Test
+ void testConfig() {
+ TestUtils.checkForFailure(webTarget);
+ }
+}
diff --git a/microprofile/health/src/test/java/io/helidon/microprofile/health/TestDeprecatedConfigPrefix.java b/microprofile/health/src/test/java/io/helidon/microprofile/health/TestDeprecatedConfigPrefix.java
new file mode 100644
index 00000000000..9ca5d09a0d3
--- /dev/null
+++ b/microprofile/health/src/test/java/io/helidon/microprofile/health/TestDeprecatedConfigPrefix.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.helidon.microprofile.health;
+
+import io.helidon.microprofile.tests.junit5.AddConfig;
+import io.helidon.microprofile.tests.junit5.HelidonTest;
+
+import jakarta.inject.Inject;
+import jakarta.ws.rs.client.WebTarget;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests the deprecated config prefix.
+ *
+ * We specify 0 values to force the statuses to DOWN. The default config settings cause the checks to return UP, so if we
+ * detect DOWN statuses we know the config has been found and applied correctly.
+ */
+@HelidonTest
+@AddConfig(key = "helidon.health.diskSpace.thresholdPercent", value = "0.0")
+@AddConfig(key = "helidon.health.heapMemory.thresholdPercent", value = "0.0")
+class TestDeprecatedConfigPrefix {
+
+ @Inject
+ private WebTarget webTarget;
+
+ @Test
+ void testConfig() {
+ TestUtils.checkForFailure(webTarget);
+ }
+}
diff --git a/microprofile/health/src/test/java/io/helidon/microprofile/health/TestUtils.java b/microprofile/health/src/test/java/io/helidon/microprofile/health/TestUtils.java
new file mode 100644
index 00000000000..f46976a335c
--- /dev/null
+++ b/microprofile/health/src/test/java/io/helidon/microprofile/health/TestUtils.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.helidon.microprofile.health;
+
+import io.helidon.common.http.Http;
+
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Response;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+class TestUtils {
+ static JsonObject getLivenessCheck(JsonObject health, String checkName) {
+ return health.getJsonArray("checks").stream()
+ .map(JsonValue::asJsonObject)
+ .filter(jo -> jo.getString("name").equals(checkName))
+ .findFirst()
+ .orElse(null);
+ }
+
+ static void checkForFailure(WebTarget webTarget) {
+ Response response = webTarget.path("/health")
+ .request()
+ .get();
+
+ assertThat("Health endpoint status", response.getStatus(), is(Http.Status.SERVICE_UNAVAILABLE_503.code()));
+
+ JsonObject healthJson = response.readEntity(JsonObject.class);
+ JsonObject diskSpace = TestUtils.getLivenessCheck(healthJson, "diskSpace");
+ JsonObject heapMemory = TestUtils.getLivenessCheck(healthJson, "heapMemory");
+ assertThat("Disk space liveness return data", diskSpace, is(notNullValue()));
+ assertThat("Disk space liveness check status", diskSpace.getString("status"), is("DOWN"));
+ assertThat("Heap memory liveness return data", heapMemory, is(notNullValue()));
+ assertThat("Heap memory liveness check status", heapMemory.getString("status"), is("DOWN"));
+ }
+}