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 <jamesnether...@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); + } }