You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2022/01/20 09:40:02 UTC

[camel-quarkus] branch main updated: Avoid creating CamelBeanBuildItem for health checks if they are disabled

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-quarkus.git


The following commit(s) were added to refs/heads/main by this push:
     new 73ffc7e  Avoid creating CamelBeanBuildItem for health checks if they are disabled
73ffc7e is described below

commit 73ffc7ef7f8882f0ba49bb89d8f7bfbe233a5f82
Author: James Netherton <ja...@gmail.com>
AuthorDate: Thu Jan 20 07:18:02 2022 +0000

    Avoid creating CamelBeanBuildItem for health checks if they are disabled
    
    Fixes #3470
---
 .../deployment/MicroProfileHealthProcessor.java    | 82 +++++++++++++++---
 .../MicroProfileHealthCamelChecksDisabledTest.java | 96 ++++++++++++++++++++++
 .../deployment/MicroProfileHealthEnabledTest.java  | 24 +++++-
 3 files changed, 188 insertions(+), 14 deletions(-)

diff --git a/extensions/microprofile-health/deployment/src/main/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthProcessor.java b/extensions/microprofile-health/deployment/src/main/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthProcessor.java
index e1261c0..351c9eb 100644
--- a/extensions/microprofile-health/deployment/src/main/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthProcessor.java
+++ b/extensions/microprofile-health/deployment/src/main/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthProcessor.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.function.BooleanSupplier;
+import java.util.function.Predicate;
 
 import javax.enterprise.inject.Vetoed;
 
@@ -34,12 +35,17 @@ import io.quarkus.smallrye.health.deployment.HealthBuildTimeConfig;
 import org.apache.camel.health.HealthCheck;
 import org.apache.camel.health.HealthCheckRegistry;
 import org.apache.camel.health.HealthCheckRepository;
-import org.apache.camel.impl.health.DefaultHealthCheckRegistry;
+import org.apache.camel.impl.health.ConsumersHealthCheckRepository;
+import org.apache.camel.impl.health.ContextHealthCheck;
+import org.apache.camel.impl.health.HealthCheckRegistryRepository;
+import org.apache.camel.impl.health.RoutesHealthCheckRepository;
 import org.apache.camel.microprofile.health.AbstractCamelMicroProfileHealthCheck;
 import org.apache.camel.quarkus.component.microprofile.health.runtime.CamelMicroProfileHealthConfig;
 import org.apache.camel.quarkus.component.microprofile.health.runtime.CamelMicroProfileHealthRecorder;
 import org.apache.camel.quarkus.core.deployment.spi.CamelBeanBuildItem;
 import org.apache.camel.quarkus.core.deployment.util.CamelSupport;
+import org.apache.camel.util.ObjectHelper;
+import org.eclipse.microprofile.config.Config;
 import org.eclipse.microprofile.config.ConfigProvider;
 import org.eclipse.microprofile.health.Liveness;
 import org.eclipse.microprofile.health.Readiness;
@@ -79,14 +85,23 @@ class MicroProfileHealthProcessor {
         }
     }
 
+    static final class HealthRegistryEnabled implements BooleanSupplier {
+        @Override
+        public boolean getAsBoolean() {
+            return ConfigProvider.getConfig()
+                    .getOptionalValue("camel.health.registryEnabled", boolean.class)
+                    .orElse(true);
+        }
+    }
+
     @BuildStep
     FeatureBuildItem feature() {
         return new FeatureBuildItem(FEATURE);
     }
 
     @Record(ExecutionTime.STATIC_INIT)
