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>

Reply via email to