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
commit 016ee4ed3e9d4425296ce5c88486f771fe366621 Author: Luca Burgazzoli <[email protected]> AuthorDate: Wed Feb 3 10:22:20 2021 +0100 CAMEL-15560: generic route loader (fix findings) --- .../java/org/apache/camel/CamelContextAware.java | 18 --- .../org/apache/camel/ExtendedCamelContext.java | 60 ++++++---- .../main/java/org/apache/camel/spi/Resource.java | 2 - .../org/apache/camel/spi/RoutesBuilderLoader.java | 2 + .../java/org/apache/camel/spi/RoutesLoader.java | 4 +- .../camel/spi/XMLRoutesDefinitionLoader.java | 2 +- .../camel/impl/engine/AbstractCamelContext.java | 20 ++++ .../camel/impl/engine/DefaultRoutesLoader.java | 22 ++-- .../camel/impl/lw/LightweightCamelContext.java | 5 + .../impl/lw/LightweightRuntimeCamelContext.java | 5 + .../camel/main/DefaultConfigurationProperties.java | 127 +-------------------- 11 files changed, 88 insertions(+), 179 deletions(-) diff --git a/core/camel-api/src/main/java/org/apache/camel/CamelContextAware.java b/core/camel-api/src/main/java/org/apache/camel/CamelContextAware.java index abbe2e0..ee565ff 100644 --- a/core/camel-api/src/main/java/org/apache/camel/CamelContextAware.java +++ b/core/camel-api/src/main/java/org/apache/camel/CamelContextAware.java @@ -45,22 +45,4 @@ public interface CamelContextAware { * @param camelContext the Camel context */ void setCamelContext(CamelContext camelContext); - - /** - * Get the {@link CamelContext} adapted to the specialized type. - * <p/> - * - * @param type the type to adapt to - * @return this {@link CamelContext} adapted to the given type - * - * @see CamelContext#adapt(Class) - */ - default <T extends CamelContext> T getCamelContext(Class<T> type) { - if (getCamelContext() == null) { - return null; - } - - return getCamelContext().adapt(type); - } - } diff --git a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java index 94b7b13..830a460 100644 --- a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java +++ b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java @@ -242,18 +242,18 @@ public interface ExtendedCamelContext extends CamelContext { void setErrorHandlerFactory(ErrorHandlerFactory errorHandlerFactory); /** - * Uses a custom node id factory when generating auto assigned ids to the nodes in the route definitions + * Gets the node id factory * - * @param factory custom factory to use + * @return the node id factory */ - void setNodeIdFactory(NodeIdFactory factory); + NodeIdFactory getNodeIdFactory(); /** - * Gets the node id factory + * Uses a custom node id factory when generating auto assigned ids to the nodes in the route definitions * - * @return the node id factory + * @param factory custom factory to use */ - NodeIdFactory getNodeIdFactory(); + void setNodeIdFactory(NodeIdFactory factory); /** * Gets the {@link ComponentResolver} to use. @@ -353,6 +353,16 @@ public interface ExtendedCamelContext extends CamelContext { void setBootstrapFactoryFinder(FactoryFinder factoryFinder); /** + * Gets the bootstrap FactoryFinder which will be used for the loading the factory class from META-INF in the given + * path. This bootstrap factory finder is only intended to be used during bootstrap (starting) CamelContext. + * + * @param path the META-INF path + * @return the bootstrap factory finder + * @see #getDefaultFactoryFinder() + */ + FactoryFinder getBootstrapFactoryFinder(String path); + + /** * Gets the bootstrap {@link ConfigurerResolver} to use. This bootstrap resolver is only intended to be used during * bootstrap (starting) CamelContext. */ @@ -373,18 +383,18 @@ public interface ExtendedCamelContext extends CamelContext { FactoryFinder getFactoryFinder(String path); /** - * Sets the factory finder resolver to use. + * Gets the factory finder resolver to use * - * @param resolver the factory finder resolver + * @return the factory finder resolver */ - void setFactoryFinderResolver(FactoryFinderResolver resolver); + FactoryFinderResolver getFactoryFinderResolver(); /** - * Gets the factory finder resolver to use + * Sets the factory finder resolver to use. * - * @return the factory finder resolver + * @param resolver the factory finder resolver */ - FactoryFinderResolver getFactoryFinderResolver(); + void setFactoryFinderResolver(FactoryFinderResolver resolver); /** * Gets the current {@link org.apache.camel.spi.ProcessorFactory} @@ -594,11 +604,6 @@ public interface ExtendedCamelContext extends CamelContext { void setEventNotificationApplicable(boolean eventNotificationApplicable); /** - * Sets a custom {@link XMLRoutesDefinitionLoader} to be used. - */ - void setXMLRoutesDefinitionLoader(XMLRoutesDefinitionLoader xmlRoutesDefinitionLoader); - - /** * Gets the {@link XMLRoutesDefinitionLoader} to be used. * * @deprecated use {@link #getRoutesLoader()} @@ -607,9 +612,9 @@ public interface ExtendedCamelContext extends CamelContext { XMLRoutesDefinitionLoader getXMLRoutesDefinitionLoader(); /** - * Sets a custom {@link RoutesLoader} to be used. + * Sets a custom {@link XMLRoutesDefinitionLoader} to be used. */ - void setRoutesLoader(RoutesLoader routesLoader); + void setXMLRoutesDefinitionLoader(XMLRoutesDefinitionLoader xmlRoutesDefinitionLoader); /** * Gets the {@link RoutesLoader} to be used. @@ -617,9 +622,9 @@ public interface ExtendedCamelContext extends CamelContext { RoutesLoader getRoutesLoader(); /** - * Sets a custom {@link ModelToXMLDumper} to be used. + * Sets a custom {@link RoutesLoader} to be used. */ - void setModelToXMLDumper(ModelToXMLDumper modelToXMLDumper); + void setRoutesLoader(RoutesLoader routesLoader); /** * Gets the {@link ModelToXMLDumper} to be used. @@ -627,9 +632,9 @@ public interface ExtendedCamelContext extends CamelContext { ModelToXMLDumper getModelToXMLDumper(); /** - * Sets a custom {@link RestBindingJaxbDataFormatFactory} to be used. + * Sets a custom {@link ModelToXMLDumper} to be used. */ - void setRestBindingJaxbDataFormatFactory(RestBindingJaxbDataFormatFactory restBindingJaxbDataFormatFactory); + void setModelToXMLDumper(ModelToXMLDumper modelToXMLDumper); /** * Gets the {@link RestBindingJaxbDataFormatFactory} to be used. @@ -637,6 +642,11 @@ public interface ExtendedCamelContext extends CamelContext { RestBindingJaxbDataFormatFactory getRestBindingJaxbDataFormatFactory(); /** + * Sets a custom {@link RestBindingJaxbDataFormatFactory} to be used. + */ + void setRestBindingJaxbDataFormatFactory(RestBindingJaxbDataFormatFactory restBindingJaxbDataFormatFactory); + + /** * Gets the {@link RuntimeCamelCatalog} if available on the classpath. */ RuntimeCamelCatalog getRuntimeCamelCatalog(); @@ -706,13 +716,13 @@ public interface ExtendedCamelContext extends CamelContext { * Whether to run in lightweight mode which triggers some optimizations and memory reduction. Danger this causes * Camel to be less dynamic such as adding new route after Camel is started would not be possible. */ - void setLightweight(boolean lightweight); + boolean isLightweight(); /** * Whether to run in lightweight mode which triggers some optimizations and memory reduction. Danger this causes * Camel to be less dynamic such as adding new route after Camel is started would not be possible. */ - boolean isLightweight(); + void setLightweight(boolean lightweight); /** * Danger!!! This will dispose the route model from the {@link CamelContext} which is used for lightweight mode. diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Resource.java b/core/camel-api/src/main/java/org/apache/camel/spi/Resource.java index bcfb8f0..1c3b765 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/Resource.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/Resource.java @@ -39,7 +39,6 @@ public interface Resource { * Finds a resource with a given name. * * @see Class#getResourceAsStream(String) - * */ static Resource fromClasspath(String location) { return fromClasspath(Resource.class, location); @@ -49,7 +48,6 @@ public interface Resource { * Finds a resource with a given name. * * @see Class#getResourceAsStream(String) - * */ static Resource fromClasspath(Class<?> type, String location) { return new Resource() { diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/RoutesBuilderLoader.java b/core/camel-api/src/main/java/org/apache/camel/spi/RoutesBuilderLoader.java index 747e1a5..c43c74f 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/RoutesBuilderLoader.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/RoutesBuilderLoader.java @@ -34,6 +34,8 @@ public interface RoutesBuilderLoader { /** * The supported file extension. + * <p/> + * Implementations should support a single extension only. */ String getSupportedExtension(); diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/RoutesLoader.java b/core/camel-api/src/main/java/org/apache/camel/spi/RoutesLoader.java index 84fa7f1..3c564c0 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/RoutesLoader.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/RoutesLoader.java @@ -59,7 +59,7 @@ public interface RoutesLoader extends CamelContextAware { * Find {@link RoutesBuilder} from the give list of {@link Resource}. * * @param resources the resource to be loaded. - * @return a {@link RoutesBuilder} + * @return a collection of {@link RoutesBuilder} */ default Collection<RoutesBuilder> findRoutesBuilders(Resource... resources) throws Exception { return findRoutesBuilders(Arrays.asList(resources)); @@ -69,7 +69,7 @@ public interface RoutesLoader extends CamelContextAware { * Find {@link RoutesBuilder} from the give list of {@link Resource}. * * @param resources the resource to be loaded. - * @return a {@link RoutesBuilder} + * @return a collection {@link RoutesBuilder} */ Collection<RoutesBuilder> findRoutesBuilders(Collection<Resource> resources) throws Exception; } diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/XMLRoutesDefinitionLoader.java b/core/camel-api/src/main/java/org/apache/camel/spi/XMLRoutesDefinitionLoader.java index 812cce9..95f3db1 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/XMLRoutesDefinitionLoader.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/XMLRoutesDefinitionLoader.java @@ -23,7 +23,7 @@ import org.apache.camel.CamelContext; /** * SPI for loading routes/rests from XML input streams and parsing this to model definition classes. * - * @deprecated sue {@link RoutesLoader} + * @deprecated use {@link RoutesLoader} */ @Deprecated public interface XMLRoutesDefinitionLoader { diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java index 79cf81d..9ae5702 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java @@ -206,6 +206,7 @@ public abstract class AbstractCamelContext extends BaseService private final ThreadLocal<Boolean> isStartingRoutes = new ThreadLocal<>(); private final ThreadLocal<Boolean> isSetupRoutes = new ThreadLocal<>(); private final Map<String, FactoryFinder> factories = new ConcurrentHashMap<>(); + private final Map<String, FactoryFinder> bootstrapFactories = new ConcurrentHashMap<>(); private volatile FactoryFinder bootstrapFactoryFinder; private volatile ConfigurerResolver bootstrapConfigurerResolver; private final Map<String, RouteService> routeServices = new LinkedHashMap<>(); @@ -366,6 +367,14 @@ public abstract class AbstractCamelContext extends BaseService // add the default bootstrap closer this.bootstraps.add(new DefaultServiceBootstrapCloseable(this)); + // add a cleaner for FactoryFinder used only when bootstrapping the context + this.bootstraps.add(new BootstrapCloseable() { + @Override + public void close() throws IOException { + bootstrapFactories.clear(); + } + }); + if (build) { try { build(); @@ -3637,6 +3646,8 @@ public abstract class AbstractCamelContext extends BaseService getModelJAXBContextFactory(); getUnitOfWorkFactory(); getRouteController(); + getRoutesLoader(); + try { getRestRegistryFactory(); } catch (IllegalArgumentException e) { @@ -3761,6 +3772,15 @@ public abstract class AbstractCamelContext extends BaseService } @Override + public FactoryFinder getBootstrapFactoryFinder(String path) { + return bootstrapFactories.computeIfAbsent(path, this::createBootstrapFactoryFinder); + } + + protected FactoryFinder createBootstrapFactoryFinder(String path) { + return getFactoryFinderResolver().resolveBootstrapFactoryFinder(getClassResolver(), path); + } + + @Override public FactoryFinderResolver getFactoryFinderResolver() { if (factoryFinderResolver == null) { synchronized (lock) { 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 5d3b822..e0ff2e9 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 @@ -59,30 +59,33 @@ public class DefaultRoutesLoader implements RoutesLoader { List<RoutesBuilder> answer = new ArrayList<>(resources.size()); for (Resource resource : resources) { - // language is derived from the file extension + // the loader to use is derived from the file extension final String extension = FileUtil.onlyExt(resource.getLocation(), true); if (ObjectHelper.isEmpty(extension)) { - throw new IllegalArgumentException("Unable to determine extension for resource: " + resource.getLocation()); + throw new IllegalArgumentException( + "Unable to determine file extension for resource: " + resource.getLocation()); } - answer.add(getLoader(extension).loadRoutesBuilder(resource)); + answer.add(getRoutesLoader(extension).loadRoutesBuilder(resource)); } return answer; } /** + * Looks up a {@link RoutesBuilderLoader} in the registry or fallback to a factory finder mechanism if none found. * - * @param extension - * @return + * @param extension the file extension for which a loader should be find. + * @return a {@link RoutesBuilderLoader} + * @throws IllegalArgumentException if no {@link RoutesBuilderLoader} can be found for the given file extension */ - private RoutesBuilderLoader getLoader(String extension) { + private RoutesBuilderLoader getRoutesLoader(String extension) { RoutesBuilderLoader answer = getCamelContext().getRegistry().lookupByNameAndType(extension, RoutesBuilderLoader.class); if (answer == null) { - final ExtendedCamelContext ecc = getCamelContext(ExtendedCamelContext.class); - final FactoryFinder finder = ecc.getFactoryFinder(RoutesBuilderLoader.FACTORY_PATH); + 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); @@ -95,7 +98,8 @@ public class DefaultRoutesLoader implements RoutesLoader { } if (answer == null) { - throw new IllegalArgumentException("Unable to fina a RoutesBuilderLoader for extension " + extension); + throw new IllegalArgumentException( + "Unable to fina a RoutesBuilderLoader for resource with file extension: " + extension); } return answer; diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java index 1f98975..033417a 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java @@ -1271,6 +1271,11 @@ public class LightweightCamelContext implements ExtendedCamelContext, CatalogCam } @Override + public FactoryFinder getBootstrapFactoryFinder(String path) { + return getExtendedCamelContext().getBootstrapFactoryFinder(path); + } + + @Override public FactoryFinder getFactoryFinder(String path) { return getExtendedCamelContext().getFactoryFinder(path); } diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java index 31f4bbb..8ff2277 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java @@ -1414,6 +1414,11 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat } @Override + public FactoryFinder getBootstrapFactoryFinder(String path) { + throw new UnsupportedOperationException(); + } + + @Override public FactoryFinder getFactoryFinder(String path) { throw new UnsupportedOperationException(); } diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java index b0fbf9e..9413cfd 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java @@ -911,66 +911,6 @@ public abstract class DefaultConfigurationProperties<T> { this.routesExcludePattern = routesExcludePattern; } - // public String getXmlRoutes() { - // return xmlRoutes; - // } - // - // /** - // * Directory to scan for adding additional XML routes. You can turn this off by setting the value to false. - // * - // * Files can be loaded from either classpath or file by prefixing with classpath: or file: Wildcards is supported - // * using a ANT pattern style paths, such as classpath:**/*camel*.xml - // * - // * Notice when using wildcards, then there is additional overhead as the classpath is scanned, where as if you - // * specific the exact name for each XML file is faster as no classpath scanning is needed. - // * - // * Multiple directories can be specified and separated by comma, such as: - // * file:/myapp/mycamel/*.xml,file:/myapp/myothercamel/*.xml - // */ - // public void setXmlRoutes(String xmlRoutes) { - // this.xmlRoutes = xmlRoutes; - // } - // - // public String getXmlRouteTemplates() { - // return xmlRouteTemplates; - // } - // - // /** - // * Directory to scan for adding additional XML route templates. You can turn this off by setting the value to false. - // * - // * Files can be loaded from either classpath or file by prefixing with classpath: or file: Wildcards is supported - // * using a ANT pattern style paths, such as classpath:**/*template-*.xml - // * - // * Notice when using wildcards, then there is additional overhead as the classpath is scanned, where as if you - // * specific the exact name for each XML file is faster as no classpath scanning is needed. - // * - // * Multiple directories can be specified and separated by comma, such as: - // * file:/myapp/mycamel/*.xml,file:/myapp/myothercamel/*.xml - // */ - // public void setXmlRouteTemplates(String xmlRouteTemplates) { - // this.xmlRouteTemplates = xmlRouteTemplates; - // } - // - // public String getXmlRests() { - // return xmlRests; - // } - // - // /** - // * Directory to scan for adding additional XML rests. You can turn this off by setting the value to false. - // * - // * Files can be loaded from either classpath or file by prefixing with classpath: or file: Wildcards is supported - // * using a ANT pattern style paths, such as classpath:**/*camel*.xml - // * - // * Notice when using wildcards, then there is additional overhead as the classpath is scanned, where as if you - // * specific the exact name for each XML file is faster as no classpath scanning is needed. - // * - // * Multiple directories can be specified and separated by comma, such as: - // * file:/myapp/mycamel/*.xml,file:/myapp/myothercamel/*.xml - // */ - // public void setXmlRests(String xmlRests) { - // this.xmlRests = xmlRests; - // } - // @Experimental public boolean isLightweight() { return lightweight; @@ -1831,69 +1771,12 @@ public abstract class DefaultConfigurationProperties<T> { return (T) this; } - // /** - // * Directory to scan for adding additional XML routes. You can turn this off by setting the value to false. - // * - // * Files can be loaded from either classpath or file by prefixing with classpath: or file: By default classpath is - // * assumed if no prefix is specified. - // * - // * Wildcards is supported using a ANT pattern style paths, such as classpath:**/*camel*.xml - // * - // * Notice when using wildcards, then there is additional overhead as the classpath is scanned, where as if you - // * specific the exact name for each XML file is faster as no classpath scanning is needed. - // * - // * Multiple directories can be specified and separated by comma, such as: - // * file:/myapp/mycamel/*.xml,file:/myapp/myothercamel/*.xml - // */ - // public T withXmlRoutes(String xmlRoutes) { - // this.xmlRoutes = xmlRoutes; - // return (T) this; - // } - // - // /** - // * Directory to scan for adding additional XML route templates. You can turn this off by setting the value to false. - // * - // * Files can be loaded from either classpath or file by prefixing with classpath: or file: Wildcards is supported - // * using a ANT pattern style paths, such as classpath:**/*template-*.xml - // * - // * Notice when using wildcards, then there is additional overhead as the classpath is scanned, where as if you - // * specific the exact name for each XML file is faster as no classpath scanning is needed. - // * - // * Multiple directories can be specified and separated by comma, such as: - // * file:/myapp/mycamel/*.xml,file:/myapp/myothercamel/*.xml - // */ - // public T withXmlRouteTemplates(String xmlRouteTemplates) { - // this.xmlRouteTemplates = xmlRouteTemplates; - // return (T) this; - // } - // - // /** - // * Directory to scan for adding additional XML rests. You can turn this off by setting the value to false. - // * - // * Files can be loaded from either classpath or file by prefixing with classpath: or file: By default classpath is - // * assumed if no prefix is specified. - // * - // * Wildcards is supported using a ANT pattern style paths, such as classpath:**/*camel*.xml - // * - // * Notice when using wildcards, then there is additional overhead as the classpath is scanned, where as if you - // * specific the exact name for each XML file is faster as no classpath scanning is needed. - // * - // * Multiple directories can be specified and separated by comma, such as: - // * file:/myapp/mycamel/*.xml,file:/myapp/myothercamel/*.xml - // */ - // public T withXmlRests(String xmlRests) { - // this.xmlRests = xmlRests; - // return (T) this; - // } - - /* - * Configure the context to be lightweight. This will trigger some optimizations - * and memory reduction options. + /** + * Configure the context to be lightweight. This will trigger some optimizations and memory reduction options. * <p/> - * Lightweight context have some limitations. At the moment, dynamic endpoint - * destinations are not supported. Also, this should only be done on a JVM with - * a single Camel application (microservice like camel-main, camel-quarkus, camel-spring-boot). - * As this affects the entire JVM where Camel JARs are on the classpath. + * Lightweight context have some limitations. At the moment, dynamic endpoint destinations are not supported. Also, + * this should only be done on a JVM with a single Camel application (microservice like camel-main, camel-quarkus, + * camel-spring-boot). As this affects the entire JVM where Camel JARs are on the classpath. */ @Experimental public T withLightweight(boolean lightweight) {
