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 d3d13835f899190bfe1dac7236621f7ce7a41b7d Author: Claus Ibsen <[email protected]> AuthorDate: Tue May 4 16:51:54 2021 +0200 CAMEL-16394: Route Template local beans. WIP --- .../main/java/org/apache/camel/spi/Registry.java | 12 +++ .../camel/builder/TemplatedRouteBuilder.java | 41 ++++++++++ .../camel/model/RouteTemplateDefinition.java | 9 +-- .../camel/builder/RouteTemplateLocalBeanTest.java | 90 ++++++++++++++++++++++ 4 files changed, 144 insertions(+), 8 deletions(-) diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Registry.java b/core/camel-api/src/main/java/org/apache/camel/spi/Registry.java index e350ee0..fb1061b 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/Registry.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/Registry.java @@ -53,6 +53,18 @@ public interface Registry extends BeanRepository { */ void bind(String id, Class<?> type, Object bean) throws RuntimeCamelException; + /** + * 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 + * @throws RuntimeCamelException is thrown if binding is not possible + */ void bind(String id, Class<?> type, Supplier<Object> bean) throws RuntimeCamelException; /** 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 8ec7dd2..8939b9f 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 @@ -19,11 +19,14 @@ package org.apache.camel.builder; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; +import java.util.function.Supplier; import org.apache.camel.CamelContext; import org.apache.camel.RuntimeCamelException; import org.apache.camel.model.ModelCamelContext; import org.apache.camel.model.RouteTemplateDefinition; +import org.apache.camel.spi.Registry; +import org.apache.camel.support.DefaultRegistry; /** * Fluent builder for adding new routes from route templates. @@ -34,6 +37,7 @@ public final class TemplatedRouteBuilder { private final String routeTemplateId; private String routeId; private final Map<String, Object> parameters = new HashMap<>(); + private final Registry localRegistry = new DefaultRegistry(); private Consumer<RouteTemplateDefinition> handler; private TemplatedRouteBuilder(CamelContext camelContext, String routeTemplateId) { @@ -85,6 +89,41 @@ 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 + */ + public TemplatedRouteBuilder bind(String id, Object bean) { + localRegistry.bind(id, bean); + return this; + } + + /** + * 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 + */ + public TemplatedRouteBuilder bind(String id, Class<?> type, Object bean) { + localRegistry.bind(id, type, bean); + return this; + } + + /** + * 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 + */ + public TemplatedRouteBuilder bind(String id, Class<?> type, Supplier<Object> bean) { + localRegistry.bind(id, type, bean); + return this; + } + + /** * Sets a handler which gives access to the route template model that will be used for creating the route. This can * be used to do validation. Any changes to the model happens before the route is created and added, however these * changes affect future usage of the same template. @@ -111,6 +150,8 @@ 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); } catch (Exception e) { throw RuntimeCamelException.wrapRuntimeException(e); 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 71094e6..724a657 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 @@ -221,6 +221,7 @@ public class RouteTemplateDefinition extends OptionalIdentifiedDefinition { @FunctionalInterface public interface Converter { + /** * Default implementation that uses {@link #asRouteDefinition()} to convert a {@link RouteTemplateDefinition} to * a {@link RouteDefinition} @@ -233,14 +234,6 @@ public class RouteTemplateDefinition extends OptionalIdentifiedDefinition { }; /** - * @deprecated use {@link #apply(RouteTemplateDefinition, Map)} - */ - @Deprecated - default RouteDefinition apply(RouteTemplateDefinition in) throws Exception { - return apply(in, Collections.emptyMap()); - } - - /** * Convert a {@link RouteTemplateDefinition} to a {@link RouteDefinition}. * * @param in the {@link RouteTemplateDefinition} to convert 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 new file mode 100644 index 0000000..c91938a --- /dev/null +++ b/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateLocalBeanTest.java @@ -0,0 +1,90 @@ +/* + * 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 org.apache.camel.ContextTestSupport; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class RouteTemplateLocalBeanTest extends ContextTestSupport { + + @Override + public boolean isUseRouteBuilder() { + return false; + } + + @Test + public void testGlobalBean() throws Exception { + context.getRegistry().bind("myBar", (Processor) ex -> ex.getMessage().setBody("Global " + ex.getMessage().getBody())); + + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + routeTemplate("myTemplate").templateParameter("foo").templateParameter("bar") + .from("direct:{{foo}}") + .to("bean:{{bar}}"); + } + }); + + context.start(); + + TemplatedRouteBuilder.builder(context, "myTemplate") + .parameter("foo", "one") + .parameter("bar", "myBar") + .routeId("myRoute") + .add(); + + assertEquals(1, context.getRoutes().size()); + + Object out = template.requestBody("direct:one", "World"); + assertEquals("Global World", out); + + context.stop(); + } + + @Test + public void testLocalBeanInBuilder() throws Exception { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + routeTemplate("myTemplate").templateParameter("foo").templateParameter("bar") + .from("direct:{{foo}}") + .to("bean:{{bar}}"); + } + }); + + context.start(); + + TemplatedRouteBuilder.builder(context, "myTemplate") + .parameter("foo", "one") + .parameter("bar", "myBar") + .bind("myBar", (Processor) ex -> ex.getMessage().setBody("Builder " + ex.getMessage().getBody())) + .routeId("myRoute") + .add(); + + assertEquals(1, context.getRoutes().size()); + + Object out = template.requestBody("direct:one", "World"); + assertEquals("Builder World", out); + + context.stop(); + } + +}
