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 2021/02/03 13:57:46 UTC

[camel] branch master updated: CAMEL-16136: replace BaseServiceResolver with a static helper method

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


The following commit(s) were added to refs/heads/master by this push:
     new 04ba30c  CAMEL-16136: replace BaseServiceResolver with a static helper method
04ba30c is described below

commit 04ba30cc74304d7ff219051faa1fac4f13c49adc
Author: Luca Burgazzoli <lb...@gmail.com>
AuthorDate: Wed Feb 3 12:57:16 2021 +0100

    CAMEL-16136: replace BaseServiceResolver with a static helper method
---
 .../apache/camel/openapi/RestOpenApiSupport.java   | 365 +++++++++++----------
 .../services/org/apache/camel/routes-loader        |   2 -
 .../impl/engine/BaseExecutorServiceManager.java    |  16 +-
 .../camel/impl/engine/BaseServiceResolver.java     |  67 ----
 .../camel/impl/engine/DefaultRoutesLoader.java     |  16 +-
 .../camel/impl/engine/SimpleCamelContext.java      | 178 +++++-----
 .../org/apache/camel/support/ResolverHelper.java   |  86 ++++-
 7 files changed, 383 insertions(+), 347 deletions(-)

diff --git a/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiSupport.java b/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiSupport.java
index ed779ce..97ed492 100644
--- a/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiSupport.java
+++ b/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiSupport.java
@@ -44,11 +44,11 @@ import io.apicurio.datamodels.openapi.v3.models.Oas30Server;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.ExtendedCamelContext;
-import org.apache.camel.impl.engine.BaseServiceResolver;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.RestConfiguration;
 import org.apache.camel.support.PatternHelper;
+import org.apache.camel.support.ResolverHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.URISupport;
 import org.slf4j.Logger;
