This is an automated email from the ASF dual-hosted git repository. lburgazzoli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit 30908ac710919c987c382f7aa8896d532324a1d6 Author: Peter Palaga <ppal...@redhat.com> AuthorDate: Fri Jan 17 16:15:15 2020 +0100 Fix #617 Registerable and discoverable Camel services --- .../quarkus/core/deployment/BuildProcessor.java | 117 ++++++++++++++-- .../CamelFactoryFinderResolverBuildItem.java} | 27 ++-- ...ServiceInfo.java => CamelServiceBuildItem.java} | 62 ++++---- .../core/deployment/CamelServiceFilter.java | 2 +- .../deployment/CamelServicePatternBuildItem.java | 84 +++++++++++ .../quarkus/core/deployment/CamelSupport.java | 64 ++------- .../core/deployment/NativeImageProcessor.java | 43 ++---- .../quarkus/core/deployment/util/PathFilter.java | 156 +++++++++++++++++++++ .../PathFilterTest.java} | 46 +++++- .../org/apache/camel/quarkus/core/CamelConfig.java | 87 ++++++++++++ .../apache/camel/quarkus/core/CamelRecorder.java | 17 ++- .../camel/quarkus/core/FastCamelContext.java | 8 +- .../quarkus/core/FastFactoryFinderResolver.java | 147 +++++++++++++++++++ .../component/file/deployment/FileProcessor.java | 5 +- .../hystrix/deployment/HystrixProcessor.java | 4 - .../src/main/resources/application.properties | 2 + 16 files changed, 724 insertions(+), 147 deletions(-) diff --git a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/BuildProcessor.java b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/BuildProcessor.java index 594ec28..63c6e8d 100644 --- a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/BuildProcessor.java +++ b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/BuildProcessor.java @@ -21,7 +21,6 @@ import java.lang.reflect.Modifier; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -54,8 +53,11 @@ import org.apache.camel.quarkus.core.CamelMainRecorder; import org.apache.camel.quarkus.core.CamelProducers; import org.apache.camel.quarkus.core.CamelRecorder; import org.apache.camel.quarkus.core.CoreAttachmentsRecorder; +import org.apache.camel.quarkus.core.FastFactoryFinderResolver.Builder; import org.apache.camel.quarkus.core.Flags; import org.apache.camel.quarkus.core.UploadAttacher; +import org.apache.camel.quarkus.core.deployment.CamelServicePatternBuildItem.CamelServiceDestination; +import org.apache.camel.quarkus.core.deployment.util.PathFilter; import org.apache.camel.quarkus.support.common.CamelCapabilities; import org.apache.camel.spi.TypeConverterLoader; import org.apache.camel.spi.TypeConverterRegistry; @@ -125,6 +127,68 @@ class BuildProcessor { new CamelServiceFilterBuildItem(CamelServiceFilter.forService("properties-component-factory"))); } + @BuildStep + void coreServicePatterns(BuildProducer<CamelServicePatternBuildItem> services) { + + services.produce(new CamelServicePatternBuildItem( + CamelServiceDestination.REGISTRY, + true, + "META-INF/services/org/apache/camel/component/*", + "META-INF/services/org/apache/camel/language/*", + "META-INF/services/org/apache/camel/dataformat/*")); + + services.produce(new CamelServicePatternBuildItem( + CamelServiceDestination.DISCOVERY, + true, + "META-INF/services/org/apache/camel/*", + "META-INF/services/org/apache/camel/management/*", + "META-INF/services/org/apache/camel/model/*", + "META-INF/services/org/apache/camel/configurer/*")); + } + + @BuildStep + void userServicePatterns( + CamelConfig camelConfig, + BuildProducer<CamelServicePatternBuildItem> services) { + + camelConfig.service.discovery.includePatterns.ifPresent(list -> services.produce(new CamelServicePatternBuildItem( + CamelServiceDestination.DISCOVERY, + true, + list))); + + camelConfig.service.discovery.excludePatterns.ifPresent(list -> services.produce(new CamelServicePatternBuildItem( + CamelServiceDestination.DISCOVERY, + false, + list))); + + camelConfig.service.registry.includePatterns.ifPresent(list -> services.produce(new CamelServicePatternBuildItem( + CamelServiceDestination.REGISTRY, + true, + list))); + + camelConfig.service.registry.excludePatterns.ifPresent(list -> services.produce(new CamelServicePatternBuildItem( + CamelServiceDestination.REGISTRY, + false, + list))); + } + + @BuildStep + void camelServices( + ApplicationArchivesBuildItem applicationArchives, + List<CamelServicePatternBuildItem> servicePatterns, + BuildProducer<CamelServiceBuildItem> camelServices) { + + final PathFilter pathFilter = servicePatterns.stream() + .filter(patterns -> patterns.getDestination() == CamelServiceDestination.DISCOVERY) + .collect( + PathFilter.Builder::new, + (bldr, patterns) -> bldr.patterns(patterns.isInclude(), patterns.getPatterns()), + PathFilter.Builder::combine) + .build(); + CamelSupport.services(applicationArchives, pathFilter) + .forEach(camelServices::produce); + } + /* * Discover {@link TypeConverterLoader}. */ @@ -145,8 +209,8 @@ class BuildProcessor { // account even if it should not. // // TODO: we could add a filter to discard AnnotationTypeConverterLoader but maybe we should introduce - // a marker interface like StaticTypeConverterLoader for loaders that do not require to perform - // any discovery at runtime. + // a marker interface like StaticTypeConverterLoader for loaders that do not require to perform + // any discovery at runtime. // for (ApplicationArchive archive : applicationArchives.getAllApplicationArchives()) { Path path = archive.getArchiveRoot().resolve(BaseTypeConverterRegistry.META_INF_SERVICES_TYPE_CONVERTER_LOADER); @@ -182,14 +246,26 @@ class BuildProcessor { CamelRegistryBuildItem registry( CamelRecorder recorder, RecorderContext recorderContext, + CamelConfig camelConfig, ApplicationArchivesBuildItem applicationArchives, ContainerBeansBuildItem containerBeans, List<CamelBeanBuildItem> registryItems, - List<CamelServiceFilterBuildItem> serviceFilters) { + List<CamelServiceFilterBuildItem> serviceFilters, + List<CamelServicePatternBuildItem> servicePatterns) { final RuntimeValue<org.apache.camel.spi.Registry> registry = recorder.createRegistry(); - CamelSupport.services(applicationArchives) + final PathFilter pathFilter = servicePatterns.stream() + .filter(patterns -> patterns.getDestination() == CamelServiceDestination.REGISTRY) + .collect( + PathFilter.Builder::new, + (builder, patterns) -> builder.patterns(patterns.isInclude(), patterns.getPatterns()), + PathFilter.Builder::combine) + .include(camelConfig.service.registry.includePatterns) + .exclude(camelConfig.service.registry.excludePatterns) + .build(); + + CamelSupport.services(applicationArchives, pathFilter) .filter(si -> !containerBeans.getBeans().contains(si)) .filter(si -> { // @@ -268,6 +344,7 @@ class BuildProcessor { CamelTypeConverterRegistryBuildItem typeConverterRegistry, CamelModelJAXBContextFactoryBuildItem contextFactory, CamelRoutesLoaderBuildItems.Xml xmlLoader, + CamelFactoryFinderResolverBuildItem factoryFinderResolverBuildItem, BeanContainerBuildItem beanContainer) { RuntimeValue<CamelContext> context = recorder.createContext( @@ -275,6 +352,7 @@ class BuildProcessor { typeConverterRegistry.getRegistry(), contextFactory.getContextFactory(), xmlLoader.getLoader(), + factoryFinderResolverBuildItem.getFactoryFinderResolver(), beanContainer.getValue()); return new CamelContextBuildItem(context); @@ -312,6 +390,27 @@ class BuildProcessor { return new CamelRuntimeRegistryBuildItem(registry.getRegistry()); } + + @Record(ExecutionTime.STATIC_INIT) + @BuildStep + CamelFactoryFinderResolverBuildItem factoryFinderResolver( + RecorderContext recorderContext, + CamelRecorder recorder, + List<CamelServiceBuildItem> camelServices) { + + RuntimeValue<Builder> builder = recorder.factoryFinderResolverBuilder(); + + camelServices.stream() + .forEach(service -> { + recorder.factoryFinderResolverEntry( + builder, + service.path.toString(), + recorderContext.classProxy(service.type)); + }); + + return new CamelFactoryFinderResolverBuildItem(recorder.factoryFinderResolver(builder)); + } + } /* @@ -343,10 +442,10 @@ class BuildProcessor { // public and non-abstract .filter(ci -> ((ci.flags() & (Modifier.ABSTRACT | Modifier.PUBLIC)) == Modifier.PUBLIC)) .map(ClassInfo::name) - .filter(dotName -> CamelSupport.isPathIncluded( - dotName.toString('/'), - config.main.routesDiscovery.excludePatterns.orElse(Collections.emptyList()), - config.main.routesDiscovery.includePatterns.orElse(Collections.emptyList()))) + .filter(new PathFilter.Builder() + .exclude(config.main.routesDiscovery.excludePatterns) + .include(config.main.routesDiscovery.includePatterns) + .build().asDotNamePredicate()) .map(CamelRoutesBuilderClassBuildItem::new) .collect(Collectors.toList()); } diff --git a/extensions/file/deployment/src/main/java/org/apache/camel/quarkus/component/file/deployment/FileProcessor.java b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelFactoryFinderResolverBuildItem.java similarity index 52% copy from extensions/file/deployment/src/main/java/org/apache/camel/quarkus/component/file/deployment/FileProcessor.java copy to extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelFactoryFinderResolverBuildItem.java index 8a38547..be9bbfa 100644 --- a/extensions/file/deployment/src/main/java/org/apache/camel/quarkus/component/file/deployment/FileProcessor.java +++ b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelFactoryFinderResolverBuildItem.java @@ -14,24 +14,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.quarkus.component.file.deployment; +package org.apache.camel.quarkus.core.deployment; -import io.quarkus.deployment.annotations.BuildStep; -import io.quarkus.deployment.builditem.FeatureBuildItem; -import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; -import org.apache.camel.component.file.GenericFile; +import io.quarkus.builder.item.SimpleBuildItem; +import io.quarkus.runtime.RuntimeValue; +import org.apache.camel.spi.FactoryFinderResolver; -class FileProcessor { - - private static final String FEATURE = "camel-file"; +/** + * A {@link SimpleBuildItem} holding a {@link FastFactoryFinderResolver} {@link RuntimeValue}. + */ +public final class CamelFactoryFinderResolverBuildItem extends SimpleBuildItem { + private final RuntimeValue<FactoryFinderResolver> factoryFinderResolver; - @BuildStep - FeatureBuildItem feature() { - return new FeatureBuildItem(FEATURE); + public CamelFactoryFinderResolverBuildItem(RuntimeValue<FactoryFinderResolver> factoryFinderResolverBuilder) { + this.factoryFinderResolver = factoryFinderResolverBuilder; } - @BuildStep - ReflectiveClassBuildItem registerForReflection() { - return new ReflectiveClassBuildItem(true, false, GenericFile.class); + public RuntimeValue<FactoryFinderResolver> getFactoryFinderResolver() { + return factoryFinderResolver; } } diff --git a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfo.java b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceBuildItem.java similarity index 57% rename from extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfo.java rename to extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceBuildItem.java index 8c46e13..b460bf0 100644 --- a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfo.java +++ b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceBuildItem.java @@ -19,50 +19,57 @@ package org.apache.camel.quarkus.core.deployment; import java.nio.file.Path; import java.util.Objects; +import io.quarkus.builder.item.MultiBuildItem; + /** - * Utility class to describe a camel service which is a result of reading - * services from resources belonging to META-INF/services/org/apache/camel. + * A {@link MultiBuildItem} holding information about a service defined in a property file somewhere under + * {@code META-INF/services/org/apache/camel}. */ -public class CamelServiceInfo implements CamelBeanInfo { - /** - * The path of the service file like META-INF/services/org/apache/camel/component/file. - */ - public final Path path; +public final class CamelServiceBuildItem extends MultiBuildItem implements CamelBeanInfo { - /** - * The name of the service entry which is derived from the service path. As example the - * name for a service with path <code>META-INF/services/org/apache/camel/component/file</code> - * will be <code>file</code> - */ - public final String name; + final Path path; - /** - * The full qualified class name of the service. - */ - public final String type; + final String name; + + final String type; - public CamelServiceInfo(Path path, String type) { + public CamelServiceBuildItem(Path path, String type) { this(path, path.getFileName().toString(), type); } - public CamelServiceInfo(Path path, String name, String type) { + public CamelServiceBuildItem(Path path, String name, String type) { + Objects.requireNonNull(path, "path"); + Objects.requireNonNull(type, () -> "type for path " + path); this.path = path; this.name = name; this.type = type; } - @Override + /** + * @return the path of the service file like {@code META-INF/services/org/apache/camel/component/file}. + */ + public Path getPath() { + return path; + } + + /** + * @return the name under which this service will be registered in the Camel registry. + * This name may or may not be the same as the last segment of {@link #path}. + */ public String getName() { - return this.name; + return name; } - @Override + /** + * @return The fully qualified class name of the service. + */ public String getType() { - return this.type; + return type; } @Override public boolean equals(Object o) { + /* This must be the same as in other implementations of CamelBeanInfo */ if (this == o) { return true; } @@ -76,15 +83,8 @@ public class CamelServiceInfo implements CamelBeanInfo { @Override public int hashCode() { + /* This must be the same as in other implementations of CamelBeanInfo */ return Objects.hash(getName(), getType()); } - @Override - public String toString() { - return "ServiceInfo{" - + "path='" + path.toString() + '\'' - + ", name=" + name - + ", type=" + type - + '}'; - } } diff --git a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceFilter.java b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceFilter.java index 87c96a9..9e9c508 100644 --- a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceFilter.java +++ b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceFilter.java @@ -19,7 +19,7 @@ package org.apache.camel.quarkus.core.deployment; import java.util.function.Predicate; @FunctionalInterface -public interface CamelServiceFilter extends Predicate<CamelServiceInfo> { +public interface CamelServiceFilter extends Predicate<CamelServiceBuildItem> { String CAMEL_SERVICE_BASE_PATH = "META-INF/services/org/apache/camel"; static CamelServiceFilter forPathEndingWith(String path) { diff --git a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServicePatternBuildItem.java b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServicePatternBuildItem.java new file mode 100644 index 0000000..906b21e --- /dev/null +++ b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServicePatternBuildItem.java @@ -0,0 +1,84 @@ +/* + * 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.core.deployment; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import io.quarkus.builder.item.MultiBuildItem; + +/** + * A {@link MultiBuildItem} holding a collection of path patterns to select files under + * {@code META-INF/services/org/apache/camel} which define discoverable Camel services. + */ +public final class CamelServicePatternBuildItem extends MultiBuildItem { + + /** + * Where a Camel service should be further processed + */ + public enum CamelServiceDestination { + /** Service marked with {@link #DISCOVERY} should be made discoverable via FactoryFinder mechanism */ + DISCOVERY, + /** Service marked with {@link #DISCOVERY} should be registered in the Camel registry */ + REGISTRY + } + + public CamelServicePatternBuildItem(CamelServiceDestination destination, boolean include, + String... patterns) { + this(destination, include, Arrays.asList(patterns)); + } + + public CamelServicePatternBuildItem(CamelServiceDestination destination, boolean include, + Collection<String> patterns) { + this.destination = destination; + this.include = include; + this.patterns = Collections.unmodifiableList(new ArrayList<>(patterns)); + } + + private final CamelServiceDestination destination; + + private final boolean include; + + private final List<String> patterns; + + /** + * @return a {@link CamelServiceDestination} that says where this service should be further processed. See + * {@link CamelServiceDestination} and its members. + */ + public CamelServiceDestination getDestination() { + return destination; + } + + /** + * @return {@code true} if the {@link #patterns} should be interpreted as includes; otherwise the {@link #patterns} + * should be interpreted as excludes + */ + public boolean isInclude() { + return include; + } + + /** + * @return a {@link List} or Ant-like path patterns. By convention these + */ + public List<String> getPatterns() { + return patterns; + } + +} diff --git a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelSupport.java b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelSupport.java index f8f7d10..296229d 100644 --- a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelSupport.java +++ b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelSupport.java @@ -22,19 +22,15 @@ import java.io.InputStream; import java.lang.reflect.Modifier; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; +import java.util.AbstractMap; import java.util.HashSet; -import java.util.List; -import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem; -import org.apache.camel.util.AntPathMatcher; -import org.apache.camel.util.ObjectHelper; +import org.apache.camel.quarkus.core.deployment.util.PathFilter; import org.jboss.jandex.ClassInfo; public final class CamelSupport { @@ -60,29 +56,6 @@ public final class CamelSupport { } } - public static boolean isPathIncluded(String path, Collection<String> excludePatterns, Collection<String> includePatterns) { - final AntPathMatcher matcher = new AntPathMatcher(); - - if (ObjectHelper.isEmpty(excludePatterns) && ObjectHelper.isEmpty(includePatterns)) { - return true; - } - - // same logic as org.apache.camel.main.DefaultRoutesCollector so exclude - // take precedence over include - for (String part : excludePatterns) { - if (matcher.match(part.trim(), path)) { - return false; - } - } - for (String part : includePatterns) { - if (matcher.match(part.trim(), path)) { - return true; - } - } - - return ObjectHelper.isEmpty(includePatterns); - } - public static Stream<Path> resources(ApplicationArchivesBuildItem archives, String path) { return archives.getAllApplicationArchives().stream() .map(arch -> arch.getArchiveRoot().resolve(path)) @@ -91,29 +64,22 @@ public final class CamelSupport { .filter(Files::isRegularFile); } - public static Stream<CamelServiceInfo> services(ApplicationArchivesBuildItem applicationArchivesBuildItem) { - return CamelSupport.resources(applicationArchivesBuildItem, CamelSupport.CAMEL_SERVICE_BASE_PATH) - .map(CamelSupport::services) - .flatMap(Collection::stream); + public static Stream<CamelServiceBuildItem> services(ApplicationArchivesBuildItem archives, PathFilter pathFilter) { + return resources(archives, CAMEL_SERVICE_BASE_PATH) + .filter(pathFilter.asPathPredicate()) + .map(path -> new AbstractMap.SimpleImmutableEntry<>(path, readProperties(path))) + .filter(entry -> entry.getValue().getProperty("class") != null) + .map(entry -> new CamelServiceBuildItem(entry.getKey(), entry.getValue().getProperty("class"))); } - private static List<CamelServiceInfo> services(Path p) { - List<CamelServiceInfo> answer = new ArrayList<>(); - - try (InputStream is = Files.newInputStream(p)) { - Properties props = new Properties(); - props.load(is); - for (Map.Entry<Object, Object> entry : props.entrySet()) { - String k = entry.getKey().toString(); - if (k.equals("class")) { - answer.add(new CamelServiceInfo(p, entry.getValue().toString())); - } - } - } catch (Exception e) { - throw new RuntimeException(e); + private static Properties readProperties(Path path) { + try (InputStream in = Files.newInputStream(path)) { + final Properties result = new Properties(); + result.load(in); + return result; + } catch (IOException e) { + throw new RuntimeException("Could not read " + path, e); } - - return answer; } @SafeVarargs diff --git a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/NativeImageProcessor.java b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/NativeImageProcessor.java index 9c9f346..034b191 100644 --- a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/NativeImageProcessor.java +++ b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/NativeImageProcessor.java @@ -16,14 +16,9 @@ */ package org.apache.camel.quarkus.core.deployment; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.Map; -import java.util.Properties; import java.util.stream.Collectors; import io.quarkus.deployment.annotations.BuildProducer; @@ -41,6 +36,7 @@ import org.apache.camel.Endpoint; import org.apache.camel.Producer; import org.apache.camel.TypeConverter; import org.apache.camel.quarkus.core.Flags; +import org.apache.camel.spi.DataFormat; import org.apache.camel.spi.ExchangeFormatter; import org.apache.camel.spi.PropertiesComponent; import org.apache.camel.spi.ScheduledPollConsumerScheduler; @@ -69,7 +65,8 @@ class NativeImageProcessor { CamelContext.class, StreamCachingStrategy.class, StreamCachingStrategy.SpoolUsedHeapMemoryLimit.class, - PropertiesComponent.class); + PropertiesComponent.class, + DataFormat.class); @BuildStep void reflectiveItems( @@ -125,36 +122,24 @@ class NativeImageProcessor { } @BuildStep - void resourcesAndServices( + void resources( ApplicationArchivesBuildItem applicationArchivesBuildItem, - BuildProducer<ReflectiveClassBuildItem> reflectiveClass, BuildProducer<NativeImageResourceBuildItem> resource) { CamelSupport.resources(applicationArchivesBuildItem, "META-INF/maven/org.apache.camel/camel-base") .forEach(p -> resource.produce(new NativeImageResourceBuildItem(p.toString().substring(1)))); - CamelSupport.resources(applicationArchivesBuildItem, CamelSupport.CAMEL_SERVICE_BASE_PATH) - .forEach(path -> addCamelService(path, reflectiveClass, resource)); } - static void addCamelService( - Path p, - BuildProducer<ReflectiveClassBuildItem> reflectiveClass, - BuildProducer<NativeImageResourceBuildItem> resource) { - try (InputStream is = Files.newInputStream(p)) { - Properties props = new Properties(); - props.load(is); - for (Map.Entry<Object, Object> entry : props.entrySet()) { - String k = entry.getKey().toString(); - if (k.equals("class")) { - reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, entry.getValue().toString())); - } else if (k.endsWith(".class")) { - reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, entry.getValue().toString())); - resource.produce(new NativeImageResourceBuildItem(p.toString().substring(1))); - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } + @BuildStep + void camelServices( + List<CamelServiceBuildItem> camelServices, + BuildProducer<ReflectiveClassBuildItem> reflectiveClass) { + + camelServices.stream() + .forEach(service -> { + reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, service.type)); + }); + } } diff --git a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/util/PathFilter.java b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/util/PathFilter.java new file mode 100644 index 0000000..4c6772d --- /dev/null +++ b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/util/PathFilter.java @@ -0,0 +1,156 @@ +/* + * 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.core.deployment.util; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; + +import org.apache.camel.util.AntPathMatcher; +import org.apache.camel.util.ObjectHelper; +import org.jboss.jandex.DotName; + +/** + * A utility able to filter resource paths using Ant-like includes and excludes. + */ +public class PathFilter { + private final AntPathMatcher matcher = new AntPathMatcher(); + private final List<String> includePatterns; + private final List<String> excludePatterns; + private final Predicate<String> stringPredicate; + + PathFilter(List<String> includePatterns, List<String> excludePatterns) { + this.includePatterns = includePatterns; + this.excludePatterns = excludePatterns; + + if (ObjectHelper.isEmpty(excludePatterns) && ObjectHelper.isEmpty(includePatterns)) { + this.stringPredicate = path -> true; + } else { + this.stringPredicate = path -> { + path = sanitize(path); + // same logic as org.apache.camel.main.DefaultRoutesCollector so exclude + // take precedence over include + for (String part : excludePatterns) { + if (matcher.match(part, path)) { + return false; + } + } + for (String part : includePatterns) { + if (matcher.match(part, path)) { + return true; + } + } + return ObjectHelper.isEmpty(includePatterns); + }; + } + ; + } + + public Predicate<String> asStringPredicate() { + return stringPredicate; + } + + public Predicate<DotName> asDotNamePredicate() { + if (ObjectHelper.isEmpty(excludePatterns) && ObjectHelper.isEmpty(includePatterns)) { + return dotName -> true; + } else { + return dotName -> stringPredicate.test(dotName.toString().replace('.', '/')); + } + } + + public Predicate<Path> asPathPredicate() { + if (ObjectHelper.isEmpty(excludePatterns) && ObjectHelper.isEmpty(includePatterns)) { + return path -> true; + } else { + return path -> stringPredicate.test(sanitize(path.toString())); + } + } + + static String sanitize(String path) { + path = path.trim(); + return (!path.isEmpty() && path.charAt(0) == '/') + ? path.substring(1) + : path; + } + + public static class Builder { + private List<String> includePatterns = new ArrayList<String>(); + private List<String> excludePatterns = new ArrayList<String>(); + + public Builder patterns(boolean isInclude, Collection<String> patterns) { + if (isInclude) { + include(patterns); + } else { + exclude(patterns); + } + return this; + } + + public Builder include(String pattern) { + includePatterns.add(sanitize(pattern)); + return this; + } + + public Builder include(Collection<String> patterns) { + patterns.stream().map(PathFilter::sanitize).forEach(includePatterns::add); + return this; + } + + public Builder include(Optional<? extends Collection<String>> patterns) { + patterns.ifPresent(ps -> include(ps)); + return this; + } + + public Builder exclude(String pattern) { + excludePatterns.add(sanitize(pattern)); + return this; + } + + public Builder exclude(Collection<String> patterns) { + patterns.stream().map(PathFilter::sanitize).forEach(excludePatterns::add); + return this; + } + + public Builder exclude(Optional<? extends Collection<String>> patterns) { + patterns.ifPresent(ps -> exclude(ps)); + return this; + } + + public Builder combine(Builder other) { + includePatterns.addAll(other.includePatterns); + excludePatterns.addAll(other.excludePatterns); + return this; + } + + /** + * @throws NullPointerException if this method is called more than once for the same {@link Builder} instance. + * @return a new {@link PathFilter} + */ + public PathFilter build() { + final List<String> incl = includePatterns; + includePatterns = null; // avoid leaking the collection trough reuse of the builder + final List<String> excl = excludePatterns; + excludePatterns = null; // avoid leaking the collection trough reuse of the builder + return new PathFilter(incl, excl); + } + + } + +} diff --git a/extensions/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/CamelSupportTest.java b/extensions/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/util/PathFilterTest.java similarity index 55% rename from extensions/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/CamelSupportTest.java rename to extensions/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/util/PathFilterTest.java index a93d05f..2956860 100644 --- a/extensions/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/CamelSupportTest.java +++ b/extensions/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/util/PathFilterTest.java @@ -14,20 +14,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.quarkus.core.deployment; +package org.apache.camel.quarkus.core.deployment.util; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import org.jboss.jandex.DotName; import org.junit.jupiter.api.Test; -import static org.apache.camel.quarkus.core.deployment.CamelSupport.isPathIncluded; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -public class CamelSupportTest { +public class PathFilterTest { @Test - public void testPathFiltering() { + public void stringFilter() { assertFalse(isPathIncluded( "org/acme/MyClass", Arrays.asList("org/**"), @@ -58,4 +62,38 @@ public class CamelSupportTest { Arrays.asList("org/acme/A*"), Arrays.asList("org/acme/MyClass"))); } + + @Test + public void pathFilter() { + Predicate<Path> predicate = new PathFilter.Builder() + .include("/foo/bar/*") + .include("moo/mar/*") + .exclude("/foo/baz/*") + .exclude("moo/maz/*") + .build().asPathPredicate(); + assertTrue(predicate.test(Paths.get("/foo/bar/file"))); + assertTrue(predicate.test(Paths.get("foo/bar/file"))); + assertFalse(predicate.test(Paths.get("/foo/baz/file"))); + assertFalse(predicate.test(Paths.get("foo/baz/file"))); + + assertTrue(predicate.test(Paths.get("/moo/mar/file"))); + assertTrue(predicate.test(Paths.get("moo/mar/file"))); + assertFalse(predicate.test(Paths.get("/moo/marz/file"))); + assertFalse(predicate.test(Paths.get("moo/maz/file"))); + } + + @Test + public void dotNameFilter() { + Predicate<DotName> predicate = new PathFilter.Builder() + .include("foo/bar/*") + .exclude("foo/baz/*") + .build().asDotNamePredicate(); + assertTrue(predicate.test(DotName.createSimple("foo.bar.Class"))); + assertFalse(predicate.test(DotName.createSimple("foo.baz.Class"))); + } + + static boolean isPathIncluded(String path, List<String> excludePatterns, List<String> includePatterns) { + return new PathFilter(includePatterns, excludePatterns).asStringPredicate().test(path); + } + } diff --git a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java index d10f6f5..b564d8f 100644 --- a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java +++ b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java @@ -32,6 +32,12 @@ public class CamelConfig { @ConfigItem public MainConfig main; + /** + * Build time configuration options for Camel services. + */ + @ConfigItem + public ServiceConfig service; + @ConfigGroup public static class MainConfig { /** @@ -87,4 +93,85 @@ public class CamelConfig { @ConfigItem public Optional<List<String>> includePatterns; } + + @ConfigGroup + public static class ServiceConfig { + + /** + * Build time configuration related to discoverability of Camel services via the + * {@code org.apache.camel.spi.FactoryFinder} mechanism + */ + @ConfigItem + public ServiceDiscoveryConfig discovery; + + /** Build time configuration related to registering of Camel services to the Camel registry */ + @ConfigItem + public ServiceRegistryConfig registry; + } + + @ConfigGroup + public static class ServiceDiscoveryConfig { + + /** + * A comma-separated list of Ant-path style patterns to match Camel service definition files in the classpath. + * The services defined in the matching files will <strong>not<strong> be discoverable via the + * {@code org.apache.camel.spi.FactoryFinder} mechanism. + * <p> + * The excludes have higher precedence than includes. The excludes defined here can also be used to veto the + * discoverability of services included by Camel Quarkus extensions. + * <p> + * Example values: + * <code>META-INF/services/org/apache/camel/foo/*,META-INF/services/org/apache/camel/foo/**/bar</code> + */ + @ConfigItem + public Optional<List<String>> excludePatterns; + + /** + * A comma-separated list of Ant-path style patterns to match Camel service definition files in the classpath. + * The services defined in the matching files will be discoverable via the + * {@code org.apache.camel.spi.FactoryFinder} mechanism unless the given file is excluded via + * {@code exclude-patterns}. + * <p> + * Note that Camel Quarkus extensions may include some services by default. The services selected here added + * to those services and the exclusions defined in {@code exclude-patterns} are applied to the union set. + * <p> + * Example values: + * <code>META-INF/services/org/apache/camel/foo/*,META-INF/services/org/apache/camel/foo/**/bar</code> + */ + @ConfigItem + public Optional<List<String>> includePatterns; + } + + @ConfigGroup + public static class ServiceRegistryConfig { + + /** + * A comma-separated list of Ant-path style patterns to match Camel service definition files in the classpath. + * The services defined in the matching files will <strong>not<strong> be added to Camel registry during + * application's static initialization. + * <p> + * The excludes have higher precedence than includes. The excludes defined here can also be used to veto the + * registration of services included by Camel Quarkus extensions. + * <p> + * Example values: + * <code>META-INF/services/org/apache/camel/foo/*,META-INF/services/org/apache/camel/foo/**/bar</code> + */ + @ConfigItem + public Optional<List<String>> excludePatterns; + + /** + * A comma-separated list of Ant-path style patterns to match Camel service definition files in the classpath. + * The services defined in the matching files will be added to Camel registry during application's static + * initialization unless the given file is excluded via {@code exclude-patterns}. + * <p> + * Note that Camel Quarkus extensions may include some services by default. The services selected here added + * to those services and the exclusions defined in {@code exclude-patterns} are applied to the union set. + * <p> + * Example values: + * <code>META-INF/services/org/apache/camel/foo/*,META-INF/services/org/apache/camel/foo/**/bar</code> + */ + @ConfigItem + public Optional<List<String>> includePatterns; + } + } diff --git a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRecorder.java b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRecorder.java index ab2d8c5..5a5824d 100644 --- a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRecorder.java +++ b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelRecorder.java @@ -22,8 +22,10 @@ import io.quarkus.runtime.annotations.Recorder; import org.apache.camel.CamelContext; import org.apache.camel.model.ValidateDefinition; import org.apache.camel.model.validator.PredicateValidatorDefinition; +import org.apache.camel.quarkus.core.FastFactoryFinderResolver.Builder; import org.apache.camel.reifier.ProcessorReifier; import org.apache.camel.reifier.validator.ValidatorReifier; +import org.apache.camel.spi.FactoryFinderResolver; import org.apache.camel.spi.ModelJAXBContextFactory; import org.apache.camel.spi.Registry; import org.apache.camel.spi.TypeConverterLoader; @@ -58,8 +60,9 @@ public class CamelRecorder { RuntimeValue<TypeConverterRegistry> typeConverterRegistry, RuntimeValue<ModelJAXBContextFactory> contextFactory, RuntimeValue<XmlRoutesLoader> xmlLoader, + RuntimeValue<FactoryFinderResolver> factoryFinderResolver, BeanContainer beanContainer) { - FastCamelContext context = new FastCamelContext(); + FastCamelContext context = new FastCamelContext(factoryFinderResolver.getValue()); context.setRegistry(registry.getValue()); context.setTypeConverterRegistry(typeConverterRegistry.getValue()); context.setLoadTypeConverters(false); @@ -121,4 +124,16 @@ public class CamelRecorder { public RuntimeValue<RegistryRoutesLoader> newDefaultRegistryRoutesLoader() { return new RuntimeValue<>(new RegistryRoutesLoaders.Default()); } + + public RuntimeValue<Builder> factoryFinderResolverBuilder() { + return new RuntimeValue<>(new FastFactoryFinderResolver.Builder()); + } + + public void factoryFinderResolverEntry(RuntimeValue<Builder> builder, String resourcePath, Class<?> cl) { + builder.getValue().entry(resourcePath, cl); + } + + public RuntimeValue<FactoryFinderResolver> factoryFinderResolver(RuntimeValue<Builder> builder) { + return new RuntimeValue<>(builder.getValue().build()); + } } diff --git a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java index e864c84..8e8ff03 100644 --- a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java +++ b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastCamelContext.java @@ -42,7 +42,6 @@ import org.apache.camel.impl.engine.DefaultCamelBeanPostProcessor; import org.apache.camel.impl.engine.DefaultCamelContextNameStrategy; import org.apache.camel.impl.engine.DefaultClassResolver; import org.apache.camel.impl.engine.DefaultEndpointRegistry; -import org.apache.camel.impl.engine.DefaultFactoryFinderResolver; import org.apache.camel.impl.engine.DefaultInflightRepository; import org.apache.camel.impl.engine.DefaultInjector; import org.apache.camel.impl.engine.DefaultMessageHistoryFactory; @@ -109,9 +108,9 @@ import org.apache.camel.spi.ValidatorRegistry; public class FastCamelContext extends AbstractCamelContext { private Model model; - public FastCamelContext() { + public FastCamelContext(FactoryFinderResolver factoryFinderResolver) { super(false); - setInitialization(Initialization.Eager); + setFactoryFinderResolver(factoryFinderResolver); setTracing(Boolean.FALSE); setDebugging(Boolean.FALSE); setMessageHistory(Boolean.FALSE); @@ -238,7 +237,8 @@ public class FastCamelContext extends AbstractCamelContext { @Override protected FactoryFinderResolver createFactoryFinderResolver() { - return new DefaultFactoryFinderResolver(); + throw new UnsupportedOperationException( + "FactoryFinderResolver should have been set in the FastCamelContext constructor"); } @Override diff --git a/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastFactoryFinderResolver.java b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastFactoryFinderResolver.java new file mode 100644 index 0000000..0c8f7db --- /dev/null +++ b/extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastFactoryFinderResolver.java @@ -0,0 +1,147 @@ +/* + * 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.core; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import org.apache.camel.impl.engine.DefaultFactoryFinderResolver; +import org.apache.camel.spi.ClassResolver; +import org.apache.camel.spi.FactoryFinder; +import org.apache.camel.spi.FactoryFinderResolver; +import org.apache.camel.support.ObjectHelper; +import org.jboss.logging.Logger; + +/** + * A build time assembled {@link FactoryFinderResolver}. + */ +public class FastFactoryFinderResolver extends DefaultFactoryFinderResolver { + private static final Logger LOG = Logger.getLogger(FastFactoryFinderResolver.class); + private final Map<String, Class<?>> classMap; + + FastFactoryFinderResolver(Map<String, Class<?>> classMap) { + this.classMap = classMap; + } + + @Override + public FactoryFinder resolveFactoryFinder(ClassResolver classResolver, String resourcePath) { + return new FastFactoryFinder(resourcePath); + } + + static String mapKey(String resourcePath, String prefix, String key) { + final int len = resourcePath.length() + (prefix == null ? 0 : prefix.length()) + key.length() + 1; + final StringBuilder sb = new StringBuilder(len); + if (resourcePath.startsWith("/")) { + sb.append(resourcePath, 1, resourcePath.length()); + } else { + sb.append(resourcePath); + } + if (!resourcePath.endsWith("/")) { + sb.append("/"); + } + if (prefix != null) { + sb.append(prefix); + } + sb.append(key); + return sb.toString(); + } + + public static class Builder { + private Map<String, Class<?>> classMap = new HashMap<>(); + + public Builder entry(String resourcePath, Class<?> cl) { + if (resourcePath.startsWith("/")) { + resourcePath = resourcePath.substring(1); + } + classMap.put(resourcePath, cl); + return this; + } + + public FastFactoryFinderResolver build() { + Map<String, Class<?>> cm = classMap; + classMap = null; // make sure the classMap does not leak through re-using the builder + + if (LOG.isDebugEnabled()) { + cm.entrySet().forEach( + e -> LOG.debugf("FactoryFinder entry " + e.getKey() + ": " + e.getValue().getName())); + } + + return new FastFactoryFinderResolver(cm); + } + } + + public class FastFactoryFinder implements FactoryFinder { + + private final String path; + + FastFactoryFinder(String resourcePath) { + this.path = resourcePath; + } + + @Override + public String getResourcePath() { + return path; + } + + @Override + public Optional<Object> newInstance(String key) { + return Optional.ofNullable(doNewInstance(key, null)); + } + + @Override + public <T> Optional<T> newInstance(String key, Class<T> type) { + Object obj = doNewInstance(key, null); + return Optional.ofNullable(type.cast(obj)); + } + + @Override + public Optional<Class<?>> findClass(String key) { + return findClass(key, null); + } + + @Override + public Optional<Class<?>> findClass(String key, String propertyPrefix) { + final String mapKey = mapKey(path, propertyPrefix, key); + final Class<?> cl = classMap.get(mapKey); + if (cl == null) { + LOG.warnf("Could not find a non-optional class for key %s", mapKey); + } + return Optional.ofNullable(cl); + } + + @Override + public Optional<Class<?>> findClass(String key, String propertyPrefix, Class<?> clazz) { + // Just ignore clazz which is only useful for OSGiFactoryFinder + return findClass(key, propertyPrefix); + } + + @Override + public Optional<Class<?>> findOptionalClass(String key, String propertyPrefix) { + final String mapKey = mapKey(path, propertyPrefix, key); + LOG.tracef("Found an optional class for key %s: %s", mapKey); + return Optional.ofNullable(classMap.get(mapKey)); + } + + private Object doNewInstance(String key, String propertyPrefix) { + Optional<Class<?>> clazz = findClass(key, propertyPrefix); + return clazz.map(ObjectHelper::newInstance).orElse(null); + } + + } + +} diff --git a/extensions/file/deployment/src/main/java/org/apache/camel/quarkus/component/file/deployment/FileProcessor.java b/extensions/file/deployment/src/main/java/org/apache/camel/quarkus/component/file/deployment/FileProcessor.java index 8a38547..3739d70 100644 --- a/extensions/file/deployment/src/main/java/org/apache/camel/quarkus/component/file/deployment/FileProcessor.java +++ b/extensions/file/deployment/src/main/java/org/apache/camel/quarkus/component/file/deployment/FileProcessor.java @@ -20,6 +20,7 @@ import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.FeatureBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import org.apache.camel.component.file.GenericFile; +import org.apache.camel.component.file.strategy.GenericFileProcessStrategyFactory; class FileProcessor { @@ -32,6 +33,8 @@ class FileProcessor { @BuildStep ReflectiveClassBuildItem registerForReflection() { - return new ReflectiveClassBuildItem(true, false, GenericFile.class); + return new ReflectiveClassBuildItem(true, false, + GenericFile.class, + GenericFileProcessStrategyFactory.class); } } diff --git a/extensions/hystrix/deployment/src/main/java/org/apache/camel/quarkus/component/hystrix/deployment/HystrixProcessor.java b/extensions/hystrix/deployment/src/main/java/org/apache/camel/quarkus/component/hystrix/deployment/HystrixProcessor.java index e0ecd6d..acd7554 100644 --- a/extensions/hystrix/deployment/src/main/java/org/apache/camel/quarkus/component/hystrix/deployment/HystrixProcessor.java +++ b/extensions/hystrix/deployment/src/main/java/org/apache/camel/quarkus/component/hystrix/deployment/HystrixProcessor.java @@ -19,7 +19,6 @@ package org.apache.camel.quarkus.component.hystrix.deployment; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.FeatureBuildItem; -import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageSystemPropertyBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import org.apache.camel.model.CircuitBreakerDefinition; @@ -38,7 +37,6 @@ class HystrixProcessor { @BuildStep void registerForReflection(BuildProducer<ReflectiveClassBuildItem> reflectiveClass, - BuildProducer<NativeImageResourceBuildItem> resource, BuildProducer<NativeImageSystemPropertyBuildItem> systemProperty) { reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, @@ -47,8 +45,6 @@ class HystrixProcessor { CircuitBreakerDefinition.class, OnFallbackDefinition.class)); - resource.produce(new NativeImageResourceBuildItem("META-INF/services/org/apache/camel/model/CircuitBreakerDefinition")); - // Force RxJava to not use Unsafe API systemProperty.produce(new NativeImageSystemPropertyBuildItem("rx.unsafe-disable", "true")); } diff --git a/integration-tests/dozer/src/main/resources/application.properties b/integration-tests/dozer/src/main/resources/application.properties index f0917e9..9540e06 100644 --- a/integration-tests/dozer/src/main/resources/application.properties +++ b/integration-tests/dozer/src/main/resources/application.properties @@ -15,6 +15,8 @@ ## limitations under the License. ## --------------------------------------------------------------------------- +#quarkus.log.category."org.apache.camel.quarkus.core.FastFactoryFinderResolver".level = TRACE + # # Quarkus - Camel Dozer #