This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 4865a1c CAMEL-17426: Prevent MicroProfile Health conflicting health
data
4865a1c is described below
commit 4865a1c0da461b1c1ef97b1c922e80d335251593
Author: James Netherton <[email protected]>
AuthorDate: Tue Jan 18 14:35:14 2022 +0000
CAMEL-17426: Prevent MicroProfile Health conflicting health data
* Introduce CamelMicroProfileHealthCheckRegistry
* Register individual Camel health check with SmallRye Health registries
* Aggregate routes & consumers health check results
'WIP - complete
---
.../camel-microprofile-health/pom.xml | 48 +++--
.../src/main/docs/microprofile-health.adoc | 18 +-
.../AbstractCamelMicroProfileHealthCheck.java | 122 -----------
.../AbstractCamelMicroProfileLivenessCheck.java | 48 -----
.../AbstractCamelMicroProfileReadinessCheck.java | 42 ----
.../health/CamelMicroProfileHealthCheck.java | 66 ++++++
.../CamelMicroProfileHealthCheckRegistry.java | 195 +++++++++++++++++
.../health/CamelMicroProfileHealthHelper.java | 122 +++++++++++
.../health/CamelMicroProfileLivenessCheck.java | 41 ----
.../health/CamelMicroProfileReadinessCheck.java | 41 ----
.../CamelMicroProfileRepositoryHealthCheck.java | 71 +++++++
...CamelMicroProfileHealthCheckRepositoryTest.java | 140 ++++++++++--
.../health/CamelMicroProfileHealthCheckTest.java | 236 ++++++++++++++-------
.../CamelMicroProfileHealthConsumerTest.java | 52 +++--
...CamelMicroProfileHealthRegistryBindingTest.java | 44 ++++
.../health/CamelMicroProfileHealthTestSupport.java | 88 +++++---
.../impl/health/DefaultHealthCheckRegistry.java | 9 +-
parent/pom.xml | 2 +-
18 files changed, 918 insertions(+), 467 deletions(-)
diff --git a/components/camel-microprofile/camel-microprofile-health/pom.xml
b/components/camel-microprofile/camel-microprofile-health/pom.xml
index 846b06e..07c9783 100644
--- a/components/camel-microprofile/camel-microprofile-health/pom.xml
+++ b/components/camel-microprofile/camel-microprofile-health/pom.xml
@@ -46,16 +46,22 @@
</dependency>
<dependency>
- <groupId>org.eclipse.microprofile.health</groupId>
- <artifactId>microprofile-health-api</artifactId>
- <version>${microprofile-health-version}</version>
- <scope>provided</scope>
+ <groupId>io.smallrye</groupId>
+ <artifactId>smallrye-health</artifactId>
+ <version>${smallrye-health-version}</version>
</dependency>
- <!-- smallrye health uses cdi api -->
+ <dependency>
+ <groupId>io.smallrye.config</groupId>
+ <artifactId>smallrye-config</artifactId>
+ <version>${smallrye-config-version}</version>
+ </dependency>
+
+ <!-- smallrye health uses CDI api -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>${cdi-api-2.0-version}</version>
+ <scope>provided</scope>
</dependency>
<!-- testing -->
@@ -64,17 +70,10 @@
<artifactId>camel-test-junit5</artifactId>
<scope>test</scope>
</dependency>
-
<dependency>
- <groupId>io.smallrye</groupId>
- <artifactId>smallrye-health</artifactId>
- <version>${smallrye-health-version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>io.smallrye.config</groupId>
- <artifactId>smallrye-config</artifactId>
- <version>${smallrye-config-version}</version>
+ <groupId>org.jboss.weld</groupId>
+ <artifactId>weld-junit5</artifactId>
+ <version>${weld-junit5-version}</version>
<scope>test</scope>
</dependency>
@@ -104,4 +103,23 @@
</dependency>
</dependencies>
+
+ <profiles>
+ <profile>
+ <id>jdk17-build</id>
+ <activation>
+ <jdk>[17,)</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>--add-opens
java.base/java.lang=ALL-UNNAMED</argLine>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
</project>
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/main/docs/microprofile-health.adoc
b/components/camel-microprofile/camel-microprofile-health/src/main/docs/microprofile-health.adoc
index aad6994..bd0c25c 100644
---
a/components/camel-microprofile/camel-microprofile-health/src/main/docs/microprofile-health.adoc
+++
b/components/camel-microprofile/camel-microprofile-health/src/main/docs/microprofile-health.adoc
@@ -27,6 +27,13 @@ for this component:
== Usage
+This component provides a custom `HealthCheckRegistry` implementation that
needs to be registered on the `CamelContext`.
+[source,java]
+----
+HealthCheckRegistry registry = new CamelMicroProfileHealthCheckRegistry();
+camelContext.setExtension(HealthCheckRegistry.class, registry);
+----
+
By default, Camel health checks are registered as both MicroProfile Health
liveness and readiness checks. To have finer control over whether a Camel
health check should
be considered either a readiness or liveness check, you can extend
`AbstractHealthCheck` and override the `isLiveness()` and `isReadiness()`
methods.
@@ -57,14 +64,3 @@ public class MyHealthCheck extends AbstractHealthCheck {
}
}
----
-
-== Auto discovery
-
-The expectation is that this component is run within a MicroProfile container,
where CDI and a library implementing the MicroProfile health specification is
available.
-E.g https://github.com/smallrye/smallrye-health[SmallRye Health].
-
-In this scenario, the readiness and liveness checks are automatically
discovered and registered for you.
-
-However, it's still possible to manually
-register Health checks without CDI. Ensure your camel health checks are
available in the Camel registry and add an instance of
-`CamelMicroProfileReadinessCheck` and `CamelMicroProfileLivenessCheck` to the
health check registry of your MicroProfile Health implementation.
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/AbstractCamelMicroProfileHealthCheck.java
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/AbstractCamelMicroProfileHealthCheck.java
deleted file mode 100644
index d573d29..0000000
---
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/AbstractCamelMicroProfileHealthCheck.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.camel.microprofile.health;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Collection;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.CamelContextAware;
-import org.apache.camel.health.HealthCheck.Result;
-import org.apache.camel.health.HealthCheck.State;
-import org.apache.camel.health.HealthCheckFilter;
-import org.apache.camel.health.HealthCheckHelper;
-import org.apache.camel.impl.health.AbstractHealthCheck;
-import org.eclipse.microprofile.health.HealthCheck;
-import org.eclipse.microprofile.health.HealthCheckResponse;
-import org.eclipse.microprofile.health.HealthCheckResponseBuilder;
-
-/**
- * Invokes Camel health checks and adds their results into the
HealthCheckResponseBuilder
- */
-public abstract class AbstractCamelMicroProfileHealthCheck implements
HealthCheck, CamelContextAware {
-
- @Inject
- protected CamelContext camelContext;
-
- protected abstract boolean acceptHealthCheck(AbstractHealthCheck check);
-
- @Override
- public HealthCheckResponse call() {
- final HealthCheckResponseBuilder builder =
HealthCheckResponse.builder();
- builder.name(getHealthCheckName());
- builder.up();
-
- if (camelContext != null) {
- Collection<Result> results = HealthCheckHelper.invoke(camelContext,
- (HealthCheckFilter) check -> check instanceof
AbstractHealthCheck
- && !acceptHealthCheck((AbstractHealthCheck)
check));
-
- for (Result result : results) {
- Map<String, Object> details = result.getDetails();
- boolean enabled = true;
-
- if (details.containsKey(AbstractHealthCheck.CHECK_ENABLED)) {
- enabled = (boolean)
details.get(AbstractHealthCheck.CHECK_ENABLED);
- }
-
- if (enabled) {
- details.forEach((key, value) -> builder.withData(key,
value.toString()));
-
- result.getError().ifPresent(error -> {
- builder.withData("error.message", error.getMessage());
- try (final StringWriter stackTraceWriter = new
StringWriter();
- final PrintWriter pw = new
PrintWriter(stackTraceWriter, true)) {
- error.printStackTrace(pw);
- builder.withData("error.stacktrace",
stackTraceWriter.getBuffer().toString());
- } catch (IOException exception) {
- // ignore
- }
- });
-
- builder.withData(result.getCheck().getId(),
result.getState().name());
- if (result.getState() == State.DOWN) {
- builder.down();
- }
- }
- }
- }
-
- return builder.build();
- }
-
- @Override
- public CamelContext getCamelContext() {
- return this.camelContext;
- }
-
- @Override
- public void setCamelContext(CamelContext camelContext) {
- this.camelContext = camelContext;
- }
-
- /**
- * Whether this health check can be used for readiness checks
- */
- public boolean isReadiness() {
- return true;
- }
-
- /**
- * Whether this health check can be used for liveness checks
- */
- public boolean isLiveness() {
- return true;
- }
-
- /**
- * Gets the name of the health check which will be used as a heading for
the associated checks.
- *
- * @return the health check name
- */
- abstract String getHealthCheckName();
-}
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/AbstractCamelMicroProfileLivenessCheck.java
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/AbstractCamelMicroProfileLivenessCheck.java
deleted file mode 100644
index 37c6388..0000000
---
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/AbstractCamelMicroProfileLivenessCheck.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.camel.microprofile.health;
-
-import java.util.Map;
-
-import org.apache.camel.impl.health.AbstractHealthCheck;
-
-/**
- * Ensures the implemented health check will be considered as a MicroProfile
Health liveness check
- *
- * @deprecated extend {@link AbstractHealthCheck} then override and return
false from isReadiness
- */
-@Deprecated
-public abstract class AbstractCamelMicroProfileLivenessCheck extends
AbstractHealthCheck {
-
- public AbstractCamelMicroProfileLivenessCheck(String id) {
- super("camel", id);
- }
-
- protected AbstractCamelMicroProfileLivenessCheck(String group, String id) {
- super(group, id);
- }
-
- protected AbstractCamelMicroProfileLivenessCheck(String group, String id,
Map<String, Object> meta) {
- super(group, id, meta);
- }
-
- @Override
- public boolean isReadiness() {
- return false;
- }
-
-}
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/AbstractCamelMicroProfileReadinessCheck.java
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/AbstractCamelMicroProfileReadinessCheck.java
deleted file mode 100644
index 7971e10..0000000
---
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/AbstractCamelMicroProfileReadinessCheck.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.camel.microprofile.health;
-
-import org.apache.camel.impl.health.AbstractHealthCheck;
-
-/**
- * Ensures the implemented health check will be considered as a MicroProfile
Health readiness check
- *
- * @deprecated extend {@link AbstractHealthCheck} then override and return
false from isLiveness
- */
-@Deprecated
-public abstract class AbstractCamelMicroProfileReadinessCheck extends
AbstractHealthCheck {
-
- public AbstractCamelMicroProfileReadinessCheck(String id) {
- super("camel", id);
- }
-
- public AbstractCamelMicroProfileReadinessCheck(String group, String id) {
- super(group, id);
- }
-
- @Override
- public boolean isLiveness() {
- return false;
- }
-
-}
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheck.java
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheck.java
new file mode 100644
index 0000000..efa22c9
--- /dev/null
+++
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheck.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.camel.microprofile.health;
+
+import java.util.Map;
+
+import org.apache.camel.impl.health.AbstractHealthCheck;
+import org.eclipse.microprofile.health.HealthCheck;
+import org.eclipse.microprofile.health.HealthCheckResponse;
+import org.eclipse.microprofile.health.HealthCheckResponseBuilder;
+
+import static org.apache.camel.health.HealthCheck.*;
+
+/**
+ * A MicroProfile {@link HealthCheck} that invokes the supplied Camel health
check, reports its health status and
+ * associated details.
+ */
+final class CamelMicroProfileHealthCheck implements HealthCheck {
+
+ private final org.apache.camel.health.HealthCheck camelHealthCheck;
+
+ CamelMicroProfileHealthCheck(org.apache.camel.health.HealthCheck
camelHealthCheck) {
+ this.camelHealthCheck = camelHealthCheck;
+ }
+
+ @Override
+ public HealthCheckResponse call() {
+ final HealthCheckResponseBuilder builder =
HealthCheckResponse.builder();
+ builder.name(camelHealthCheck.getId());
+ builder.up();
+
+ Result result = camelHealthCheck.call();
+ Map<String, Object> details = result.getDetails();
+ boolean enabled = true;
+
+ if (details.containsKey(AbstractHealthCheck.CHECK_ENABLED)) {
+ enabled = (boolean) details.get(AbstractHealthCheck.CHECK_ENABLED);
+ }
+
+ if (enabled) {
+ CamelMicroProfileHealthHelper.applyHealthDetail(builder, result);
+
+ if (result.getState() == State.DOWN) {
+ builder.down();
+ }
+ } else {
+ builder.withData(AbstractHealthCheck.CHECK_ENABLED, false);
+ }
+
+ return builder.build();
+ }
+}
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheckRegistry.java
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheckRegistry.java
new file mode 100644
index 0000000..536d843
--- /dev/null
+++
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheckRegistry.java
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.camel.microprofile.health;
+
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import io.smallrye.health.api.HealthRegistry;
+import org.apache.camel.CamelContext;
+import org.apache.camel.StartupListener;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckRegistry;
+import org.apache.camel.health.HealthCheckRepository;
+import org.apache.camel.impl.health.ConsumersHealthCheckRepository;
+import org.apache.camel.impl.health.DefaultHealthCheckRegistry;
+import org.apache.camel.impl.health.RoutesHealthCheckRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * {@link HealthCheckRegistry} implementation to register Camel health checks
as MicroProfile health checks on SmallRye
+ * Health.
+ */
+public class CamelMicroProfileHealthCheckRegistry extends
DefaultHealthCheckRegistry implements StartupListener {
+
+ public static final String CONSUMERS_CHECK_NAME = "camel-consumers";
+ public static final String ROUTES_CHECK_NAME = "camel-routes";
+ private static final Logger LOG =
LoggerFactory.getLogger(CamelMicroProfileHealthCheckRegistry.class);
+ private final Set<HealthCheckRepository> repositories = new
CopyOnWriteArraySet<>();
+ private HealthRegistry livenessRegistry;
+ private HealthRegistry readinessRegistry;
+
+ public CamelMicroProfileHealthCheckRegistry() {
+ this(null);
+ }
+
+ public CamelMicroProfileHealthCheckRegistry(CamelContext camelContext) {
+ super(camelContext);
+ super.setId("camel-microprofile-health");
+ }
+
+ @Override
+ protected void doInit() throws Exception {
+ super.doInit();
+ super.getCamelContext().addStartupListener(this);
+ }
+
+ @Override
+ public boolean register(Object obj) {
+ boolean registered = super.register(obj);
+ if (obj instanceof HealthCheck) {
+ HealthCheck check = (HealthCheck) obj;
+ if (check.getConfiguration().isEnabled()) {
+ registerMicroProfileHealthCheck(check);
+ }
+ } else {
+ HealthCheckRepository repository = (HealthCheckRepository) obj;
+ if (repository.stream().findAny().isPresent()) {
+ registerRepositoryChecks(repository);
+ } else {
+ // Try health check registration again on CamelContext started
+ repositories.add(repository);
+ }
+ }
+ return registered;
+ }
+
+ @Override
+ public boolean unregister(Object obj) {
+ boolean unregistered = super.unregister(obj);
+ if (obj instanceof HealthCheck) {
+ HealthCheck check = (HealthCheck) obj;
+ removeMicroProfileHealthCheck(check);
+ } else {
+ HealthCheckRepository repository = (HealthCheckRepository) obj;
+ if (repository instanceof ConsumersHealthCheckRepository ||
repository instanceof RoutesHealthCheckRepository) {
+ try {
+ getReadinessRegistry().remove(repository.getId());
+ } catch (IllegalStateException e) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Failed to remove repository readiness
health {} check due to: {}", repository.getId(),
+ e.getMessage());
+ }
+ }
+ } else {
+
repository.stream().forEach(this::removeMicroProfileHealthCheck);
+ }
+ }
+ return unregistered;
+ }
+
+ @Override
+ public void onCamelContextStarted(CamelContext context, boolean
alreadyStarted) throws Exception {
+ //Noop
+ }
+
+ @Override
+ public void onCamelContextFullyStarted(CamelContext context, boolean
alreadyStarted) throws Exception {
+ // Some repository checks may not be resolvable earlier in the
lifecycle, so try one last time on CamelContext started
+ if (alreadyStarted) {
+ repositories.stream()
+ .filter(repository ->
repository.stream().findAny().isPresent())
+ .forEach(this::registerRepositoryChecks);
+ repositories.clear();
+ }
+ }
+
+ private void registerRepositoryChecks(HealthCheckRepository repository) {
+ if (repository.isEnabled()) {
+ // Since the number of potential checks for consumers / routes is
non-deterministic
+ // avoid registering each one with SmallRye health and instead
aggregate the results so
+ // that we avoid highly verbose health output
+ if (repository instanceof ConsumersHealthCheckRepository) {
+ CamelMicroProfileRepositoryHealthCheck repositoryHealthCheck
+ = new
CamelMicroProfileRepositoryHealthCheck(repository, CONSUMERS_CHECK_NAME);
+ getReadinessRegistry().register(repository.getId(),
repositoryHealthCheck);
+ } else if (repository instanceof RoutesHealthCheckRepository) {
+ CamelMicroProfileRepositoryHealthCheck repositoryHealthCheck
+ = new
CamelMicroProfileRepositoryHealthCheck(repository, ROUTES_CHECK_NAME);
+ getReadinessRegistry().register(repository.getId(),
repositoryHealthCheck);
+ } else {
+ repository.stream()
+ .filter(healthCheck ->
healthCheck.getConfiguration().isEnabled())
+ .forEach(this::registerMicroProfileHealthCheck);
+ }
+ }
+ }
+
+ private void registerMicroProfileHealthCheck(HealthCheck camelHealthCheck)
{
+ org.eclipse.microprofile.health.HealthCheck microProfileHealthCheck
+ = new CamelMicroProfileHealthCheck(camelHealthCheck);
+
+ if (camelHealthCheck.isReadiness()) {
+ getReadinessRegistry().register(camelHealthCheck.getId(),
microProfileHealthCheck);
+ }
+
+ if (camelHealthCheck.isLiveness()) {
+ getLivenessRegistry().register(camelHealthCheck.getId(),
microProfileHealthCheck);
+ }
+ }
+
+ private void removeMicroProfileHealthCheck(HealthCheck camelHealthCheck) {
+ if (camelHealthCheck.isReadiness()) {
+ try {
+ getReadinessRegistry().remove(camelHealthCheck.getId());
+ } catch (IllegalStateException e) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Failed to remove readiness health check due to:
{}", e.getMessage());
+ }
+ }
+ }
+
+ if (camelHealthCheck.isLiveness()) {
+ try {
+ getLivenessRegistry().remove(camelHealthCheck.getId());
+ } catch (IllegalStateException e) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Failed to remove liveness health check due to:
{}", e.getMessage());
+ }
+ }
+ }
+ }
+
+ private HealthRegistry getLivenessRegistry() {
+ synchronized (this) {
+ if (livenessRegistry == null) {
+ livenessRegistry =
CamelMicroProfileHealthHelper.getLivenessRegistry();
+ }
+ }
+ return livenessRegistry;
+ }
+
+ private HealthRegistry getReadinessRegistry() {
+ synchronized (this) {
+ if (readinessRegistry == null) {
+ readinessRegistry =
CamelMicroProfileHealthHelper.getReadinessRegistry();
+ }
+ }
+ return readinessRegistry;
+ }
+}
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthHelper.java
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthHelper.java
new file mode 100644
index 0000000..ecd9fff
--- /dev/null
+++
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthHelper.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.camel.microprofile.health;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.annotation.Annotation;
+import java.util.Set;
+
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.CDI;
+
+import io.smallrye.health.api.HealthRegistry;
+import io.smallrye.health.registry.LivenessHealthRegistry;
+import io.smallrye.health.registry.ReadinessHealthRegistry;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheck.Result;
+import org.eclipse.microprofile.health.HealthCheckResponseBuilder;
+import org.eclipse.microprofile.health.Liveness;
+import org.eclipse.microprofile.health.Readiness;
+
+/**
+ * Helper utility class for MicroProfile health checks.
+ */
+final class CamelMicroProfileHealthHelper {
+
+ private CamelMicroProfileHealthHelper() {
+ // Utility class
+ }
+
+ /**
+ * Propagates details from the Camel Health {@link Result} to the
MicroProfile {@link HealthCheckResponseBuilder}.
+ *
+ * @param builder The health check response builder
+ * @param result The Camel health check result
+ */
+ public static void applyHealthDetail(HealthCheckResponseBuilder builder,
Result result) {
+ HealthCheck check = result.getCheck();
+ Set<String> metaKeys = check.getMetaData().keySet();
+
+ result.getDetails().forEach((key, value) -> {
+ // Filter health check metadata to have a less verbose output
+ if (!metaKeys.contains(key)) {
+ builder.withData(key, value.toString());
+ }
+ });
+
+ result.getError().ifPresent(error -> {
+ builder.withData("error.message", error.getMessage());
+
+ final StringWriter stackTraceWriter = new StringWriter();
+ try (final PrintWriter pw = new PrintWriter(stackTraceWriter,
true)) {
+ error.printStackTrace(pw);
+ builder.withData("error.stacktrace",
stackTraceWriter.toString());
+ }
+ });
+ }
+
+ /**
+ * Retrieves the {@link LivenessHealthRegistry} bean instance.
+ *
+ * @return The {@link LivenessHealthRegistry} bean.
+ */
+ public static HealthRegistry getLivenessRegistry() {
+ return getHealthRegistryBean(LivenessHealthRegistry.class,
Liveness.Literal.INSTANCE);
+ }
+
+ /**
+ * Retrieves the {@link ReadinessHealthRegistry} bean instance.
+ *
+ * @return The {@link ReadinessHealthRegistry} bean.
+ */
+ public static HealthRegistry getReadinessRegistry() {
+ return getHealthRegistryBean(ReadinessHealthRegistry.class,
Readiness.Literal.INSTANCE);
+ }
+
+ /**
+ * Retrieves a {@link HealthRegistry} bean from the CDI bean manager for
the given type and qualifier.
+ *
+ * Registry beans are looked up from the CDI {@link BeanManager} to avoid
CDI injection in
+ * {@link CamelMicroProfileHealthCheckRegistry} and also avoid having to
add CDI bean defining annotations to
+ * {@link CamelMicroProfileHealthCheckRegistry}.
+ *
+ * Eventually this can be removed when upgrading to a future SmallRye
Health release where static health registry
+ * lookups will be supported.
+ *
+ * https://github.com/smallrye/smallrye-health/issues/172
+ *
+ * @param type The implementation class of the {@link
HealthRegistry} bean
+ * @param qualifier The annotation qualifier applied to the
{@link HealthRegistry} bean
+ * @return The {@link HealthRegistry} bean
+ * @throws IllegalStateException if no beans matching the {@link
HealthRegistry} bean type and annotation qualifier
+ * were found
+ */
+ private static HealthRegistry getHealthRegistryBean(Class<? extends
HealthRegistry> type, Annotation qualifier) {
+ BeanManager beanManager = CDI.current().getBeanManager();
+ Set<Bean<?>> beans = beanManager.getBeans(type, qualifier);
+ if (beans.isEmpty()) {
+ throw new IllegalStateException(
+ "Beans for type " + type.getName() + " with qualifier " +
qualifier + " could not be found.");
+ }
+
+ Bean<?> bean = beanManager.resolve(beans);
+ Object reference = beanManager.getReference(bean, type,
beanManager.createCreationalContext(bean));
+ return type.cast(reference);
+ }
+}
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileLivenessCheck.java
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileLivenessCheck.java
deleted file mode 100644
index 61ef1c4..0000000
---
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileLivenessCheck.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.camel.microprofile.health;
-
-import org.apache.camel.impl.health.AbstractHealthCheck;
-import org.eclipse.microprofile.health.Liveness;
-
-/**
- * Liveness checks
- */
-@Liveness
-public class CamelMicroProfileLivenessCheck extends
AbstractCamelMicroProfileHealthCheck {
-
- @Override
- public boolean isReadiness() {
- return false;
- }
-
- protected boolean acceptHealthCheck(AbstractHealthCheck check) {
- return check.isLiveness();
- }
-
- @Override
- String getHealthCheckName() {
- return "camel-liveness-checks";
- }
-}
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileReadinessCheck.java
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileReadinessCheck.java
deleted file mode 100644
index 0ff301c..0000000
---
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileReadinessCheck.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.camel.microprofile.health;
-
-import org.apache.camel.impl.health.AbstractHealthCheck;
-import org.eclipse.microprofile.health.Readiness;
-
-/**
- * Readiness checks
- */
-@Readiness
-public class CamelMicroProfileReadinessCheck extends
AbstractCamelMicroProfileHealthCheck {
-
- @Override
- public boolean isLiveness() {
- return false;
- }
-
- protected boolean acceptHealthCheck(AbstractHealthCheck check) {
- return check.isReadiness();
- }
-
- @Override
- String getHealthCheckName() {
- return "camel-readiness-checks";
- }
-}
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileRepositoryHealthCheck.java
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileRepositoryHealthCheck.java
new file mode 100644
index 0000000..4cc8530
--- /dev/null
+++
b/components/camel-microprofile/camel-microprofile-health/src/main/java/org/apache/camel/microprofile/health/CamelMicroProfileRepositoryHealthCheck.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.camel.microprofile.health;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.camel.health.HealthCheck.Result;
+import org.apache.camel.health.HealthCheck.State;
+import org.apache.camel.health.HealthCheckRepository;
+import org.apache.camel.impl.health.AbstractHealthCheck;
+import org.eclipse.microprofile.health.HealthCheck;
+import org.eclipse.microprofile.health.HealthCheckResponse;
+import org.eclipse.microprofile.health.HealthCheckResponseBuilder;
+
+/**
+ * Invokes health checks registered with a {@link HealthCheckRepository} and
resolves / aggregates the results into a
+ * single UP / DOWN status.
+ */
+final class CamelMicroProfileRepositoryHealthCheck implements HealthCheck {
+
+ private final HealthCheckRepository repository;
+ private final String name;
+
+ CamelMicroProfileRepositoryHealthCheck(HealthCheckRepository repository,
String name) {
+ this.repository = repository;
+ this.name = name;
+ }
+
+ @Override
+ public HealthCheckResponse call() {
+ final HealthCheckResponseBuilder builder =
HealthCheckResponse.builder();
+ builder.name(name);
+ builder.up();
+
+ if (repository.isEnabled()) {
+ List<Result> results = repository.stream()
+ .filter(healthCheck ->
healthCheck.getConfiguration().isEnabled())
+ .map(org.apache.camel.health.HealthCheck::call)
+ .filter(result -> result != null)
+ .collect(Collectors.toList());
+
+ // If any of the result statuses is DOWN, find the first one and
report any error details
+ results.stream()
+ .filter(result -> result.getState().equals(State.DOWN))
+ .findFirst()
+ .ifPresent(result -> {
+
CamelMicroProfileHealthHelper.applyHealthDetail(builder, result);
+ builder.down();
+ });
+ } else {
+ builder.withData(AbstractHealthCheck.CHECK_ENABLED, false);
+ }
+
+ return builder.build();
+ }
+}
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheckRepositoryTest.java
b/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheckRepositoryTest.java
index 83d1be8..33e9ad3 100644
---
a/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheckRepositoryTest.java
+++
b/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheckRepositoryTest.java
@@ -16,17 +16,27 @@
*/
package org.apache.camel.microprofile.health;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+
import javax.json.JsonArray;
import javax.json.JsonObject;
import io.smallrye.health.SmallRyeHealth;
import org.apache.camel.RoutesBuilder;
+import org.apache.camel.ServiceStatus;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckConfiguration;
import org.apache.camel.health.HealthCheckRegistry;
+import org.apache.camel.health.HealthCheckRepository;
import org.eclipse.microprofile.health.HealthCheckResponse.Status;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import static
org.apache.camel.microprofile.health.CamelMicroProfileHealthCheckRegistry.ROUTES_CHECK_NAME;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CamelMicroProfileHealthCheckRepositoryTest extends
CamelMicroProfileHealthTestSupport {
@@ -38,10 +48,6 @@ public class CamelMicroProfileHealthCheckRepositoryTest
extends CamelMicroProfil
Object hc = healthCheckRegistry.resolveById("routes");
healthCheckRegistry.register(hc);
- CamelMicroProfileReadinessCheck readinessCheck = new
CamelMicroProfileReadinessCheck();
- readinessCheck.setCamelContext(context);
- reporter.addHealthCheck(readinessCheck);
-
SmallRyeHealth health = reporter.getHealth();
JsonObject healthObject = getHealthJson(health);
@@ -50,13 +56,7 @@ public class CamelMicroProfileHealthCheckRepositoryTest
extends CamelMicroProfil
JsonArray checks = healthObject.getJsonArray("checks");
assertEquals(1, checks.size());
-
Assertions.assertNotNull(checks.getJsonObject(0).getJsonObject("data"));
- Assertions.assertEquals("healthyRoute",
checks.getJsonObject(0).getJsonObject("data").getString("route.id"));
-
- assertHealthCheckOutput("camel-readiness-checks", Status.UP,
checks.getJsonObject(0), jsonObject -> {
- assertEquals(Status.UP.name(),
jsonObject.getString("route:healthyRoute"));
- assertEquals("Started", jsonObject.getString("route.status"));
- });
+ assertHealthCheckOutput(ROUTES_CHECK_NAME, Status.UP,
checks.getJsonObject(0));
}
@Test
@@ -66,10 +66,6 @@ public class CamelMicroProfileHealthCheckRepositoryTest
extends CamelMicroProfil
Object hc = healthCheckRegistry.resolveById("routes");
healthCheckRegistry.register(hc);
- CamelMicroProfileReadinessCheck readinessCheck = new
CamelMicroProfileReadinessCheck();
- readinessCheck.setCamelContext(context);
- reporter.addHealthCheck(readinessCheck);
-
context.getRouteController().stopRoute("healthyRoute");
SmallRyeHealth health = reporter.getHealth();
@@ -80,12 +76,118 @@ public class CamelMicroProfileHealthCheckRepositoryTest
extends CamelMicroProfil
JsonArray checks = healthObject.getJsonArray("checks");
assertEquals(1, checks.size());
- assertHealthCheckOutput("camel-readiness-checks", Status.DOWN,
checks.getJsonObject(0), jsonObject -> {
- assertEquals(Status.DOWN.name(),
jsonObject.getString("route:healthyRoute"));
- assertEquals("Stopped", jsonObject.getString("route.status"));
+ assertHealthCheckOutput(ROUTES_CHECK_NAME, Status.DOWN,
checks.getJsonObject(0), jsonObject -> {
+ assertEquals("healthyRoute", jsonObject.getString("route.id"));
+ assertEquals(ServiceStatus.Stopped.name(),
jsonObject.getString("route.status"));
});
}
+ @Test
+ public void testCamelHealthCheckRepositoryDisabled() throws Exception {
+ HealthCheckRegistry healthCheckRegistry =
HealthCheckRegistry.get(context);
+ // register disabled routes health check repository
+ HealthCheckRepository hc = (HealthCheckRepository)
healthCheckRegistry.resolveById("routes");
+ hc.setEnabled(false);
+ healthCheckRegistry.register(hc);
+
+ context.getRouteController().stopRoute("healthyRoute");
+
+ SmallRyeHealth health = reporter.getHealth();
+
+ JsonObject healthObject = getHealthJson(health);
+ assertEquals(Status.UP.name(), healthObject.getString("status"));
+
+ JsonArray checks = healthObject.getJsonArray("checks");
+ assertEquals(0, checks.size());
+ }
+
+ @Test
+ public void testCamelHealthCheckRepositorySpecificChecksDisabled() throws
Exception {
+ List<HealthCheck> repositoryChecks = new ArrayList<>();
+ repositoryChecks.add(createLivenessCheck("check-1", true, builder ->
builder.up()));
+ repositoryChecks.add(createLivenessCheck("check-2", false, builder ->
builder.up()));
+ repositoryChecks.add(createLivenessCheck("check-3", true, builder ->
builder.down()));
+
+ HealthCheckRepository repository = new HealthCheckRepository() {
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ // Noop
+ }
+
+ @Override
+ public void setConfigurations(Map<String,
HealthCheckConfiguration> configurations) {
+ // Noop
+ }
+
+ @Override
+ public Map<String, HealthCheckConfiguration> getConfigurations() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public void addConfiguration(String id, HealthCheckConfiguration
configuration) {
+ // Noop
+ }
+
+ @Override
+ public Stream<HealthCheck> stream() {
+ return repositoryChecks.stream();
+ }
+
+ @Override
+ public String getId() {
+ return "custom-repository";
+ }
+ };
+
+ HealthCheckRegistry healthCheckRegistry =
HealthCheckRegistry.get(context);
+ healthCheckRegistry.register(repository);
+
+ SmallRyeHealth health = reporter.getHealth();
+
+ JsonObject healthObject = getHealthJson(health);
+ assertEquals(Status.DOWN.name(), healthObject.getString("status"));
+
+ JsonArray checks = healthObject.getJsonArray("checks");
+ assertEquals(2, checks.size());
+
+ assertHealthCheckOutput("check-3", Status.DOWN,
checks.getJsonObject(0));
+
+ assertHealthCheckOutput("check-1", Status.UP, checks.getJsonObject(1));
+ }
+
+ @Test
+ public void testRoutesRepositoryUnregister() {
+ HealthCheckRegistry healthCheckRegistry =
HealthCheckRegistry.get(context);
+ Object hc = healthCheckRegistry.resolveById("routes");
+ healthCheckRegistry.register(hc);
+
+ SmallRyeHealth health = reporter.getHealth();
+
+ JsonObject healthObject = getHealthJson(health);
+ assertEquals(Status.UP.name(), healthObject.getString("status"));
+
+ JsonArray checks = healthObject.getJsonArray("checks");
+ assertEquals(1, checks.size());
+
+ assertHealthCheckOutput(ROUTES_CHECK_NAME, Status.UP,
checks.getJsonObject(0));
+
+ healthCheckRegistry.unregister(hc);
+
+ health = reporter.getHealth();
+
+ healthObject = getHealthJson(health);
+ assertEquals(Status.UP.name(), healthObject.getString("status"));
+
+ checks = healthObject.getJsonArray("checks");
+ assertEquals(0, checks.size());
+ }
+
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheckTest.java
b/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheckTest.java
index c040e77..298c842 100644
---
a/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheckTest.java
+++
b/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheckTest.java
@@ -16,41 +16,44 @@
*/
package org.apache.camel.microprofile.health;
+import java.util.Map;
+
import javax.json.JsonArray;
import javax.json.JsonObject;
import io.smallrye.health.SmallRyeHealth;
+import org.apache.camel.ServiceStatus;
+import org.apache.camel.health.HealthCheck;
import org.apache.camel.health.HealthCheckRegistry;
+import org.apache.camel.health.HealthCheckResultBuilder;
import org.apache.camel.impl.engine.ExplicitCamelContextNameStrategy;
+import org.apache.camel.impl.health.AbstractHealthCheck;
import org.apache.camel.impl.health.ContextHealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse.Status;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
public class CamelMicroProfileHealthCheckTest extends
CamelMicroProfileHealthTestSupport {
@Test
- public void testCamelContextHealthCheckUpStatus() {
+ public void testCamelContextHealthCheckUpStatus() throws Exception {
context.setNameStrategy(new
ExplicitCamelContextNameStrategy("health-context"));
context.getExtension(HealthCheckRegistry.class).register(new
ContextHealthCheck());
- CamelMicroProfileReadinessCheck check = new
CamelMicroProfileReadinessCheck();
- check.setCamelContext(context);
- reporter.addHealthCheck(check);
-
SmallRyeHealth health = reporter.getHealth();
JsonObject healthObject = getHealthJson(health);
-
assertEquals(Status.UP.name(), healthObject.getString("status"));
JsonArray checks = healthObject.getJsonArray("checks");
assertEquals(1, checks.size());
- assertHealthCheckOutput("camel-readiness-checks", Status.UP,
checks.getJsonObject(0), checksJson -> {
- assertEquals(Status.UP.name(), checksJson.getString("context"));
+ assertHealthCheckOutput("context", Status.UP, checks.getJsonObject(0),
checksJson -> {
+ assertEquals("health-context",
checksJson.getString("context.name"));
+ assertEquals(ServiceStatus.Started.name(),
checksJson.getString("context.status"));
});
}
@@ -59,10 +62,6 @@ public class CamelMicroProfileHealthCheckTest extends
CamelMicroProfileHealthTes
context.setNameStrategy(new
ExplicitCamelContextNameStrategy("health-context"));
context.getExtension(HealthCheckRegistry.class).register(new
ContextHealthCheck());
- CamelMicroProfileReadinessCheck check = new
CamelMicroProfileReadinessCheck();
- check.setCamelContext(context);
- reporter.addHealthCheck(check);
-
context.stop();
SmallRyeHealth health = reporter.getHealth();
@@ -73,8 +72,9 @@ public class CamelMicroProfileHealthCheckTest extends
CamelMicroProfileHealthTes
JsonArray checks = healthObject.getJsonArray("checks");
assertEquals(1, checks.size());
- assertHealthCheckOutput("camel-readiness-checks", Status.DOWN,
checks.getJsonObject(0), checksJson -> {
- assertEquals(Status.DOWN.name(), checksJson.getString("context"));
+ assertHealthCheckOutput("context", Status.DOWN,
checks.getJsonObject(0), checksJson -> {
+ assertEquals("health-context",
checksJson.getString("context.name"));
+ assertEquals(ServiceStatus.Stopped.name(),
checksJson.getString("context.status"));
});
}
@@ -86,23 +86,16 @@ public class CamelMicroProfileHealthCheckTest extends
CamelMicroProfileHealthTes
healthCheckRegistry.register(createLivenessCheck("liveness-2", true,
builder -> builder.up()));
healthCheckRegistry.register(createReadinessCheck("readiness-3", true,
builder -> builder.up()));
- CamelMicroProfileLivenessCheck livenessCheck = new
CamelMicroProfileLivenessCheck();
- livenessCheck.setCamelContext(context);
- reporter.addHealthCheck(livenessCheck);
-
- SmallRyeHealth health = reporter.getHealth();
+ SmallRyeHealth health = reporter.getLiveness();
JsonObject healthObject = getHealthJson(health);
assertEquals(Status.UP.name(), healthObject.getString("status"));
JsonArray checks = healthObject.getJsonArray("checks");
- assertEquals(1, checks.size());
+ assertEquals(2, checks.size());
- JsonObject checksObject = checks.getJsonObject(0);
- assertHealthCheckOutput("camel-liveness-checks", Status.UP,
checksObject, checksJson -> {
- assertEquals(Status.UP.name(), checksJson.getString("liveness-1"));
- assertEquals(Status.UP.name(), checksJson.getString("liveness-2"));
- });
+ assertHealthCheckOutput("liveness-1", Status.UP,
checks.getJsonObject(0));
+ assertHealthCheckOutput("liveness-2", Status.UP,
checks.getJsonObject(1));
}
@Test
@@ -113,23 +106,16 @@ public class CamelMicroProfileHealthCheckTest extends
CamelMicroProfileHealthTes
healthCheckRegistry.register(createLivenessCheck("liveness-2", true,
builder -> builder.down()));
healthCheckRegistry.register(createReadinessCheck("readiness-3", true,
builder -> builder.up()));
- CamelMicroProfileLivenessCheck livenessCheck = new
CamelMicroProfileLivenessCheck();
- livenessCheck.setCamelContext(context);
- reporter.addHealthCheck(livenessCheck);
-
- SmallRyeHealth health = reporter.getHealth();
+ SmallRyeHealth health = reporter.getLiveness();
JsonObject healthObject = getHealthJson(health);
assertEquals(Status.DOWN.name(), healthObject.getString("status"));
JsonArray checks = healthObject.getJsonArray("checks");
- assertEquals(1, checks.size());
+ assertEquals(2, checks.size());
- JsonObject checksObject = checks.getJsonObject(0);
- assertHealthCheckOutput("camel-liveness-checks", Status.DOWN,
checksObject, checksJson -> {
- assertEquals(Status.UP.name(), checksJson.getString("liveness-1"));
- assertEquals(Status.DOWN.name(),
checksJson.getString("liveness-2"));
- });
+ assertHealthCheckOutput("liveness-1", Status.UP,
checks.getJsonObject(0));
+ assertHealthCheckOutput("liveness-2", Status.DOWN,
checks.getJsonObject(1));
}
@Test
@@ -140,22 +126,16 @@ public class CamelMicroProfileHealthCheckTest extends
CamelMicroProfileHealthTes
healthCheckRegistry.register(createReadinessCheck("readiness-1", true,
builder -> builder.up()));
healthCheckRegistry.register(createReadinessCheck("readiness-2", true,
builder -> builder.up()));
- CamelMicroProfileReadinessCheck readinessCheck = new
CamelMicroProfileReadinessCheck();
- readinessCheck.setCamelContext(context);
- reporter.addHealthCheck(readinessCheck);
-
- SmallRyeHealth health = reporter.getHealth();
+ SmallRyeHealth health = reporter.getReadiness();
JsonObject healthObject = getHealthJson(health);
assertEquals(Status.UP.name(), healthObject.getString("status"));
JsonArray checks = healthObject.getJsonArray("checks");
- assertEquals(1, checks.size());
+ assertEquals(2, checks.size());
- assertHealthCheckOutput("camel-readiness-checks", Status.UP,
checks.getJsonObject(0), jsonObject -> {
- assertEquals(Status.UP.name(),
jsonObject.getString("readiness-1"));
- assertEquals(Status.UP.name(),
jsonObject.getString("readiness-2"));
- });
+ assertHealthCheckOutput("readiness-2", Status.UP,
checks.getJsonObject(0));
+ assertHealthCheckOutput("readiness-1", Status.UP,
checks.getJsonObject(1));
}
@Test
@@ -166,22 +146,16 @@ public class CamelMicroProfileHealthCheckTest extends
CamelMicroProfileHealthTes
healthCheckRegistry.register(createReadinessCheck("readiness-1", true,
builder -> builder.up()));
healthCheckRegistry.register(createReadinessCheck("readiness-2", true,
builder -> builder.down()));
- CamelMicroProfileReadinessCheck readinessCheck = new
CamelMicroProfileReadinessCheck();
- readinessCheck.setCamelContext(context);
- reporter.addHealthCheck(readinessCheck);
-
- SmallRyeHealth health = reporter.getHealth();
+ SmallRyeHealth health = reporter.getReadiness();
JsonObject healthObject = getHealthJson(health);
assertEquals(Status.DOWN.name(), healthObject.getString("status"));
JsonArray checks = healthObject.getJsonArray("checks");
- assertEquals(1, checks.size());
+ assertEquals(2, checks.size());
- assertHealthCheckOutput("camel-readiness-checks", Status.DOWN,
checks.getJsonObject(0), jsonObject -> {
- assertEquals(Status.UP.name(),
jsonObject.getString("readiness-1"));
- assertEquals(Status.DOWN.name(),
jsonObject.getString("readiness-2"));
- });
+ assertHealthCheckOutput("readiness-2", Status.DOWN,
checks.getJsonObject(0));
+ assertHealthCheckOutput("readiness-1", Status.UP,
checks.getJsonObject(1));
}
@Test
@@ -190,47 +164,163 @@ public class CamelMicroProfileHealthCheckTest extends
CamelMicroProfileHealthTes
healthCheckRegistry.register(createReadinessCheck("disabled-check",
false, builder -> builder.up()));
- CamelMicroProfileReadinessCheck readinessCheck = new
CamelMicroProfileReadinessCheck();
- readinessCheck.setCamelContext(context);
- reporter.addHealthCheck(readinessCheck);
-
SmallRyeHealth health = reporter.getHealth();
JsonObject healthObject = getHealthJson(health);
assertEquals(Status.UP.name(), healthObject.getString("status"));
+ JsonArray checks = healthObject.getJsonArray("checks");
+ assertEquals(0, checks.size());
+ }
+
+ @Test
+ public void testCamelHealthCheckDisabledAtRuntime() {
+ HealthCheckRegistry healthCheckRegistry =
HealthCheckRegistry.get(context);
+
+ HealthCheck readinessCheck = createReadinessCheck("disabled-check",
true, builder -> builder.up());
+ healthCheckRegistry.register(readinessCheck);
+ readinessCheck.getConfiguration().setEnabled(false);
+
+ SmallRyeHealth health = reporter.getHealth();
+ JsonObject healthObject = getHealthJson(health);
+ assertEquals(Status.UP.name(), healthObject.getString("status"));
JsonArray checks = healthObject.getJsonArray("checks");
assertEquals(1, checks.size());
- assertHealthCheckOutput("camel-readiness-checks", Status.UP,
checks.getJsonObject(0), jsonObject -> {
- assertNull(jsonObject);
+ assertHealthCheckOutput("disabled-check", Status.UP,
checks.getJsonObject(0), jsonObject -> {
+ assertFalse(jsonObject.getBoolean("check.enabled"));
});
}
@Test
public void testNoCamelHealthChecksRegistered() {
- CamelMicroProfileReadinessCheck readinessCheck = new
CamelMicroProfileReadinessCheck();
- readinessCheck.setCamelContext(context);
- reporter.addHealthCheck(readinessCheck);
+ SmallRyeHealth health = reporter.getHealth();
+
+ JsonObject healthObject = getHealthJson(health);
+ assertEquals(Status.UP.name(), healthObject.getString("status"));
- CamelMicroProfileLivenessCheck livenessCheck = new
CamelMicroProfileLivenessCheck();
- livenessCheck.setCamelContext(context);
- reporter.addHealthCheck(livenessCheck);
+ JsonArray checks = healthObject.getJsonArray("checks");
+ assertEquals(0, checks.size());
+ }
+
+ @Test
+ public void testHealthCheckMultipleRegistrations() {
+ HealthCheckRegistry healthCheckRegistry =
HealthCheckRegistry.get(context);
+ HealthCheck check = new AbstractHealthCheck("test-check") {
+ @Override
+ protected void doCall(HealthCheckResultBuilder builder,
Map<String, Object> options) {
+ builder.up();
+ }
+ };
+
+ for (int i = 0; i < 5; i++) {
+ healthCheckRegistry.register(check);
+ }
+
+ SmallRyeHealth health = reporter.getHealth();
+
+ JsonObject healthObject = getHealthJson(health);
+ assertEquals(Status.UP.name(), healthObject.getString("status"));
+ JsonArray checks = healthObject.getJsonArray("checks");
+ assertEquals(2, checks.size());
+
+ assertHealthCheckOutput("test-check", Status.UP,
checks.getJsonObject(0));
+ assertHealthCheckOutput("test-check", Status.UP,
checks.getJsonObject(1));
+ }
+
+ @Test
+ public void testHealthCheckMultipleUnregisters() {
+ HealthCheckRegistry healthCheckRegistry =
HealthCheckRegistry.get(context);
+ HealthCheck check = new AbstractHealthCheck("test-check") {
+ @Override
+ protected void doCall(HealthCheckResultBuilder builder,
Map<String, Object> options) {
+ builder.up();
+ }
+ };
+ healthCheckRegistry.register(check);
SmallRyeHealth health = reporter.getHealth();
JsonObject healthObject = getHealthJson(health);
assertEquals(Status.UP.name(), healthObject.getString("status"));
+ JsonArray checks = healthObject.getJsonArray("checks");
+ assertEquals(2, checks.size());
+
+ assertHealthCheckOutput("test-check", Status.UP,
checks.getJsonObject(0));
+
+ assertHealthCheckOutput("test-check", Status.UP,
checks.getJsonObject(1));
+ for (int i = 0; i < 5; i++) {
+ healthCheckRegistry.unregister(check);
+ }
+
+ health = reporter.getHealth();
+ healthObject = getHealthJson(health);
+ assertEquals(Status.UP.name(), healthObject.getString("status"));
+ checks = healthObject.getJsonArray("checks");
+ assertEquals(0, checks.size());
+ }
+
+ @Test
+ public void testHealthCheckUncheckedException() {
+ String errorMessage = "Forced exception";
+
+ HealthCheckRegistry healthCheckRegistry =
HealthCheckRegistry.get(context);
+ HealthCheck check = new AbstractHealthCheck("exception-check") {
+ @Override
+ protected void doCall(HealthCheckResultBuilder builder,
Map<String, Object> options) {
+ throw new IllegalStateException(errorMessage);
+ }
+ };
+ healthCheckRegistry.register(check);
+
+ SmallRyeHealth health = reporter.getHealth();
+
+ JsonObject healthObject = getHealthJson(health);
+ assertEquals(Status.DOWN.name(), healthObject.getString("status"));
+ JsonArray checks = healthObject.getJsonArray("checks");
+ assertEquals(2, checks.size());
+
+ assertHealthCheckOutput(CamelMicroProfileHealthCheck.class.getName(),
Status.DOWN, checks.getJsonObject(0),
+ jsonObject -> {
+ assertEquals(errorMessage,
jsonObject.getString("rootCause"));
+ });
+
+ assertHealthCheckOutput(CamelMicroProfileHealthCheck.class.getName(),
Status.DOWN, checks.getJsonObject(1),
+ jsonObject -> {
+ assertEquals(errorMessage,
jsonObject.getString("rootCause"));
+ });
+ }
+
+ @Test
+ public void testHealthCheckCheckedException() {
+ String errorMessage = "Forced exception";
+
+ HealthCheckRegistry healthCheckRegistry =
HealthCheckRegistry.get(context);
+ HealthCheck check = new AbstractHealthCheck("exception-check") {
+ @Override
+ protected void doCall(HealthCheckResultBuilder builder,
Map<String, Object> options) {
+ builder.error(new Exception(errorMessage));
+ builder.down();
+ }
+ };
+ healthCheckRegistry.register(check);
+
+ SmallRyeHealth health = reporter.getHealth();
+
+ JsonObject healthObject = getHealthJson(health);
+ assertEquals(Status.DOWN.name(), healthObject.getString("status"));
JsonArray checks = healthObject.getJsonArray("checks");
assertEquals(2, checks.size());
- assertHealthCheckOutput("camel-readiness-checks", Status.UP,
checks.getJsonObject(0), jsonObject -> {
- assertNull(jsonObject);
+ assertHealthCheckOutput("exception-check", Status.DOWN,
checks.getJsonObject(0), jsonObject -> {
+ assertEquals(errorMessage, jsonObject.getString("error.message"));
+ assertNotNull(jsonObject.getString("error.stacktrace"));
});
- assertHealthCheckOutput("camel-liveness-checks", Status.UP,
checks.getJsonObject(1), jsonObject -> {
- assertNull(jsonObject);
+ assertHealthCheckOutput("exception-check", Status.DOWN,
checks.getJsonObject(1), jsonObject -> {
+ assertEquals(errorMessage, jsonObject.getString("error.message"));
+ assertNotNull(jsonObject.getString("error.stacktrace"));
});
}
}
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthConsumerTest.java
b/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthConsumerTest.java
index 6928bccf..09e2d0d 100644
---
a/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthConsumerTest.java
+++
b/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthConsumerTest.java
@@ -21,12 +21,13 @@ import javax.json.JsonObject;
import io.smallrye.health.SmallRyeHealth;
import org.apache.camel.RoutesBuilder;
+import org.apache.camel.ServiceStatus;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.health.HealthCheckRegistry;
import org.eclipse.microprofile.health.HealthCheckResponse.Status;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import static
org.apache.camel.microprofile.health.CamelMicroProfileHealthCheckRegistry.CONSUMERS_CHECK_NAME;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CamelMicroProfileHealthConsumerTest extends
CamelMicroProfileHealthTestSupport {
@@ -38,10 +39,6 @@ public class CamelMicroProfileHealthConsumerTest extends
CamelMicroProfileHealth
Object hc = healthCheckRegistry.resolveById("consumers");
healthCheckRegistry.register(hc);
- CamelMicroProfileReadinessCheck readinessCheck = new
CamelMicroProfileReadinessCheck();
- readinessCheck.setCamelContext(context);
- reporter.addHealthCheck(readinessCheck);
-
SmallRyeHealth health = reporter.getHealth();
JsonObject healthObject = getHealthJson(health);
@@ -50,14 +47,7 @@ public class CamelMicroProfileHealthConsumerTest extends
CamelMicroProfileHealth
JsonArray checks = healthObject.getJsonArray("checks");
assertEquals(1, checks.size());
-
Assertions.assertNotNull(checks.getJsonObject(0).getJsonObject("data"));
- Assertions.assertEquals("healthyRoute",
checks.getJsonObject(0).getJsonObject("data").getString("route.id"));
-
- assertHealthCheckOutput("camel-readiness-checks", Status.UP,
checks.getJsonObject(0), jsonObject -> {
- assertEquals(Status.UP.name(),
jsonObject.getString("consumer:healthyRoute"));
- assertEquals("healthyRoute", jsonObject.getString("route.id"));
- assertEquals("Started", jsonObject.getString("route.status"));
- });
+ assertHealthCheckOutput(CONSUMERS_CHECK_NAME, Status.UP,
checks.getJsonObject(0));
}
@Test
@@ -67,10 +57,6 @@ public class CamelMicroProfileHealthConsumerTest extends
CamelMicroProfileHealth
Object hc = healthCheckRegistry.resolveById("consumers");
healthCheckRegistry.register(hc);
- CamelMicroProfileReadinessCheck readinessCheck = new
CamelMicroProfileReadinessCheck();
- readinessCheck.setCamelContext(context);
- reporter.addHealthCheck(readinessCheck);
-
context.getRouteController().stopRoute("healthyRoute");
SmallRyeHealth health = reporter.getHealth();
@@ -81,13 +67,39 @@ public class CamelMicroProfileHealthConsumerTest extends
CamelMicroProfileHealth
JsonArray checks = healthObject.getJsonArray("checks");
assertEquals(1, checks.size());
- assertHealthCheckOutput("camel-readiness-checks", Status.DOWN,
checks.getJsonObject(0), jsonObject -> {
- assertEquals(Status.DOWN.name(),
jsonObject.getString("consumer:healthyRoute"));
+ assertHealthCheckOutput(CONSUMERS_CHECK_NAME, Status.DOWN,
checks.getJsonObject(0), jsonObject -> {
assertEquals("healthyRoute", jsonObject.getString("route.id"));
- assertEquals("Stopped", jsonObject.getString("route.status"));
+ assertEquals(ServiceStatus.Stopped.name(),
jsonObject.getString("route.status"));
});
}
+ @Test
+ public void testRoutesRepositoryUnregister() {
+ HealthCheckRegistry healthCheckRegistry =
HealthCheckRegistry.get(context);
+ Object hc = healthCheckRegistry.resolveById("consumers");
+ healthCheckRegistry.register(hc);
+
+ SmallRyeHealth health = reporter.getHealth();
+
+ JsonObject healthObject = getHealthJson(health);
+ assertEquals(Status.UP.name(), healthObject.getString("status"));
+
+ JsonArray checks = healthObject.getJsonArray("checks");
+ assertEquals(1, checks.size());
+
+ assertHealthCheckOutput(CONSUMERS_CHECK_NAME, Status.UP,
checks.getJsonObject(0));
+
+ healthCheckRegistry.unregister(hc);
+
+ health = reporter.getHealth();
+
+ healthObject = getHealthJson(health);
+ assertEquals(Status.UP.name(), healthObject.getString("status"));
+
+ checks = healthObject.getJsonArray("checks");
+ assertEquals(0, checks.size());
+ }
+
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthRegistryBindingTest.java
b/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthRegistryBindingTest.java
new file mode 100644
index 0000000..c3ecca5
--- /dev/null
+++
b/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthRegistryBindingTest.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.camel.microprofile.health;
+
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+
+import io.smallrye.health.SmallRyeHealth;
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.health.HealthCheck;
+import org.eclipse.microprofile.health.HealthCheckResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class CamelMicroProfileHealthRegistryBindingTest extends
CamelMicroProfileHealthTestSupport {
+
+ @BindToRegistry
+ private HealthCheck check = createReadinessCheck("registry-binding-check",
true, builder -> builder.up());
+
+ @Test
+ public void testHealthCheckCamelRegistryDiscovery() {
+ SmallRyeHealth health = reporter.getHealth();
+
+ JsonObject healthObject = getHealthJson(health);
+ assertEquals(HealthCheckResponse.Status.UP.name(),
healthObject.getString("status"));
+ JsonArray checks = healthObject.getJsonArray("checks");
+ assertEquals(1, checks.size());
+ }
+}
diff --git
a/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthTestSupport.java
b/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthTestSupport.java
index 6a0651f..be43695 100644
---
a/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthTestSupport.java
+++
b/components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthTestSupport.java
@@ -22,57 +22,61 @@ import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.function.Consumer;
+import javax.inject.Inject;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.stream.JsonParser;
-import io.smallrye.health.AsyncHealthCheckFactory;
+import io.smallrye.config.inject.ConfigExtension;
import io.smallrye.health.SmallRyeHealth;
import io.smallrye.health.SmallRyeHealthReporter;
-import io.smallrye.health.registry.LivenessHealthRegistry;
-import io.smallrye.health.registry.ReadinessHealthRegistry;
-import io.smallrye.health.registry.StartupHealthRegistry;
-import io.smallrye.health.registry.WellnessHealthRegistry;
+import org.apache.camel.CamelContext;
import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckRegistry;
import org.apache.camel.health.HealthCheckResultBuilder;
+import org.apache.camel.impl.health.AbstractHealthCheck;
import org.apache.camel.test.junit5.CamelTestSupport;
-import org.apache.camel.util.ReflectionHelper;
import org.eclipse.microprofile.health.HealthCheckResponse;
-import org.junit.jupiter.api.BeforeEach;
+import org.jboss.weld.junit5.auto.AddExtensions;
+import org.jboss.weld.junit5.auto.EnableAutoWeld;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
+@EnableAutoWeld
+@AddExtensions(ConfigExtension.class)
public class CamelMicroProfileHealthTestSupport extends CamelTestSupport {
- protected SmallRyeHealthReporter reporter;
+ @Inject
+ SmallRyeHealthReporter reporter;
@Override
- @BeforeEach
- public void setUp() throws Exception {
- super.setUp();
- reporter = new SmallRyeHealthReporter();
-
- // we do not run in CDI so we have to setup this with reflection
-
ReflectionHelper.setField(reporter.getClass().getDeclaredField("asyncHealthCheckFactory"),
reporter,
- new AsyncHealthCheckFactory());
-
ReflectionHelper.setField(reporter.getClass().getDeclaredField("livenessHealthRegistry"),
reporter,
- new LivenessHealthRegistry());
-
ReflectionHelper.setField(reporter.getClass().getDeclaredField("readinessHealthRegistry"),
reporter,
- new ReadinessHealthRegistry());
-
ReflectionHelper.setField(reporter.getClass().getDeclaredField("wellnessHealthRegistry"),
reporter,
- new WellnessHealthRegistry());
-
ReflectionHelper.setField(reporter.getClass().getDeclaredField("startupHealthRegistry"),
reporter,
- new StartupHealthRegistry());
-
ReflectionHelper.setField(reporter.getClass().getDeclaredField("timeoutSeconds"),
reporter, 60);
+ protected CamelContext createCamelContext() throws Exception {
+ CamelContext camelContext = super.createCamelContext();
+ HealthCheckRegistry registry = new
CamelMicroProfileHealthCheckRegistry();
+ camelContext.setExtension(HealthCheckRegistry.class, registry);
+ return camelContext;
}
protected void assertHealthCheckOutput(
- String expectedName, HealthCheckResponse.Status expectedState,
JsonObject healthObject,
+ String expectedName,
+ HealthCheckResponse.Status expectedState,
+ JsonObject healthObject) {
+ assertHealthCheckOutput(expectedName, expectedState, healthObject,
null);
+ }
+
+ protected void assertHealthCheckOutput(
+ String expectedName,
+ HealthCheckResponse.Status expectedState,
+ JsonObject healthObject,
Consumer<JsonObject> dataObjectAssertions) {
+
assertEquals(expectedName, healthObject.getString("name"));
assertEquals(expectedState.name(), healthObject.getString("status"));
- dataObjectAssertions.accept(healthObject.getJsonObject("data"));
+
+ if (dataObjectAssertions != null) {
+ dataObjectAssertions.accept(healthObject.getJsonObject("data"));
+ }
}
protected JsonObject getHealthJson(SmallRyeHealth health) {
@@ -89,24 +93,42 @@ public class CamelMicroProfileHealthTestSupport extends
CamelTestSupport {
}
protected HealthCheck createLivenessCheck(String id, boolean enabled,
Consumer<HealthCheckResultBuilder> consumer) {
- HealthCheck healthCheck = new
AbstractCamelMicroProfileLivenessCheck(id) {
+ HealthCheck livenessCheck = new AbstractHealthCheck(id) {
@Override
protected void doCall(HealthCheckResultBuilder builder,
Map<String, Object> options) {
consumer.accept(builder);
}
+
+ @Override
+ public boolean isReadiness() {
+ return false;
+ }
};
- healthCheck.getConfiguration().setEnabled(enabled);
- return healthCheck;
+ livenessCheck.getConfiguration().setEnabled(enabled);
+ return livenessCheck;
}
protected HealthCheck createReadinessCheck(String id, boolean enabled,
Consumer<HealthCheckResultBuilder> consumer) {
- HealthCheck healthCheck = new
AbstractCamelMicroProfileReadinessCheck(id) {
+ HealthCheck readinessCheck = new AbstractHealthCheck(id) {
@Override
protected void doCall(HealthCheckResultBuilder builder,
Map<String, Object> options) {
consumer.accept(builder);
}
+
+ @Override
+ public boolean isLiveness() {
+ return false;
+ }
};
- healthCheck.getConfiguration().setEnabled(enabled);
- return healthCheck;
+ readinessCheck.getConfiguration().setEnabled(enabled);
+ return readinessCheck;
+
+ }
+
+ /**
+ * Dump health check status to stdout, useful for debugging.
+ */
+ protected void dumpHealth(SmallRyeHealth health) {
+ reporter.reportHealth(System.out, health);
}
}
diff --git
a/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthCheckRegistry.java
b/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthCheckRegistry.java
index 29b38c8..7ef3c37 100644
---
a/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthCheckRegistry.java
+++
b/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthCheckRegistry.java
@@ -59,7 +59,6 @@ public class DefaultHealthCheckRegistry extends
ServiceSupport implements Health
public DefaultHealthCheckRegistry(CamelContext camelContext) {
this.checks = new CopyOnWriteArraySet<>();
this.repositories = new CopyOnWriteArraySet<>();
- this.repositories.add(new HealthCheckRegistryRepository());
setCamelContext(camelContext);
}
@@ -88,6 +87,14 @@ public class DefaultHealthCheckRegistry extends
ServiceSupport implements Health
protected void doInit() throws Exception {
super.doInit();
+ Optional<HealthCheckRepository> hcr = repositories.stream()
+ .filter(repository -> repository instanceof
HealthCheckRegistryRepository)
+ .findFirst();
+
+ if (!hcr.isPresent()) {
+ register(new HealthCheckRegistryRepository());
+ }
+
for (HealthCheck check : checks) {
CamelContextAware.trySetCamelContext(check, camelContext);
}
diff --git a/parent/pom.xml b/parent/pom.xml
index bad8493..9df544f 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -397,7 +397,6 @@
<micrometer-version>1.8.1</micrometer-version>
<microprofile-config-version>2.0</microprofile-config-version>
<microprofile-metrics-version>3.0</microprofile-metrics-version>
- <microprofile-health-version>3.1</microprofile-health-version>
<microprofile-fault-tolerance-version>3.0</microprofile-fault-tolerance-version>
<milo-version>0.3.7</milo-version>
<milo-guava-version>26.0-jre</milo-guava-version>
@@ -541,6 +540,7 @@
<web3j-version>3.6.0</web3j-version>
<web3j-quorum-version>0.8.0</web3j-quorum-version>
<weld3-version>3.1.8.Final</weld3-version>
+ <weld-junit5-version>2.0.2.Final</weld-junit5-version>
<wildfly-elytron>1.11.4.Final</wildfly-elytron>
<wiremock-version>2.27.2</wiremock-version>
<woodstox-version>4.4.1</woodstox-version>