This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch kamelet-local-registry in repository https://gitbox.apache.org/repos/asf/camel.git
commit c585264fc4669393f147e43dd702dd6dc80b5a71 Author: Claus Ibsen <[email protected]> AuthorDate: Tue May 4 17:55:40 2021 +0200 CAMEL-16394: Route Template local beans. WIP --- .../main/java/org/apache/camel/CamelContext.java | 13 ++++ .../org/apache/camel/RouteTemplateContext.java | 85 ++++++++++++++++++++++ .../apache/camel/spi/LocalBeanRepositoryAware.java | 32 ++++++++ .../camel/impl/engine/SimpleCamelContext.java | 7 ++ .../org/apache/camel/impl/DefaultCamelContext.java | 23 ++++++ .../java/org/apache/camel/impl/DefaultModel.java | 19 ++++- .../camel/impl/lw/LightweightCamelContext.java | 7 ++ .../impl/lw/LightweightRuntimeCamelContext.java | 7 ++ .../camel/builder/DefaultRouteTemplateContext.java | 70 ++++++++++++++++++ .../camel/builder/TemplatedRouteBuilder.java | 41 ++++++++--- .../main/java/org/apache/camel/model/Model.java | 14 ++++ .../org/apache/camel/model/RouteDefinition.java | 11 +++ .../camel/model/RouteTemplateDefinition.java | 1 - .../camel/builder/RouteTemplateLocalBeanTest.java | 1 - .../org/apache/camel/support/DefaultRegistry.java | 53 +++++++++++++- 15 files changed, 366 insertions(+), 18 deletions(-) diff --git a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java index 5053093..3a72488 100644 --- a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java +++ b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java @@ -605,9 +605,22 @@ public interface CamelContext extends CamelContextLifecycle, RuntimeConfiguratio * @return the id of the route added (for example when an id was auto assigned) * @throws Exception is thrown if error creating and adding the new route */ + @Deprecated String addRouteFromTemplate(String routeId, String routeTemplateId, Map<String, Object> parameters) throws Exception; /** + * Adds a new route from a given route template. + * + * @param routeId the id of the new route to add (optional) + * @param routeTemplateId the id of the route template (mandatory) + * @param routeTemplateContext the route template context (mandatory) + * @return the id of the route added (for example when an id was auto assigned) + * @throws Exception is thrown if error creating and adding the new route + */ + String addRouteFromTemplate(String routeId, String routeTemplateId, RouteTemplateContext routeTemplateContext) + throws Exception; + + /** * Adds the given route policy factory * * @param routePolicyFactory the factory diff --git a/core/camel-api/src/main/java/org/apache/camel/RouteTemplateContext.java b/core/camel-api/src/main/java/org/apache/camel/RouteTemplateContext.java new file mode 100644 index 0000000..c6e8842 --- /dev/null +++ b/core/camel-api/src/main/java/org/apache/camel/RouteTemplateContext.java @@ -0,0 +1,85 @@ +/* + * 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; + +import java.util.Map; +import java.util.function.Supplier; + +import org.apache.camel.spi.BeanRepository; + +/** + * The context used during creating a {@link Route} from a route template. + */ +public interface RouteTemplateContext { + + /** + * Binds the bean to the repository (if possible). + * + * If the bean is {@link CamelContextAware} then the registry will automatic inject the context if possible. + * + * @param id the id of the bean + * @param bean the bean + */ + default void bind(String id, Object bean) { + bind(id, bean.getClass(), bean); + } + + /** + * Binds the bean to the repository (if possible). + * <p/> + * Binding by id and type allows to bind multiple entries with the same id but with different type. + * + * If the bean is {@link CamelContextAware} then the registry will automatic inject the context if possible. + * + * @param id the id of the bean + * @param type the type of the bean to associate the binding + * @param bean the bean + */ + void bind(String id, Class<?> type, Object bean); + + /** + * Binds the bean (via a supplier) to the repository (if possible). + * <p/> + * Binding by id and type allows to bind multiple entries with the same id but with different type. + * + * If the bean is {@link CamelContextAware} then the registry will automatic inject the context if possible. + * + * @param id the id of the bean + * @param type the type of the bean to associate the binding + * @param bean a supplier for the bean + */ + void bind(String id, Class<?> type, Supplier<Object> bean); + + /** + * Gets the property with the given name + * + * @param name name of property + * @return the property value or <tt>null</tt> if no property exists + */ + Object getProperty(String name); + + /** + * The parameters to use for the route template when creating the new route + */ + Map<String, Object> getParameters(); + + /** + * Gets the local bean repository for the route template when creating the new route + */ + BeanRepository getLocalBeanRepository(); + +} diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/LocalBeanRepositoryAware.java b/core/camel-api/src/main/java/org/apache/camel/spi/LocalBeanRepositoryAware.java new file mode 100644 index 0000000..d0c62d5 --- /dev/null +++ b/core/camel-api/src/main/java/org/apache/camel/spi/LocalBeanRepositoryAware.java @@ -0,0 +1,32 @@ +/* + * 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.spi; + +/** + * Allows a {@link BeanRepository} to temporary have a local repository take precedence, such as when creating route + * templates to give more flexibility. + */ +public interface LocalBeanRepositoryAware { + + /** + * Sets a special local bean repository (ie thread local) that take precedence and will use first, if a bean exists. + * + * @param repository the local repository, or <tt>null</tt> to unset when no longer needed. + */ + void setLocalBeanRepository(BeanRepository repository); + +} 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 254fc2d..a5aa0f5 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 @@ -23,6 +23,7 @@ import org.apache.camel.CamelContext; import org.apache.camel.Endpoint; import org.apache.camel.Processor; import org.apache.camel.Route; +import org.apache.camel.RouteTemplateContext; import org.apache.camel.TypeConverter; import org.apache.camel.catalog.RuntimeCamelCatalog; import org.apache.camel.health.HealthCheckRegistry; @@ -623,6 +624,12 @@ public class SimpleCamelContext extends AbstractCamelContext { } @Override + public String addRouteFromTemplate(String routeId, String routeTemplateId, RouteTemplateContext routeTemplateContext) + throws Exception { + throw new UnsupportedOperationException(); + } + + @Override public String getTestExcludeRoutes() { throw new UnsupportedOperationException(); } diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java index 9801bce..1236c6e 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java @@ -31,6 +31,7 @@ import org.apache.camel.FailedToStartRouteException; import org.apache.camel.Predicate; import org.apache.camel.Processor; import org.apache.camel.Route; +import org.apache.camel.RouteTemplateContext; import org.apache.camel.StartupStep; import org.apache.camel.ValueHolder; import org.apache.camel.api.management.JmxSystemPropertyKeys; @@ -67,6 +68,7 @@ import org.apache.camel.spi.BeanRepository; import org.apache.camel.spi.DataFormat; import org.apache.camel.spi.DataType; import org.apache.camel.spi.ExecutorServiceManager; +import org.apache.camel.spi.LocalBeanRepositoryAware; import org.apache.camel.spi.ModelReifierFactory; import org.apache.camel.spi.ModelToXMLDumper; import org.apache.camel.spi.PackageScanClassResolver; @@ -393,6 +395,15 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame } @Override + public String addRouteFromTemplate(String routeId, String routeTemplateId, RouteTemplateContext routeTemplateContext) + throws Exception { + if (model == null && isLightweight()) { + throw new IllegalStateException("Access to model not supported in lightweight mode"); + } + return model.addRouteFromTemplate(routeId, routeTemplateId, routeTemplateContext); + } + + @Override public List<RestDefinition> getRestDefinitions() { if (model == null && isLightweight()) { throw new IllegalStateException("Access to model not supported in lightweight mode"); @@ -714,6 +725,10 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame } PropertiesComponent pc = getCamelContextReference().getPropertiesComponent(); + LocalBeanRepositoryAware localBeans = null; + if (getCamelContextReference().getRegistry() instanceof LocalBeanRepositoryAware) { + localBeans = (LocalBeanRepositoryAware) getCamelContextReference().getRegistry(); + } try { RouteDefinitionHelper.forceAssignIds(getCamelContextReference(), routeDefinitions); for (RouteDefinition routeDefinition : routeDefinitions) { @@ -732,6 +747,11 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame prop.putAll(routeDefinition.getTemplateParameters()); pc.setLocalProperties(prop); + // we need to shadow the bean registry on the CamelContext with the local beans from the route template context + if (localBeans != null) { + localBeans.setLocalBeanRepository(routeDefinition.getRouteTemplateContext().getLocalBeanRepository()); + } + // need to reset auto assigned ids, so there is no clash when creating routes ProcessorDefinitionHelper.resetAllAutoAssignedNodeIds(routeDefinition); } @@ -753,6 +773,9 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame // clear local after the route is created via the reifier pc.setLocalProperties(null); + if (localBeans != null) { + localBeans.setLocalBeanRepository(null); + } } } finally { if (!alreadyStartingRoutes) { diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java index c1d456c..620e678 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java @@ -29,6 +29,8 @@ import java.util.function.Function; import org.apache.camel.CamelContext; import org.apache.camel.ExtendedCamelContext; import org.apache.camel.FailedToCreateRouteFromTemplateException; +import org.apache.camel.RouteTemplateContext; +import org.apache.camel.builder.DefaultRouteTemplateContext; import org.apache.camel.model.DataFormatDefinition; import org.apache.camel.model.FaultToleranceConfigurationDefinition; import org.apache.camel.model.HystrixConfigurationDefinition; @@ -48,6 +50,7 @@ import org.apache.camel.model.rest.RestDefinition; import org.apache.camel.model.transformer.TransformerDefinition; import org.apache.camel.model.validator.ValidatorDefinition; import org.apache.camel.spi.ModelReifierFactory; +import org.apache.camel.support.SimpleRegistry; import org.apache.camel.util.AntPathMatcher; public class DefaultModel implements Model { @@ -220,8 +223,16 @@ public class DefaultModel implements Model { } @Override + @Deprecated public String addRouteFromTemplate(final String routeId, final String routeTemplateId, final Map<String, Object> parameters) throws Exception { + RouteTemplateContext rtc = new DefaultRouteTemplateContext(camelContext, new SimpleRegistry(), parameters); + return addRouteFromTemplate(routeId, routeTemplateId, rtc); + } + + @Override + public String addRouteFromTemplate(String routeId, String routeTemplateId, RouteTemplateContext routeTemplateContext) + throws Exception { RouteTemplateDefinition target = null; for (RouteTemplateDefinition def : routeTemplateDefinitions) { if (routeTemplateId.equals(def.getId())) { @@ -243,7 +254,7 @@ public class DefaultModel implements Model { prop.put(temp.getName(), temp.getDefaultValue()); } else { // this is a required parameter do we have that as input - if (!parameters.containsKey(temp.getName())) { + if (!routeTemplateContext.getParameters().containsKey(temp.getName())) { templatesBuilder.add(temp.getName()); } } @@ -256,8 +267,8 @@ public class DefaultModel implements Model { } // then override with user parameters - if (parameters != null) { - prop.putAll(parameters); + if (routeTemplateContext.getParameters() != null) { + prop.putAll(routeTemplateContext.getParameters()); } RouteTemplateDefinition.Converter converter = RouteTemplateDefinition.Converter.DEFAULT_CONVERTER; @@ -283,6 +294,8 @@ public class DefaultModel implements Model { def.setId(routeId); } def.setTemplateParameters(prop); + def.setRouteTemplateContext(routeTemplateContext); + // assign ids to the routes and validate that the id's are all unique String duplicate = RouteDefinitionHelper.validateUniqueIds(def, routeDefinitions); if (duplicate != null) { 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 9ffb1f5..14cd80c 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 @@ -41,6 +41,7 @@ import org.apache.camel.Predicate; import org.apache.camel.Processor; import org.apache.camel.ProducerTemplate; import org.apache.camel.Route; +import org.apache.camel.RouteTemplateContext; import org.apache.camel.RoutesBuilder; import org.apache.camel.Service; import org.apache.camel.ServiceStatus; @@ -1757,6 +1758,12 @@ public class LightweightCamelContext implements ExtendedCamelContext, CatalogCam } @Override + public String addRouteFromTemplate(String routeId, String routeTemplateId, RouteTemplateContext routeTemplateContext) + throws Exception { + return getModelCamelContext().addRouteFromTemplate(routeId, routeTemplateId, routeTemplateContext); + } + + @Override public List<RestDefinition> getRestDefinitions() { return getModelCamelContext().getRestDefinitions(); } 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 66ec1d4..409c494 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 @@ -49,6 +49,7 @@ import org.apache.camel.Processor; import org.apache.camel.ProducerTemplate; import org.apache.camel.ResolveEndpointFailedException; import org.apache.camel.Route; +import org.apache.camel.RouteTemplateContext; import org.apache.camel.RoutesBuilder; import org.apache.camel.RuntimeCamelException; import org.apache.camel.Service; @@ -1922,6 +1923,12 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat } @Override + public String addRouteFromTemplate(String routeId, String routeTemplateId, RouteTemplateContext routeTemplateContext) + throws Exception { + throw new UnsupportedOperationException(); + } + + @Override public void setLightweight(boolean lightweight) { throw new UnsupportedOperationException(); } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/builder/DefaultRouteTemplateContext.java b/core/camel-core-model/src/main/java/org/apache/camel/builder/DefaultRouteTemplateContext.java new file mode 100644 index 0000000..d7a2574 --- /dev/null +++ b/core/camel-core-model/src/main/java/org/apache/camel/builder/DefaultRouteTemplateContext.java @@ -0,0 +1,70 @@ +/* + * 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.builder; + +import java.util.Map; +import java.util.function.Supplier; + +import org.apache.camel.CamelContext; +import org.apache.camel.RouteTemplateContext; +import org.apache.camel.spi.BeanRepository; +import org.apache.camel.spi.Registry; + +// TODO: Should this be moved to some other module/package? + +public final class DefaultRouteTemplateContext implements RouteTemplateContext { + + private final CamelContext camelContext; + private final Registry registry; + private final Map<String, Object> parameters; + + public DefaultRouteTemplateContext(CamelContext camelContext, Registry registry, Map<String, Object> parameters) { + this.camelContext = camelContext; + this.registry = registry; + this.parameters = parameters; + } + + @Override + public void bind(String id, Object bean) { + registry.bind(id, bean); + } + + @Override + public void bind(String id, Class<?> type, Object bean) { + registry.bind(id, type, bean); + } + + @Override + public void bind(String id, Class<?> type, Supplier<Object> bean) { + registry.bind(id, type, bean); + } + + @Override + public Object getProperty(String name) { + return camelContext.resolvePropertyPlaceholders(name); + } + + @Override + public Map<String, Object> getParameters() { + return parameters; + } + + @Override + public BeanRepository getLocalBeanRepository() { + return registry; + } +} diff --git a/core/camel-core-model/src/main/java/org/apache/camel/builder/TemplatedRouteBuilder.java b/core/camel-core-model/src/main/java/org/apache/camel/builder/TemplatedRouteBuilder.java index 8939b9f..6f2322b 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/builder/TemplatedRouteBuilder.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/builder/TemplatedRouteBuilder.java @@ -22,6 +22,7 @@ import java.util.function.Consumer; import java.util.function.Supplier; import org.apache.camel.CamelContext; +import org.apache.camel.RouteTemplateContext; import org.apache.camel.RuntimeCamelException; import org.apache.camel.model.ModelCamelContext; import org.apache.camel.model.RouteTemplateDefinition; @@ -35,14 +36,18 @@ public final class TemplatedRouteBuilder { private final CamelContext camelContext; private final String routeTemplateId; - private String routeId; private final Map<String, Object> parameters = new HashMap<>(); + // TODO: Need to shadow regular camel registry during route creation private final Registry localRegistry = new DefaultRegistry(); + private final RouteTemplateContext routeTemplateContext; + private String routeId; private Consumer<RouteTemplateDefinition> handler; + private Consumer<RouteTemplateContext> configurer; private TemplatedRouteBuilder(CamelContext camelContext, String routeTemplateId) { this.camelContext = camelContext; this.routeTemplateId = routeTemplateId; + this.routeTemplateContext = new DefaultRouteTemplateContext(camelContext, localRegistry, parameters); } /** @@ -91,8 +96,8 @@ public final class TemplatedRouteBuilder { /** * Binds the bean to the template local repository (takes precedence over global beans) * - * @param id the id of the bean - * @param bean the bean + * @param id the id of the bean + * @param bean the bean */ public TemplatedRouteBuilder bind(String id, Object bean) { localRegistry.bind(id, bean); @@ -102,9 +107,9 @@ public final class TemplatedRouteBuilder { /** * Binds the bean to the template local repository (takes precedence over global beans) * - * @param id the id of the bean - * @param type the type of the bean to associate the binding - * @param bean the bean + * @param id the id of the bean + * @param type the type of the bean to associate the binding + * @param bean the bean */ public TemplatedRouteBuilder bind(String id, Class<?> type, Object bean) { localRegistry.bind(id, type, bean); @@ -114,9 +119,9 @@ public final class TemplatedRouteBuilder { /** * Binds the bean (via a supplier) to the template local repository (takes precedence over global beans) * - * @param id the id of the bean - * @param type the type of the bean to associate the binding - * @param bean the bean + * @param id the id of the bean + * @param type the type of the bean to associate the binding + * @param bean the bean */ public TemplatedRouteBuilder bind(String id, Class<?> type, Supplier<Object> bean) { localRegistry.bind(id, type, bean); @@ -136,6 +141,17 @@ public final class TemplatedRouteBuilder { } /** + * Sets a configurer which allows to do configuration while the route template is being used to create a route. This + * gives control over the creating process, such as binding local beans and doing other kind of customization. + * + * @param configurer the configurer with callback to invoke with the given route template context + */ + public TemplatedRouteBuilder configure(Consumer<RouteTemplateContext> configurer) { + this.configurer = configurer; + return this; + } + + /** * Adds the route to the {@link CamelContext} which is built from the configured route template. * * @return the route id of the route that was added. @@ -150,9 +166,10 @@ public final class TemplatedRouteBuilder { } handler.accept(def); } - // TODO: provide local beans from builder (either via new parameter here) - // or some way via a new RouteTemplateContext that stores such information - return camelContext.addRouteFromTemplate(routeId, routeTemplateId, parameters); + if (configurer != null) { + configurer.accept(routeTemplateContext); + } + return camelContext.addRouteFromTemplate(routeId, routeTemplateId, routeTemplateContext); } catch (Exception e) { throw RuntimeCamelException.wrapRuntimeException(e); } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/Model.java b/core/camel-core-model/src/main/java/org/apache/camel/model/Model.java index b619650..5d41864 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/Model.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/Model.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.function.Function; import org.apache.camel.CamelContext; +import org.apache.camel.RouteTemplateContext; import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition; import org.apache.camel.model.rest.RestDefinition; import org.apache.camel.model.transformer.TransformerDefinition; @@ -174,9 +175,22 @@ public interface Model { * @return the id of the route added (for example when an id was auto assigned) * @throws Exception is thrown if error creating and adding the new route */ + @Deprecated String addRouteFromTemplate(String routeId, String routeTemplateId, Map<String, Object> parameters) throws Exception; /** + * Adds a new route from a given route template + * + * @param routeId the id of the new route to add (optional) + * @param routeTemplateId the id of the route template (mandatory) + * @param routeTemplateContext the route template context (mandatory) + * @return the id of the route added (for example when an id was auto assigned) + * @throws Exception is thrown if error creating and adding the new route + */ + String addRouteFromTemplate(String routeId, String routeTemplateId, RouteTemplateContext routeTemplateContext) + throws Exception; + + /** * Returns a list of the current REST definitions * * @return list of the current REST definitions diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java index f41df10..e6a3d0d 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java @@ -35,6 +35,7 @@ import javax.xml.bind.annotation.XmlType; import org.apache.camel.Endpoint; import org.apache.camel.ErrorHandlerFactory; import org.apache.camel.NamedRoute; +import org.apache.camel.RouteTemplateContext; import org.apache.camel.ShutdownRoute; import org.apache.camel.ShutdownRunningTask; import org.apache.camel.builder.EndpointConsumerBuilder; @@ -82,6 +83,7 @@ public class RouteDefinition extends OutputDefinition<RouteDefinition> implement private OutputTypeDefinition outputType; private List<PropertyDefinition> routeProperties; private Map<String, Object> templateParameters; + private RouteTemplateContext routeTemplateContext; public RouteDefinition() { } @@ -672,6 +674,15 @@ public class RouteDefinition extends OutputDefinition<RouteDefinition> implement this.templateParameters = templateParameters; } + public RouteTemplateContext getRouteTemplateContext() { + return routeTemplateContext; + } + + @XmlTransient + public void setRouteTemplateContext(RouteTemplateContext routeTemplateContext) { + this.routeTemplateContext = routeTemplateContext; + } + // Properties // ----------------------------------------------------------------------- diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java index 724a657..cadb574 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java @@ -17,7 +17,6 @@ package org.apache.camel.model; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; diff --git a/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateLocalBeanTest.java b/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateLocalBeanTest.java index c91938a..c106091 100644 --- a/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateLocalBeanTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateLocalBeanTest.java @@ -17,7 +17,6 @@ package org.apache.camel.builder; import org.apache.camel.ContextTestSupport; -import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.junit.jupiter.api.Test; diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java index 86fd9ed..dba5f1c 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java @@ -32,6 +32,7 @@ import org.apache.camel.CamelContext; import org.apache.camel.CamelContextAware; import org.apache.camel.RuntimeCamelException; import org.apache.camel.spi.BeanRepository; +import org.apache.camel.spi.LocalBeanRepositoryAware; import org.apache.camel.spi.Registry; import org.apache.camel.support.service.ServiceHelper; import org.apache.camel.support.service.ServiceSupport; @@ -45,9 +46,11 @@ import org.apache.camel.util.IOHelper; * Notice that beans in the fallback registry are not managed by the first-choice registry, so these beans may not * support dependency injection and other features that the first-choice registry may offer. */ -public class DefaultRegistry extends ServiceSupport implements Registry, CamelContextAware { +public class DefaultRegistry extends ServiceSupport implements Registry, LocalBeanRepositoryAware, CamelContextAware { protected CamelContext camelContext; + protected final ThreadLocal<BeanRepository> localRepository = new ThreadLocal<>(); + protected volatile boolean localRepositoryEnabled; // flag to keep track if local is in use or not protected List<BeanRepository> repositories; protected Registry fallbackRegistry = new SimpleRegistry(); protected Registry supplierRegistry = new SupplierRegistry(); @@ -87,6 +90,19 @@ public class DefaultRegistry extends ServiceSupport implements Registry, CamelCo } /** + * Sets a special local bean repository (ie thread local) that take precedence and will use first, if a bean exists. + */ + public void setLocalBeanRepository(BeanRepository repository) { + if (repository != null) { + this.localRepository.set(repository); + this.localRepositoryEnabled = true; + } else { + this.localRepository.remove(); + this.localRepositoryEnabled = false; + } + } + + /** * Gets the fallback {@link Registry} */ public Registry getFallbackRegistry() { @@ -164,6 +180,15 @@ public class DefaultRegistry extends ServiceSupport implements Registry, CamelCo throw RuntimeCamelException.wrapRuntimeCamelException(e); } + // local repository takes precedence + BeanRepository local = localRepositoryEnabled ? localRepository.get() : null; + if (local != null) { + answer = local.lookupByName(name); + if (answer != null) { + return unwrap(answer); + } + } + if (repositories != null) { for (BeanRepository r : repositories) { answer = r.lookupByName(name); @@ -196,6 +221,14 @@ public class DefaultRegistry extends ServiceSupport implements Registry, CamelCo throw RuntimeCamelException.wrapRuntimeCamelException(e); } + // local repository takes precedence + BeanRepository local = localRepositoryEnabled ? localRepository.get() : null; + if (local != null) { + answer = local.lookupByNameAndType(name, type); + if (answer != null) { + return (T) unwrap(answer); + } + } if (repositories != null) { for (BeanRepository r : repositories) { answer = r.lookupByNameAndType(name, type); @@ -219,6 +252,15 @@ public class DefaultRegistry extends ServiceSupport implements Registry, CamelCo public <T> Map<String, T> findByTypeWithName(Class<T> type) { Map<String, T> answer = new LinkedHashMap<>(); + // local repository takes precedence + BeanRepository local = localRepositoryEnabled ? localRepository.get() : null; + if (local != null) { + Map<String, T> found = local.findByTypeWithName(type); + if (found != null && !found.isEmpty()) { + answer.putAll(found); + } + } + if (repositories != null) { for (BeanRepository r : repositories) { Map<String, T> found = r.findByTypeWithName(type); @@ -244,6 +286,15 @@ public class DefaultRegistry extends ServiceSupport implements Registry, CamelCo public <T> Set<T> findByType(Class<T> type) { Set<T> answer = new LinkedHashSet<>(); + // local repository takes precedence + BeanRepository local = localRepositoryEnabled ? localRepository.get() : null; + if (local != null) { + Set<T> found = local.findByType(type); + if (found != null && !found.isEmpty()) { + answer.addAll(found); + } + } + if (repositories != null) { for (BeanRepository r : repositories) { Set<T> found = r.findByType(type);
