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

davsclaus pushed a commit to branch health
in repository https://gitbox.apache.org/repos/asf/camel.git

commit a5146f7ce52eb28be31001f21247189fc5a660f5
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Feb 9 11:00:49 2022 +0100

    CAMEL-17587: camel-health - Make Health Check API simpler
---
 .../main/camel-main-configuration-metadata.json    |  2 +-
 .../org/apache/camel/health/HealthCheckHelper.java |  2 +-
 .../apache/camel/health/HealthCheckRegistry.java   | 11 +++-
 .../health/ConsumersHealthCheckRepository.java     |  6 +-
 .../impl/health/DefaultHealthCheckRegistry.java    | 33 ++++++++++-
 .../impl/health/HealthCheckRegistryRepository.java |  6 +-
 .../impl/health/RoutesHealthCheckRepository.java   |  6 +-
 .../camel-main-configuration-metadata.json         |  2 +-
 core/camel-main/src/main/docs/main.adoc            |  2 +-
 .../camel/main/HealthConfigurationProperties.java  |  6 +-
 ...ava => MainHealthCheckExcludedPatternTest.java} | 69 ++++++++++++++++++----
 11 files changed, 121 insertions(+), 24 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index e22879f..1d8e638 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -134,7 +134,7 @@
     { "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.excludePattern", "description": "Pattern to 
disabled health checks by their ids. Multiple patterns can be separated by 
comma.", "sourceType": "org.apache.camel.main.HealthConfigurationProperties", 
"type": "string", "javaType": "java.lang.String" },
+    { "name": "camel.health.excludePattern", "description": "Pattern to 
exclude health checks from being invoked by Camel when checking healths. 
Multiple patterns can be separated by comma.", "sourceType": 
"org.apache.camel.main.HealthConfigurationProperties", "type": "string", 
"javaType": "java.lang.String" },
     { "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 },
     { "name": "camel.health.routesEnabled", "description": "Whether routes 
health check is enabled", "sourceType": 
"org.apache.camel.main.HealthConfigurationProperties", "type": "boolean", 
"javaType": "java.lang.Boolean", "defaultValue": true },
     { "name": "camel.hystrix.allowMaximumSizeToDivergeFromCoreSize", 
"description": "Allows the configuration for maximumSize to take effect. That 
value can then be equal to, or higher, than coreSize", "sourceType": 
"org.apache.camel.main.HystrixConfigurationProperties", "type": "boolean", 
"javaType": "java.lang.Boolean", "defaultValue": "false", "deprecated": true },
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/health/HealthCheckHelper.java 
b/core/camel-api/src/main/java/org/apache/camel/health/HealthCheckHelper.java
index 336b7a2..1fe0d56 100644
--- 
a/core/camel-api/src/main/java/org/apache/camel/health/HealthCheckHelper.java
+++ 
b/core/camel-api/src/main/java/org/apache/camel/health/HealthCheckHelper.java
@@ -118,7 +118,7 @@ public final class HealthCheckHelper {
                     .entrySet().stream()
                     .map(Map.Entry::getValue)
                     .flatMap(Collection::stream)
-                    .filter(check -> !filter.test(check))
+                    .filter(check -> !registry.isExcluded(check) && 
!filter.test(check))
                     .sorted(Comparator.comparingInt(HealthCheck::getOrder))
                     .distinct()
                     .map(check -> check.call(optionsSupplier.apply(check)))
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/health/HealthCheckRegistry.java 
b/core/camel-api/src/main/java/org/apache/camel/health/HealthCheckRegistry.java
index bad246e..8101c04 100644
--- 
a/core/camel-api/src/main/java/org/apache/camel/health/HealthCheckRegistry.java
+++ 
b/core/camel-api/src/main/java/org/apache/camel/health/HealthCheckRegistry.java
@@ -122,13 +122,20 @@ public interface HealthCheckRegistry extends 
CamelContextAware, StaticService, I
     void loadHealthChecks();
 
     /**
-     * Pattern to disabled health checks by their ids. Multiple patterns can 
be separated by comma.
+     * Pattern to exclude health checks from being invoked by Camel when 
checking healths. Multiple patterns can be
+     * separated by comma.
      */
     String getExcludePattern();
 
     /**
-     * Pattern to disabled health checks by their ids. Multiple patterns can 
be separated by comma.
+     * Pattern to exclude health checks from being invoked by Camel when 
checking healths. Multiple patterns can be
+     * separated by comma.
      */
     void setExcludePattern(String excludePattern);
 
+    /**
+     * Whether the given health check has been excluded
+     */
+    boolean isExcluded(HealthCheck healthCheck);
+
 }
diff --git 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/ConsumersHealthCheckRepository.java
 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/ConsumersHealthCheckRepository.java
index bcd2bbe..b4244d2 100644
--- 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/ConsumersHealthCheckRepository.java
+++ 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/ConsumersHealthCheckRepository.java
@@ -24,16 +24,20 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.Consumer;
 import org.apache.camel.DeferredContextBinding;
+import org.apache.camel.NonManagedService;
 import org.apache.camel.Route;
+import org.apache.camel.StaticService;
 import org.apache.camel.health.HealthCheck;
 import org.apache.camel.health.HealthCheckRepository;
+import org.apache.camel.support.service.ServiceSupport;
 
 /**
  * Repository for consumers {@link HealthCheck}s.
  */
 @org.apache.camel.spi.annotations.HealthCheck("consumers-repository")
 @DeferredContextBinding
-public class ConsumersHealthCheckRepository implements CamelContextAware, 
HealthCheckRepository {
+public class ConsumersHealthCheckRepository extends ServiceSupport
+        implements CamelContextAware, HealthCheckRepository, StaticService, 
NonManagedService {
 
     private final ConcurrentMap<Consumer, HealthCheck> checks;
     private volatile CamelContext context;
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 fe1d50d..59cb0f4 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
@@ -30,6 +30,8 @@ import org.apache.camel.health.HealthCheck;
 import org.apache.camel.health.HealthCheckRegistry;
 import org.apache.camel.health.HealthCheckRepository;
 import org.apache.camel.health.HealthCheckResolver;
+import org.apache.camel.support.PatternHelper;
+import org.apache.camel.support.service.ServiceHelper;
 import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StopWatch;
@@ -113,6 +115,18 @@ public class DefaultHealthCheckRegistry extends 
ServiceSupport implements Health
         for (HealthCheckRepository repository : repositories) {
             CamelContextAware.trySetCamelContext(repository, camelContext);
         }
+
+        ServiceHelper.initService(repositories, checks);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        ServiceHelper.startService(repositories, checks);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        ServiceHelper.stopService(repositories, checks);
     }
 
     // ************************************
@@ -170,8 +184,6 @@ public class DefaultHealthCheckRegistry extends 
ServiceSupport implements Health
 
         checkIfAccepted(obj);
 
-        // TODO: exclude pattern
-
         if (obj instanceof HealthCheck) {
             HealthCheck healthCheck = (HealthCheck) obj;
             // do we have this already
@@ -264,6 +276,23 @@ public class DefaultHealthCheckRegistry extends 
ServiceSupport implements Health
         }
     }
 
+    @Override
+    public boolean isExcluded(HealthCheck healthCheck) {
+        if (excludePattern != null) {
+            String[] s = excludePattern.split(",");
+            String id = healthCheck.getId();
+            String id2 = null;
+            // special for route and consumer health checks
+            if (id.startsWith("route:")) {
+                id2 = id.substring(6);
+            } else if (id.startsWith("consumer:")) {
+                id2 = id.substring(9);
+            }
+            return PatternHelper.matchPatterns(id, s) || (id2 != null && 
PatternHelper.matchPatterns(id2, s));
+        }
+        return false;
+    }
+
     private void checkIfAccepted(Object obj) {
         boolean accept = obj instanceof HealthCheck || obj instanceof 
HealthCheckRepository;
         if (!accept) {
diff --git 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/HealthCheckRegistryRepository.java
 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/HealthCheckRegistryRepository.java
index fbb3337..54210e6 100644
--- 
a/core/camel-health/src/main/java/org/apache/camel/impl/health/HealthCheckRegistryRepository.java
+++ 
b/core/camel-health/src/main/java/org/apache/camel/impl/health/HealthCheckRegistryRepository.java
@@ -21,15 +21,19 @@ import java.util.stream.Stream;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
+import org.apache.camel.NonManagedService;
+import org.apache.camel.StaticService;
 import org.apache.camel.health.HealthCheck;
 import org.apache.camel.health.HealthCheckRepository;
+import org.apache.camel.support.service.ServiceSupport;
 
 /**
  * {@link HealthCheckRepository} that uses the Camel {@link 
org.apache.camel.spi.Registry}.
  *
  * Camel will use this by default, so there is no need to register this 
manually.
  */
-public class HealthCheckRegistryRepository implements CamelContextAware, 
HealthCheckRepository {
+public class HealthCheckRegistryRepository extends ServiceSupport
+        implements CamelContextAware, HealthCheckRepository, StaticService, 
NonManagedService {
     private CamelContext context;
     private boolean enabled = true;
 
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 3103385..f7cd2fb 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
@@ -23,16 +23,20 @@ import java.util.stream.Stream;
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.DeferredContextBinding;
+import org.apache.camel.NonManagedService;
 import org.apache.camel.Route;
+import org.apache.camel.StaticService;
 import org.apache.camel.health.HealthCheck;
 import org.apache.camel.health.HealthCheckRepository;
+import org.apache.camel.support.service.ServiceSupport;
 
 /**
  * Repository for routes {@link HealthCheck}s.
  */
 @org.apache.camel.spi.annotations.HealthCheck("routes-repository")
 @DeferredContextBinding
-public class RoutesHealthCheckRepository implements CamelContextAware, 
HealthCheckRepository {
+public class RoutesHealthCheckRepository extends ServiceSupport
+        implements CamelContextAware, HealthCheckRepository, StaticService, 
NonManagedService {
 
     private final ConcurrentMap<Route, HealthCheck> checks;
     private volatile CamelContext context;
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 e22879f..1d8e638 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
@@ -134,7 +134,7 @@
     { "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.excludePattern", "description": "Pattern to 
disabled health checks by their ids. Multiple patterns can be separated by 
comma.", "sourceType": "org.apache.camel.main.HealthConfigurationProperties", 
"type": "string", "javaType": "java.lang.String" },
+    { "name": "camel.health.excludePattern", "description": "Pattern to 
exclude health checks from being invoked by Camel when checking healths. 
Multiple patterns can be separated by comma.", "sourceType": 
"org.apache.camel.main.HealthConfigurationProperties", "type": "string", 
"javaType": "java.lang.String" },
     { "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 },
     { "name": "camel.health.routesEnabled", "description": "Whether routes 
health check is enabled", "sourceType": 
"org.apache.camel.main.HealthConfigurationProperties", "type": "boolean", 
"javaType": "java.lang.Boolean", "defaultValue": true },
     { "name": "camel.hystrix.allowMaximumSizeToDivergeFromCoreSize", 
"description": "Allows the configuration for maximumSize to take effect. That 
value can then be equal to, or higher, than coreSize", "sourceType": 
"org.apache.camel.main.HystrixConfigurationProperties", "type": "boolean", 
"javaType": "java.lang.Boolean", "defaultValue": "false", "deprecated": true },
diff --git a/core/camel-main/src/main/docs/main.adoc 
b/core/camel-main/src/main/docs/main.adoc
index 12af1c8..286680c 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -158,7 +158,7 @@ The camel.health supports 6 options, which are listed below.
 | *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.excludePattern* | Pattern to disabled health checks by their 
ids. Multiple patterns can be separated by comma. |  | String
+| *camel.health.excludePattern* | Pattern to exclude health checks from being 
invoked by Camel when checking healths. Multiple patterns can be separated by 
comma. |  | String
 | *camel.health.registryEnabled* | Whether registry health check is enabled | 
true | Boolean
 | *camel.health.routesEnabled* | Whether routes health check is enabled | true 
| Boolean
 |===
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 e2b4fb1..69dc26c 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
@@ -114,7 +114,8 @@ public class HealthConfigurationProperties implements 
BootstrapCloseable {
     }
 
     /**
-     * Pattern to disabled health checks by their ids. Multiple patterns can 
be separated by comma.
+     * Pattern to exclude health checks from being invoked by Camel when 
checking healths. Multiple patterns can be
+     * separated by comma.
      */
     public void setExcludePattern(String excludePattern) {
         this.excludePattern = excludePattern;
@@ -153,7 +154,8 @@ public class HealthConfigurationProperties implements 
BootstrapCloseable {
     }
 
     /**
-     * Pattern to exclude health checks by their ids. Multiple patterns can be 
separated by comma.
+     * Pattern to exclude health checks from being invoked by Camel when 
checking healths. Multiple patterns can be
+     * separated by comma.
      */
     public HealthConfigurationProperties withExcludePattern(String 
excludePattern) {
         this.excludePattern = excludePattern;
diff --git 
a/core/camel-main/src/test/java/org/apache/camel/main/MainHealthCheckConfigTest.java
 
b/core/camel-main/src/test/java/org/apache/camel/main/MainHealthCheckExcludedPatternTest.java
similarity index 66%
rename from 
core/camel-main/src/test/java/org/apache/camel/main/MainHealthCheckConfigTest.java
rename to 
core/camel-main/src/test/java/org/apache/camel/main/MainHealthCheckExcludedPatternTest.java
index 5013656..a541871 100644
--- 
a/core/camel-main/src/test/java/org/apache/camel/main/MainHealthCheckConfigTest.java
+++ 
b/core/camel-main/src/test/java/org/apache/camel/main/MainHealthCheckExcludedPatternTest.java
@@ -19,18 +19,19 @@ package org.apache.camel.main;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.health.HealthCheck;
+import org.apache.camel.health.HealthCheckHelper;
 import org.apache.camel.health.HealthCheckRegistry;
 import org.apache.camel.health.HealthCheckRepository;
 import org.apache.camel.health.HealthCheckResultBuilder;
 import org.apache.camel.impl.health.AbstractHealthCheck;
 import org.apache.camel.impl.health.HealthCheckRegistryRepository;
 import org.apache.camel.impl.health.RoutesHealthCheckRepository;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -38,13 +39,10 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-// TODO: exclude pattern
-
-@Disabled
-public class MainHealthCheckConfigTest {
+public class MainHealthCheckExcludedPatternTest {
 
     @Test
-    public void testMainRoutesHealthCheckConfiguration() {
+    public void testMainRoutesHealthCheckExcluded() {
         Main main = new Main();
         main.configure().addRoutesBuilder(new Routes());
         main.addInitialProperty("camel.health.routes-enabled", "true");
@@ -66,16 +64,18 @@ public class MainHealthCheckConfigTest {
 
             HealthCheck hc = healthCheckRegistry.getCheck("mydirect").get();
             assertTrue(hc.isEnabled());
+            assertFalse(healthCheckRegistry.isExcluded(hc));
 
             hc = healthCheckRegistry.getCheck("myseda").get();
-            assertFalse(hc.isEnabled());
+            assertTrue(hc.isEnabled());
+            assertTrue(healthCheckRegistry.isExcluded(hc));
         } finally {
             main.stop();
         }
     }
 
     @Test
-    public void testMainBasicHealthCheckConfiguration() {
+    public void testMainBasicHealthCheckRegistry() {
         Main main = new Main();
         main.configure().addRoutesBuilder(new Routes());
         main.addInitialProperty("camel.health.exclude-pattern", "custom");
@@ -85,10 +85,11 @@ public class MainHealthCheckConfigTest {
             CamelContext camelContext = main.getCamelContext();
             assertNotNull(camelContext);
 
+            final AtomicBoolean invoked = new AtomicBoolean();
             HealthCheck healthCheck = new AbstractHealthCheck("custom") {
                 @Override
                 protected void doCall(HealthCheckResultBuilder builder, 
Map<String, Object> options) {
-                    // Noop
+                    invoked.set(true);
                 }
             };
 
@@ -107,8 +108,54 @@ public class MainHealthCheckConfigTest {
             List<HealthCheck> healthChecks = 
registryRepository.stream().collect(Collectors.toList());
             assertEquals(1, healthChecks.size());
 
-            HealthCheck hc = healthCheckRegistry.getCheck("custom").get();
-            assertTrue(hc.isEnabled());
+            assertTrue(healthCheckRegistry.getCheck("custom").isPresent());
+
+            // custom is excluded
+            HealthCheckHelper.invoke(camelContext);
+            assertFalse(invoked.get());
+        } finally {
+            main.stop();
+        }
+    }
+
+    @Test
+    public void testMainBasicHealthCheckAdded() {
+        Main main = new Main();
+        main.configure().addRoutesBuilder(new Routes());
+        main.addInitialProperty("camel.health.exclude-pattern", "custom");
+
+        main.start();
+        try {
+            CamelContext camelContext = main.getCamelContext();
+            assertNotNull(camelContext);
+
+            final AtomicBoolean invoked = new AtomicBoolean();
+            HealthCheck healthCheck = new AbstractHealthCheck("custom") {
+                @Override
+                protected void doCall(HealthCheckResultBuilder builder, 
Map<String, Object> options) {
+                    invoked.set(true);
+                }
+            };
+
+            HealthCheckRegistry healthCheckRegistry = 
camelContext.getExtension(HealthCheckRegistry.class);
+            assertNotNull(healthCheckRegistry);
+
+            List<HealthCheck> healthChecks = 
healthCheckRegistry.stream().collect(Collectors.toList());
+            int before = healthChecks.size();
+
+            // register custom health check which should be excluded
+            boolean added = healthCheckRegistry.register(healthCheck);
+            assertTrue(added);
+
+            healthChecks = 
healthCheckRegistry.stream().collect(Collectors.toList());
+            int after = healthChecks.size();
+            assertEquals(before + 1, after);
+
+            assertTrue(healthCheckRegistry.getCheck("custom").isPresent());
+
+            // custom is excluded
+            HealthCheckHelper.invoke(camelContext);
+            assertFalse(invoked.get());
         } finally {
             main.stop();
         }

Reply via email to