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/03/04 20:16:57 UTC

[camel] branch master updated: core: DefaultRoutesLoader to cache RoutesBuilderLoader locally instead of globally to the registry

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 b58ec82  core: DefaultRoutesLoader to cache RoutesBuilderLoader locally instead of globally to the registry
b58ec82 is described below

commit b58ec827833254913a6a511ede8cbb977a6c533c
Author: Luca Burgazzoli <lb...@gmail.com>
AuthorDate: Thu Mar 4 18:44:26 2021 +0100

    core: DefaultRoutesLoader to cache RoutesBuilderLoader locally instead of globally to the registry
---
 .../camel/impl/engine/DefaultRoutesLoader.java     | 63 +++++++++++++++++-----
 1 file changed, 49 insertions(+), 14 deletions(-)

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 b7edaae..86c959a 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,8 +19,11 @@ package org.apache.camel.impl.engine;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
 import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.spi.FactoryFinder;
@@ -28,26 +31,41 @@ import org.apache.camel.spi.Resource;
 import org.apache.camel.spi.RoutesBuilderLoader;
 import org.apache.camel.spi.RoutesLoader;
 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.FileUtil;
 import org.apache.camel.util.ObjectHelper;
 
 /**
  * Default {@link RoutesLoader}.
  */
-public class DefaultRoutesLoader implements RoutesLoader {
+public class DefaultRoutesLoader extends ServiceSupport implements RoutesLoader {
 
     /**
      * Prefix to use for looking up existing {@link RoutesLoader} from the {@link org.apache.camel.spi.Registry}.
      */
     public static final String ROUTES_LOADER_KEY_PREFIX = "routes-builder-loader-";
 
+    private final Map<String, RoutesBuilderLoader> loaders;
+
     private CamelContext camelContext;
 
     public DefaultRoutesLoader() {
+        this(null);
     }
 
     public DefaultRoutesLoader(CamelContext camelContext) {
         this.camelContext = camelContext;
+        this.loaders = new ConcurrentHashMap<>();
+    }
+
+    @Override
+    public void doStop() throws Exception {
+        super.doStop();
+
+        ServiceHelper.stopService(loaders.values());
+
+        loaders.clear();
     }
 
     @Override
@@ -73,7 +91,13 @@ public class DefaultRoutesLoader implements RoutesLoader {
                         "Unable to determine file extension for resource: " + resource.getLocation());
             }
 
-            answer.add(getRoutesLoader(extension).loadRoutesBuilder(resource));
+            RoutesBuilderLoader loader = getRoutesLoader(extension);
+            if (loader == null) {
+                throw new IllegalArgumentException(
+                        "Cannot find RoutesBuilderLoader in classpath supporting file extension: " + extension);
+            }
+
+            answer.add(loader.loadRoutesBuilder(resource));
         }
 
         return answer;
@@ -87,22 +111,33 @@ public class DefaultRoutesLoader implements RoutesLoader {
      * @throws IllegalArgumentException if no {@link RoutesBuilderLoader} can be found for the given file extension
      */
     private RoutesBuilderLoader getRoutesLoader(String extension) throws Exception {
-        RoutesBuilderLoader answer = getCamelContext().getRegistry().lookupByNameAndType(ROUTES_LOADER_KEY_PREFIX + extension,
+        RoutesBuilderLoader answer = getCamelContext().getRegistry().lookupByNameAndType(
+                ROUTES_LOADER_KEY_PREFIX + extension,
                 RoutesBuilderLoader.class);
 
         if (answer == null) {
-            final ExtendedCamelContext ecc = getCamelContext().adapt(ExtendedCamelContext.class);
-            final FactoryFinder finder = ecc.getBootstrapFactoryFinder(RoutesBuilderLoader.FACTORY_PATH);
+            answer = loaders.computeIfAbsent(extension, this::resolveService);
+        }
 
-            answer = ResolverHelper.resolveService(ecc, finder, extension, RoutesBuilderLoader.class).orElse(null);
-            if (answer == null) {
-                throw new IllegalArgumentException(
-                        "Cannot find RoutesBuilderLoader in classpath supporting file extension: " + extension);
-            }
-            // add as service so its lifecycle is managed
-            getCamelContext().addService(answer);
-            // store loader so we can reuse it
-            getCamelContext().getRegistry().bind(ROUTES_LOADER_KEY_PREFIX + extension, answer);
+        return answer;
+    }
+
+    /**
+     * Looks up a {@link RoutesBuilderLoader} for the given extension with factory finder.
+     *
+     * @param  extension the file extension for which a loader should be find.
+     * @return           a {@link RoutesBuilderLoader} or null if none found
+     */
+    private RoutesBuilderLoader resolveService(String extension) {
+        final ExtendedCamelContext ecc = getCamelContext().adapt(ExtendedCamelContext.class);
+        final FactoryFinder finder = ecc.getBootstrapFactoryFinder(RoutesBuilderLoader.FACTORY_PATH);
+
+        RoutesBuilderLoader answer
+                = ResolverHelper.resolveService(ecc, finder, extension, RoutesBuilderLoader.class).orElse(null);
+
+        if (answer != null) {
+            CamelContextAware.trySetCamelContext(answer, getCamelContext());
+            ServiceHelper.startService(answer);
         }
 
         return answer;