@@ -74,6 +74,181 @@ public class RestOpenApiSupport {
     private volatile RestDefinitionsResolver jmxRestDefinitionResolver;
     private boolean cors;
 
+    private static void setupCorsHeaders(RestApiResponseAdapter response, Map<String, String> corsHeaders) {
+        // use default value if none has been configured
+        String allowOrigin = corsHeaders != null ? corsHeaders.get("Access-Control-Allow-Origin") : null;
+        if (allowOrigin == null) {
+            allowOrigin = RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_ORIGIN;
+        }
+        String allowMethods = corsHeaders != null ? corsHeaders.get("Access-Control-Allow-Methods") : null;
+        if (allowMethods == null) {
+            allowMethods = RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_METHODS;
+        }
+        String allowHeaders = corsHeaders != null ? corsHeaders.get("Access-Control-Allow-Headers") : null;
+        if (allowHeaders == null) {
+            allowHeaders = RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_HEADERS;
+        }
+        String maxAge = corsHeaders != null ? corsHeaders.get("Access-Control-Max-Age") : null;
+        if (maxAge == null) {
+            maxAge = RestConfiguration.CORS_ACCESS_CONTROL_MAX_AGE;
+        }
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Using CORS headers[");
+            LOG.trace("  Access-Control-Allow-Origin={}", allowOrigin);
+            LOG.trace("  Access-Control-Allow-Methods={}", allowMethods);
+            LOG.trace("  Access-Control-Allow-Headers={}", allowHeaders);
+            LOG.trace("  Access-Control-Max-Age={}", maxAge);
+            LOG.trace("]");
+        }
+        response.setHeader("Access-Control-Allow-Origin", allowOrigin);
+        response.setHeader("Access-Control-Allow-Methods", allowMethods);
+        response.setHeader("Access-Control-Allow-Headers", allowHeaders);
+        response.setHeader("Access-Control-Max-Age", maxAge);
+    }
+
+    static void setupXForwardedHeaders(OasDocument openApi, Map<String, Object> headers) {
+
+        String basePath = getBasePathFromOasDocument(openApi);
+
+        if (openApi instanceof Oas20Document) {
+            String host = (String) headers.get(HEADER_HOST);
+            if (ObjectHelper.isNotEmpty(host)) {
+                ((Oas20Document) openApi).host = host;
+            }
+
+            String forwardedPrefix = (String) headers.get(HEADER_X_FORWARDED_PREFIX);
+            if (ObjectHelper.isNotEmpty(forwardedPrefix)) {
+                ((Oas20Document) openApi).basePath = URISupport.joinPaths(forwardedPrefix, basePath);
+            }
+
+            String forwardedHost = (String) headers.get(HEADER_X_FORWARDED_HOST);
+            if (ObjectHelper.isNotEmpty(forwardedHost)) {
+                ((Oas20Document) openApi).host = forwardedHost;
+            }
+
+            String proto = (String) headers.get(HEADER_X_FORWARDED_PROTO);
+            if (ObjectHelper.isNotEmpty(proto)) {
+                String[] schemes = proto.split(",");
+                for (String scheme : schemes) {
+                    String trimmedScheme = scheme.trim();
+                    if (ObjectHelper.isNotEmpty(trimmedScheme)) {
+                        if (((Oas20Document) openApi).schemes == null) {
+                            ((Oas20Document) openApi).schemes = new ArrayList();
+                        }
+                        ((Oas20Document) openApi).schemes.add(trimmedScheme.toLowerCase());
+                    }
+                }
+            }
+        } else if (openApi instanceof Oas30Document) {
+
+            String host = (String) headers.get(HEADER_HOST);
+
+            String forwardedPrefix = (String) headers.get(HEADER_X_FORWARDED_PREFIX);
+
+            if (ObjectHelper.isNotEmpty(forwardedPrefix)) {
+                basePath = URISupport.joinPaths(forwardedPrefix, basePath);
+            }
+
+            String forwardedHost = (String) headers.get(HEADER_X_FORWARDED_HOST);
+            if (ObjectHelper.isNotEmpty(forwardedHost)) {
+                host = forwardedHost;
+            }
+
+            String proto = (String) headers.get(HEADER_X_FORWARDED_PROTO);
+            if (((Oas30Document) openApi).getServers() != null) {
+                ((Oas30Document) openApi).getServers().clear();
+            }
+            if (ObjectHelper.isNotEmpty(proto)) {
+                String[] schemes = proto.split(",");
+                for (String schema : schemes) {
+                    String trimmedScheme = schema.trim();
+                    String serverUrl = new StringBuilder().append(trimmedScheme.toLowerCase()).append("://").append(host)
+                            .append(basePath).toString();
+                    ((Oas30Document) openApi).addServer(serverUrl, null);
+
+                }
+            } else {
+                ((Oas30Document) openApi).addServer(basePath, null);
+            }
+
+        }
+    }
+
+    public static String getHostFromOasDocument(final OasDocument openapi) {
+        String host = null;
+        if (openapi instanceof Oas20Document) {
+            host = ((Oas20Document) openapi).host;
+        } else if (openapi instanceof Oas30Document) {
+            if (((Oas30Document) openapi).getServers() != null
+                    && ((Oas30Document) openapi).getServers().get(0) != null) {
+                try {
+                    URL serverUrl = new URL(
+                            parseVariables(((Oas30Document) openapi).getServers().get(0).url,
+                                    (Oas30Server) ((Oas30Document) openapi).getServers().get(0)));
+                    host = serverUrl.getHost();
+
+                } catch (MalformedURLException e) {
+                    LOG.info("error when parsing OpenApi 3.0 doc server url", e);
+                }
+            }
+        }
+        return host;
+
+    }
+
+    public static String getBasePathFromOasDocument(final OasDocument openapi) {
+        String basePath = null;
+        if (openapi instanceof Oas20Document) {
+            basePath = ((Oas20Document) openapi).basePath;
+        } else if (openapi instanceof Oas30Document) {
+            if (((Oas30Document) openapi).getServers() != null
+                    && ((Oas30Document) openapi).getServers().get(0) != null) {
+                try {
+                    Oas30Server server = (Oas30Server) ((Oas30Document) openapi).getServers().get(0);
+                    if (server.variables != null && server.variables.get("basePath") != null) {
+                        basePath = server.variables.get("basePath").default_;
+                    }
+                    if (basePath == null) {
+                        // parse server url as fallback
+                        URL serverUrl = new URL(
+                                parseVariables(((Oas30Document) openapi).getServers().get(0).url,
+                                        (Oas30Server) ((Oas30Document) openapi).getServers().get(0)));
+                        basePath = serverUrl.getPath();
+                        if (basePath.indexOf("//") == 0) {
+                            // strip off the first "/" if double "/" exists
+                            basePath = basePath.substring(1);
+                        }
+                        if ("/".equals(basePath)) {
+                            basePath = "";
+                        }
+                    }
+
+                } catch (MalformedURLException e) {
+                    //not a valid whole url, just the basePath
+                    basePath = ((Oas30Document) openapi).getServers().get(0).url;
+                }
+            }
+
+        }
+        return basePath;
+
+    }
+
+    public static String parseVariables(String url, Oas30Server server) {
+        Pattern p = Pattern.compile("\\{(.*?)\\}");
+        Matcher m = p.matcher(url);
+        while (m.find()) {
+
+            String var = m.group(1);
+            if (server != null && server.variables != null && server.variables.get(var) != null) {
+                String varValue = server.variables.get(var).default_;
+                url = url.replace("{" + var + "}", varValue);
+            }
+        }
+        return url;
+    }
+
     public void initOpenApi(BeanConfig openApiConfig, Map<String, Object> config) {
         // configure openApi options
         String s = (String) config.get("openapi.version");
@@ -194,12 +369,13 @@ public class RestOpenApiSupport {
     }
 
     protected RestDefinitionsResolver createJmxRestDefinitionsResolver(CamelContext camelContext) {
-        return new BaseServiceResolver<>(
-                JMX_REST_DEFINITION_RESOLVER, RestDefinitionsResolver.class,
-                camelContext.adapt(ExtendedCamelContext.class).getBootstrapFactoryFinder())
-                        .resolve(camelContext)
-                        .orElseThrow(
-                                () -> new IllegalArgumentException("Cannot find camel-openapi-java on classpath."));
+        return ResolverHelper.resolveService(
+                camelContext,
+                camelContext.adapt(ExtendedCamelContext.class).getBootstrapFactoryFinder(),
+                JMX_REST_DEFINITION_RESOLVER,
+                RestDefinitionsResolver.class)
+                .orElseThrow(
+                        () -> new IllegalArgumentException("Cannot find camel-openapi-java on classpath."));
     }
 
     public void renderResourceListing(
@@ -348,179 +524,4 @@ public class RestOpenApiSupport {
         }
         return jmxRestDefinitionResolver.findCamelContexts();
     }
-
-    private static void setupCorsHeaders(RestApiResponseAdapter response, Map<String, String> corsHeaders) {
-        // use default value if none has been configured
-        String allowOrigin = corsHeaders != null ? corsHeaders.get("Access-Control-Allow-Origin") : null;
-        if (allowOrigin == null) {
-            allowOrigin = RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_ORIGIN;
-        }
-        String allowMethods = corsHeaders != null ? corsHeaders.get("Access-Control-Allow-Methods") : null;
-        if (allowMethods == null) {
-            allowMethods = RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_METHODS;
-        }
-        String allowHeaders = corsHeaders != null ? corsHeaders.get("Access-Control-Allow-Headers") : null;
-        if (allowHeaders == null) {
-            allowHeaders = RestConfiguration.CORS_ACCESS_CONTROL_ALLOW_HEADERS;
-        }
-        String maxAge = corsHeaders != null ? corsHeaders.get("Access-Control-Max-Age") : null;
-        if (maxAge == null) {
-            maxAge = RestConfiguration.CORS_ACCESS_CONTROL_MAX_AGE;
-        }
-
-        if (LOG.isTraceEnabled()) {
-            LOG.trace("Using CORS headers[");
-            LOG.trace("  Access-Control-Allow-Origin={}", allowOrigin);
-            LOG.trace("  Access-Control-Allow-Methods={}", allowMethods);
-            LOG.trace("  Access-Control-Allow-Headers={}", allowHeaders);
-            LOG.trace("  Access-Control-Max-Age={}", maxAge);
-            LOG.trace("]");
-        }
-        response.setHeader("Access-Control-Allow-Origin", allowOrigin);
-        response.setHeader("Access-Control-Allow-Methods", allowMethods);
-        response.setHeader("Access-Control-Allow-Headers", allowHeaders);
-        response.setHeader("Access-Control-Max-Age", maxAge);
-    }
-
-    static void setupXForwardedHeaders(OasDocument openApi, Map<String, Object> headers) {
-
-        String basePath = getBasePathFromOasDocument(openApi);
-
-        if (openApi instanceof Oas20Document) {
-            String host = (String) headers.get(HEADER_HOST);
-            if (ObjectHelper.isNotEmpty(host)) {
-                ((Oas20Document) openApi).host = host;
-            }
-
-            String forwardedPrefix = (String) headers.get(HEADER_X_FORWARDED_PREFIX);
-            if (ObjectHelper.isNotEmpty(forwardedPrefix)) {
-                ((Oas20Document) openApi).basePath = URISupport.joinPaths(forwardedPrefix, basePath);
-            }
-
-            String forwardedHost = (String) headers.get(HEADER_X_FORWARDED_HOST);
-            if (ObjectHelper.isNotEmpty(forwardedHost)) {
-                ((Oas20Document) openApi).host = forwardedHost;
-            }
-
-            String proto = (String) headers.get(HEADER_X_FORWARDED_PROTO);
-            if (ObjectHelper.isNotEmpty(proto)) {
-                String[] schemes = proto.split(",");
-                for (String scheme : schemes) {
-                    String trimmedScheme = scheme.trim();
-                    if (ObjectHelper.isNotEmpty(trimmedScheme)) {
-                        if (((Oas20Document) openApi).schemes == null) {
-                            ((Oas20Document) openApi).schemes = new ArrayList();
-                        }
-                        ((Oas20Document) openApi).schemes.add(trimmedScheme.toLowerCase());
-                    }
-                }
-            }
-        } else if (openApi instanceof Oas30Document) {
-
-            String host = (String) headers.get(HEADER_HOST);
-
-            String forwardedPrefix = (String) headers.get(HEADER_X_FORWARDED_PREFIX);
-
-            if (ObjectHelper.isNotEmpty(forwardedPrefix)) {
-                basePath = URISupport.joinPaths(forwardedPrefix, basePath);
-            }
-
-            String forwardedHost = (String) headers.get(HEADER_X_FORWARDED_HOST);
-            if (ObjectHelper.isNotEmpty(forwardedHost)) {
-                host = forwardedHost;
-            }
-
-            String proto = (String) headers.get(HEADER_X_FORWARDED_PROTO);
-            if (((Oas30Document) openApi).getServers() != null) {
-                ((Oas30Document) openApi).getServers().clear();
-            }
-            if (ObjectHelper.isNotEmpty(proto)) {
-                String[] schemes = proto.split(",");
-                for (String schema : schemes) {
-                    String trimmedScheme = schema.trim();
-                    String serverUrl = new StringBuilder().append(trimmedScheme.toLowerCase()).append("://").append(host)
-                            .append(basePath).toString();
-                    ((Oas30Document) openApi).addServer(serverUrl, null);
-
-                }
-            } else {
-                ((Oas30Document) openApi).addServer(basePath, null);
-            }
-
-        }
-    }
-
-    public static String getHostFromOasDocument(final OasDocument openapi) {
-        String host = null;
-        if (openapi instanceof Oas20Document) {
-            host = ((Oas20Document) openapi).host;
-        } else if (openapi instanceof Oas30Document) {
-            if (((Oas30Document) openapi).getServers() != null
-                    && ((Oas30Document) openapi).getServers().get(0) != null) {
-                try {
-                    URL serverUrl = new URL(
-                            parseVariables(((Oas30Document) openapi).getServers().get(0).url,
-                                    (Oas30Server) ((Oas30Document) openapi).getServers().get(0)));
-                    host = serverUrl.getHost();
-
-                } catch (MalformedURLException e) {
-                    LOG.info("error when parsing OpenApi 3.0 doc server url", e);
-                }
-            }
-        }
-        return host;
-
-    }
-
-    public static String getBasePathFromOasDocument(final OasDocument openapi) {
-        String basePath = null;
-        if (openapi instanceof Oas20Document) {
-            basePath = ((Oas20Document) openapi).basePath;
-        } else if (openapi instanceof Oas30Document) {
-            if (((Oas30Document) openapi).getServers() != null
-                    && ((Oas30Document) openapi).getServers().get(0) != null) {
-                try {
-                    Oas30Server server = (Oas30Server) ((Oas30Document) openapi).getServers().get(0);
-                    if (server.variables != null && server.variables.get("basePath") != null) {
-                        basePath = server.variables.get("basePath").default_;
-                    }
-                    if (basePath == null) {
-                        // parse server url as fallback
-                        URL serverUrl = new URL(
-                                parseVariables(((Oas30Document) openapi).getServers().get(0).url,
-                                        (Oas30Server) ((Oas30Document) openapi).getServers().get(0)));
-                        basePath = serverUrl.getPath();
-                        if (basePath.indexOf("//") == 0) {
-                            // strip off the first "/" if double "/" exists
-                            basePath = basePath.substring(1);
-                        }
-                        if ("/".equals(basePath)) {
-                            basePath = "";
-                        }
-                    }
-
-                } catch (MalformedURLException e) {
-                    //not a valid whole url, just the basePath
-                    basePath = ((Oas30Document) openapi).getServers().get(0).url;
-                }
-            }
-
-        }
-        return basePath;
-
-    }
-
-    public static String parseVariables(String url, Oas30Server server) {
-        Pattern p = Pattern.compile("\\{(.*?)\\}");
-        Matcher m = p.matcher(url);
-        while (m.find()) {
-
-            String var = m.group(1);
-            if (server != null && server.variables != null && server.variables.get(var) != null) {
-                String varValue = server.variables.get(var).default_;
-                url = url.replace("{" + var + "}", varValue);
-            }
-        }
-        return url;
-    }
 }
diff --git a/core/camel-base-engine/src/generated/resources/META-INF/services/org/apache/camel/routes-loader b/core/camel-base-engine/src/generated/resources/META-INF/services/org/apache/camel/routes-loader
deleted file mode 100644
index ce58158..0000000
--- a/core/camel-base-engine/src/generated/resources/META-INF/services/org/apache/camel/routes-loader
+++ /dev/null
@@ -1,2 +0,0 @@
-# Generated by camel build tools - do NOT edit this file!
-class=org.apache.camel.impl.engine.DefaultRoutesLoader
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BaseExecutorServiceManager.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BaseExecutorServiceManager.java
index 40ab6a8..43cdd96 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BaseExecutorServiceManager.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BaseExecutorServiceManager.java
@@ -40,6 +40,7 @@ import org.apache.camel.spi.ThreadPoolFactory;
 import org.apache.camel.spi.ThreadPoolProfile;
 import org.apache.camel.support.CamelContextHelper;
 import org.apache.camel.support.DefaultThreadPoolFactory;
+import org.apache.camel.support.ResolverHelper;
 import org.apache.camel.support.service.ServiceHelper;
 import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.ObjectHelper;
@@ -61,12 +62,12 @@ public class BaseExecutorServiceManager extends ServiceSupport implements Execut
     private static final Logger LOG = LoggerFactory.getLogger(BaseExecutorServiceManager.class);
 
     private final CamelContext camelContext;
-    private ThreadPoolFactory threadPoolFactory;
     private final List<ExecutorService> executorServices = new CopyOnWriteArrayList<>();
+    private final Map<String, ThreadPoolProfile> threadPoolProfiles = new ConcurrentHashMap<>();
+    private ThreadPoolFactory threadPoolFactory;
     private String threadNamePattern;
     private long shutdownAwaitTermination = 10000;
     private String defaultThreadPoolProfileId = "defaultThreadPoolProfile";
-    private final Map<String, ThreadPoolProfile> threadPoolProfiles = new ConcurrentHashMap<>();
     private ThreadPoolProfile defaultProfile;
 
     public BaseExecutorServiceManager(CamelContext camelContext) {
@@ -447,11 +448,12 @@ public class BaseExecutorServiceManager extends ServiceSupport implements Execut
 
         // discover thread pool factory
         if (threadPoolFactory == null) {
-            threadPoolFactory = new BaseServiceResolver<>(
-                    ThreadPoolFactory.FACTORY, ThreadPoolFactory.class,
-                    camelContext.adapt(ExtendedCamelContext.class).getBootstrapFactoryFinder())
-                            .resolve(camelContext)
-                            .orElseGet(DefaultThreadPoolFactory::new);
+            threadPoolFactory = ResolverHelper.resolveService(
+                    camelContext,
+                    camelContext.adapt(ExtendedCamelContext.class).getBootstrapFactoryFinder(),
+                    ThreadPoolFactory.FACTORY,
+                    ThreadPoolFactory.class)
+                    .orElseGet(DefaultThreadPoolFactory::new);
         }
         if (threadPoolFactory instanceof CamelContextAware) {
             ((CamelContextAware) threadPoolFactory).setCamelContext(camelContext);
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BaseServiceResolver.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BaseServiceResolver.java
deleted file mode 100644
index 73b0fe5..0000000
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/BaseServiceResolver.java
+++ /dev/null
@@ -1,67 +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.impl.engine;
-
-import java.util.Optional;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.spi.FactoryFinder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class BaseServiceResolver<T> {
-
-    protected final Logger log = LoggerFactory.getLogger(getClass());
-
-    protected final String factoryKey;
-    protected final Class<T> factoryClass;
-    protected final FactoryFinder factoryFinder;
-
-    public BaseServiceResolver(String factoryKey, Class<T> factoryClass, FactoryFinder factoryFinder) {
-        this.factoryKey = factoryKey;
-        this.factoryClass = factoryClass;
-        this.factoryFinder = factoryFinder;
-    }
-
-    public Optional<T> resolve(CamelContext context) {
-        // use factory finder to find a custom implementations
-        Class<?> type = null;
-
-        try {
-            type = factoryFinder.findClass(factoryKey).orElse(null);
-        } catch (Exception e) {
-            // ignore
-        }
-
-        if (type != null) {
-            if (log.isDebugEnabled()) {
-                log.debug("Found {}: {} via: {}{}", factoryClass.getSimpleName(), type.getName(), FactoryFinder.DEFAULT_PATH,
-                        factoryKey);
-            }
-            if (factoryClass.isAssignableFrom(type)) {
-                T answer = factoryClass.cast(context.getInjector().newInstance(type, false));
-                log.debug("Detected and using {}: {}", factoryClass.getSimpleName(), answer);
-                return Optional.of(answer);
-            } else {
-                throw new IllegalArgumentException(
-                        "Type is not a " + factoryClass.getSimpleName() + " implementation. Found: " + type.getName());
-            }
-        }
-        return Optional.empty();
-    }
-
-}
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoutesLoader.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoutesLoader.java
index e0ff2e9..7f7f1b0 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoutesLoader.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoutesLoader.java
@@ -19,7 +19,6 @@ package org.apache.camel.impl.engine;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
-import java.util.Optional;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
@@ -29,11 +28,10 @@ import org.apache.camel.spi.FactoryFinder;
 import org.apache.camel.spi.Resource;
 import org.apache.camel.spi.RoutesBuilderLoader;
 import org.apache.camel.spi.RoutesLoader;
-import org.apache.camel.spi.annotations.JdkService;
+import org.apache.camel.support.ResolverHelper;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.ObjectHelper;
 
-@JdkService(RoutesLoader.FACTORY)
 public class DefaultRoutesLoader implements RoutesLoader {
     private CamelContext camelContext;
 
@@ -87,21 +85,13 @@ public class DefaultRoutesLoader implements RoutesLoader {
             final ExtendedCamelContext ecc = getCamelContext().adapt(ExtendedCamelContext.class);
             final FactoryFinder finder = ecc.getBootstrapFactoryFinder(RoutesBuilderLoader.FACTORY_PATH);
 
-            final BaseServiceResolver<RoutesBuilderLoader> resolver
-                    = new BaseServiceResolver<>(extension, RoutesBuilderLoader.class, finder);
-            final Optional<RoutesBuilderLoader> loader
-                    = resolver.resolve(ecc);
-
-            if (loader.isPresent()) {
-                return CamelContextAware.trySetCamelContext(loader.get(), ecc);
-            }
+            answer = ResolverHelper.resolveService(ecc, finder, extension, RoutesBuilderLoader.class).orElse(null);
         }
-
         if (answer == null) {
             throw new IllegalArgumentException(
                     "Unable to fina a RoutesBuilderLoader for resource with file extension: " + extension);
         }
 
-        return answer;
+        return CamelContextAware.trySetCamelContext(answer, getCamelContext());
     }
 }
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
index 9ca22de..92b95f7 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
@@ -78,6 +78,7 @@ import org.apache.camel.spi.ValidatorRegistry;
 import org.apache.camel.spi.XMLRoutesDefinitionLoader;
 import org.apache.camel.support.DefaultRegistry;
 import org.apache.camel.support.DefaultUuidGenerator;
+import org.apache.camel.support.ResolverHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -116,9 +117,12 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected HealthCheckRegistry createHealthCheckRegistry() {
-        BaseServiceResolver<HealthCheckRegistry> resolver = new BaseServiceResolver<>(
-                HealthCheckRegistry.FACTORY, HealthCheckRegistry.class, getBootstrapFactoryFinder());
-        Optional<HealthCheckRegistry> result = resolver.resolve(getCamelContextReference());
+        Optional<HealthCheckRegistry> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                HealthCheckRegistry.FACTORY,
+                HealthCheckRegistry.class);
+
         return result.orElse(null);
     }
 
@@ -155,14 +159,13 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected PropertiesComponent createPropertiesComponent() {
-        BaseServiceResolver<PropertiesComponent> resolver = new BaseServiceResolver<>(
-                PropertiesComponent.FACTORY, PropertiesComponent.class, getBootstrapFactoryFinder());
-        Optional<PropertiesComponent> result = resolver.resolve(getCamelContextReference());
-        if (result.isPresent()) {
-            return result.get();
-        } else {
-            return new org.apache.camel.component.properties.PropertiesComponent();
-        }
+        Optional<PropertiesComponent> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                PropertiesComponent.FACTORY,
+                PropertiesComponent.class);
+
+        return result.orElseGet(org.apache.camel.component.properties.PropertiesComponent::new);
     }
 
     @Override
