You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2020/01/20 21:06:07 UTC

[camel-quarkus] branch master updated (1c428cb -> a2e1dc2)

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

lburgazzoli pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git.


    from 1c428cb  Merge pull request #639 from apache/camel-3.0.1
     new e728940  Revert "Fix #620 Introduce CamelServiceInfo transformers"
     new 06f9625  Avoid using field injection in the core NativeImageProcessor
     new 30908ac  Fix #617 Registerable and discoverable Camel services
     new a2e1dc2  Do not register languages and dataformats so that they can be used in parallel with conflicting configs

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../quarkus/core/deployment/BuildProcessor.java    | 123 +++++++++++++---
 ...va => CamelFactoryFinderResolverBuildItem.java} |  16 +--
 ...ServiceInfo.java => CamelServiceBuildItem.java} |  66 ++++-----
 .../core/deployment/CamelServiceFilter.java        |   2 +-
 .../CamelServiceInfoTransformerBuildItem.java      |  42 ------
 .../deployment/CamelServiceInfoTransformers.java   |  43 ------
 .../deployment/CamelServicePatternBuildItem.java   |  84 +++++++++++
 .../quarkus/core/deployment/CamelSupport.java      |  64 ++-------
 .../core/deployment/NativeImageProcessor.java      |  82 ++++-------
 .../quarkus/core/deployment/util/PathFilter.java   | 156 +++++++++++++++++++++
 .../CamelServiceInfoTransformersTest.java          |  46 ------
 .../PathFilterTest.java}                           |  46 +++++-
 .../org/apache/camel/quarkus/core/CamelConfig.java |  87 ++++++++++++
 .../apache/camel/quarkus/core/CamelRecorder.java   |  17 ++-
 .../camel/quarkus/core/FastCamelContext.java       |  41 ++----
 .../quarkus/core/FastFactoryFinderResolver.java    | 147 +++++++++++++++++++
 .../component/file/deployment/FileProcessor.java   |   5 +-
 .../hystrix/deployment/HystrixProcessor.java       |   4 -
 .../src/main/resources/application.properties      |   2 +
 19 files changed, 731 insertions(+), 342 deletions(-)
 copy extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/{CamelTypeConverterRegistryBuildItem.java => CamelFactoryFinderResolverBuildItem.java} (62%)
 rename extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/{CamelServiceInfo.java => CamelServiceBuildItem.java} (54%)
 delete mode 100644 extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfoTransformerBuildItem.java
 delete mode 100644 extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfoTransformers.java
 create mode 100644 extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServicePatternBuildItem.java
 create mode 100644 extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/util/PathFilter.java
 delete mode 100644 extensions/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfoTransformersTest.java
 rename extensions/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/{CamelSupportTest.java => util/PathFilterTest.java} (55%)
 create mode 100644 extensions/core/runtime/src/main/java/org/apache/camel/quarkus/core/FastFactoryFinderResolver.java


[camel-quarkus] 03/04: Fix #617 Registerable and discoverable Camel services

Posted by lb...@apache.org.
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 <pp...@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/&#42;,META-INF/services/org/apache/camel/foo/&#42;&#42;/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/&#42;,META-INF/services/org/apache/camel/foo/&#42;&#42;/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/&#42;,META-INF/services/org/apache/camel/foo/&#42;&#42;/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/&#42;,META-INF/services/org/apache/camel/foo/&#42;&#42;/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
 #


[camel-quarkus] 04/04: Do not register languages and dataformats so that they can be used in parallel with conflicting configs

Posted by lb...@apache.org.
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 a2e1dc2984c484b817299e8cef0ac27ddd2511d2
Author: Peter Palaga <pp...@redhat.com>
AuthorDate: Fri Jan 17 17:47:26 2020 +0100

    Do not register languages and dataformats so that they can be used in parallel with conflicting configs
---
 .../quarkus/core/deployment/BuildProcessor.java    |  8 +++---
 .../camel/quarkus/core/FastCamelContext.java       | 33 +++-------------------
 2 files changed, 8 insertions(+), 33 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 63c6e8d..e4c2c46 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
