This is an automated email from the ASF dual-hosted git repository.

davsclaus 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 e582a52  CAMEL-15333: camel-health - Consumers have their own 
health-check-repo. Make it possible to turn them off, and have similar 
configuration like routes.
e582a52 is described below

commit e582a528f446f8c13b7b9b9707948eaf44a69ea3
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Nov 5 09:18:33 2021 +0100

    CAMEL-15333: camel-health - Consumers have their own health-check-repo. 
Make it possible to turn them off, and have similar configuration like routes.
---
 ...CamelMicroProfileHealthCheckRepositoryTest.java |  2 +
 ...va => CamelMicroProfileHealthConsumerTest.java} | 18 +++--
 ...sumerHealthCheckErrorDisabledConsumerTest.java} | 38 ++++-----
 .../TelegramConsumerHealthCheckErrorTest.java      | 11 +--
 .../TelegramConsumerHealthCheckOkTest.java         |  7 +-
 .../apache/camel/consumers-health-check-repository |  2 +
 .../camel/impl/health/AbstractHealthCheck.java     | 15 +++-
 .../camel/impl/health/ConsumerHealthCheck.java     | 90 ++++++++++++++++++++++
 ...ry.java => ConsumersHealthCheckRepository.java} | 30 ++++----
 .../camel/impl/health/ContextHealthCheck.java      |  3 +-
 .../apache/camel/impl/health/RouteHealthCheck.java | 35 ---------
 .../impl/health/RoutesHealthCheckRepository.java   |  1 +
 .../HealthConfigurationPropertiesConfigurer.java   |  6 ++
 .../camel-main-configuration-metadata.json         |  1 +
 core/camel-main/src/main/docs/main.adoc            |  3 +-
 .../org/apache/camel/main/BaseMainSupport.java     | 24 ++++--
 .../camel/main/HealthConfigurationProperties.java  | 13 ++++
 .../modules/ROOT/pages/health-check.adoc           | 37 +++++++--
 18 files changed, 236 insertions(+), 100 deletions(-)

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 eb93c69..83d1be8 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
@@ -55,6 +55,7 @@ public class CamelMicroProfileHealthCheckRepositoryTest 
extends CamelMicroProfil
 
         assertHealthCheckOutput("camel-readiness-checks", Status.UP, 
checks.getJsonObject(0), jsonObject -> {
             assertEquals(Status.UP.name(), 
jsonObject.getString("route:healthyRoute"));
+            assertEquals("Started", jsonObject.getString("route.status"));
         });
     }
 
@@ -81,6 +82,7 @@ public class CamelMicroProfileHealthCheckRepositoryTest 
extends CamelMicroProfil
 
         assertHealthCheckOutput("camel-readiness-checks", Status.DOWN, 
checks.getJsonObject(0), jsonObject -> {
             assertEquals(Status.DOWN.name(), 
jsonObject.getString("route:healthyRoute"));
+            assertEquals("Stopped", jsonObject.getString("route.status"));
         });
     }
 
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/CamelMicroProfileHealthConsumerTest.java
similarity index 84%
copy from 
components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthCheckRepositoryTest.java
copy to 
components/camel-microprofile/camel-microprofile-health/src/test/java/org/apache/camel/microprofile/health/CamelMicroProfileHealthConsumerTest.java
index eb93c69..6928bccf 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/CamelMicroProfileHealthConsumerTest.java
@@ -29,13 +29,13 @@ import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
-public class CamelMicroProfileHealthCheckRepositoryTest extends 
CamelMicroProfileHealthTestSupport {
+public class CamelMicroProfileHealthConsumerTest extends 
CamelMicroProfileHealthTestSupport {
 
     @Test
     public void testCamelHealthRepositoryUpStatus() {
         HealthCheckRegistry healthCheckRegistry = 
HealthCheckRegistry.get(context);
-        // enable routes health check
-        Object hc = healthCheckRegistry.resolveById("routes");
+        // enable consumers health check
+        Object hc = healthCheckRegistry.resolveById("consumers");
         healthCheckRegistry.register(hc);
 
         CamelMicroProfileReadinessCheck readinessCheck = new 
CamelMicroProfileReadinessCheck();
@@ -54,15 +54,17 @@ public class CamelMicroProfileHealthCheckRepositoryTest 
extends CamelMicroProfil
         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(Status.UP.name(), 
jsonObject.getString("consumer:healthyRoute"));
+            assertEquals("healthyRoute", jsonObject.getString("route.id"));
+            assertEquals("Started", jsonObject.getString("route.status"));
         });
     }
 
     @Test
     public void testCamelHealthRepositoryDownStatus() throws Exception {
         HealthCheckRegistry healthCheckRegistry = 
HealthCheckRegistry.get(context);
-        // enable routes health check
-        Object hc = healthCheckRegistry.resolveById("routes");
+        // enable consumers health check
+        Object hc = healthCheckRegistry.resolveById("consumers");
         healthCheckRegistry.register(hc);
 
         CamelMicroProfileReadinessCheck readinessCheck = new 
CamelMicroProfileReadinessCheck();
@@ -80,7 +82,9 @@ public class CamelMicroProfileHealthCheckRepositoryTest 
extends CamelMicroProfil
         assertEquals(1, checks.size());
 
         assertHealthCheckOutput("camel-readiness-checks", Status.DOWN, 
checks.getJsonObject(0), jsonObject -> {
-            assertEquals(Status.DOWN.name(), 
jsonObject.getString("route:healthyRoute"));
+            assertEquals(Status.DOWN.name(), 
jsonObject.getString("consumer:healthyRoute"));
+            assertEquals("healthyRoute", jsonObject.getString("route.id"));
+            assertEquals("Stopped", jsonObject.getString("route.status"));
         });
     }
 