-    @BuildStep(onlyIf = HealthEnabled.class)
-    CamelBeanBuildItem metricRegistry(CamelMicroProfileHealthRecorder recorder, CamelMicroProfileHealthConfig config) {
+    @BuildStep(onlyIf = { HealthEnabled.class, HealthRegistryEnabled.class })
+    CamelBeanBuildItem healthCheckRegistry(CamelMicroProfileHealthRecorder recorder, CamelMicroProfileHealthConfig config) {
         return new CamelBeanBuildItem(
                 "HealthCheckRegistry",
                 HealthCheckRegistry.class.getName(),
@@ -94,22 +109,43 @@ class MicroProfileHealthProcessor {
     }
 
     @BuildStep(onlyIf = HealthEnabled.class)
-    List<CamelBeanBuildItem> camelHealthDiscovery(
-            CombinedIndexBuildItem combinedIndex,
-            CamelMicroProfileHealthConfig config) {
-
+    List<CamelBeanBuildItem> camelHealthDiscovery(CombinedIndexBuildItem combinedIndex) {
         IndexView index = combinedIndex.getIndex();
         List<CamelBeanBuildItem> buildItems = new ArrayList<>();
         Collection<ClassInfo> healthChecks = index.getAllKnownImplementors(CAMEL_HEALTH_CHECK_DOTNAME);
         Collection<ClassInfo> healthCheckRepositories = index
                 .getAllKnownImplementors(CAMEL_HEALTH_CHECK_REPOSITORY_DOTNAME);
 
+        Config config = ConfigProvider.getConfig();
+        Predicate<ClassInfo> healthCheckFilter = classInfo -> {
+            String className = classInfo.name().toString();
+            if (className.equals(HealthCheckRegistryRepository.class.getName())) {
+                // HealthCheckRegistryRepository is created internally by Camel
+                return false;
+            }
+
+            if (className.equals(ContextHealthCheck.class.getName())) {
+                return config.getOptionalValue("camel.health.contextEnabled", boolean.class).orElse(true);
+            }
+
+            if (className.equals(RoutesHealthCheckRepository.class.getName())) {
+                return config.getOptionalValue("camel.health.routesEnabled", boolean.class).orElse(true);
+            }
+
+            if (className.equals(ConsumersHealthCheckRepository.class.getName())) {
+                return config.getOptionalValue("camel.health.consumersEnabled", boolean.class).orElse(true);
+            }
+
+            return true;
+        };
+
         // Create CamelBeanBuildItem to bind instances of HealthCheck to the camel registry
         healthChecks.stream()
                 .filter(CamelSupport::isConcrete)
                 .filter(CamelSupport::isPublic)
                 .filter(ClassInfo::hasNoArgsConstructor)
-                .map(classInfo -> new CamelBeanBuildItem(classInfo.simpleName(), classInfo.name().toString()))
+                .filter(healthCheckFilter)
+                .map(this::createHealthCamelBeanBuildItem)
                 .forEach(buildItems::add);
 
         // Create CamelBeanBuildItem to bind instances of HealthCheckRepository to the camel registry
@@ -117,8 +153,8 @@ class MicroProfileHealthProcessor {
                 .filter(CamelSupport::isConcrete)
                 .filter(CamelSupport::isPublic)
                 .filter(ClassInfo::hasNoArgsConstructor)
-                .filter(classInfo -> !classInfo.simpleName().equals(DefaultHealthCheckRegistry.class.getSimpleName()))
-                .map(classInfo -> new CamelBeanBuildItem(classInfo.simpleName(), classInfo.name().toString()))
+                .filter(healthCheckFilter)
+                .map(this::createHealthCamelBeanBuildItem)
                 .forEach(buildItems::add);
 
         return buildItems;
@@ -145,4 +181,30 @@ class MicroProfileHealthProcessor {
                 && (classInfo.classAnnotation(MICROPROFILE_LIVENESS_DOTNAME) != null
                         || classInfo.classAnnotation(MICROPROFILE_READINESS_DOTNAME) != null);
     }
+
+    private CamelBeanBuildItem createHealthCamelBeanBuildItem(ClassInfo classInfo) {
+        String beanName;
+        String className = classInfo.name().toString();
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+        try {
+            Class<?> clazz = classLoader.loadClass(className);
+            Object health = clazz.getDeclaredConstructor().newInstance();
+            if (health instanceof HealthCheck) {
+                beanName = ((HealthCheck) health).getId();
+            } else if (health instanceof HealthCheckRepository) {
+                beanName = ((HealthCheckRepository) health).getId();
+            } else {
+                throw new IllegalArgumentException("Unknown health type " + className);
+            }
+
+            if (ObjectHelper.isEmpty(beanName)) {
+                beanName = className;
+            }
+
+            return new CamelBeanBuildItem(beanName, className);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
 }
diff --git a/extensions/microprofile-health/deployment/src/test/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthCamelChecksDisabledTest.java b/extensions/microprofile-health/deployment/src/test/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthCamelChecksDisabledTest.java
new file mode 100644
index 0000000..16e194a5
--- /dev/null
+++ b/extensions/microprofile-health/deployment/src/test/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthCamelChecksDisabledTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.quarkus.component.microprofile.health.deployment;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import io.quarkus.test.QuarkusUnitTest;
+import org.apache.camel.CamelContext;
+import org.apache.camel.health.HealthCheckRegistry;
+import org.apache.camel.impl.health.ConsumersHealthCheckRepository;
+import org.apache.camel.impl.health.ContextHealthCheck;
+import org.apache.camel.impl.health.RoutesHealthCheckRepository;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.Asset;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class MicroProfileHealthCamelChecksDisabledTest {
+
+    @RegisterExtension
+    static final QuarkusUnitTest CONFIG = new QuarkusUnitTest()
+            .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
+                    .addAsResource(applicationProperties(), "application.properties"));
+
+    @Inject
+    CamelContext context;
+
+    public static final Asset applicationProperties() {
+        Writer writer = new StringWriter();
+
+        Properties props = new Properties();
+        props.put("camel.health.contextEnabled", "false");
+        props.put("camel.health.routesEnabled", "false");
+        props.put("camel.health.consumersEnabled", "false");
+        props.put("camel.health.registryEnabled", "false");
+
+        try {
+            props.store(writer, "");
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        return new StringAsset(writer.toString());
+    }
+
+    @Test
+    public void contextHealthCheckNull() {
+        ContextHealthCheck contextHealthCheck = context.getRegistry().lookupByNameAndType("context", ContextHealthCheck.class);
+        assertNull(contextHealthCheck);
+    }
+
+    @Test
+    public void routesHealthCheckNull() {
+        RoutesHealthCheckRepository routesRepository = context.getRegistry().lookupByNameAndType("routes",
+                RoutesHealthCheckRepository.class);
+        assertNull(routesRepository);
+    }
+
+    @Test
+    public void consumersHealthCheckNull() {
+        ConsumersHealthCheckRepository consumersRepository = context.getRegistry().lookupByNameAndType("consumers",
+                ConsumersHealthCheckRepository.class);
+        assertNull(consumersRepository);
+    }
+
+    @Test
+    public void healthRegistryNull() {
+        Set<HealthCheckRegistry> healthCheckRegistries = context.getRegistry().findByType(HealthCheckRegistry.class);
+        assertTrue(healthCheckRegistries.isEmpty());
+    }
+}
diff --git a/extensions/microprofile-health/deployment/src/test/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthEnabledTest.java b/extensions/microprofile-health/deployment/src/test/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthEnabledTest.java
index d44bd81..c46e047 100644
--- a/extensions/microprofile-health/deployment/src/test/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthEnabledTest.java
+++ b/extensions/microprofile-health/deployment/src/test/java/org/apache/camel/quarkus/component/microprofile/health/deployment/MicroProfileHealthEnabledTest.java
@@ -23,14 +23,17 @@ import javax.inject.Inject;
 import io.quarkus.test.QuarkusUnitTest;
 import org.apache.camel.CamelContext;
 import org.apache.camel.health.HealthCheckRegistry;
+import org.apache.camel.impl.health.ConsumersHealthCheckRepository;
+import org.apache.camel.impl.health.ContextHealthCheck;
 import org.apache.camel.impl.health.DefaultHealthCheckRegistry;
-import org.eclipse.microprofile.health.HealthCheck;
+import org.apache.camel.impl.health.RoutesHealthCheckRepository;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.JavaArchive;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class MicroProfileHealthEnabledTest {
@@ -52,9 +55,22 @@ public class MicroProfileHealthEnabledTest {
     }
 
     @Test
-    public void camelMicroProfileHealthCheckBeansNotNull() {
-        Set<HealthCheck> healthChecks = context.getRegistry().findByType(HealthCheck.class);
-        assertEquals(2, healthChecks.size());
+    public void contextHealthCheckNotNull() {
+        ContextHealthCheck contextHealthCheck = context.getRegistry().lookupByNameAndType("context", ContextHealthCheck.class);
+        assertNotNull(contextHealthCheck);
     }
 
+    @Test
+    public void routesHealthCheckNotNull() {
+        RoutesHealthCheckRepository routesRepository = context.getRegistry().lookupByNameAndType("routes",
+                RoutesHealthCheckRepository.class);
+        assertNotNull(routesRepository);
+    }
+
+    @Test
+    public void consumersHealthCheckNotNull() {
+        ConsumersHealthCheckRepository consumersRepository = context.getRegistry().lookupByNameAndType("consumers",
+                ConsumersHealthCheckRepository.class);
+        assertNotNull(consumersRepository);
+    }
 }