@@ -133,9 +133,7 @@ class BuildProcessor {
             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/*"));
+                    "META-INF/services/org/apache/camel/component/*"));
 
             services.produce(new CamelServicePatternBuildItem(
                     CamelServiceDestination.DISCOVERY,
@@ -143,7 +141,9 @@ class BuildProcessor {
                     "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/*"));
+                    "META-INF/services/org/apache/camel/configurer/*",
+                    "META-INF/services/org/apache/camel/language/*",
+                    "META-INF/services/org/apache/camel/dataformat/*"));
         }
 
         @BuildStep
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 8e8ff03..1eb3d3d 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
@@ -21,10 +21,8 @@ import java.util.Map;
 import java.util.concurrent.ExecutorService;
 
 import org.apache.camel.AsyncProcessor;
-import org.apache.camel.CamelContext;
 import org.apache.camel.Component;
 import org.apache.camel.Endpoint;
-import org.apache.camel.NoSuchLanguageException;
 import org.apache.camel.PollingConsumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
@@ -41,9 +39,11 @@ import org.apache.camel.impl.engine.DefaultBeanIntrospection;
 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.DefaultDataFormatResolver;
 import org.apache.camel.impl.engine.DefaultEndpointRegistry;
 import org.apache.camel.impl.engine.DefaultInflightRepository;
 import org.apache.camel.impl.engine.DefaultInjector;
+import org.apache.camel.impl.engine.DefaultLanguageResolver;
 import org.apache.camel.impl.engine.DefaultMessageHistoryFactory;
 import org.apache.camel.impl.engine.DefaultNodeIdFactory;
 import org.apache.camel.impl.engine.DefaultPackageScanClassResolver;
@@ -74,7 +74,6 @@ import org.apache.camel.spi.CamelBeanPostProcessor;
 import org.apache.camel.spi.CamelContextNameStrategy;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.ComponentResolver;
-import org.apache.camel.spi.DataFormat;
 import org.apache.camel.spi.DataFormatResolver;
 import org.apache.camel.spi.EndpointRegistry;
 import org.apache.camel.spi.ExecutorServiceManager;
@@ -82,7 +81,6 @@ import org.apache.camel.spi.FactoryFinderResolver;
 import org.apache.camel.spi.HeadersMapFactory;
 import org.apache.camel.spi.InflightRepository;
 import org.apache.camel.spi.Injector;
-import org.apache.camel.spi.Language;
 import org.apache.camel.spi.LanguageResolver;
 import org.apache.camel.spi.ManagementNameStrategy;
 import org.apache.camel.spi.MessageHistoryFactory;
@@ -174,35 +172,12 @@ public class FastCamelContext extends AbstractCamelContext {
 
     @Override
     protected LanguageResolver createLanguageResolver() {
-        // languages are automatically discovered by build steps so we can reduce the
-        // operations done by the standard resolver by looking them up directly from the
-        // registry
-        return (name, context) -> {
-            Language answer = context.getRegistry().lookupByNameAndType(name, Language.class);
-            if (answer == null) {
-                throw new NoSuchLanguageException(name);
-            }
-
-            return answer;
-        };
+        return new DefaultLanguageResolver();
     }
 
     @Override
     protected DataFormatResolver createDataFormatResolver() {
-        return new DataFormatResolver() {
-            @Override
-            public DataFormat resolveDataFormat(String name, CamelContext context) {
-                return createDataFormat(name, context);
-            }
-
-            @Override
-            public DataFormat createDataFormat(String name, CamelContext context) {
-                // data formats are automatically discovered by build steps so we can reduce the
-                // operations done by the standard resolver by looking them up directly from the
-                // registry
-                return context.getRegistry().lookupByNameAndType(name, DataFormat.class);
-            }
-        };
+        return new DefaultDataFormatResolver();
     }
 
     @Override


[camel-quarkus] 02/04: Avoid using field injection in the core NativeImageProcessor

Posted by lb...@apache.org.
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 06f9625b84353fb0879daa145cf0970b022da7e8
Author: Peter Palaga <pp...@redhat.com>
AuthorDate: Wed Jan 15 17:28:16 2020 +0100

    Avoid using field injection in the core NativeImageProcessor
---
 .../core/deployment/NativeImageProcessor.java      | 65 +++++++++-------------
 1 file changed, 27 insertions(+), 38 deletions(-)

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 ede3d3f..9c9f346 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
@@ -26,8 +26,6 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.stream.Collectors;
 
-import javax.inject.Inject;
-
 import io.quarkus.deployment.annotations.BuildProducer;
 import io.quarkus.deployment.annotations.BuildStep;
 import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem;
@@ -52,7 +50,6 @@ import org.jboss.jandex.AnnotationValue;
 import org.jboss.jandex.ClassInfo;
 import org.jboss.jandex.DotName;
 import org.jboss.jandex.IndexView;
-import org.jboss.jandex.MethodInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -74,18 +71,13 @@ class NativeImageProcessor {
                 StreamCachingStrategy.SpoolUsedHeapMemoryLimit.class,
                 PropertiesComponent.class);
 
-        @Inject
-        BuildProducer<ReflectiveClassBuildItem> reflectiveClass;
-        @Inject
-        BuildProducer<ReflectiveMethodBuildItem> reflectiveMethod;
-        @Inject
-        BuildProducer<NativeImageResourceBuildItem> resource;
-        @Inject
-        ApplicationArchivesBuildItem applicationArchivesBuildItem;
-
         @BuildStep
-        void process(CombinedIndexBuildItem combinedIndex) {
-            IndexView view = combinedIndex.getIndex();
+        void reflectiveItems(
+                CombinedIndexBuildItem combinedIndex,
+                BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
+                BuildProducer<ReflectiveMethodBuildItem> reflectiveMethod) {
+
+            final IndexView view = combinedIndex.getIndex();
 
             CAMEL_REFLECTIVE_CLASSES.stream()
                     .map(Class::getName)
@@ -93,7 +85,7 @@ class NativeImageProcessor {
                     .map(view::getAllKnownImplementors)
                     .flatMap(Collection::stream)
                     .filter(CamelSupport::isPublic)
-                    .forEach(v -> addReflectiveClass(true, v.name().toString()));
+                    .forEach(v -> reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, v.name().toString())));
 
             Logger log = LoggerFactory.getLogger(NativeImageProcessor.class);
             DotName converter = DotName.createSimple(Converter.class.getName());
@@ -120,32 +112,44 @@ class NativeImageProcessor {
                     .collect(Collectors.toList());
 
             log.debug("Converter classes: " + converterClasses);
-            converterClasses.forEach(ci -> addReflectiveClass(false, ci.name().toString()));
+            converterClasses
+                    .forEach(ci -> reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, ci.name().toString())));
 
             view.getAnnotations(converter)
                     .stream()
                     .filter(ai -> ai.target().kind() == Kind.METHOD)
                     .filter(ai -> converterClasses.contains(ai.target().asMethod().declaringClass()))
                     .map(ai -> ai.target().asMethod())
-                    .forEach(this::addReflectiveMethod);
+                    .forEach(mi -> reflectiveMethod.produce(new ReflectiveMethodBuildItem(mi)));
+
+        }
+
+        @BuildStep
+        void resourcesAndServices(
+                ApplicationArchivesBuildItem applicationArchivesBuildItem,
+                BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
+                BuildProducer<NativeImageResourceBuildItem> resource) {
 
             CamelSupport.resources(applicationArchivesBuildItem, "META-INF/maven/org.apache.camel/camel-base")
-                    .forEach(this::addResource);
+                    .forEach(p -> resource.produce(new NativeImageResourceBuildItem(p.toString().substring(1))));
             CamelSupport.resources(applicationArchivesBuildItem, CamelSupport.CAMEL_SERVICE_BASE_PATH)
-                    .forEach(this::addCamelService);
+                    .forEach(path -> addCamelService(path, reflectiveClass, resource));
         }
 
-        protected void addCamelService(Path p) {
+        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")) {
-                        addReflectiveClass(true, entry.getValue().toString());
+                        reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, entry.getValue().toString()));
                     } else if (k.endsWith(".class")) {
-                        addReflectiveClass(true, entry.getValue().toString());
-                        addResource(p);
+                        reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, entry.getValue().toString()));
+                        resource.produce(new NativeImageResourceBuildItem(p.toString().substring(1)));
                     }
                 }
             } catch (Exception e) {
@@ -153,21 +157,6 @@ class NativeImageProcessor {
             }
         }
 
-        protected void addResource(Path p) {
-            addResource(p.toString().substring(1));
-        }
-
-        protected void addResource(String r) {
-            resource.produce(new NativeImageResourceBuildItem(r));
-        }
-
-        protected void addReflectiveClass(boolean methods, String... className) {
-            reflectiveClass.produce(new ReflectiveClassBuildItem(methods, false, className));
-        }
-
-        protected void addReflectiveMethod(MethodInfo mi) {
-            reflectiveMethod.produce(new ReflectiveMethodBuildItem(mi));
-        }
     }
 
     /*


[camel-quarkus] 01/04: Revert "Fix #620 Introduce CamelServiceInfo transformers"

Posted by lb...@apache.org.
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 e728940db17a0d5947d8c7fd374322f8804841c7
Author: Peter Palaga <pp...@redhat.com>
AuthorDate: Thu Jan 16 18:04:30 2020 +0100

    Revert "Fix #620 Introduce CamelServiceInfo transformers"
    
    This reverts commit e6920d014fec0ea4ec52ab527fdd0d1ac05ad7ee.
    
    We decided to adopt another approach
---
 .../quarkus/core/deployment/BuildProcessor.java    | 16 +-------
 .../quarkus/core/deployment/CamelServiceInfo.java  | 14 ++-----
 .../CamelServiceInfoTransformerBuildItem.java      | 42 --------------------
 .../deployment/CamelServiceInfoTransformers.java   | 43 --------------------
 .../CamelServiceInfoTransformersTest.java          | 46 ----------------------
 5 files changed, 4 insertions(+), 157 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 4d0d192..594ec28 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
@@ -25,7 +25,6 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
@@ -126,12 +125,6 @@ class BuildProcessor {
                     new CamelServiceFilterBuildItem(CamelServiceFilter.forService("properties-component-factory")));
         }
 
-        @BuildStep
-        void serviceInfoTransformers(BuildProducer<CamelServiceInfoTransformerBuildItem> mapperBuildItems) {
-            mapperBuildItems.produce(
-                    new CamelServiceInfoTransformerBuildItem(CamelServiceInfoTransformers::configurer));
-        }
-
         /*
          * Discover {@link TypeConverterLoader}.
          */
@@ -192,8 +185,7 @@ class BuildProcessor {
                 ApplicationArchivesBuildItem applicationArchives,
                 ContainerBeansBuildItem containerBeans,
                 List<CamelBeanBuildItem> registryItems,
-                List<CamelServiceFilterBuildItem> serviceFilters,
-                List<CamelServiceInfoTransformerBuildItem> serviceMappers) {
+                List<CamelServiceFilterBuildItem> serviceFilters) {
 
             final RuntimeValue<org.apache.camel.spi.Registry> registry = recorder.createRegistry();
 
@@ -213,12 +205,6 @@ class BuildProcessor {
 
                         return !blacklisted;
                     })
-                    .map(
-                            /* apply the CamelServiceInfo transformers */
-                            serviceMappers.stream()
-                                    .map(CamelServiceInfoTransformerBuildItem::getTransformer)
-                                    .reduce(Function::andThen)
-                                    .orElse(Function.identity()))
                     .forEach(si -> {
                         LOGGER.debug("Binding bean with name: {}, type {}", si.name, si.type);
 
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/CamelServiceInfo.java
index 2b6a2cf..8c46e13 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/CamelServiceInfo.java
@@ -30,8 +30,9 @@ public class CamelServiceInfo implements CamelBeanInfo {
     public final Path path;
 
     /**
-     * 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}.
+     * 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;
 
@@ -60,15 +61,6 @@ public class CamelServiceInfo implements CamelBeanInfo {
         return this.type;
     }
 
-    /**
-     * @param  newName the overriding name
-     * @return         a new {@link CamelServiceInfo} having all fields the same as the current {@link CamelServiceInfo}
-     *                 except for {@link #name} which is set to the given {@code newName}
-     */
-    public CamelServiceInfo withName(String newName) {
-        return new CamelServiceInfo(path, newName, type);
-    }
-
     @Override
     public boolean equals(Object o) {
         if (this == o) {
diff --git a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfoTransformerBuildItem.java b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfoTransformerBuildItem.java
deleted file mode 100644
index 4da677a..0000000
--- a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfoTransformerBuildItem.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.function.Function;
-
-import io.quarkus.builder.item.MultiBuildItem;
-
-/**
- * A {@link MultiBuildItem} holding a transformer function to be used to transform {@link CamelServiceInfo}s discovered
- * in the classpath. This can be used e.g. for changing the name under which some particular service will be registered
- * in the Camel registry.
- */
-public final class CamelServiceInfoTransformerBuildItem extends MultiBuildItem {
-    private final Function<CamelServiceInfo, CamelServiceInfo> transformer;
-
-    public CamelServiceInfoTransformerBuildItem(Function<CamelServiceInfo, CamelServiceInfo> mapper) {
-        this.transformer = mapper;
-    }
-
-    /**
-     * @return the transformer function
-     */
-    public Function<CamelServiceInfo, CamelServiceInfo> getTransformer() {
-        return transformer;
-    }
-
-}
diff --git a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfoTransformers.java b/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfoTransformers.java
deleted file mode 100644
index 5d2db73..0000000
--- a/extensions/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfoTransformers.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.nio.file.Path;
-import java.nio.file.Paths;
-
-public final class CamelServiceInfoTransformers {
-
-    private static final Path CONFIGURER_PATH = Paths.get("configurer");
-
-    private CamelServiceInfoTransformers() {
-    }
-
-    /**
-     * Configurers need to get registered under a different name in the registry than the name of
-     * the service file
-     *
-     * @param  serviceInfo the {@link CamelServiceInfo} that will possibly be transformed
-     * @return             the given {@code serviceInfo} or a new {@link CamelServiceInfo}
-     */
-    public static CamelServiceInfo configurer(CamelServiceInfo serviceInfo) {
-        final Path path = serviceInfo.path;
-        final int pathLen = path.getNameCount();
-        return (pathLen >= 2 && CONFIGURER_PATH.equals(path.getName(pathLen - 2)))
-                ? serviceInfo.withName(path.getFileName().toString() + "-configurer")
-                : serviceInfo;
-    }
-}
diff --git a/extensions/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfoTransformersTest.java b/extensions/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfoTransformersTest.java
deleted file mode 100644
index cdef8db..0000000
--- a/extensions/core/deployment/src/test/java/org/apache/camel/quarkus/core/deployment/CamelServiceInfoTransformersTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.nio.file.Paths;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-public class CamelServiceInfoTransformersTest {
-
-    @Test
-    void configurer() {
-        {
-            final CamelServiceInfo info = new CamelServiceInfo(Paths.get(""), "foo", "org.foo.Foo");
-            Assertions.assertEquals(info, CamelServiceInfoTransformers.configurer(info));
-        }
-        {
-            final CamelServiceInfo info = new CamelServiceInfo(Paths.get("foo"), "foo", "org.foo.Foo");
-            Assertions.assertEquals(info, CamelServiceInfoTransformers.configurer(info));
-        }
-        {
-            final CamelServiceInfo info = new CamelServiceInfo(Paths.get("foo/bar/baz"), "foo", "org.foo.Foo");
-            Assertions.assertEquals(info, CamelServiceInfoTransformers.configurer(info));
-        }
-        {
-            final CamelServiceInfo info = new CamelServiceInfo(Paths.get("foo/configurer/baz"), "foo", "org.foo.Foo");
-            Assertions.assertEquals(new CamelServiceInfo(Paths.get("foo/configurer/baz"), "baz-configurer", "org.foo.Foo"),
-                    CamelServiceInfoTransformers.configurer(info));
-        }
-    }
-}