diff --git 
a/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckErrorTest.java
 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckErrorDisabledConsumerTest.java
similarity index 74%
copy from 
components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckErrorTest.java
copy to 
components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckErrorDisabledConsumerTest.java
index 885e61b..1544d99 100644
--- 
a/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckErrorTest.java
+++ 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckErrorDisabledConsumerTest.java
@@ -33,7 +33,7 @@ import org.awaitility.Awaitility;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-public class TelegramConsumerHealthCheckErrorTest extends TelegramTestSupport {
+public class TelegramConsumerHealthCheckErrorDisabledConsumerTest extends 
TelegramTestSupport {
 
     @EndpointInject("mock:telegram")
     private MockEndpoint endpoint;
@@ -46,7 +46,15 @@ public class TelegramConsumerHealthCheckErrorTest extends 
TelegramTestSupport {
         HealthCheckRegistry hcr = 
context.getExtension(HealthCheckRegistry.class);
         HealthCheckRepository repo = 
hcr.getRepository("routes").orElse((HealthCheckRepository) 
hcr.resolveById("routes"));
         // add some slack so the check should fail 5 times in a row to be DOWN
-        repo.addConfiguration("telegram", 
HealthCheckConfiguration.builder().failureThreshold(5).build());
+        repo.addConfiguration("*", 
HealthCheckConfiguration.builder().failureThreshold(5).build());
+        repo.setEnabled(true);
+        hcr.register(repo);
+        // enabling consumers health check is a bit cumbersome via low-level 
Java code
+        repo = hcr.getRepository("consumers").orElse((HealthCheckRepository) 
hcr.resolveById("consumers"));
+        // add some slack so the check should fail 5 times in a row to be DOWN
+        repo.addConfiguration("consumer:telegram", 
HealthCheckConfiguration.builder().failureThreshold(5).build());
+        // turn off all consumer health checks
+        repo.addConfiguration("consumer:*", 
HealthCheckConfiguration.builder().enabled(false).build());
         repo.setEnabled(true);
         hcr.register(repo);
 
@@ -58,34 +66,22 @@ public class TelegramConsumerHealthCheckErrorTest extends 
TelegramTestSupport {
         HealthCheckRegistry hcr = 
context.getExtension(HealthCheckRegistry.class);
         HealthCheckRepository repo = hcr.getRepository("routes").get();
 
-        // should not be DOWN from the start
+        // should not be UP from the start as routes can be started
         boolean down = repo.stream().anyMatch(h -> 
h.call().getState().equals(HealthCheck.State.DOWN));
         Assertions.assertFalse(down, "None health-check should be DOWN");
 
-        // wait until HC is DOWN
+        // wait until HC is UP
         Awaitility.waitAtMost(5, TimeUnit.SECONDS).until(
-                () -> repo.stream().anyMatch(h -> 
h.call().getState().equals(HealthCheck.State.DOWN)));
+                () -> repo.stream().anyMatch(h -> 
h.call().getState().equals(HealthCheck.State.UP)));
 
         // if we grab the health check by id, we can also check it afterwards
         HealthCheck hc = hcr.getCheck("telegram").get();
         HealthCheck.Result rc = hc.call();
 
-        // and get the detailed error message (and exception)
-        Assertions.assertEquals(HealthCheck.State.DOWN, rc.getState());
-        String msg = rc.getMessage().get();
-        long count = (long) 
rc.getDetails().get(HealthCheck.FAILURE_ERROR_COUNT);
-        if (count == 0) {
-            Assertions.assertEquals("Consumer has not yet polled route: 
telegram (telegram://bots)", msg);
-        } else {
-            Assertions.assertEquals("Consumer failed polling " + count + " 
times route: telegram (telegram://bots)", msg);
-        }
-        
Assertions.assertEquals("telegram://bots?authorizationToken=mock-token",
-                rc.getDetails().get(HealthCheck.FAILURE_ENDPOINT_URI));
-
-        if (rc.getError().isPresent()) {
-            Throwable e = rc.getError().get();
-            Assertions.assertTrue(e.getMessage().contains("401 Unauthorized"));
-        }
+        // so routes health check just check the status of the route which is 
started (UP)
+        // but the telegram consumer is not healthy as it keeps getting 401 
errors
+        // to detect this we needed the consumer health check which has been 
disabled
+        Assertions.assertEquals(HealthCheck.State.UP, rc.getState());
     }
 
     @Override
diff --git 
a/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckErrorTest.java
 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckErrorTest.java
index 885e61b..b7a4892 100644
--- 
a/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckErrorTest.java
+++ 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckErrorTest.java
@@ -42,11 +42,12 @@ public class TelegramConsumerHealthCheckErrorTest extends 
TelegramTestSupport {
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
 
-        // enabling routes health check is a bit cumbersome via low-level Java 
code
+        // enabling consumers health check is a bit cumbersome via low-level 
Java code
         HealthCheckRegistry hcr = 
context.getExtension(HealthCheckRegistry.class);
-        HealthCheckRepository repo = 
hcr.getRepository("routes").orElse((HealthCheckRepository) 
hcr.resolveById("routes"));
+        HealthCheckRepository repo
+                = 
hcr.getRepository("consumers").orElse((HealthCheckRepository) 
hcr.resolveById("consumers"));
         // add some slack so the check should fail 5 times in a row to be DOWN
-        repo.addConfiguration("telegram", 
HealthCheckConfiguration.builder().failureThreshold(5).build());
+        repo.addConfiguration("consumer:telegram", 
HealthCheckConfiguration.builder().failureThreshold(5).build());
         repo.setEnabled(true);
         hcr.register(repo);
 
@@ -56,7 +57,7 @@ public class TelegramConsumerHealthCheckErrorTest extends 
TelegramTestSupport {
     @Test
     public void testReceptionOfTwoMessages() throws Exception {
         HealthCheckRegistry hcr = 
context.getExtension(HealthCheckRegistry.class);
-        HealthCheckRepository repo = hcr.getRepository("routes").get();
+        HealthCheckRepository repo = hcr.getRepository("consumers").get();
 
         // should not be DOWN from the start
         boolean down = repo.stream().anyMatch(h -> 
h.call().getState().equals(HealthCheck.State.DOWN));
@@ -67,7 +68,7 @@ public class TelegramConsumerHealthCheckErrorTest extends 
TelegramTestSupport {
                 () -> repo.stream().anyMatch(h -> 
h.call().getState().equals(HealthCheck.State.DOWN)));
 
         // if we grab the health check by id, we can also check it afterwards
-        HealthCheck hc = hcr.getCheck("telegram").get();
+        HealthCheck hc = hcr.getCheck("consumer:telegram").get();
         HealthCheck.Result rc = hc.call();
 
         // and get the detailed error message (and exception)
diff --git 
a/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckOkTest.java
 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckOkTest.java
index b68db20..526b843 100644
--- 
a/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckOkTest.java
+++ 
b/components/camel-telegram/src/test/java/org/apache/camel/component/telegram/TelegramConsumerHealthCheckOkTest.java
@@ -40,9 +40,10 @@ public class TelegramConsumerHealthCheckOkTest extends 
TelegramTestSupport {
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
 
-        // enabling routes health check is a bit cumbersome via low-level Java 
code
+        // enabling consumers health check is a bit cumbersome via low-level 
Java code
         HealthCheckRegistry hcr = 
context.getExtension(HealthCheckRegistry.class);
-        HealthCheckRepository repo = 
hcr.getRepository("routes").orElse((HealthCheckRepository) 
hcr.resolveById("routes"));
+        HealthCheckRepository repo
+                = 
hcr.getRepository("consumers").orElse((HealthCheckRepository) 
hcr.resolveById("consumers"));
         repo.setEnabled(true);
         hcr.register(repo);
 
@@ -52,7 +53,7 @@ public class TelegramConsumerHealthCheckOkTest extends 
TelegramTestSupport {
     @Test
     public void testReceptionOfTwoMessages() throws Exception {
         HealthCheckRegistry hcr = 
context.getExtension(HealthCheckRegistry.class);
-        HealthCheckRepository repo = hcr.getRepository("routes").get();
+        HealthCheckRepository repo = hcr.getRepository("consumers").get();
 
         endpoint.expectedMinimumMessageCount(2);
         endpoint.expectedBodiesReceived("message1", "message2");
diff --git 
a/core/camel-health/src/generated/resources/META-INF/services/org/apache/camel/consumers-health-check-repository
 
b/core/camel-health/src/generated/resources/META-INF/services/org/apache/camel/consumers-health-check-repository
new file mode 100644
index 0000000..fc36fe3
--- /dev/null
+++ 
b/core/camel-health/src/generated/resources/META-INF/services/org/apache/camel/consumers-health-check-repository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.impl.health.ConsumersHealthCheckRepository
diff --git 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/AbstractHealthCheck.java
 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/AbstractHealthCheck.java
index 24fdd64..4e70c7e 100644
--- 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/AbstractHealthCheck.java
+++ 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/AbstractHealthCheck.java
@@ -24,6 +24,8 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
 import org.apache.camel.health.HealthCheck;
 import org.apache.camel.health.HealthCheckConfiguration;
 import org.apache.camel.health.HealthCheckResultBuilder;
@@ -34,10 +36,11 @@ import org.slf4j.LoggerFactory;
 /**
  * Base implementation for {@link HealthCheck}.
  */
-public abstract class AbstractHealthCheck implements HealthCheck {
+public abstract class AbstractHealthCheck implements HealthCheck, 
CamelContextAware {
 
     private static final Logger LOGGER = 
LoggerFactory.getLogger(AbstractHealthCheck.class);
 
+    private CamelContext camelContext;
     private final Object lock;
     private final String group;
     private final String id;
@@ -73,6 +76,16 @@ public abstract class AbstractHealthCheck implements 
HealthCheck {
     }
 
     @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
     public String getId() {
         return id;
     }
diff --git 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/ConsumerHealthCheck.java
 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/ConsumerHealthCheck.java
new file mode 100644
index 0000000..6f56c76
--- /dev/null
+++ 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/ConsumerHealthCheck.java
@@ -0,0 +1,90 @@
+/*
+ * 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.impl.health;
+
+import java.util.Map;
+
+import org.apache.camel.Consumer;
+import org.apache.camel.ServiceStatus;
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckAware;
+import org.apache.camel.health.HealthCheckResultBuilder;
+import org.apache.camel.support.service.ServiceSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * {@link HealthCheck} for a given consumer.
+ */
+public class ConsumerHealthCheck extends AbstractHealthCheck {
+
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(ConsumerHealthCheck.class);
+
+    private final Consumer consumer;
+    private final String routeId;
+
+    public ConsumerHealthCheck(Consumer consumer, String id) {
+        super("camel", id);
+        this.consumer = consumer;
+        this.routeId = id.replace("consumer:", "");
+    }
+
+    @Override
+    public boolean isLiveness() {
+        // this check is only for readiness
+        return false;
+    }
+
+    @Override
+    protected void doCall(HealthCheckResultBuilder builder, Map<String, 
Object> options) {
+        final ServiceStatus status = 
getCamelContext().getRouteController().getRouteStatus(routeId);
+        builder.detail("route.id", routeId);
+        builder.detail("route.status", status.name());
+        builder.detail("route.context.name", getCamelContext().getName());
+
+        if (consumer instanceof HealthCheckAware) {
+            // health check is optional
+            HealthCheck hc = ((HealthCheckAware) consumer).getHealthCheck();
+            if (hc != null) {
+                if (LOGGER.isTraceEnabled()) {
+                    LOGGER.trace("Calling HealthCheck on consumer route: {}", 
routeId);
+                }
+                Result result = hc.call();
+                if (LOGGER.isDebugEnabled()) {
+                    LOGGER.debug("HealthCheck consumer route: {} -> {}", 
routeId, result.getState());
+                }
+
+                builder.state(result.getState());
+                if (result.getMessage().isPresent()) {
+                    builder.message(result.getMessage().get());
+                }
+                if (result.getError().isPresent()) {
+                    builder.error(result.getError().get());
+                }
+                builder.details(result.getDetails());
+                return;
+            }
+        }
+
+        // consumer has no fine-grained health-check so check whether is 
started
+        boolean started = true;
+        if (consumer instanceof ServiceSupport) {
+            started = ((ServiceSupport) consumer).isStarted();
+        }
+        builder.state(started ? State.UP : State.DOWN);
+    }
+}
diff --git 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/RoutesHealthCheckRepository.java
 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/ConsumersHealthCheckRepository.java
similarity index 80%
copy from 
core/camel-health/src/main/java/org/apache/camel/impl/health/RoutesHealthCheckRepository.java
copy to 
core/camel-health/src/main/java/org/apache/camel/impl/health/ConsumersHealthCheckRepository.java
index f7b9912..6ec18f2 100644
--- 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/RoutesHealthCheckRepository.java
+++ 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/ConsumersHealthCheckRepository.java
@@ -24,6 +24,7 @@ import java.util.stream.Stream;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
+import org.apache.camel.Consumer;
 import org.apache.camel.DeferredContextBinding;
 import org.apache.camel.Route;
 import org.apache.camel.health.HealthCheck;
@@ -33,18 +34,18 @@ import org.apache.camel.spi.annotations.JdkService;
 import org.apache.camel.support.PatternHelper;
 
 /**
- * Repository for routes {@link HealthCheck}s.
+ * Repository for consumers {@link HealthCheck}s.
  */
-@JdkService("routes-health-check-repository")
+@JdkService("consumers-health-check-repository")
 @DeferredContextBinding
-public class RoutesHealthCheckRepository implements CamelContextAware, 
HealthCheckRepository {
-    private final ConcurrentMap<Route, HealthCheck> checks;
+public class ConsumersHealthCheckRepository implements CamelContextAware, 
HealthCheckRepository {
+    private final ConcurrentMap<Consumer, HealthCheck> checks;
     private volatile CamelContext context;
     private Map<String, HealthCheckConfiguration> configurations;
     private HealthCheckConfiguration fallbackConfiguration;
     private boolean enabled = true;
 
-    public RoutesHealthCheckRepository() {
+    public ConsumersHealthCheckRepository() {
         this.checks = new ConcurrentHashMap<>();
     }
 
@@ -55,7 +56,7 @@ public class RoutesHealthCheckRepository implements 
CamelContextAware, HealthChe
 
     @Override
     public String getId() {
-        return "routes";
+        return "consumers";
     }
 
     @Override
@@ -112,7 +113,7 @@ public class RoutesHealthCheckRepository implements 
CamelContextAware, HealthChe
                 ? this.context.getRoutes()
                         .stream()
                         .filter(route -> route.getId() != null)
-                        .map(this::toRouteHealthCheck)
+                        .map(this::toConsumerHealthCheck)
                 : Stream.empty();
     }
 
@@ -120,14 +121,17 @@ public class RoutesHealthCheckRepository implements 
CamelContextAware, HealthChe
     // Helpers
     // *****************************
 
-    private HealthCheck toRouteHealthCheck(Route route) {
-        return checks.computeIfAbsent(route, r -> {
-            RouteHealthCheck rhc = new RouteHealthCheck(route);
-            HealthCheckConfiguration hcc = 
matchConfiguration(route.getRouteId());
+    private HealthCheck toConsumerHealthCheck(Route route) {
+        return checks.computeIfAbsent(route.getConsumer(), r -> {
+            // must prefix id with consumer: to not clash with route
+            String id = "consumer:" + route.getRouteId();
+            ConsumerHealthCheck chc = new 
ConsumerHealthCheck(route.getConsumer(), id);
+            CamelContextAware.trySetCamelContext(chc, route.getCamelContext());
+            HealthCheckConfiguration hcc = matchConfiguration(id);
             if (hcc != null) {
-                rhc.setConfiguration(hcc);
+                chc.setConfiguration(hcc);
             }
-            return rhc;
+            return chc;
         });
     }
 
diff --git 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/ContextHealthCheck.java
 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/ContextHealthCheck.java
index fe99b98..b2f9f71 100644
--- 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/ContextHealthCheck.java
+++ 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/ContextHealthCheck.java
@@ -19,7 +19,6 @@ package org.apache.camel.impl.health;
 import java.util.Map;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.CamelContextAware;
 import org.apache.camel.health.HealthCheckResultBuilder;
 import org.apache.camel.spi.annotations.JdkService;
 
@@ -28,7 +27,7 @@ import org.apache.camel.spi.annotations.JdkService;
  * not.
  */
 @JdkService("context-health-check")
-public final class ContextHealthCheck extends AbstractHealthCheck implements 
CamelContextAware {
+public final class ContextHealthCheck extends AbstractHealthCheck {
     private CamelContext camelContext;
 
     public ContextHealthCheck() {
diff --git 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/RouteHealthCheck.java
 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/RouteHealthCheck.java
index e925c1d..44cde6b 100644
--- 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/RouteHealthCheck.java
+++ 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/RouteHealthCheck.java
@@ -19,22 +19,15 @@ package org.apache.camel.impl.health;
 import java.util.Map;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.Consumer;
 import org.apache.camel.Route;
 import org.apache.camel.ServiceStatus;
-import org.apache.camel.health.HealthCheck;
-import org.apache.camel.health.HealthCheckAware;
 import org.apache.camel.health.HealthCheckResultBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * {@link org.apache.camel.health.HealthCheck} for a given route.
  */
 public class RouteHealthCheck extends AbstractHealthCheck {
 
-    private static final Logger LOGGER = 
LoggerFactory.getLogger(RouteHealthCheck.class);
-
     private final Route route;
 
     public RouteHealthCheck(Route route) {
@@ -82,34 +75,6 @@ public class RouteHealthCheck extends AbstractHealthCheck {
                     }
                 }
             }
-
-            // check fine-grained consumer health check if we are up as the 
route may be up and running
-            // but the consumer can be un-healthy
-            if (State.UP.equals(builder.state())) {
-                Consumer consumer = route.getConsumer();
-                if (consumer instanceof HealthCheckAware) {
-                    // health check is optional
-                    HealthCheck hc = ((HealthCheckAware) 
consumer).getHealthCheck();
-                    if (hc != null) {
-                        if (LOGGER.isTraceEnabled()) {
-                            LOGGER.trace("Calling HealthCheck on consumer 
route: {}", route.getId());
-                        }
-                        Result result = hc.call();
-                        if (LOGGER.isDebugEnabled()) {
-                            LOGGER.debug("HealthCheck consumer route: {} -> 
{}", route.getId(), result.getState());
-                        }
-
-                        builder.state(result.getState());
-                        if (result.getMessage().isPresent()) {
-                            builder.message(result.getMessage().get());
-                        }
-                        if (result.getError().isPresent()) {
-                            builder.error(result.getError().get());
-                        }
-                        builder.details(result.getDetails());
-                    }
-                }
-            }
         }
     }
 }
diff --git 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/RoutesHealthCheckRepository.java
 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/RoutesHealthCheckRepository.java
index f7b9912..da9e794 100644
--- 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/RoutesHealthCheckRepository.java
+++ 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/RoutesHealthCheckRepository.java
@@ -123,6 +123,7 @@ public class RoutesHealthCheckRepository implements 
CamelContextAware, HealthChe
     private HealthCheck toRouteHealthCheck(Route route) {
         return checks.computeIfAbsent(route, r -> {
             RouteHealthCheck rhc = new RouteHealthCheck(route);
+            CamelContextAware.trySetCamelContext(rhc, route.getCamelContext());
             HealthCheckConfiguration hcc = 
matchConfiguration(route.getRouteId());
             if (hcc != null) {
                 rhc.setConfiguration(hcc);
diff --git 
a/core/camel-main/src/generated/java/org/apache/camel/main/HealthConfigurationPropertiesConfigurer.java
 
b/core/camel-main/src/generated/java/org/apache/camel/main/HealthConfigurationPropertiesConfigurer.java
index 906d623..e44bf31 100644
--- 
a/core/camel-main/src/generated/java/org/apache/camel/main/HealthConfigurationPropertiesConfigurer.java
+++ 
b/core/camel-main/src/generated/java/org/apache/camel/main/HealthConfigurationPropertiesConfigurer.java
@@ -23,6 +23,8 @@ public class HealthConfigurationPropertiesConfigurer extends 
org.apache.camel.su
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "config":
         case "Config": target.setConfig(property(camelContext, 
java.util.Map.class, value)); return true;
+        case "consumersenabled":
+        case "ConsumersEnabled": 
target.setConsumersEnabled(property(camelContext, java.lang.Boolean.class, 
value)); return true;
         case "contextenabled":
         case "ContextEnabled": target.setContextEnabled(property(camelContext, 
java.lang.Boolean.class, value)); return true;
         case "enabled":
@@ -40,6 +42,8 @@ public class HealthConfigurationPropertiesConfigurer extends 
org.apache.camel.su
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "config":
         case "Config": return java.util.Map.class;
+        case "consumersenabled":
+        case "ConsumersEnabled": return java.lang.Boolean.class;
         case "contextenabled":
         case "ContextEnabled": return java.lang.Boolean.class;
         case "enabled":
@@ -58,6 +62,8 @@ public class HealthConfigurationPropertiesConfigurer extends 
org.apache.camel.su
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "config":
         case "Config": return target.getConfig();
+        case "consumersenabled":
+        case "ConsumersEnabled": return target.getConsumersEnabled();
         case "contextenabled":
         case "ContextEnabled": return target.getContextEnabled();
         case "enabled":
diff --git 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index ab4da55..58c12b9 100644
--- 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -119,6 +119,7 @@
     { "name": "camel.faulttolerance.timeoutPoolSize", "description": 
"Configures the pool size of the thread pool when timeout is enabled. Default 
value is 10.", "sourceType": 
"org.apache.camel.main.FaultToleranceConfigurationProperties", "type": 
"integer", "javaType": "java.lang.Integer", "defaultValue": 10 },
     { "name": "camel.faulttolerance.timeoutScheduledExecutorServiceRef", 
"description": "References to a custom thread pool to use when timeout is 
enabled", "sourceType": 
"org.apache.camel.main.FaultToleranceConfigurationProperties", "type": 
"string", "javaType": "java.lang.String" },
     { "name": "camel.health.config", "description": "Set additional 
HealthConfigurationProperties for fine grained configuration of health 
checks.", "sourceType": "org.apache.camel.main.HealthConfigurationProperties", 
"type": "object", "javaType": "java.util.Map" },
+    { "name": "camel.health.consumersEnabled", "description": "Whether 
consumers health check is enabled", "sourceType": 
"org.apache.camel.main.HealthConfigurationProperties", "type": "boolean", 
"javaType": "java.lang.Boolean", "defaultValue": true },
     { "name": "camel.health.contextEnabled", "description": "Whether context 
health check is enabled", "sourceType": 
"org.apache.camel.main.HealthConfigurationProperties", "type": "boolean", 
"javaType": "java.lang.Boolean", "defaultValue": true },
     { "name": "camel.health.enabled", "description": "Whether health check is 
enabled globally", "sourceType": 
"org.apache.camel.main.HealthConfigurationProperties", "type": "boolean", 
"javaType": "java.lang.Boolean", "defaultValue": true },
     { "name": "camel.health.registryEnabled", "description": "Whether registry 
health check is enabled", "sourceType": 
"org.apache.camel.main.HealthConfigurationProperties", "type": "boolean", 
"javaType": "java.lang.Boolean", "defaultValue": true },
diff --git a/core/camel-main/src/main/docs/main.adoc 
b/core/camel-main/src/main/docs/main.adoc
index 341a352..32e17a9 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -140,12 +140,13 @@ The camel.threadpool supports 8 options, which are listed 
below.
 |===
 
 === Camel Health Check configurations
-The camel.health supports 5 options, which are listed below.
+The camel.health supports 6 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
 | *camel.health.config* | Set additional HealthConfigurationProperties for 
fine grained configuration of health checks. |  | Map
+| *camel.health.consumersEnabled* | Whether consumers health check is enabled 
| true | Boolean
 | *camel.health.contextEnabled* | Whether context health check is enabled | 
true | Boolean
 | *camel.health.enabled* | Whether health check is enabled globally | true | 
Boolean
 | *camel.health.registryEnabled* | Whether registry health check is enabled | 
true | Boolean
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java 
b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
index b7e4782..e98ebd5 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
@@ -969,7 +969,7 @@ public abstract class BaseMainSupport extends BaseService {
                 hcr.register(hc);
             }
         }
-        // routes is enabled by default
+        // routes are enabled by default
         if (hcr.isEnabled() && (!health.getConfig().containsKey("routes") || 
health.getRoutesEnabled() != null)) {
             HealthCheckRepository hc = 
hcr.getRepository("routes").orElse((HealthCheckRepository) 
hcr.resolveById("routes"));
             if (hc != null) {
@@ -979,13 +979,27 @@ public abstract class BaseMainSupport extends BaseService 
{
                 hcr.register(hc);
             }
         }
-        // registry is enabled by default
+        // consumers are enabled by default
+        if (hcr.isEnabled() && (!health.getConfig().containsKey("consumers") 
|| health.getRegistryEnabled() != null)) {
+            HealthCheckRepository hc
+                    = 
hcr.getRepository("consumers").orElse((HealthCheckRepository) 
hcr.resolveById("consumers"));
+            if (hc != null) {
+                if (health.getConsumersEnabled() != null) {
+                    hc.setEnabled(health.getConsumersEnabled());
+                }
+                hcr.register(hc);
+            }
+        }
+        // registry are enabled by default
         if (hcr.isEnabled() && (!health.getConfig().containsKey("registry") || 
health.getRegistryEnabled() != null)) {
-            hcr.getRepository("registry").ifPresent(h -> {
+            HealthCheckRepository hc
+                    = 
hcr.getRepository("registry").orElse((HealthCheckRepository) 
hcr.resolveById("registry"));
+            if (hc != null) {
                 if (health.getRegistryEnabled() != null) {
-                    h.setEnabled(health.getRegistryEnabled());
+                    hc.setEnabled(health.getRegistryEnabled());
                 }
-            });
+                hcr.register(hc);
+            }
         }
 
         // configure health checks configurations
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/HealthConfigurationProperties.java
 
b/core/camel-main/src/main/java/org/apache/camel/main/HealthConfigurationProperties.java
index b652291..6c403fa 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/HealthConfigurationProperties.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/HealthConfigurationProperties.java
@@ -38,6 +38,8 @@ public class HealthConfigurationProperties implements 
BootstrapCloseable {
     @Metadata(defaultValue = "true")
     private Boolean routesEnabled;
     @Metadata(defaultValue = "true")
+    private Boolean consumersEnabled;
+    @Metadata(defaultValue = "true")
     private Boolean registryEnabled;
     private Map<String, HealthCheckConfigurationProperties> config = new 
HashMap<>();
 
@@ -89,6 +91,17 @@ public class HealthConfigurationProperties implements 
BootstrapCloseable {
         this.routesEnabled = routesEnabled;
     }
 
+    public Boolean getConsumersEnabled() {
+        return consumersEnabled;
+    }
+
+    /**
+     * Whether consumers health check is enabled
+     */
+    public void setConsumersEnabled(Boolean consumersEnabled) {
+        this.consumersEnabled = consumersEnabled;
+    }
+
     public Boolean getRegistryEnabled() {
         return registryEnabled;
     }
diff --git a/docs/user-manual/modules/ROOT/pages/health-check.adoc 
b/docs/user-manual/modules/ROOT/pages/health-check.adoc
index 948d0a6..db219e0 100644
--- a/docs/user-manual/modules/ROOT/pages/health-check.adoc
+++ b/docs/user-manual/modules/ROOT/pages/health-check.adoc
@@ -12,19 +12,19 @@ Camel provides support to probe the state of an integration 
via a pluggable Heal
 
 Camel provides the following health checks out of the box:
 
-- context - A `HealthCheck` which performs check whether the `CamelContext` is 
started. This can be used for readiness checks; to know when Camel is fully 
started and ready to handle traffic.
+- _context_ - A `HealthCheck` which performs check whether the `CamelContext` 
is started. This can be used for readiness checks; to know when Camel is fully 
started and ready to handle traffic.
 - routes - A `HealthCheckRegistry` which discovers all the available routes in 
`CamelContext` and checks whether they are all started.
   This can be used for readiness checks; to know when Camel is fully started 
and ready to handle traffic.
   Combining with the supervised `RouteController` this allows to perform 
readiness check for routes that are under supervising,
   such as troublesome routes that may not start up the first time, and are 
retried to be started in the background with backoff delays.
-- consumer (scheduled polling consumer) - A `ScheduledPollConsumerHealthCheck` 
which automatic integrates with the *routes* health check
-  which enables fine-grained checks for the route input. This means if the 
consumer is failing to poll new messages
+- _consumers_ A `HealthCheckRegistry` which discovers all the consumers from 
all the routes in `CamelContext`
+  enabling fine-grained checks for the route input. This means if the consumer 
is failing to poll new messages
   then the health check can detect this and report as un-healthy. Note that 
the consumer will be DOWN during its initialization and until at least
   one poll run has been executed, to know whether that poll was a success or 
not. And if the poll was a success
   then the consumer is UP. This is on purpose to avoid having the health check 
to be initially UP
   and then after first poll run then DOWN again because the consumer cannot 
poll from external system;
   which causes the health check to be _flaky_.
-- registry - A `HealthCheckRegistry` which discovers all the available custom 
`HealthCheck` instances in the `Registry`.
+- _registry_ - A `HealthCheckRegistry` which discovers all the available 
custom `HealthCheck` instances in the `Registry`.
 
 == IDs
 
@@ -33,8 +33,8 @@ With the suffix `-health-check` or 
`-health-check-repository`. When looking up o
 
 For example `context-health-check` is the ID but can also be used by its 
shorthand `context`.
 
-The ID of the `ScheduledPollConsumerHealthCheck` is the route id with `route:` 
as prefix, eg if the route
-is named foo, then the ID is `route:foo`.
+The ID of the consumer health checks is the route id with `consumer:` as 
prefix, i.e. if the route
+is named foo, then the ID is `consumer:foo`.
 
 == Readiness and Liveness
 
@@ -78,7 +78,7 @@ By default, this is not in use, and the first successful 
check will result in UP
 Camel supports via `camel-main` to configure health-checks from configuration 
files. This is possible for runtimes that leverage `camel-main`
 such as Camel on Spring Boot, or Camel K.
 
-Camel will automatically enable `context`, `routes` and `registry` 
health-checks if `camel-health` is detected on the classpath.
+Camel will automatically enable `context`, `routes`, `consumers`, and 
`registry` health-checks if `camel-health` is detected on the classpath.
 They are all enabled by default. However, you can configure them, for example 
to turn it off:
 
 [source,properties]
@@ -90,6 +90,7 @@ They are all enabled by default. However, you can configure 
them, for example to
 # for example to only use context health-check
 camel.health.contextEnabled=true
 camel.health.routesEnabled=false
+camel.health.consumersEnabled=false
 camel.health.registryEnabled=false
 ----
 
@@ -119,6 +120,28 @@ camel.health.config[*].success-threshold=3
 camel.health.config[*].failure-threshold=10
 ----
 
+=== Turning off consumer level health-checks
+
+If routes health check is enabled then they will execute consumer 
health-checks as well
+as part of an aggregated response.
+
+The consumer checks can be turned off, to only use the route level checks 
(status of the route)
+
+[source,properties]
+----
+camel.health.consumersEnabled=false
+----
+
+You can also turn off individual consumers by prefixing the ID with 
`consumer:` such as:
+
+[source,properties]
+----
+camel.health.config[consumer:kafka*].enabled=false
+----
+
+which will turn off checks for all consumers on routes that starts with 
`kafka` in the route ID.
+
+
 == JMX management
 
 The health check is manageable via JMX (requires `camel-management` JAR on the 
classpath).

Reply via email to