diff --git a/archetypes/helidon/src/main/archetype/common/observability.xml b/archetypes/helidon/src/main/archetype/common/observability.xml
index 0deb6d8d808..7bf21990e60 100644
--- a/archetypes/helidon/src/main/archetype/common/observability.xml
+++ b/archetypes/helidon/src/main/archetype/common/observability.xml
@@ -152,8 +152,7 @@ curl -H 'Accept: application/json' -X GET http://localhost:8080/metrics
+ * Also there is no difference regardless whether we return a single value, or a list of values.
* If the method returns a list, the provider configuration must be under config key {@code providers} under
* the configured option. On the same level as {@code providers}, there can be {@code discover-services} boolean
- * defining whether to look for services from service loader even if not configured in the configuration (this would
- * override {@link #discoverServices()} defined on this annotation.
*
* Option called {@code myProvider} that returns a single provider, or an {@link java.util.Optional} provider example
* in configuration:
@@ -108,14 +120,13 @@ private Option() {
* Option called {@code myProviders} that returns a list of providers in configuration:
*
-
@@ -463,8 +462,8 @@ curl -H 'Accept: application/json' -X GET http://localhost:8080/metrics
-
-
-
* my-type:
+ * my-providers-discover-services: true # default of this value is controlled by annotation
* my-providers:
- * discover-services: true # default of this value is controlled by annotation
- * providers:
- * provider-id:
- * provider-key1: "providerValue"
- * provider-key2: "providerValue"
- * provider2-id:
- * provider2-key1: "provider2Value"
+ * provider-id:
+ * provider-key1: "providerValue"
+ * provider-key2: "providerValue"
+ * provider2-id:
+ * provider2-key1: "provider2Value"
*
*/
@Target(ElementType.METHOD)
diff --git a/builder/api/src/main/java/io/helidon/builder/api/Prototype.java b/builder/api/src/main/java/io/helidon/builder/api/Prototype.java
index ec9f299ddba..516b0fb0757 100644
--- a/builder/api/src/main/java/io/helidon/builder/api/Prototype.java
+++ b/builder/api/src/main/java/io/helidon/builder/api/Prototype.java
@@ -95,7 +95,8 @@ public interface ConfiguredBuilder
discoverServices(Config config,
+ String configKey,
HelidonServiceLoader configType,
boolean allFromServiceLoader) {
- return ProvidedUtil.discoverServices(config, serviceLoader, providerType, configType, allFromServiceLoader);
+ return ProvidedUtil.discoverServices(config,
+ configKey,
+ serviceLoader,
+ providerType,
+ configType,
+ allFromServiceLoader);
}
/**
* Discover service from configuration.
*
- * @param config configuration located at the node of the service providers
+ * @param config configuration located at the parent node of the service providers
+ * @param configKey configuration key of the provider list
* (either a list node, or object, where each child is one service - this method requires
- * zero to one configured services)
+ * * zero to one configured services)
* @param serviceLoader helidon service loader for the expected type
* @param providerType type of the service provider interface
* @param configType type of the configured service
@@ -129,15 +137,16 @@ public interface ConfiguredBuilder> Optional
discoverService(Config config,
- HelidonServiceLoader configType,
- boolean allFromServiceLoader) {
- return ProvidedUtil.discoverService(config, serviceLoader, providerType, configType, allFromServiceLoader);
+ String configKey,
+ HelidonServiceLoader configType,
+ boolean allFromServiceLoader) {
+ return ProvidedUtil.discoverService(config, configKey, serviceLoader, providerType, configType, allFromServiceLoader);
}
}
@@ -185,6 +194,7 @@ public interface Factory
- * Each {@code OpenAPIMediaType} stands for a single format (e.g., yaml,
- * json). That said, each can map to multiple file types (e.g., yml and
- * yaml) and multiple actual media types (the proposed OpenAPI media type
- * vnd.oai.openapi and various other YAML types proposed or in use).
- */
- public enum OpenAPIMediaType {
- /**
- * JSON media type.
- */
- JSON(new MediaType[] {MediaTypes.APPLICATION_OPENAPI_JSON,
- MediaTypes.APPLICATION_JSON},
- "json"),
- /**
- * YAML media type.
- */
- YAML(new MediaType[] {MediaTypes.APPLICATION_OPENAPI_YAML,
- MediaTypes.APPLICATION_X_YAML,
- MediaTypes.APPLICATION_YAML,
- MediaTypes.TEXT_PLAIN,
- MediaTypes.TEXT_X_YAML,
- MediaTypes.TEXT_YAML},
- "yaml", "yml");
-
- /**
- * Default media type (YAML).
- */
- public static final OpenAPIMediaType DEFAULT_TYPE = YAML;
-
- static final String TYPE_LIST = "json|yaml|yml"; // must be a true constant so it can be used in an annotation
-
- private final List
- * Most likely invoked by the concrete implementations of {@link #openApiContent(OpenAPIMediaType)} as needed
- * to find static content as needed.
+ * Most likely invoked by the concrete implementations of {@link #openApiContent(OpenAPIMediaType)} as needed
+ * to find static content as needed.
*
+ * Each {@code OpenAPIMediaType} stands for a single format (e.g., yaml,
+ * json). That said, each can map to multiple file types (e.g., yml and
+ * yaml) and multiple actual media types (the proposed OpenAPI media type
+ * vnd.oai.openapi and various other YAML types proposed or in use).
+ */
+ public enum OpenAPIMediaType {
+ /**
+ * JSON media type.
+ */
+ JSON(new MediaType[] {MediaTypes.APPLICATION_OPENAPI_JSON,
+ MediaTypes.APPLICATION_JSON},
+ "json"),
+ /**
+ * YAML media type.
+ */
+ YAML(new MediaType[] {MediaTypes.APPLICATION_OPENAPI_YAML,
+ MediaTypes.APPLICATION_X_YAML,
+ MediaTypes.APPLICATION_YAML,
+ MediaTypes.TEXT_PLAIN,
+ MediaTypes.TEXT_X_YAML,
+ MediaTypes.TEXT_YAML},
+ "yaml", "yml");
+
+ /**
+ * Default media type (YAML).
+ */
+ public static final OpenAPIMediaType DEFAULT_TYPE = YAML;
+
+ static final String TYPE_LIST = "json|yaml|yml"; // must be a true constant so it can be used in an annotation
+
+ private final List
+ * Patterns always added:
+ *
* Log endpoint is protected by default and is available at {@code /observe/log} (configurable).
*/
+@Feature(value = "Log",
+ description = "WebServer Info observability support",
+ in = HelidonFlavor.SE,
+ path = {"Observe", "Log"})
module io.helidon.webserver.observe.log {
+ requires static io.helidon.common.features.api;
requires io.helidon.http.media.jsonp;
requires io.helidon.webserver;
@@ -34,6 +39,7 @@
exports io.helidon.webserver.observe.log;
- provides ObserveProvider with LogObserveProvider;
+ provides io.helidon.webserver.observe.spi.ObserveProvider
+ with io.helidon.webserver.observe.log.LogObserveProvider;
}
\ No newline at end of file
diff --git a/webserver/observe/metrics/pom.xml b/webserver/observe/metrics/pom.xml
index 3a34b7195ca..848bde9160b 100644
--- a/webserver/observe/metrics/pom.xml
+++ b/webserver/observe/metrics/pom.xml
@@ -27,6 +27,7 @@
- * By defaults creates the /metrics endpoint with three sub-paths: application,
- * vendor and base.
- *
- * To register with web server:
- *
- * This class supports finer grained configuration using Helidon Config:
- * {@link #create(io.helidon.config.Config)}. The following configuration parameters can be used:
- *
- * The application metrics registry is then available as follows:
- *
- * If this method is not called,
- * {@link MetricsFeature} would use the shared
- * instance as provided by
- * {@link io.helidon.metrics.api.MetricsFactory#globalRegistry()}.
- *
- * @param meterRegistry meterRegistry to use in this metric support
- * @return updated builder instance
- */
- public Builder meterRegistry(MeterRegistry meterRegistry) {
- this.meterRegistry = LazyValue.create(() -> meterRegistry);
- return this;
- }
-
- MeterRegistry meterRegistry() {
- return meterRegistry.get();
- }
-
- MetricsConfig metricsConfig() {
- return metricsSettingsBuilder.build();
+ @Override
+ public void afterStop() {
+ kpiMetrics.close();
}
}
}
diff --git a/webserver/observe/metrics/src/main/java/io/helidon/webserver/observe/metrics/MetricsObserveProvider.java b/webserver/observe/metrics/src/main/java/io/helidon/webserver/observe/metrics/MetricsObserveProvider.java
index bb19530745c..3d404c3ab98 100644
--- a/webserver/observe/metrics/src/main/java/io/helidon/webserver/observe/metrics/MetricsObserveProvider.java
+++ b/webserver/observe/metrics/src/main/java/io/helidon/webserver/observe/metrics/MetricsObserveProvider.java
@@ -13,53 +13,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package io.helidon.webserver.observe.metrics;
import io.helidon.common.config.Config;
-import io.helidon.http.Status;
-import io.helidon.webserver.http.HttpRouting;
import io.helidon.webserver.observe.spi.ObserveProvider;
+import io.helidon.webserver.observe.spi.Observer;
/**
* {@link java.util.ServiceLoader} provider implementation for metrics observe provider.
+ *
+ * @deprecated only for {@link java.util.ServiceLoader}
*/
+@Deprecated
public class MetricsObserveProvider implements ObserveProvider {
- private final MetricsFeature explicitService;
-
/**
* Default constructor required by {@link java.util.ServiceLoader}. Do not use.
*
- * @deprecated use {@link #create(MetricsFeature)} or
- * {@link #create()} instead.
+ * @deprecated only for {@link java.util.ServiceLoader}
*/
@Deprecated
public MetricsObserveProvider() {
- this(null);
- }
-
- private MetricsObserveProvider(MetricsFeature explicitService) {
- this.explicitService = explicitService;
- }
-
- /**
- * Create a new instance with health checks discovered through {@link java.util.ServiceLoader}.
- *
- * @return a new provider
- */
- public static ObserveProvider create() {
- return create(MetricsFeature.create());
- }
-
- /**
- * Create using a configured observer.
- * In this case configuration provided by the {@link io.helidon.webserver.observe.ObserveFeature} is ignored except for
- * the reserved option {@code endpoint}).
- *
- * @param service service to use
- * @return a new provider based on the observer
- */
- public static ObserveProvider create(MetricsFeature service) {
- return new MetricsObserveProvider(service);
}
@Override
@@ -68,27 +42,10 @@ public String configKey() {
}
@Override
- public String defaultEndpoint() {
- return explicitService == null ? "metrics" : explicitService.configuredContext();
- }
-
- @Override
- public void register(Config config, String componentPath, HttpRouting.Builder routing) {
- MetricsFeature observer = explicitService == null
- ? MetricsFeature.builder()
- .webContext(componentPath)
+ public Observer create(Config config, String name) {
+ return MetricsObserver.builder()
.config(config)
- .build()
- : explicitService;
-
- if (observer.enabled()) {
- // when created as part of observer, we need to use component path
- observer.context(componentPath);
- routing.addFeature(observer);
- } else {
- String finalPath = componentPath + (componentPath.endsWith("/") ? "*" : "/*");
- routing.get(finalPath, (req, res) -> res.status(Status.SERVICE_UNAVAILABLE_503)
- .send());
- }
+ .name(name)
+ .build();
}
}
diff --git a/webserver/observe/metrics/src/main/java/io/helidon/webserver/observe/metrics/MetricsObserver.java b/webserver/observe/metrics/src/main/java/io/helidon/webserver/observe/metrics/MetricsObserver.java
new file mode 100644
index 00000000000..89cb1fa7363
--- /dev/null
+++ b/webserver/observe/metrics/src/main/java/io/helidon/webserver/observe/metrics/MetricsObserver.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2023 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.webserver.observe.metrics;
+
+import java.util.function.Consumer;
+
+import io.helidon.builder.api.RuntimeType;
+import io.helidon.common.config.Config;
+import io.helidon.webserver.http.HttpRouting;
+import io.helidon.webserver.observe.spi.Observer;
+
+/**
+ * Support for metrics for Helidon WebServer.
+ *
+ *
+ * By default, creates the {@code /metrics} endpoint with three sub-paths: application,
+ * vendor and base.
+ *
+ * To register with web server, discovered from classpath:
+ *
+ * This class supports finer grained configuration using Helidon Config:
+ * {@link #create(io.helidon.common.config.Config)}.
+ *
+ * The application metrics registry is then available as follows:
+ *
+ * If this method is not called,
+ * {@link MetricsFeature} would use the shared
+ * instance as provided by
+ * {@link io.helidon.metrics.api.MetricsFactory#globalRegistry()}.
+ *
+ * @return meterRegistry to use in this metric support
+ */
+ Optional
+ * Example:
+ *
- * Example:
- *
+ * An observer may register features, services, filters on routing, or do some other magic that is related to
+ * observability. Some observers may expose endpoints, some may use a push approach.
+ *
+ * Configuration of an observer is located under {@code observe.observer} root configuration node, with
+ * {@link io.helidon.webserver.observe.spi.ObserveProvider#configKey()} key below it.
+ */
+public interface Observer extends NamedService {
+ /**
+ * Configuration of this observer.
+ *
+ * @return configuration of the observer
+ */
+ ObserverConfigBase prototype();
+
+ /**
+ * Type of this observer, to make sure we do not configure an observer both from {@link java.util.ServiceLoader} and
+ * using programmatic approach.
+ * If it is desired to have more than one observer of the same type, always use programmatic approach
+ *
+ * @return type of this observer, should match {@link io.helidon.webserver.observe.spi.ObserveProvider#type()}
+ */
+ @Override
+ String type();
+
+ @Override
+ default String name() {
+ return prototype().name();
+ }
+
+ /**
+ * Register the observer features, services, and/or filters.
+ * This is used by the observe feature.
+ * Do NOT use this method directly, kindly start with {@link io.helidon.webserver.observe.ObserveFeature} and register
+ * it with the routing.
+ *
+ * If this method is used directly, it will NOT do the following (as this is handled by
+ * {@link io.helidon.webserver.observe.ObserveFeature}):
+ *
+ *
+ *
+ * @return set of regular expression patterns for keys, where values should be excluded from output
+ */
+ @Option.Configured
+ @Option.Singular
+ @Option.Default({".*password", ".*passphrase", ".*secret"})
+ Set{@code
- * Routing.builder()
- * .register(MetricsSupport.create())
- * }
- *
- *
- *
- * key default value description
- * helidon.metrics.context /metrics Context root under
- * which the rest endpoints are available
- * helidon.metrics.base.${metricName}.enabled true Can
- * control which base metrics are exposed, set to false to disable a base
- * metric {@code
- * req.context().get(MetricRegistry.class).ifPresent(reg -> reg.counter("myCounter").inc());
- * }
- */
-public class MetricsFeature extends HelidonFeatureSupport {
+class MetricsFeature {
/**
* Prefix for key performance indicator metrics names.
@@ -91,83 +55,24 @@ public class MetricsFeature extends HelidonFeatureSupport {
static final String KPI_METER_NAME_PREFIX = "requests";
private static final String KPI_METER_NAME_PREFIX_WITH_DOT = KPI_METER_NAME_PREFIX + ".";
- private static final System.Logger LOGGER = System.getLogger(MetricsFeature.class.getName());
private static final Handler DISABLED_ENDPOINT_HANDLER = (req, res) -> res.status(Status.NOT_FOUND_404)
.send("Metrics are disabled");
- private static final Iterable{@code
+ * Routing.builder()
+ * .register(ObserveFeature.create())
+ * }
+ *
+ * See {@link io.helidon.webserver.observe.ObserveFeature#just(io.helidon.webserver.observe.spi.Observer...)}
+ * to customize observer setup.
+ * {@code
+ * req.context().get(MetricRegistry.class).ifPresent(reg -> reg.counter("myCounter").inc());
+ * }
+ */
+@RuntimeType.PrototypedBy(MetricsObserverConfig.class)
+public class MetricsObserver implements Observer, RuntimeType.Api
+ * If root endpoint is {@code /observe} (the default), and default health endpoint is {@code health} (relative),
+ * health endpoint would be {@code /observe/health}.
+ *
+ * @return endpoint to use
+ */
+ @Option.Default("/observe")
+ @Option.Configured
+ String endpoint();
+
+ /**
+ * Change the weight of this feature. This may change the order of registration of this feature.
+ * By default, observability weight is {@value #WEIGHT} so it is registered after routing.
+ *
+ * @return weight to use
+ */
+ @Option.DefaultDouble(WEIGHT)
+ @Option.Configured
+ double weight();
+
+ /**
+ * Observers to use with this observe features.
+ * Each observer type is registered only once, unless it uses a custom name (default name is the same as the type).
+ *
+ * @return list of observers to use in this feature
+ */
+ @Option.Singular
+ @Option.Configured
+ @Option.Provider(ObserveProvider.class)
+ List
- * If root endpoint is {@code /observe} (the default), and default health endpoint is {@code health} (relative),
- * health endpoint would be {@code /observe/health}.
- *
- * @param endpoint endpoint to use
- * @return updated builder
- */
- public Builder endpoint(String endpoint) {
- this.endpoint = endpoint;
- return this;
+ private static String endpoint(String observeEndpoint, String observerEndpoint) {
+ if (observerEndpoint.startsWith("/")) {
+ return observerEndpoint;
}
-
- private String providerEndpoint(String endpoint) {
- if (endpoint.startsWith("/")) {
- return endpoint;
- }
- return this.endpoint + "/" + endpoint;
+ if (observeEndpoint.endsWith("/")) {
+ return observeEndpoint + observerEndpoint;
}
+ return observeEndpoint + "/" + observerEndpoint;
}
- private record ProviderSetup(String endpoint, Config config, CorsSupport cors, ObserveProvider provider) {
+ private record ObserverSetup(String endpoint,
+ boolean enabled,
+ CrossOriginConfig cors,
+ Observer observer) {
}
}
diff --git a/webserver/observe/observe/src/main/java/io/helidon/webserver/observe/ObserverConfigBaseBlueprint.java b/webserver/observe/observe/src/main/java/io/helidon/webserver/observe/ObserverConfigBaseBlueprint.java
new file mode 100644
index 00000000000..d499d0ba91f
--- /dev/null
+++ b/webserver/observe/observe/src/main/java/io/helidon/webserver/observe/ObserverConfigBaseBlueprint.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2023 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.webserver.observe;
+
+import java.util.Optional;
+
+import io.helidon.builder.api.Option;
+import io.helidon.builder.api.Prototype;
+import io.helidon.cors.CrossOriginConfig;
+
+/**
+ * Base configuration for any observer that exposes an endpoint.
+ */
+@Prototype.Blueprint(builderPublic = false, createEmptyPublic = false, createFromConfigPublic = false)
+@Prototype.Configured
+interface ObserverConfigBaseBlueprint {
+ /**
+ * Cors support specific to this observer.
+ *
+ * @return cors support to use
+ */
+ @Option.Configured
+ Optional
*
*
* @return configuration key of this provider (such as {@code health})
*/
+ @Override
String configKey();
/**
- * Default endpoint of this provider. To define a relative path, do not include forward slash (such as {@code health}
- * would resolve into {@code /observe/health}).
+ * Type of this observe provider, to map to {@link io.helidon.webserver.observe.spi.Observer} when explicitly configured
+ * by user (so we do not duplicate observers).
*
- * @return default endpoint under {@code /observe}
+ * @return type of this observer, defaults to {@link #configKey()}
*/
- String defaultEndpoint();
+ default String type() {
+ return configKey();
+ }
/**
- * Register the provider's services and handlers to the routing builder.
- * The component MUST honor the provided component path.
+ * Create a new observer from the provided configuration.
*
- * @param config configuration of this provider
- * @param componentPath component path to register under (such as {@code /observe/health}, based on configured
- * endpoint and {@link #defaultEndpoint()})
- * @param routing routing builder
+ * @param config configuration of this provider
+ * @param name name of the instance
+ * @return a new observer to be registered with routing
*/
- void register(Config config, String componentPath, HttpRouting.Builder routing);
+ @Override
+ Observer create(Config config, String name);
}
diff --git a/webserver/observe/observe/src/main/java/io/helidon/webserver/observe/spi/Observer.java b/webserver/observe/observe/src/main/java/io/helidon/webserver/observe/spi/Observer.java
new file mode 100644
index 00000000000..87e0dbef33d
--- /dev/null
+++ b/webserver/observe/observe/src/main/java/io/helidon/webserver/observe/spi/Observer.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2023 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.webserver.observe.spi;
+
+import io.helidon.common.config.NamedService;
+import io.helidon.webserver.http.HttpRouting;
+import io.helidon.webserver.observe.ObserverConfigBase;
+
+/**
+ * An observer adds observability feature to Helidon {@link io.helidon.webserver.observe.ObserveFeature},
+ * such as health, metrics.
+ *
+ *
+ *
+ * @param routing routing builder
+ * @param endpoint observer endpoint, combined with observability feature endpoint if needed
+ */
+ void register(HttpRouting.Builder routing,
+ String endpoint);
+}
diff --git a/webserver/observe/observe/src/main/java/module-info.java b/webserver/observe/observe/src/main/java/module-info.java
index ba5a27061ac..4ac4fa7e940 100644
--- a/webserver/observe/observe/src/main/java/module-info.java
+++ b/webserver/observe/observe/src/main/java/module-info.java
@@ -14,16 +14,27 @@
* limitations under the License.
*/
+import io.helidon.common.features.api.Feature;
+import io.helidon.common.features.api.HelidonFlavor;
/**
* Helidon WebServer Observability Support.
*/
+@Feature(value = "Observe",
+ description = "Observability support",
+ in = HelidonFlavor.SE,
+ path = "Observe"
+)
module io.helidon.webserver.observe {
+ requires static io.helidon.common.features.api;
+
requires io.helidon.http;
requires io.helidon.webserver;
+ requires transitive io.helidon.builder.api;
requires transitive io.helidon.common.config;
+ requires transitive io.helidon.cors;
requires transitive io.helidon.webserver.cors;
exports io.helidon.webserver.observe;
diff --git a/webserver/tests/observe/health/src/test/java/io/helidon/webserver/tests/observe/health/ObserveHealthDetailsTest.java b/webserver/tests/observe/health/src/test/java/io/helidon/webserver/tests/observe/health/ObserveHealthDetailsTest.java
index 8382b5c1e93..a505103e554 100644
--- a/webserver/tests/observe/health/src/test/java/io/helidon/webserver/tests/observe/health/ObserveHealthDetailsTest.java
+++ b/webserver/tests/observe/health/src/test/java/io/helidon/webserver/tests/observe/health/ObserveHealthDetailsTest.java
@@ -25,8 +25,7 @@
import io.helidon.webclient.http1.Http1ClientResponse;
import io.helidon.webserver.http.HttpRouting;
import io.helidon.webserver.observe.ObserveFeature;
-import io.helidon.webserver.observe.health.HealthFeature;
-import io.helidon.webserver.observe.health.HealthObserveProvider;
+import io.helidon.webserver.observe.health.HealthObserver;
import io.helidon.webserver.testing.junit5.ServerTest;
import io.helidon.webserver.testing.junit5.SetUpRoute;
@@ -54,11 +53,11 @@ class ObserveHealthDetailsTest {
@SetUpRoute
static void routing(HttpRouting.Builder routing) {
healthCheck = new MyHealthCheck();
- routing.addFeature(ObserveFeature.create(HealthObserveProvider.create(HealthFeature
- .builder()
- .addCheck(healthCheck)
- .details(true)
- .build())));
+ routing.addFeature(ObserveFeature.just(HealthObserver
+ .builder()
+ .addCheck(healthCheck)
+ .details(true)
+ .build()));
}
@BeforeEach
diff --git a/webserver/tests/observe/health/src/test/java/io/helidon/webserver/tests/observe/health/ObserveHealthTest.java b/webserver/tests/observe/health/src/test/java/io/helidon/webserver/tests/observe/health/ObserveHealthTest.java
index 36e9cd8f043..3ed3e68ffa1 100644
--- a/webserver/tests/observe/health/src/test/java/io/helidon/webserver/tests/observe/health/ObserveHealthTest.java
+++ b/webserver/tests/observe/health/src/test/java/io/helidon/webserver/tests/observe/health/ObserveHealthTest.java
@@ -22,8 +22,7 @@
import io.helidon.webclient.http1.Http1ClientResponse;
import io.helidon.webserver.http.HttpRouting;
import io.helidon.webserver.observe.ObserveFeature;
-import io.helidon.webserver.observe.health.HealthFeature;
-import io.helidon.webserver.observe.health.HealthObserveProvider;
+import io.helidon.webserver.observe.health.HealthObserver;
import io.helidon.webserver.testing.junit5.ServerTest;
import io.helidon.webserver.testing.junit5.SetUpRoute;
@@ -49,7 +48,7 @@ class ObserveHealthTest {
@SetUpRoute
static void routing(HttpRouting.Builder routing) {
healthCheck = new MyHealthCheck();
- routing.addFeature(ObserveFeature.create(HealthObserveProvider.create(HealthFeature.create(healthCheck))));
+ routing.addFeature(ObserveFeature.just(HealthObserver.create(healthCheck)));
}
@BeforeEach
diff --git a/webserver/tests/observe/observe/pom.xml b/webserver/tests/observe/observe/pom.xml
new file mode 100644
index 00000000000..cdc18ed106f
--- /dev/null
+++ b/webserver/tests/observe/observe/pom.xml
@@ -0,0 +1,71 @@
+
+
+