@@ -192,9 +195,12 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected ModelJAXBContextFactory createModelJAXBContextFactory() {
-        BaseServiceResolver<ModelJAXBContextFactory> resolver = new BaseServiceResolver<>(
-                ModelJAXBContextFactory.FACTORY, ModelJAXBContextFactory.class, getBootstrapFactoryFinder());
-        Optional<ModelJAXBContextFactory> result = resolver.resolve(getCamelContextReference());
+        Optional<ModelJAXBContextFactory> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                ModelJAXBContextFactory.FACTORY,
+                ModelJAXBContextFactory.class);
+
         if (result.isPresent()) {
             return result.get();
         } else {
@@ -220,9 +226,12 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected ProcessorFactory createProcessorFactory() {
-        BaseServiceResolver<ProcessorFactory> resolver
-                = new BaseServiceResolver<>(ProcessorFactory.FACTORY, ProcessorFactory.class, getBootstrapFactoryFinder());
-        Optional<ProcessorFactory> result = resolver.resolve(getCamelContextReference());
+        Optional<ProcessorFactory> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                ProcessorFactory.FACTORY,
+                ProcessorFactory.class);
+
         if (result.isPresent()) {
             return result.get();
         } else {
@@ -233,9 +242,12 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected InternalProcessorFactory createInternalProcessorFactory() {
-        BaseServiceResolver<InternalProcessorFactory> resolver = new BaseServiceResolver<>(
-                InternalProcessorFactory.FACTORY, InternalProcessorFactory.class, getBootstrapFactoryFinder());
-        Optional<InternalProcessorFactory> result = resolver.resolve(getCamelContextReference());
+        Optional<InternalProcessorFactory> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                InternalProcessorFactory.FACTORY,
+                InternalProcessorFactory.class);
+
         if (result.isPresent()) {
             return result.get();
         } else {
@@ -310,9 +322,12 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected RuntimeCamelCatalog createRuntimeCamelCatalog() {
-        BaseServiceResolver<RuntimeCamelCatalog> resolver = new BaseServiceResolver<>(
-                RuntimeCamelCatalog.FACTORY, RuntimeCamelCatalog.class, getBootstrapFactoryFinder());
-        Optional<RuntimeCamelCatalog> result = resolver.resolve(getCamelContextReference());
+        Optional<RuntimeCamelCatalog> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                RuntimeCamelCatalog.FACTORY,
+                RuntimeCamelCatalog.class);
+
         if (result.isPresent()) {
             return result.get();
         } else {
@@ -333,21 +348,23 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected HeadersMapFactory createHeadersMapFactory() {
-        BaseServiceResolver<HeadersMapFactory> resolver
-                = new BaseServiceResolver<>(HeadersMapFactory.FACTORY, HeadersMapFactory.class, getBootstrapFactoryFinder());
-        Optional<HeadersMapFactory> result = resolver.resolve(getCamelContextReference());
-        if (result.isPresent()) {
-            return result.get();
-        } else {
-            return new DefaultHeadersMapFactory();
-        }
+        Optional<HeadersMapFactory> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                HeadersMapFactory.FACTORY,
+                HeadersMapFactory.class);
+
+        return result.orElseGet(DefaultHeadersMapFactory::new);
     }
 
     @Override
     protected BeanProxyFactory createBeanProxyFactory() {
-        BaseServiceResolver<BeanProxyFactory> resolver
-                = new BaseServiceResolver<>(BeanProxyFactory.FACTORY, BeanProxyFactory.class, getBootstrapFactoryFinder());
-        Optional<BeanProxyFactory> result = resolver.resolve(getCamelContextReference());
+        Optional<BeanProxyFactory> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                BeanProxyFactory.FACTORY,
+                BeanProxyFactory.class);
+
         if (result.isPresent()) {
             return result.get();
         } else {
@@ -357,9 +374,12 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected AnnotationBasedProcessorFactory createAnnotationBasedProcessorFactory() {
-        BaseServiceResolver<AnnotationBasedProcessorFactory> resolver = new BaseServiceResolver<>(
-                AnnotationBasedProcessorFactory.FACTORY, AnnotationBasedProcessorFactory.class, getBootstrapFactoryFinder());
-        Optional<AnnotationBasedProcessorFactory> result = resolver.resolve(getCamelContextReference());
+        Optional<AnnotationBasedProcessorFactory> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                AnnotationBasedProcessorFactory.FACTORY,
+                AnnotationBasedProcessorFactory.class);
+
         if (result.isPresent()) {
             return result.get();
         } else {
@@ -370,9 +390,12 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected DeferServiceFactory createDeferServiceFactory() {
-        BaseServiceResolver<DeferServiceFactory> resolver = new BaseServiceResolver<>(
-                DeferServiceFactory.FACTORY, DeferServiceFactory.class, getBootstrapFactoryFinder());
-        Optional<DeferServiceFactory> result = resolver.resolve(getCamelContextReference());
+        Optional<DeferServiceFactory> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                DeferServiceFactory.FACTORY,
+                DeferServiceFactory.class);
+
         if (result.isPresent()) {
             return result.get();
         } else {
@@ -383,9 +406,12 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected BeanProcessorFactory createBeanProcessorFactory() {
-        BaseServiceResolver<BeanProcessorFactory> resolver = new BaseServiceResolver<>(
-                BeanProcessorFactory.FACTORY, BeanProcessorFactory.class, getBootstrapFactoryFinder());
-        Optional<BeanProcessorFactory> result = resolver.resolve(getCamelContextReference());
+        Optional<BeanProcessorFactory> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                BeanProcessorFactory.FACTORY,
+                BeanProcessorFactory.class);
+
         if (result.isPresent()) {
             return result.get();
         } else {
@@ -400,9 +426,12 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected XMLRoutesDefinitionLoader createXMLRoutesDefinitionLoader() {
-        BaseServiceResolver<XMLRoutesDefinitionLoader> resolver = new BaseServiceResolver<>(
-                XMLRoutesDefinitionLoader.FACTORY, XMLRoutesDefinitionLoader.class, getBootstrapFactoryFinder());
-        Optional<XMLRoutesDefinitionLoader> result = resolver.resolve(getCamelContextReference());
+        Optional<XMLRoutesDefinitionLoader> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                XMLRoutesDefinitionLoader.FACTORY,
+                XMLRoutesDefinitionLoader.class);
+
         if (result.isPresent()) {
             return result.get();
         } else {
@@ -413,25 +442,23 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected RoutesLoader createRoutesLoader() {
-        BaseServiceResolver<RoutesLoader> resolver = new BaseServiceResolver<>(
+        Optional<RoutesLoader> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
                 RoutesLoader.FACTORY,
-                RoutesLoader.class,
-                getBootstrapFactoryFinder());
+                RoutesLoader.class);
 
-        Optional<RoutesLoader> result = resolver.resolve(getCamelContextReference());
-        if (result.isPresent()) {
-            return result.get();
-        } else {
-            throw new IllegalArgumentException(
-                    "Cannot find RoutesLoader on classpath.");
-        }
+        return result.orElseGet(DefaultRoutesLoader::new);
     }
 
     @Override
     protected ModelToXMLDumper createModelToXMLDumper() {
-        BaseServiceResolver<ModelToXMLDumper> resolver
-                = new BaseServiceResolver<>(ModelToXMLDumper.FACTORY, ModelToXMLDumper.class, getBootstrapFactoryFinder());
-        Optional<ModelToXMLDumper> result = resolver.resolve(getCamelContextReference());
+        Optional<ModelToXMLDumper> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                ModelToXMLDumper.FACTORY,
+                ModelToXMLDumper.class);
+
         if (result.isPresent()) {
             return result.get();
         } else {
@@ -441,9 +468,12 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected RestBindingJaxbDataFormatFactory createRestBindingJaxbDataFormatFactory() {
-        BaseServiceResolver<RestBindingJaxbDataFormatFactory> resolver = new BaseServiceResolver<>(
-                RestBindingJaxbDataFormatFactory.FACTORY, RestBindingJaxbDataFormatFactory.class, getBootstrapFactoryFinder());
-        Optional<RestBindingJaxbDataFormatFactory> result = resolver.resolve(getCamelContextReference());
+        Optional<RestBindingJaxbDataFormatFactory> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                RestBindingJaxbDataFormatFactory.FACTORY,
+                RestBindingJaxbDataFormatFactory.class);
+
         if (result.isPresent()) {
             return result.get();
         } else {
@@ -489,9 +519,12 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected RestRegistryFactory createRestRegistryFactory() {
-        BaseServiceResolver<RestRegistryFactory> resolver = new BaseServiceResolver<>(
-                RestRegistryFactory.FACTORY, RestRegistryFactory.class, getBootstrapFactoryFinder());
-        Optional<RestRegistryFactory> result = resolver.resolve(getCamelContextReference());
+        Optional<RestRegistryFactory> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                RestRegistryFactory.FACTORY,
+                RestRegistryFactory.class);
+
         if (result.isPresent()) {
             return result.get();
         } else {
@@ -511,14 +544,13 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected ReactiveExecutor createReactiveExecutor() {
-        BaseServiceResolver<ReactiveExecutor> resolver
-                = new BaseServiceResolver<>(ReactiveExecutor.FACTORY, ReactiveExecutor.class, getBootstrapFactoryFinder());
-        Optional<ReactiveExecutor> result = resolver.resolve(getCamelContextReference());
-        if (result.isPresent()) {
-            return result.get();
-        } else {
-            return new DefaultReactiveExecutor();
-        }
+        Optional<ReactiveExecutor> result = ResolverHelper.resolveService(
+                getCamelContextReference(),
+                getBootstrapFactoryFinder(),
+                ReactiveExecutor.FACTORY,
+                ReactiveExecutor.class);
+
+        return result.orElseGet(DefaultReactiveExecutor::new);
     }
 
     @Override
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ResolverHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/ResolverHelper.java
index 3ca4ccc..5557c73 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ResolverHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ResolverHelper.java
@@ -16,10 +16,14 @@
  */
 package org.apache.camel.support;
 
+import java.util.Optional;
+
 import org.apache.camel.CamelContext;
 import org.apache.camel.Component;
+import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.spi.DataFormat;
 import org.apache.camel.spi.DataFormatFactory;
+import org.apache.camel.spi.FactoryFinder;
 import org.apache.camel.spi.Language;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -128,12 +132,80 @@ public final class ResolverHelper {
         return null;
     }
 
-    public static class LookupExceptionHandler {
+    /**
+     * Create an instance of the given factory.
+     *
+     * @param  camelContext the {@link CamelContext}
+     * @param  factoryPath  the path of the factory file
+     * @param  factoryKey   the key used top lookup the factory class
+     * @param  factoryClass the type of the class
+     * @return              an instance fo the given factory
+     */
+    public static <T> Optional<T> resolveService(
+            CamelContext camelContext, String factoryPath, String factoryKey, Class<T> factoryClass) {
+        return resolveService(
+                camelContext,
+                camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(factoryPath),
+                factoryKey, factoryClass);
+    }
 
-        public void handleException(Exception e, Logger log, String name) {
-            log.debug("Ignored error looking up bean: {}", name, e);
+    /**
+     * Create an instance of the given factory using the default factory finder
+     *
+     * @param  camelContext the {@link CamelContext}
+     * @param  factoryKey   the key used top lookup the factory class
+     * @param  factoryClass the type of the class
+     * @return              an instance fo the given factory
+     */
+    public static <T> Optional<T> resolveService(
+            CamelContext camelContext, String factoryKey, Class<T> factoryClass) {
+        return resolveService(
+                camelContext,
+                camelContext.adapt(ExtendedCamelContext.class).getDefaultFactoryFinder(),
+                factoryKey, factoryClass);
+    }
+
+    /**
+     * Create an instance of the given factory.
+     *
+     * @param  camelContext  the {@link CamelContext}
+     * @param  factoryFinder the {@link FactoryFinder} to use
+     * @param  factoryKey    the key used top lookup the factory class
+     * @param  factoryClass  the type of the class
+     * @return               an instance fo the given factory
+     */
+    public static <T> Optional<T> resolveService(
+            CamelContext camelContext, FactoryFinder factoryFinder, String factoryKey, Class<T> factoryClass) {
+
+        // use factory finder to find a custom implementations
+        Class<?> type = null;
+
+        try {
+            type = factoryFinder.findClass(factoryKey).orElse(null);
+        } catch (Exception e) {
+            // ignore
         }
 
+        if (type != null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Found {}: {} via: {}{}", factoryClass.getSimpleName(), type.getName(), FactoryFinder.DEFAULT_PATH,
+                        factoryKey);
+            }
+            if (factoryClass.isAssignableFrom(type)) {
+                final Object instance = camelContext.getInjector().newInstance(type, false);
+                final T answer = factoryClass.cast(instance);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Detected and using {}: {}", factoryClass.getSimpleName(), answer);
+                }
+
+                return Optional.of(answer);
+            } else {
+                throw new IllegalArgumentException(
+                        "Type is not a " + factoryClass.getSimpleName() + " implementation. Found: " + type.getName());
+            }
+        }
+        return Optional.empty();
     }
 
     private static Object lookupInRegistry(
@@ -159,4 +231,12 @@ public final class ResolverHelper {
         return null;
     }
 
+    public static class LookupExceptionHandler {
+
+        public void handleException(Exception e, Logger log, String name) {
+            log.debug("Ignored error looking up bean: {}", name, e);
+        }
+
+    }
+
 }