diff --git a/camel-k-loader-groovy/pom.xml b/camel-k-loader-groovy/pom.xml index 992ff9e8f..1c7a2461a 100644 --- a/camel-k-loader-groovy/pom.xml +++ b/camel-k-loader-groovy/pom.xml @@ -65,6 +65,17 @@ provided + + org.apache.camel.k + camel-k-apt + true + + + org.apache.camel.k + camel-k-annotations + true + + diff --git a/camel-k-loader-groovy/src/main/groovy/org/apache/camel/k/loader/groovy/GroovyRoutesLoader.groovy b/camel-k-loader-groovy/src/main/groovy/org/apache/camel/k/loader/groovy/GroovySourceLoader.groovy similarity index 86% rename from camel-k-loader-groovy/src/main/groovy/org/apache/camel/k/loader/groovy/GroovyRoutesLoader.groovy rename to camel-k-loader-groovy/src/main/groovy/org/apache/camel/k/loader/groovy/GroovySourceLoader.groovy index 6ed4f3140..f721ceb2c 100644 --- a/camel-k-loader-groovy/src/main/groovy/org/apache/camel/k/loader/groovy/GroovyRoutesLoader.groovy +++ b/camel-k-loader-groovy/src/main/groovy/org/apache/camel/k/loader/groovy/GroovySourceLoader.groovy @@ -16,24 +16,23 @@ */ package org.apache.camel.k.loader.groovy -import org.apache.camel.CamelContext -import org.apache.camel.builder.RouteBuilder import org.apache.camel.builder.endpoint.EndpointRouteBuilder -import org.apache.camel.k.RoutesLoader +import org.apache.camel.k.Runtime import org.apache.camel.k.Source +import org.apache.camel.k.SourceLoader import org.apache.camel.k.loader.groovy.dsl.IntegrationConfiguration import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.control.customizers.ImportCustomizer -class GroovyRoutesLoader implements RoutesLoader { +class GroovySourceLoader implements SourceLoader { @Override List getSupportedLanguages() { - return Collections.singletonList("groovy") + return Collections.singletonList('groovy') } @Override - RouteBuilder load(CamelContext camelContext, Source source) throws Exception { - return new EndpointRouteBuilder() { + void load(Runtime runtime, Source source) throws Exception { + def builder = new EndpointRouteBuilder() { @Override void configure() throws Exception { def ic = new ImportCustomizer() @@ -58,5 +57,7 @@ class GroovyRoutesLoader implements RoutesLoader { } } } + + runtime.addRoutes(builder) } } diff --git a/camel-k-loader-groovy/src/main/resources/META-INF/services/org/apache/camel/k/loader/groovy b/camel-k-loader-groovy/src/main/resources/META-INF/services/org/apache/camel/k/loader/groovy index 006db95f9..4c39f93ab 100644 --- a/camel-k-loader-groovy/src/main/resources/META-INF/services/org/apache/camel/k/loader/groovy +++ b/camel-k-loader-groovy/src/main/resources/META-INF/services/org/apache/camel/k/loader/groovy @@ -15,4 +15,4 @@ # limitations under the License. # -class=org.apache.camel.k.loader.groovy.GroovyRoutesLoader \ No newline at end of file +class=org.apache.camel.k.loader.groovy.GroovySourceLoader \ No newline at end of file diff --git a/camel-k-loader-groovy/src/test/groovy/org/apache/camel/k/loader/groovy/LoaderTest.groovy b/camel-k-loader-groovy/src/test/groovy/org/apache/camel/k/loader/groovy/LoaderTest.groovy index 48e5285db..64b4010d9 100644 --- a/camel-k-loader-groovy/src/test/groovy/org/apache/camel/k/loader/groovy/LoaderTest.groovy +++ b/camel-k-loader-groovy/src/test/groovy/org/apache/camel/k/loader/groovy/LoaderTest.groovy @@ -16,7 +16,11 @@ */ package org.apache.camel.k.loader.groovy +import org.apache.camel.CamelContext +import org.apache.camel.RoutesBuilder +import org.apache.camel.builder.RouteBuilder import org.apache.camel.impl.DefaultCamelContext +import org.apache.camel.k.Runtime import org.apache.camel.k.Sources import org.apache.camel.k.support.RuntimeSupport import org.apache.camel.model.FromDefinition @@ -27,52 +31,76 @@ class LoaderTest extends Specification { def "load routes"() { given: - def context = new DefaultCamelContext() + def runtime = new TestRuntime() def source = Sources.fromURI("classpath:routes.groovy") when: - def loader = RuntimeSupport.loaderFor(context, source) - def builder = loader.load(context, source) + def loader = RuntimeSupport.loaderFor(runtime.camelContext, source) + loader.load(runtime, source) then: - loader instanceof GroovyRoutesLoader - builder != null + loader instanceof GroovySourceLoader + runtime.builders.size() == 1 + runtime.builders[0] instanceof RouteBuilder - builder.setContext(context) - builder.configure() + with(runtime.builders[0], RouteBuilder) { + it.setContext(runtime.camelContext) + it.configure() - def routes = builder.routeCollection.routes + def routes = it.routeCollection.routes - routes.size() == 1 - routes[0].outputs[0] instanceof ToDefinition - routes[0].input.endpointUri == 'timer:tick' + routes.size() == 1 + routes[0].outputs[0] instanceof ToDefinition + routes[0].input.endpointUri == 'timer:tick' + } } def "load routes with endpoint dsl"() { given: - def context = new DefaultCamelContext() + def runtime = new TestRuntime() def source = Sources.fromURI("classpath:routes-with-endpoint-dsl.groovy") when: - def loader = RuntimeSupport.loaderFor(context, source) - def builder = loader.load(context, source) + def loader = RuntimeSupport.loaderFor(runtime.camelContext, source) + loader.load(runtime, source) then: - loader instanceof GroovyRoutesLoader - builder != null - - builder.setContext(context) - builder.configure() + loader instanceof GroovySourceLoader + runtime.builders.size() == 1 - def routes = builder.routeCollection.routes + with(runtime.builders[0], RouteBuilder) { + it.setContext(runtime.camelContext) + it.configure() - routes.size() == 1 + def routes = it.routeCollection.routes + routes.size() == 1 - with(routes[0].input, FromDefinition) { - it.endpointUri == 'timer:tick?period=1s' - } - with(routes[0].outputs[0], ToDefinition) { - it.endpointUri == 'log:info' + with(routes[0].input, FromDefinition) { + it.endpointUri == 'timer:tick?period=1s' + } + with(routes[0].outputs[0], ToDefinition) { + it.endpointUri == 'log:info' + } } } + + static class TestRuntime implements Runtime { + private final CamelContext camelContext + private final List builders + + TestRuntime() { + this.camelContext = new DefaultCamelContext() + this.builders = new ArrayList<>() + } + + @Override + CamelContext getCamelContext() { + return this.camelContext + } + + @Override + void addRoutes(RoutesBuilder builder) { + this.builders.add(builder) + } + } } diff --git a/camel-k-loader-java/pom.xml b/camel-k-loader-java/pom.xml index bfc7e72f4..a49d0b542 100644 --- a/camel-k-loader-java/pom.xml +++ b/camel-k-loader-java/pom.xml @@ -48,6 +48,17 @@ ${joor.version} + + org.apache.camel.k + camel-k-apt + true + + + org.apache.camel.k + camel-k-annotations + true + + org.apache.camel camel-main diff --git a/camel-k-loader-java/src/main/java/org/apache/camel/k/loader/java/JavaSourceRoutesLoader.java b/camel-k-loader-java/src/main/java/org/apache/camel/k/loader/java/JavaSourceLoader.java similarity index 74% rename from camel-k-loader-java/src/main/java/org/apache/camel/k/loader/java/JavaSourceRoutesLoader.java rename to camel-k-loader-java/src/main/java/org/apache/camel/k/loader/java/JavaSourceLoader.java index 8208fdc0f..1a5b3f20e 100644 --- a/camel-k-loader-java/src/main/java/org/apache/camel/k/loader/java/JavaSourceRoutesLoader.java +++ b/camel-k-loader-java/src/main/java/org/apache/camel/k/loader/java/JavaSourceLoader.java @@ -23,33 +23,39 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.camel.CamelContext; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.k.RoutesLoader; +import org.apache.camel.RoutesBuilder; +import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; +import org.apache.camel.k.annotation.Loader; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.joor.Reflect; -public class JavaSourceRoutesLoader implements RoutesLoader { +@Loader("java") +public class JavaSourceLoader implements SourceLoader { @Override public List getSupportedLanguages() { return Collections.singletonList("java"); } @Override - public RouteBuilder load(CamelContext camelContext, Source source) throws Exception { - try (InputStream is = source.resolveAsInputStream(camelContext)) { + public void load(Runtime runtime, Source source) throws Exception { + try (InputStream is = source.resolveAsInputStream(runtime.getCamelContext())) { final String content = IOUtils.toString(is, StandardCharsets.UTF_8); final String name = determineQualifiedName(source, content); final Reflect compiled = Reflect.compile(name, content); + final Object instance = compiled.create().get(); - RouteBuilder rb = compiled.create().get(); - return rb; + if (instance instanceof RoutesBuilder) { + runtime.addRoutes((RoutesBuilder)instance); + } else { + runtime.addConfiguration(instance); + } } } - private static String determineQualifiedName(Source source, String content) throws Exception { + private static String determineQualifiedName(Source source, String content) { String name = source.getName(); name = StringUtils.removeEnd(name, ".java"); diff --git a/camel-k-loader-java/src/main/resources/META-INF/services/org/apache/camel/k/loader/java b/camel-k-loader-java/src/main/resources/META-INF/services/org/apache/camel/k/loader/java deleted file mode 100644 index 2118cbc9d..000000000 --- a/camel-k-loader-java/src/main/resources/META-INF/services/org/apache/camel/k/loader/java +++ /dev/null @@ -1,18 +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. -# - -class=org.apache.camel.k.loader.java.JavaSourceRoutesLoader \ No newline at end of file diff --git a/camel-k-loader-java/src/test/java/org/apache/camel/k/loader/java/RoutesLoaderTest.java b/camel-k-loader-java/src/test/java/org/apache/camel/k/loader/java/RoutesLoaderTest.java index 6d73eb543..f1c56c604 100644 --- a/camel-k-loader-java/src/test/java/org/apache/camel/k/loader/java/RoutesLoaderTest.java +++ b/camel-k-loader-java/src/test/java/org/apache/camel/k/loader/java/RoutesLoaderTest.java @@ -16,17 +16,19 @@ */ package org.apache.camel.k.loader.java; +import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; import org.apache.camel.CamelContext; +import org.apache.camel.RoutesBuilder; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.DefaultCamelContext; -import org.apache.camel.k.RoutesLoader; +import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; import org.apache.camel.k.Sources; import org.apache.camel.k.support.RuntimeSupport; -import org.apache.camel.model.ModelCamelContext; import org.apache.camel.model.ProcessDefinition; import org.apache.camel.model.RouteDefinition; import org.apache.camel.model.SetBodyDefinition; @@ -41,16 +43,18 @@ public class RoutesLoaderTest { @Test public void testLoadJavaWithNestedClass() throws Exception { - CamelContext context = new DefaultCamelContext(); - + TestRuntime runtime = new TestRuntime(); Source source = Sources.fromURI("classpath:MyRoutesWithNestedClass.java"); - RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source); - RouteBuilder builder = loader.load(context, source); + SourceLoader loader = RuntimeSupport.loaderFor(runtime.camelContext, source); + + loader.load(runtime, source); - assertThat(loader).isInstanceOf(JavaSourceRoutesLoader.class); - assertThat(builder).isNotNull(); + assertThat(loader).isInstanceOf(JavaSourceLoader.class); + assertThat(runtime.builders).hasSize(1); + assertThat(runtime.builders).first().isInstanceOf(RouteBuilder.class); - builder.setContext(context); + RouteBuilder builder = (RouteBuilder)runtime.builders.get(0); + builder.setContext(runtime.getCamelContext()); builder.configure(); List routes = builder.getRouteCollection().getRoutes(); @@ -63,35 +67,50 @@ public void testLoadJavaWithNestedClass() throws Exception { @Test public void testLoadJavaWithRestConfiguration() throws Exception { - CamelContext context = new DefaultCamelContext(); - + TestRuntime runtime = new TestRuntime(); Source source = Sources.fromURI("classpath:MyRoutesWithRestConfiguration.java"); - RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source); - RouteBuilder builder = loader.load(context, source); + SourceLoader loader = RuntimeSupport.loaderFor(runtime.camelContext, source); + + loader.load(runtime, source); - assertThat(loader).isInstanceOf(JavaSourceRoutesLoader.class); - assertThat(builder).isNotNull(); + assertThat(loader).isInstanceOf(JavaSourceLoader.class); + assertThat(runtime.builders).hasSize(1); + assertThat(runtime.builders).first().isInstanceOf(RouteBuilder.class); - context.addRoutes(builder); + runtime.getCamelContext().addRoutes(runtime.builders.get(0)); - assertThat(context.getRestConfigurations()).hasSize(1); - assertThat(context.getRestConfigurations().iterator().next()).hasFieldOrPropertyWithValue("component", "restlet"); + assertThat(runtime.getCamelContext().getRestConfigurations()).hasSize(1); + assertThat(runtime.getCamelContext().getRestConfigurations().iterator().next()).hasFieldOrPropertyWithValue("component", "restlet"); } @Test - public void testLoadJavaWithModel() throws Exception { - CamelContext context = new DefaultCamelContext(); + public void testLoadJavaConfiguration() throws Exception { + TestRuntime runtime = new TestRuntime(); + Source source = Sources.fromURI("classpath:MyRoutesConfig.java"); + SourceLoader loader = RuntimeSupport.loaderFor(runtime.camelContext, source); + + loader.load(runtime, source); + + assertThat(loader).isInstanceOf(JavaSourceLoader.class); + assertThat(runtime.builders).isEmpty(); + assertThat(runtime.configurations).hasSize(1); + } + @Test + public void testLoadJavaWithModel() throws Exception { + TestRuntime runtime = new TestRuntime(); Source source = Sources.fromURI("classpath:MyRoutesWithModel.java"); - RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source); - RouteBuilder builder = loader.load(context, source); + SourceLoader loader = RuntimeSupport.loaderFor(runtime.camelContext, source); - assertThat(loader).isInstanceOf(JavaSourceRoutesLoader.class); - assertThat(builder).isNotNull(); + loader.load(runtime, source); - context.addRoutes(builder); + assertThat(loader).isInstanceOf(JavaSourceLoader.class); + assertThat(runtime.builders).hasSize(1); + assertThat(runtime.builders).first().isInstanceOf(RouteBuilder.class); - assertThat(context.adapt(ModelCamelContext.class).getRestDefinitions()).first().satisfies(definition -> { + runtime.getCamelContext().addRoutes(runtime.builders.get(0)); + + assertThat(runtime.camelContext.getRestDefinitions()).first().satisfies(definition -> { assertThat(definition.getVerbs()).first().satisfies(verb -> { assertThat(verb).hasFieldOrPropertyWithValue("outType", "org.apache.camel.k.loader.java.model.EmployeeDTO"); }); @@ -100,15 +119,19 @@ public void testLoadJavaWithModel() throws Exception { @ParameterizedTest @MethodSource("parameters") - public void testLoaders(String location, Class type) throws Exception { + public void testLoaders(String location, Class type) throws Exception { + TestRuntime runtime = new TestRuntime(); Source source = Sources.fromURI(location); - RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source); - RouteBuilder builder = loader.load(new DefaultCamelContext(), source); + SourceLoader loader = RuntimeSupport.loaderFor(runtime.camelContext, source); + + loader.load(runtime, source); assertThat(loader).isInstanceOf(type); - assertThat(builder).isNotNull(); + assertThat(runtime.builders).hasSize(1); + assertThat(runtime.builders).first().isInstanceOf(RouteBuilder.class); - builder.setContext(new DefaultCamelContext()); + RouteBuilder builder = (RouteBuilder)runtime.builders.get(0); + builder.setContext(runtime.getCamelContext()); builder.configure(); List routes = builder.getRouteCollection().getRoutes(); @@ -119,10 +142,38 @@ public void testLoaders(String location, Class type) thr static Stream parameters() { return Stream.of( - Arguments.arguments("classpath:MyRoutes.java", JavaSourceRoutesLoader.class), - Arguments.arguments("classpath:MyRoutesWithNameOverride.java?name=MyRoutes.java", JavaSourceRoutesLoader.class), - Arguments.arguments("classpath:MyRoutesWithPackage.java", JavaSourceRoutesLoader.class), - Arguments.arguments("classpath:MyRoutesWithEndpointDsl.java", JavaSourceRoutesLoader.class) + Arguments.arguments("classpath:MyRoutes.java", JavaSourceLoader.class), + Arguments.arguments("classpath:MyRoutesWithNameOverride.java?name=MyRoutes.java", JavaSourceLoader.class), + Arguments.arguments("classpath:MyRoutesWithPackage.java", JavaSourceLoader.class), + Arguments.arguments("classpath:MyRoutesWithEndpointDsl.java", JavaSourceLoader.class) ); } + + static class TestRuntime implements Runtime { + private final DefaultCamelContext camelContext; + private final List builders; + private final List configurations; + + public TestRuntime() { + this.camelContext = new DefaultCamelContext(); + this.builders = new ArrayList<>(); + this.configurations = new ArrayList<>(); + } + + @Override + public CamelContext getCamelContext() { + return this.camelContext; + } + + @Override + public void addRoutes(RoutesBuilder builder) { + this.builders.add(builder); + } + + @Override + public void addConfiguration(Object configuration) { + this.configurations.add(configuration); + } + } } + diff --git a/camel-k-loader-java/src/test/resources/MyRoutesConfig.java b/camel-k-loader-java/src/test/resources/MyRoutesConfig.java new file mode 100644 index 000000000..bf733e7a1 --- /dev/null +++ b/camel-k-loader-java/src/test/resources/MyRoutesConfig.java @@ -0,0 +1,33 @@ +/* + * 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. + */ +import org.apache.camel.BindToRegistry; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; + +public class MyRoutesConfig { + @BindToRegistry + public static MyProcessor myProcessor() { + return new MyProcessor(); + } + + public static class MyProcessor implements Processor { + @Override + public void process(Exchange exchange) throws Exception { + } + } +} \ No newline at end of file diff --git a/camel-k-loader-js/pom.xml b/camel-k-loader-js/pom.xml index ed8ad8cba..fa3f9c12c 100644 --- a/camel-k-loader-js/pom.xml +++ b/camel-k-loader-js/pom.xml @@ -48,6 +48,17 @@ ${graalvm.version} + + org.apache.camel.k + camel-k-apt + true + + + org.apache.camel.k + camel-k-annotations + true + + diff --git a/camel-k-loader-js/src/main/java/org/apache/camel/k/loader/js/JavaScriptRoutesLoader.java b/camel-k-loader-js/src/main/java/org/apache/camel/k/loader/js/JavaScriptSourceLoader.java similarity index 86% rename from camel-k-loader-js/src/main/java/org/apache/camel/k/loader/js/JavaScriptRoutesLoader.java rename to camel-k-loader-js/src/main/java/org/apache/camel/k/loader/js/JavaScriptSourceLoader.java index 9ed6119e8..371b589c1 100644 --- a/camel-k-loader-js/src/main/java/org/apache/camel/k/loader/js/JavaScriptRoutesLoader.java +++ b/camel-k-loader-js/src/main/java/org/apache/camel/k/loader/js/JavaScriptSourceLoader.java @@ -22,17 +22,20 @@ import java.util.List; import org.apache.camel.CamelContext; -import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.RoutesBuilder; import org.apache.camel.builder.endpoint.EndpointRouteBuilder; -import org.apache.camel.k.RoutesLoader; +import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; +import org.apache.camel.k.annotation.Loader; import org.apache.camel.k.loader.js.dsl.IntegrationConfiguration; import org.apache.camel.support.LifecycleStrategySupport; import org.apache.commons.io.IOUtils; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; -public class JavaScriptRoutesLoader implements RoutesLoader { +@Loader("js") +public class JavaScriptSourceLoader implements SourceLoader { private static final String LANGUAGE_ID = "js"; @Override @@ -41,8 +44,8 @@ public List getSupportedLanguages() { } @Override - public RouteBuilder load(CamelContext camelContext, Source source) throws Exception { - return new EndpointRouteBuilder() { + public void load(Runtime runtime, Source source) throws Exception { + RoutesBuilder builder = new EndpointRouteBuilder() { @Override public void configure() throws Exception { final Context context = Context.newBuilder("js").allowAllAccess(true).build(); @@ -70,5 +73,7 @@ public void onContextStop(CamelContext camelContext) { } } }; + + runtime.addRoutes(builder); } } diff --git a/camel-k-loader-js/src/main/resources/META-INF/services/org/apache/camel/k/loader/js b/camel-k-loader-js/src/main/resources/META-INF/services/org/apache/camel/k/loader/js deleted file mode 100644 index dc6af3bf4..000000000 --- a/camel-k-loader-js/src/main/resources/META-INF/services/org/apache/camel/k/loader/js +++ /dev/null @@ -1,18 +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. -# - -class=org.apache.camel.k.loader.js.JavaScriptRoutesLoader \ No newline at end of file diff --git a/camel-k-loader-js/src/test/java/org/apache/camel/k/loader/js/RoutesLoaderTest.java b/camel-k-loader-js/src/test/java/org/apache/camel/k/loader/js/RoutesLoaderTest.java index 012b9ee11..72e355dcd 100644 --- a/camel-k-loader-js/src/test/java/org/apache/camel/k/loader/js/RoutesLoaderTest.java +++ b/camel-k-loader-js/src/test/java/org/apache/camel/k/loader/js/RoutesLoaderTest.java @@ -16,13 +16,17 @@ */ package org.apache.camel.k.loader.js; +import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; +import org.apache.camel.CamelContext; +import org.apache.camel.RoutesBuilder; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.DefaultCamelContext; -import org.apache.camel.k.RoutesLoader; +import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; import org.apache.camel.k.Sources; import org.apache.camel.k.support.RuntimeSupport; import org.apache.camel.model.RouteDefinition; @@ -36,15 +40,19 @@ public class RoutesLoaderTest { @ParameterizedTest @MethodSource("parameters") - public void testLoaders(String location, Class type) throws Exception { + public void testLoaders(String location, Class type) throws Exception { + TestRuntime runtime = new TestRuntime(); Source source = Sources.fromURI(location); - RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source); - RouteBuilder builder = loader.load(new DefaultCamelContext(), source); + SourceLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source); + + loader.load(runtime, source); assertThat(loader).isInstanceOf(type); - assertThat(builder).isNotNull(); + assertThat(runtime.builders).hasSize(1); + assertThat(runtime.builders).first().isInstanceOf(RouteBuilder.class); - builder.setContext(new DefaultCamelContext()); + RouteBuilder builder = (RouteBuilder)runtime.builders.get(0); + builder.setContext(runtime.getCamelContext()); builder.configure(); List routes = builder.getRouteCollection().getRoutes(); @@ -55,10 +63,30 @@ public void testLoaders(String location, Class type) thr static Stream parameters() { return Stream.of( - Arguments.arguments("classpath:routes.js", JavaScriptRoutesLoader.class), - Arguments.arguments("classpath:routes-with-endpoint-dsl.js", JavaScriptRoutesLoader.class), - Arguments.arguments("classpath:routes-compressed.js.gz.b64?language=js&compression=true", JavaScriptRoutesLoader.class), - Arguments.arguments("classpath:routes.mytype?language=js", JavaScriptRoutesLoader.class) + Arguments.arguments("classpath:routes.js", JavaScriptSourceLoader.class), + Arguments.arguments("classpath:routes-with-endpoint-dsl.js", JavaScriptSourceLoader.class), + Arguments.arguments("classpath:routes-compressed.js.gz.b64?language=js&compression=true", JavaScriptSourceLoader.class), + Arguments.arguments("classpath:routes.mytype?language=js", JavaScriptSourceLoader.class) ); } + + static class TestRuntime implements Runtime { + private final CamelContext camelContext; + private final List builders; + + public TestRuntime() { + this.camelContext = new DefaultCamelContext(); + this.builders = new ArrayList<>(); + } + + @Override + public CamelContext getCamelContext() { + return this.camelContext; + } + + @Override + public void addRoutes(RoutesBuilder builder) { + this.builders.add(builder); + } + } } diff --git a/camel-k-loader-knative/pom.xml b/camel-k-loader-knative/pom.xml index 1f0cf4e74..0a4d9eaf4 100644 --- a/camel-k-loader-knative/pom.xml +++ b/camel-k-loader-knative/pom.xml @@ -38,6 +38,17 @@ provided + + org.apache.camel.k + camel-k-apt + true + + + org.apache.camel.k + camel-k-annotations + true + + diff --git a/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceLoader.java b/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceLoader.java new file mode 100644 index 000000000..c5b11b8f0 --- /dev/null +++ b/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceLoader.java @@ -0,0 +1,143 @@ +/* + * 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.k.loader.knative; + +import java.util.Arrays; +import java.util.List; + +import org.apache.camel.CamelContext; +import org.apache.camel.ExtendedCamelContext; +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.k.Runtime; +import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; +import org.apache.camel.k.annotation.Loader; +import org.apache.camel.k.support.RuntimeSupport; +import org.apache.camel.model.RouteDefinition; +import org.apache.camel.model.ToDefinition; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Loader({ + "knative-source", + "knative-source-groovy", + "knative-source-java", + "knative-source-js", + "knative-source-kts", + "knative-source-xml", + "knative-source-yaml", +}) +public class KnativeSourceLoader implements SourceLoader { + private static final Logger LOGGER = LoggerFactory.getLogger(KnativeSourceLoader.class); + private static final String LOADER_ID = "knative-source"; + private static final String LANGUAGE_PREFIX = LOADER_ID + "-"; + + @Override + public List getSupportedLanguages() { + return Arrays.asList(LANGUAGE_PREFIX + "yaml"); + } + + @Override + public void load(Runtime runtime, Source source) throws Exception { + if (LOADER_ID.equals(source.getLanguage())) { + throw new IllegalArgumentException("Cannot load source of type " + source.getLanguage()); + } + + String languageId = source.getLanguage(); + if (languageId.startsWith(LANGUAGE_PREFIX)) { + languageId = languageId.substring(LANGUAGE_PREFIX.length()); + } + + final CamelContext camelContext = runtime.getCamelContext(); + final SourceLoader loader = RuntimeSupport.lookupLoaderByLanguage(camelContext, languageId); + + loader.load(new RuntimeWrapper(runtime), source); + } + + private static class RuntimeWrapper implements Runtime { + private final Runtime runtime; + + RuntimeWrapper(Runtime runtime) { + this.runtime = runtime; + } + + @Override + public CamelContext getCamelContext() { + return runtime.getCamelContext(); + } + + @Override + public void addRoutes(RoutesBuilder builder) { + if (builder instanceof RouteBuilder) { + runtime.addRoutes(new RouteBuilderWrapper((RouteBuilder)builder)); + } else { + runtime.addRoutes(builder); + } + } + } + + private static class RouteBuilderWrapper extends RouteBuilder { + private final RouteBuilder builder; + + RouteBuilderWrapper(RouteBuilder builder) { + this.builder = builder; + } + + @Override + public void setContext(CamelContext context) { + builder.setContext(context); + } + + @Override + public void configure() throws Exception { + } + + @Override + public void addRoutesToCamelContext(CamelContext context) throws Exception { + //TODO: this is a little hack as then configureRoutes will + // be invoked twice: 1 by this hack and 1 by delegated + // builder. Maybe, we should add builder lifecycle events. + List definitions = builder.configureRoutes(context).getRoutes(); + + if (definitions.size() == 1) { + final String sink = context.resolvePropertyPlaceholders("{{env:KNATIVE_SINK:sink}}"); + final String uri = String.format("knative://endpoint/%s", sink); + final RouteDefinition definition = definitions.get(0); + + LOGGER.info("Add sink:{} to route:{}", uri, definition.getId()); + + // assuming that route is linear like there's no content based routing + // or ant other EIP that would branch the flow + definition.getOutputs().add(new ToDefinition(uri)); + } else { + LOGGER.warn("Cannot determine route to enrich. the knative enpoint need to explicitly be defined"); + } + + //TODO: this is needed for java language because by default + // camel main inspects route builders to detect beans + // to be registered to the camel registry but as the + // original builder is masked by this wrapping builder, + // beans can't be automatically discovered + context.adapt(ExtendedCamelContext.class) + .getBeanPostProcessor() + .postProcessBeforeInitialization(builder, builder.getClass().getName()); + + builder.addRoutesToCamelContext(context); + } + } +} diff --git a/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoader.java b/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoader.java deleted file mode 100644 index be67dc93c..000000000 --- a/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoader.java +++ /dev/null @@ -1,101 +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.k.loader.knative; - -import java.util.Arrays; -import java.util.List; - -import org.apache.camel.CamelContext; -import org.apache.camel.ExtendedCamelContext; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.k.RoutesLoader; -import org.apache.camel.k.Source; -import org.apache.camel.k.support.RuntimeSupport; -import org.apache.camel.model.RouteDefinition; -import org.apache.camel.model.ToDefinition; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class KnativeSourceRoutesLoader implements RoutesLoader { - private static final Logger LOGGER = LoggerFactory.getLogger(KnativeSourceRoutesLoader.class); - private static final String LOADER_ID = "knative-source"; - private static final String LANGUAGE_PREFIX = LOADER_ID + "-"; - - @Override - public List getSupportedLanguages() { - return Arrays.asList(LANGUAGE_PREFIX + "yaml"); - } - - @Override - public RouteBuilder load(CamelContext camelContext, Source source) throws Exception { - if (LOADER_ID.equals(source.getLanguage())) { - throw new IllegalArgumentException("Cannot load source of type " + source.getLanguage()); - } - - String languageId = source.getLanguage(); - if (languageId.startsWith(LANGUAGE_PREFIX)) { - languageId = languageId.substring(LANGUAGE_PREFIX.length()); - } - - final RoutesLoader loader = RuntimeSupport.lookupLoaderByLanguage(camelContext, languageId); - final RouteBuilder builder = loader.load(camelContext, source); - - return new RouteBuilder() { - @Override - public void setContext(CamelContext context) { - builder.setContext(context); - } - - @Override - public void configure() throws Exception { - } - - @Override - public void addRoutesToCamelContext(CamelContext context) throws Exception { - //TODO: this is a little hack as then configureRoutes will - // be invoked twice: 1 by this hack and 1 by delegated - // builder. Maybe, we should add builder lifecycle events. - List definitions = builder.configureRoutes(context).getRoutes(); - - if (definitions.size() == 1) { - final String sink = context.resolvePropertyPlaceholders("{{env:KNATIVE_SINK:sink}}"); - final String uri = String.format("knative://endpoint/%s", sink); - final RouteDefinition definition = definitions.get(0); - - LOGGER.info("Add sink:{} to route:{}", uri, definition.getId()); - - // assuming that route is linear like there's no content based routing - // or ant other EIP that would branch the flow - definition.getOutputs().add(new ToDefinition(uri)); - } else { - LOGGER.warn("Cannot determine route to enrich. the knative enpoint need to explicitly be defined"); - } - - //TODO: this is needed for java language because by default - // camel main inspects route builders to detect beans - // to be registered to the camel registry but as the - // original builder is masked by this wrapping builder, - // beans can't be automatically discovered - context.adapt(ExtendedCamelContext.class) - .getBeanPostProcessor() - .postProcessBeforeInitialization(builder, builder.getClass().getName()); - - builder.addRoutesToCamelContext(context); - } - }; - } -} diff --git a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source deleted file mode 100644 index 6245d3401..000000000 --- a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source +++ /dev/null @@ -1,18 +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. -# - -class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader \ No newline at end of file diff --git a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-groovy b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-groovy deleted file mode 100644 index 6245d3401..000000000 --- a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-groovy +++ /dev/null @@ -1,18 +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. -# - -class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader \ No newline at end of file diff --git a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-java b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-java deleted file mode 100644 index 6245d3401..000000000 --- a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-java +++ /dev/null @@ -1,18 +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. -# - -class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader \ No newline at end of file diff --git a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-js b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-js deleted file mode 100644 index 6245d3401..000000000 --- a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-js +++ /dev/null @@ -1,18 +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. -# - -class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader \ No newline at end of file diff --git a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-kts b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-kts deleted file mode 100644 index 6245d3401..000000000 --- a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-kts +++ /dev/null @@ -1,18 +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. -# - -class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader \ No newline at end of file diff --git a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-xml b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-xml deleted file mode 100644 index 6245d3401..000000000 --- a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-xml +++ /dev/null @@ -1,18 +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. -# - -class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader \ No newline at end of file diff --git a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-yaml b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-yaml deleted file mode 100644 index 6245d3401..000000000 --- a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-yaml +++ /dev/null @@ -1,18 +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. -# - -class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader \ No newline at end of file diff --git a/camel-k-loader-knative/src/test/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoaderTest.java b/camel-k-loader-knative/src/test/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoaderTest.java index bde067b57..1e615fcf2 100644 --- a/camel-k-loader-knative/src/test/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoaderTest.java +++ b/camel-k-loader-knative/src/test/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoaderTest.java @@ -16,19 +16,22 @@ */ package org.apache.camel.k.loader.knative; +import java.util.ArrayList; import java.util.List; import java.util.UUID; import java.util.stream.Stream; import org.apache.camel.CamelContext; +import org.apache.camel.RoutesBuilder; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.knative.KnativeComponent; import org.apache.camel.component.knative.spi.Knative; import org.apache.camel.component.knative.spi.KnativeEnvironment; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.impl.DefaultCamelContext; -import org.apache.camel.k.RoutesLoader; +import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; import org.apache.camel.k.Sources; import org.apache.camel.k.support.RuntimeSupport; import org.apache.camel.model.ModelCamelContext; @@ -76,20 +79,23 @@ public void testWrapLoader(String uri) throws Exception { KnativeEnvironment.endpoint(Knative.EndpointKind.sink, "sink", "localhost", port) )); - CamelContext context = new DefaultCamelContext(); + TestRuntime runtime = new TestRuntime(); + + CamelContext context = runtime.getCamelContext(); context.disableJMX(); context.setStreamCaching(true); context.addComponent("knative", component); Source source = Sources.fromURI(uri); - RoutesLoader loader = RuntimeSupport.loaderFor(context, source); - RouteBuilder builder = loader.load(context, source); + SourceLoader loader = RuntimeSupport.loaderFor(context, source); + + loader.load(runtime, source); - assertThat(loader).isInstanceOf(KnativeSourceRoutesLoader.class); - assertThat(builder).isNotNull(); + assertThat(loader).isInstanceOf(KnativeSourceLoader.class); + assertThat(runtime.builders).hasSize(1); try { - context.addRoutes(builder); + context.addRoutes(runtime.builders.get(0)); context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { @@ -135,20 +141,23 @@ public void testWrapLoaderWithBeanRegistration() throws Exception { KnativeEnvironment.endpoint(Knative.EndpointKind.source, "sink", "localhost", port) )); - CamelContext context = new DefaultCamelContext(); + TestRuntime runtime = new TestRuntime(); + + CamelContext context = runtime.getCamelContext(); context.disableJMX(); context.setStreamCaching(true); context.addComponent("knative", component); Source source = Sources.fromURI("classpath:routes.java?name=MyRoutes.java&loader=knative-source"); - RoutesLoader loader = RuntimeSupport.loaderFor(context, source); - RouteBuilder builder = loader.load(context, source); + SourceLoader loader = RuntimeSupport.loaderFor(context, source); - assertThat(loader).isInstanceOf(KnativeSourceRoutesLoader.class); - assertThat(builder).isNotNull(); + loader.load(runtime, source); + + assertThat(loader).isInstanceOf(KnativeSourceLoader.class); + assertThat(runtime.builders).hasSize(1); try { - context.addRoutes(builder); + context.addRoutes(runtime.builders.get(0)); context.start(); assertThat(context.getRegistry().lookupByName("my-bean")).isInstanceOfSatisfying(String.class, "my-bean-string"::equals); @@ -156,4 +165,24 @@ public void testWrapLoaderWithBeanRegistration() throws Exception { context.stop(); } } + + static class TestRuntime implements Runtime { + private final CamelContext camelContext; + private final List builders; + + public TestRuntime() { + this.camelContext = new DefaultCamelContext(); + this.builders = new ArrayList<>(); + } + + @Override + public CamelContext getCamelContext() { + return this.camelContext; + } + + @Override + public void addRoutes(RoutesBuilder builder) { + this.builders.add(builder); + } + } } diff --git a/camel-k-loader-kotlin/pom.xml b/camel-k-loader-kotlin/pom.xml index 028dbde9d..f518f49ca 100644 --- a/camel-k-loader-kotlin/pom.xml +++ b/camel-k-loader-kotlin/pom.xml @@ -73,6 +73,12 @@ ${kotlin.version} + + org.apache.camel.k + camel-k-annotations + true + + @@ -156,8 +162,6 @@ - ${project.basedir}/src/main/kotlin - ${project.basedir}/src/test/kotlin kotlin-maven-plugin @@ -167,17 +171,45 @@ ${maven.compiler.target} + + kapt + + kapt + + + + src/main/kotlin + + + + org.apache.camel.k + camel-k-apt + ${project.version} + + + + compile compile + + + src/main/kotlin + + test-compile test-compile + + + src/test/kotlin + + diff --git a/camel-k-loader-kotlin/src/main/kotlin/org/apache/camel/k/loader/kotlin/KotlinRoutesLoader.kt b/camel-k-loader-kotlin/src/main/kotlin/org/apache/camel/k/loader/kotlin/KotlinSourceLoader.kt similarity index 87% rename from camel-k-loader-kotlin/src/main/kotlin/org/apache/camel/k/loader/kotlin/KotlinRoutesLoader.kt rename to camel-k-loader-kotlin/src/main/kotlin/org/apache/camel/k/loader/kotlin/KotlinSourceLoader.kt index 90d3aa497..6fa851876 100644 --- a/camel-k-loader-kotlin/src/main/kotlin/org/apache/camel/k/loader/kotlin/KotlinRoutesLoader.kt +++ b/camel-k-loader-kotlin/src/main/kotlin/org/apache/camel/k/loader/kotlin/KotlinSourceLoader.kt @@ -16,10 +16,11 @@ */ package org.apache.camel.k.loader.kotlin -import org.apache.camel.CamelContext import org.apache.camel.builder.endpoint.EndpointRouteBuilder -import org.apache.camel.k.RoutesLoader +import org.apache.camel.k.Runtime import org.apache.camel.k.Source +import org.apache.camel.k.SourceLoader +import org.apache.camel.k.annotation.Loader import org.apache.camel.k.loader.kotlin.dsl.IntegrationConfiguration import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -33,9 +34,10 @@ import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost import kotlin.script.experimental.jvmhost.JvmScriptCompiler import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate -class KotlinRoutesLoader : RoutesLoader { +@Loader("kts") +class KotlinSourceLoader : SourceLoader { companion object { - val LOGGER : Logger = LoggerFactory.getLogger(KotlinRoutesLoader::class.java) + val LOGGER : Logger = LoggerFactory.getLogger(KotlinSourceLoader::class.java) } override fun getSupportedLanguages(): List { @@ -43,8 +45,8 @@ class KotlinRoutesLoader : RoutesLoader { } @Throws(Exception::class) - override fun load(camelContext: CamelContext, source: Source): EndpointRouteBuilder? { - return object : EndpointRouteBuilder() { + override fun load(runtime: Runtime, source: Source) { + var builder = object : EndpointRouteBuilder() { @Throws(Exception::class) override fun configure() { val builder = this @@ -52,6 +54,7 @@ class KotlinRoutesLoader : RoutesLoader { val evaluator = BasicJvmScriptEvaluator() val host = BasicJvmScriptingHost(compiler = compiler, evaluator = evaluator) val config = createJvmCompilationConfigurationFromTemplate() + val camelContext = runtime.camelContext source.resolveAsInputStream(camelContext).use { `is` -> val result = host.eval( @@ -75,5 +78,7 @@ class KotlinRoutesLoader : RoutesLoader { } } } + + runtime.addRoutes(builder) } } diff --git a/camel-k-loader-kotlin/src/main/resources/META-INF/services/org/apache/camel/k/loader/kts b/camel-k-loader-kotlin/src/main/resources/META-INF/services/org/apache/camel/k/loader/kts deleted file mode 100644 index 48b587d92..000000000 --- a/camel-k-loader-kotlin/src/main/resources/META-INF/services/org/apache/camel/k/loader/kts +++ /dev/null @@ -1,18 +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. -# - -class=org.apache.camel.k.loader.kotlin.KotlinRoutesLoader \ No newline at end of file diff --git a/camel-k-loader-kotlin/src/test/kotlin/org/apache/camel/k/loader/kotlin/LoaderTest.kt b/camel-k-loader-kotlin/src/test/kotlin/org/apache/camel/k/loader/kotlin/LoaderTest.kt index 00387ee2e..567a3d811 100644 --- a/camel-k-loader-kotlin/src/test/kotlin/org/apache/camel/k/loader/kotlin/LoaderTest.kt +++ b/camel-k-loader-kotlin/src/test/kotlin/org/apache/camel/k/loader/kotlin/LoaderTest.kt @@ -16,27 +16,35 @@ */ package org.apache.camel.k.loader.kotlin +import org.apache.camel.CamelContext +import org.apache.camel.RoutesBuilder +import org.apache.camel.builder.RouteBuilder import org.apache.camel.impl.DefaultCamelContext +import org.apache.camel.k.Runtime import org.apache.camel.k.Sources import org.apache.camel.k.support.RuntimeSupport import org.apache.camel.model.ProcessDefinition import org.apache.camel.model.ToDefinition import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test +import java.util.* class LoaderTest { @Test fun `load routes`() { - var context = DefaultCamelContext() + var runtime = TestRuntime() var source = Sources.fromURI("classpath:routes.kts") - val loader = RuntimeSupport.loaderFor(context, source) - val builder = loader.load(context, source) + val loader = RuntimeSupport.loaderFor(runtime.camelContext, source) - assertThat(loader).isInstanceOf(KotlinRoutesLoader::class.java) - assertThat(builder).isNotNull + loader.load(runtime, source) - builder.context = context + assertThat(loader).isInstanceOf(KotlinSourceLoader::class.java) + assertThat(runtime.builders).hasSize(1) + assertThat(runtime.builders[0]).isInstanceOf(RouteBuilder::class.java) + + var builder = runtime.builders[0] as RouteBuilder + builder.context = runtime.camelContext builder.configure() val routes = builder.routeCollection.routes @@ -48,15 +56,18 @@ class LoaderTest { @Test fun `load routes with endpoint dsl`() { - var context = DefaultCamelContext() + var runtime = TestRuntime() var source = Sources.fromURI("classpath:routes-with-endpoint-dsl.kts") - val loader = RuntimeSupport.loaderFor(context, source) - val builder = loader.load(context, source) + val loader = RuntimeSupport.loaderFor(runtime.camelContext, source) + + loader.load(runtime, source) - assertThat(loader).isInstanceOf(KotlinRoutesLoader::class.java) - assertThat(builder).isNotNull + assertThat(loader).isInstanceOf(KotlinSourceLoader::class.java) + assertThat(runtime.builders).hasSize(1) + assertThat(runtime.builders[0]).isInstanceOf(RouteBuilder::class.java) - builder.context = context + var builder = runtime.builders[0] as RouteBuilder + builder.context = runtime.camelContext builder.configure() val routes = builder.routeCollection.routes @@ -65,6 +76,23 @@ class LoaderTest { assertThat(routes[0].outputs[0]).isInstanceOfSatisfying(ToDefinition::class.java) { assertThat(it.endpointUri).isEqualTo("log:info") } + } + internal class TestRuntime : Runtime { + private val context: CamelContext + val builders: MutableList + + init { + this.context = DefaultCamelContext() + this.builders = ArrayList() + } + + override fun getCamelContext(): CamelContext { + return this.context + } + + override fun addRoutes(builder: RoutesBuilder) { + this.builders.add(builder) + } } } diff --git a/camel-k-loader-xml/pom.xml b/camel-k-loader-xml/pom.xml index 322f5fcff..094d6cc97 100644 --- a/camel-k-loader-xml/pom.xml +++ b/camel-k-loader-xml/pom.xml @@ -46,6 +46,17 @@ provided + + org.apache.camel.k + camel-k-apt + true + + + org.apache.camel.k + camel-k-annotations + true + + diff --git a/camel-k-loader-xml/src/main/java/org/apache/camel/k/loader/xml/XmlRoutesLoader.java b/camel-k-loader-xml/src/main/java/org/apache/camel/k/loader/xml/XmlSourceLoader.java similarity index 88% rename from camel-k-loader-xml/src/main/java/org/apache/camel/k/loader/xml/XmlRoutesLoader.java rename to camel-k-loader-xml/src/main/java/org/apache/camel/k/loader/xml/XmlSourceLoader.java index f981075a3..2da6fe64f 100644 --- a/camel-k-loader-xml/src/main/java/org/apache/camel/k/loader/xml/XmlRoutesLoader.java +++ b/camel-k-loader-xml/src/main/java/org/apache/camel/k/loader/xml/XmlSourceLoader.java @@ -21,18 +21,20 @@ import java.util.List; import javax.xml.bind.UnmarshalException; -import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.k.RoutesLoader; +import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; +import org.apache.camel.k.annotation.Loader; import org.apache.camel.model.ModelHelper; import org.apache.camel.model.RoutesDefinition; import org.apache.camel.model.rest.RestsDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class XmlRoutesLoader implements RoutesLoader { - private static final Logger LOGGER = LoggerFactory.getLogger(XmlRoutesLoader.class); +@Loader("xml") +public class XmlSourceLoader implements SourceLoader { + private static final Logger LOGGER = LoggerFactory.getLogger(XmlSourceLoader.class); @Override public List getSupportedLanguages() { @@ -40,8 +42,8 @@ public List getSupportedLanguages() { } @Override - public RouteBuilder load(CamelContext camelContext, Source source) throws Exception { - return new RouteBuilder() { + public void load(Runtime runtime, Source source) throws Exception { + RouteBuilder builder = new RouteBuilder() { @Override public void configure() throws Exception { try (InputStream is = source.resolveAsInputStream(getContext())) { @@ -71,5 +73,7 @@ public void configure() throws Exception { } } }; + + runtime.addRoutes(builder); } } diff --git a/camel-k-loader-xml/src/main/resources/META-INF/services/org/apache/camel/k/loader/xml b/camel-k-loader-xml/src/main/resources/META-INF/services/org/apache/camel/k/loader/xml deleted file mode 100644 index 5670bf105..000000000 --- a/camel-k-loader-xml/src/main/resources/META-INF/services/org/apache/camel/k/loader/xml +++ /dev/null @@ -1,18 +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. -# - -class=org.apache.camel.k.loader.xml.XmlRoutesLoader \ No newline at end of file diff --git a/camel-k-loader-xml/src/test/java/org/apache/camel/k/loader/xml/RoutesLoaderTest.java b/camel-k-loader-xml/src/test/java/org/apache/camel/k/loader/xml/RoutesLoaderTest.java index 541a8b2e9..5af5d963d 100644 --- a/camel-k-loader-xml/src/test/java/org/apache/camel/k/loader/xml/RoutesLoaderTest.java +++ b/camel-k-loader-xml/src/test/java/org/apache/camel/k/loader/xml/RoutesLoaderTest.java @@ -16,13 +16,17 @@ */ package org.apache.camel.k.loader.xml; +import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; +import org.apache.camel.CamelContext; +import org.apache.camel.RoutesBuilder; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.DefaultCamelContext; -import org.apache.camel.k.RoutesLoader; +import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; import org.apache.camel.k.Sources; import org.apache.camel.k.support.RuntimeSupport; import org.apache.camel.model.RouteDefinition; @@ -36,15 +40,19 @@ public class RoutesLoaderTest { @ParameterizedTest @MethodSource("parameters") - public void testLoaders(String location, Class type) throws Exception { + public void testLoaders(String location, Class type) throws Exception { + TestRuntime runtime = new TestRuntime(); Source source = Sources.fromURI(location); - RoutesLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source); - RouteBuilder builder = loader.load(new DefaultCamelContext(), source); + SourceLoader loader = RuntimeSupport.loaderFor(new DefaultCamelContext(), source); + + loader.load(runtime, source); assertThat(loader).isInstanceOf(type); - assertThat(builder).isNotNull(); + assertThat(runtime.builders).hasSize(1); + assertThat(runtime.builders).first().isInstanceOf(RouteBuilder.class); - builder.setContext(new DefaultCamelContext()); + RouteBuilder builder = (RouteBuilder)runtime.builders.get(0); + builder.setContext(runtime.getCamelContext()); builder.configure(); List routes = builder.getRouteCollection().getRoutes(); @@ -55,7 +63,27 @@ public void testLoaders(String location, Class type) thr static Stream parameters() { return Stream.of( - Arguments.arguments("classpath:routes.xml", XmlRoutesLoader.class) + Arguments.arguments("classpath:routes.xml", XmlSourceLoader.class) ); } + + static class TestRuntime implements Runtime { + private final CamelContext camelContext; + private final List builders; + + public TestRuntime() { + this.camelContext = new DefaultCamelContext(); + this.builders = new ArrayList<>(); + } + + @Override + public CamelContext getCamelContext() { + return this.camelContext; + } + + @Override + public void addRoutes(RoutesBuilder builder) { + this.builders.add(builder); + } + } } diff --git a/camel-k-loader-yaml/pom.xml b/camel-k-loader-yaml/pom.xml index 11631a834..9a6016dd3 100644 --- a/camel-k-loader-yaml/pom.xml +++ b/camel-k-loader-yaml/pom.xml @@ -60,7 +60,6 @@ camel-k-apt true - org.apache.camel.k camel-k-annotations diff --git a/camel-k-loader-yaml/src/main/java/org/apache/camel/k/loader/yaml/YamlRoutesLoader.java b/camel-k-loader-yaml/src/main/java/org/apache/camel/k/loader/yaml/YamlSourceLoader.java similarity index 93% rename from camel-k-loader-yaml/src/main/java/org/apache/camel/k/loader/yaml/YamlRoutesLoader.java rename to camel-k-loader-yaml/src/main/java/org/apache/camel/k/loader/yaml/YamlSourceLoader.java index 45d5801dc..5b1582837 100644 --- a/camel-k-loader-yaml/src/main/java/org/apache/camel/k/loader/yaml/YamlRoutesLoader.java +++ b/camel-k-loader-yaml/src/main/java/org/apache/camel/k/loader/yaml/YamlSourceLoader.java @@ -31,8 +31,9 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.k.RoutesLoader; +import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; import org.apache.camel.k.annotation.Loader; import org.apache.camel.k.loader.yaml.model.Step; import org.apache.camel.k.loader.yaml.parser.StartStepParser; @@ -46,10 +47,10 @@ @Loader("yaml") -public class YamlRoutesLoader implements RoutesLoader { +public class YamlSourceLoader implements SourceLoader { private final ObjectMapper mapper; - public YamlRoutesLoader() { + public YamlSourceLoader() { YAMLFactory yamlFactory = new YAMLFactory() .configure(YAMLGenerator.Feature.MINIMIZE_QUOTES, true) .configure(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID, false); @@ -71,8 +72,10 @@ public List getSupportedLanguages() { } @Override - public RouteBuilder load(CamelContext camelContext, Source source) throws Exception { - return builder(source.resolveAsInputStream(camelContext)); + public void load(Runtime runtime, Source source) throws Exception { + runtime.addRoutes( + builder(source.resolveAsInputStream(runtime.getCamelContext())) + ); } final ObjectMapper mapper() { diff --git a/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/RouteDefinitionTest.groovy b/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/RouteDefinitionTest.groovy index 534992abe..b63d4baa8 100644 --- a/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/RouteDefinitionTest.groovy +++ b/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/RouteDefinitionTest.groovy @@ -45,7 +45,7 @@ class RouteDefinitionTest extends TestSupport { def camelContext = new DefaultCamelContext() def istream = IOUtils.toInputStream(content, StandardCharsets.UTF_8) when: - camelContext.addRoutes(new YamlRoutesLoader().builder(istream)) + camelContext.addRoutes(new YamlSourceLoader().builder(istream)) then: camelContext.routeDefinitions[0].id == 'my-route-id' camelContext.routeDefinitions[0].group == 'my-route-group' @@ -84,7 +84,7 @@ class RouteDefinitionTest extends TestSupport { def camelContext = new DefaultCamelContext() def istream = IOUtils.toInputStream(content, StandardCharsets.UTF_8) when: - camelContext.addRoutes(new YamlRoutesLoader().builder(istream)) + camelContext.addRoutes(new YamlSourceLoader().builder(istream)) then: camelContext.routeDefinitions[0].input.endpointUri == 'direct:start' @@ -130,7 +130,7 @@ class RouteDefinitionTest extends TestSupport { def camelContext = new DefaultCamelContext() def istream = IOUtils.toInputStream(content, StandardCharsets.UTF_8) when: - camelContext.addRoutes(new YamlRoutesLoader().builder(istream)) + camelContext.addRoutes(new YamlSourceLoader().builder(istream)) then: camelContext.routeDefinitions[0].input.endpointUri == 'direct:start' camelContext.routeDefinitions[0].outputs.size() == 2 @@ -169,7 +169,7 @@ class RouteDefinitionTest extends TestSupport { def camelContext = new DefaultCamelContext() def istream = IOUtils.toInputStream(content, StandardCharsets.UTF_8) when: - camelContext.addRoutes(new YamlRoutesLoader().builder(istream)) + camelContext.addRoutes(new YamlSourceLoader().builder(istream)) then: camelContext.routeDefinitions[0].input.endpointUri == 'direct:start' camelContext.routeDefinitions[0].outputs.size() == 1 @@ -204,7 +204,7 @@ class RouteDefinitionTest extends TestSupport { def camelContext = new DefaultCamelContext() def istream = IOUtils.toInputStream(content, StandardCharsets.UTF_8) when: - camelContext.addRoutes(new YamlRoutesLoader().builder(istream)) + camelContext.addRoutes(new YamlSourceLoader().builder(istream)) then: camelContext.routeDefinitions[0].input.endpointUri == 'direct:start' camelContext.routeDefinitions[0].outputs.size() == 2 @@ -243,7 +243,7 @@ class RouteDefinitionTest extends TestSupport { def camelContext = new DefaultCamelContext() def istream = IOUtils.toInputStream(content, StandardCharsets.UTF_8) when: - camelContext.addRoutes(new YamlRoutesLoader().builder(istream)) + camelContext.addRoutes(new YamlSourceLoader().builder(istream)) then: camelContext.routeDefinitions[0].input.endpointUri == 'direct:start' camelContext.routeDefinitions[0].outputs.size() == 1 diff --git a/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/TestSupport.groovy b/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/TestSupport.groovy index 776c5502e..400c59f5b 100644 --- a/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/TestSupport.groovy +++ b/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/TestSupport.groovy @@ -29,7 +29,7 @@ import java.nio.charset.StandardCharsets @Slf4j class TestSupport extends Specification { - static def MAPPER = new YamlRoutesLoader().mapper() + static def MAPPER = new YamlSourceLoader().mapper() static StepParser.Context stepContext(String content) { def node = MAPPER.readTree(content.stripMargin()) @@ -45,7 +45,7 @@ class TestSupport extends Specification { static CamelContext startContext(String content) { def context = new DefaultCamelContext() def istream = IOUtils.toInputStream(content.stripMargin(), StandardCharsets.UTF_8) - def builder = new YamlRoutesLoader().builder(istream) + def builder = new YamlSourceLoader().builder(istream) context.disableJMX() context.setStreamCaching(true) diff --git a/camel-k-quarkus/camel-k-quarkus-core/runtime/src/main/java/org/apache/camel/k/core/quarkus/RuntimeListenerAdapter.java b/camel-k-quarkus/camel-k-quarkus-core/runtime/src/main/java/org/apache/camel/k/core/quarkus/RuntimeListenerAdapter.java index 2ca4f0996..cd940322c 100644 --- a/camel-k-quarkus/camel-k-quarkus-core/runtime/src/main/java/org/apache/camel/k/core/quarkus/RuntimeListenerAdapter.java +++ b/camel-k-quarkus/camel-k-quarkus-core/runtime/src/main/java/org/apache/camel/k/core/quarkus/RuntimeListenerAdapter.java @@ -17,7 +17,6 @@ package org.apache.camel.k.core.quarkus; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -43,10 +42,6 @@ public void setListeners(List listeners) { this.listeners.addAll(listeners); } - public List getListeners() { - return Collections.unmodifiableList(listeners); - } - @Override public void beforeStart(BaseMainSupport main) { invokeListeners(listeners, on(main), Runtime.Phase.Starting); @@ -104,6 +99,11 @@ public CamelContext getCamelContext() { public void addRoutes(RoutesBuilder builder) { main.addRoutesBuilder(builder); } + + @Override + public void addConfiguration(Object configuration) { + main.addConfiguration(configuration); + } }; } } diff --git a/camel-k-quarkus/camel-k-quarkus-loader-js/it/src/main/java/org/apache/camel/k/loader/js/quarkus/deployment/Application.java b/camel-k-quarkus/camel-k-quarkus-loader-js/it/src/main/java/org/apache/camel/k/loader/js/quarkus/deployment/Application.java index 076bb89fa..88150d519 100644 --- a/camel-k-quarkus/camel-k-quarkus-loader-js/it/src/main/java/org/apache/camel/k/loader/js/quarkus/deployment/Application.java +++ b/camel-k-quarkus/camel-k-quarkus-loader-js/it/src/main/java/org/apache/camel/k/loader/js/quarkus/deployment/Application.java @@ -30,11 +30,11 @@ import org.apache.camel.CamelContext; import org.apache.camel.Consume; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.k.RoutesLoader; +import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; import org.apache.camel.k.Sources; -import org.apache.camel.k.loader.js.JavaScriptRoutesLoader; +import org.apache.camel.k.loader.js.JavaScriptSourceLoader; @Path("/test") @ApplicationScoped @@ -48,10 +48,9 @@ public class Application { @Produces(MediaType.APPLICATION_JSON) public JsonObject loadRoutes(@PathParam("name") String name, String code) throws Exception { final Source source = Sources.fromBytes(name, "js", null, code.getBytes(StandardCharsets.UTF_8)); - final RoutesLoader loader = new JavaScriptRoutesLoader(); - final RouteBuilder routes = loader.load(context, source); + final SourceLoader loader = new JavaScriptSourceLoader(); - context.addRoutes(routes); + loader.load(Runtime.on(context), source); return Json.createObjectBuilder() .add("components", extractComponents()) diff --git a/camel-k-quarkus/camel-k-quarkus-loader-xml/it/src/main/java/org/apache/camel/k/loader/xml/quarkus/deployment/Application.java b/camel-k-quarkus/camel-k-quarkus-loader-xml/it/src/main/java/org/apache/camel/k/loader/xml/quarkus/deployment/Application.java index 4a89fbda8..b5d9bfa77 100644 --- a/camel-k-quarkus/camel-k-quarkus-loader-xml/it/src/main/java/org/apache/camel/k/loader/xml/quarkus/deployment/Application.java +++ b/camel-k-quarkus/camel-k-quarkus-loader-xml/it/src/main/java/org/apache/camel/k/loader/xml/quarkus/deployment/Application.java @@ -30,11 +30,11 @@ import org.apache.camel.CamelContext; import org.apache.camel.Consume; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.k.RoutesLoader; +import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; import org.apache.camel.k.Sources; -import org.apache.camel.k.loader.xml.XmlRoutesLoader; +import org.apache.camel.k.loader.xml.XmlSourceLoader; @Path("/test") @ApplicationScoped @@ -48,10 +48,9 @@ public class Application { @Produces(MediaType.APPLICATION_JSON) public JsonObject loadRoutes(@PathParam("name") String name, String code) throws Exception { final Source source = Sources.fromBytes(name, "xml", null, code.getBytes(StandardCharsets.UTF_8)); - final RoutesLoader loader = new XmlRoutesLoader(); - final RouteBuilder routes = loader.load(context, source); + final SourceLoader loader = new XmlSourceLoader(); - context.addRoutes(routes); + loader.load(Runtime.on(context), source); return Json.createObjectBuilder() .add("components", extractComponents()) diff --git a/camel-k-quarkus/camel-k-quarkus-loader-yaml/it/src/main/java/org/apache/camel/k/loader/yaml/quarkus/deployment/Application.java b/camel-k-quarkus/camel-k-quarkus-loader-yaml/it/src/main/java/org/apache/camel/k/loader/yaml/quarkus/deployment/Application.java index c2eab1e9a..93d0d446d 100644 --- a/camel-k-quarkus/camel-k-quarkus-loader-yaml/it/src/main/java/org/apache/camel/k/loader/yaml/quarkus/deployment/Application.java +++ b/camel-k-quarkus/camel-k-quarkus-loader-yaml/it/src/main/java/org/apache/camel/k/loader/yaml/quarkus/deployment/Application.java @@ -30,11 +30,11 @@ import org.apache.camel.CamelContext; import org.apache.camel.Consume; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.k.RoutesLoader; +import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; import org.apache.camel.k.Sources; -import org.apache.camel.k.loader.yaml.YamlRoutesLoader; +import org.apache.camel.k.loader.yaml.YamlSourceLoader; @Path("/test") @ApplicationScoped @@ -48,10 +48,9 @@ public class Application { @Produces(MediaType.APPLICATION_JSON) public JsonObject loadRoutes(@PathParam("name") String name, String code) throws Exception { final Source source = Sources.fromBytes(name, "yaml", null, code.getBytes(StandardCharsets.UTF_8)); - final RoutesLoader loader = new YamlRoutesLoader(); - final RouteBuilder routes = loader.load(context, source); + final SourceLoader loader = new YamlSourceLoader(); - context.addRoutes(routes); + loader.load(Runtime.on(context), source); return Json.createObjectBuilder() .add("components", extractComponents()) diff --git a/camel-k-runtime-core/src/main/java/org/apache/camel/k/Runtime.java b/camel-k-runtime-core/src/main/java/org/apache/camel/k/Runtime.java index a7990fea2..e75d3890f 100644 --- a/camel-k-runtime-core/src/main/java/org/apache/camel/k/Runtime.java +++ b/camel-k-runtime-core/src/main/java/org/apache/camel/k/Runtime.java @@ -53,6 +53,10 @@ default void addRoutes(RoutesBuilder builder) { } } + default void addConfiguration(Object configuration) { + throw new UnsupportedOperationException(); + } + enum Phase { Starting, ConfigureContext, diff --git a/camel-k-runtime-core/src/main/java/org/apache/camel/k/RoutesLoader.java b/camel-k-runtime-core/src/main/java/org/apache/camel/k/SourceLoader.java similarity index 87% rename from camel-k-runtime-core/src/main/java/org/apache/camel/k/RoutesLoader.java rename to camel-k-runtime-core/src/main/java/org/apache/camel/k/SourceLoader.java index c2a75f625..470a930fb 100644 --- a/camel-k-runtime-core/src/main/java/org/apache/camel/k/RoutesLoader.java +++ b/camel-k-runtime-core/src/main/java/org/apache/camel/k/SourceLoader.java @@ -18,10 +18,9 @@ import java.util.List; -import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; -public interface RoutesLoader { +public interface SourceLoader { /** * Provides a list of the languages supported by this loader. * @@ -32,10 +31,10 @@ public interface RoutesLoader { /** * Creates a camel {@link RouteBuilder} from the given resource. * - * @param context the camel runtime. + * @param runtime the runtime. * @param source the source to load. * @return the RouteBuilder. * @throws Exception */ - RouteBuilder load(CamelContext context, Source source) throws Exception; + void load(Runtime runtime, Source source) throws Exception; } diff --git a/camel-k-runtime-core/src/main/java/org/apache/camel/k/listener/RoutesConfigurer.java b/camel-k-runtime-core/src/main/java/org/apache/camel/k/listener/RoutesConfigurer.java index 53ed7e0b5..489670570 100644 --- a/camel-k-runtime-core/src/main/java/org/apache/camel/k/listener/RoutesConfigurer.java +++ b/camel-k-runtime-core/src/main/java/org/apache/camel/k/listener/RoutesConfigurer.java @@ -17,11 +17,10 @@ package org.apache.camel.k.listener; import org.apache.camel.RuntimeCamelException; -import org.apache.camel.builder.RouteBuilder; import org.apache.camel.k.Constants; -import org.apache.camel.k.RoutesLoader; import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; import org.apache.camel.k.Sources; import org.apache.camel.k.support.RuntimeSupport; import org.apache.camel.util.ObjectHelper; @@ -58,24 +57,18 @@ protected void load(Runtime runtime, String[] routes) { } final Source source; - final RoutesLoader loader; - final RouteBuilder builder; + final SourceLoader loader; try { source = Sources.fromURI(route); loader = RuntimeSupport.loaderFor(runtime.getCamelContext(), source); - builder = loader.load(runtime.getCamelContext(), source); + + loader.load(runtime, source); } catch (Exception e) { throw RuntimeCamelException.wrapRuntimeCamelException(e); } - if (builder == null) { - throw new IllegalStateException("Unable to load route from: " + route); - } - LOGGER.info("Loading routes from: {}", route); - - runtime.addRoutes(builder); } } diff --git a/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/RuntimeSupport.java b/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/RuntimeSupport.java index 52012ce3a..107b48475 100644 --- a/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/RuntimeSupport.java +++ b/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/RuntimeSupport.java @@ -31,8 +31,8 @@ import org.apache.camel.NoFactoryAvailableException; import org.apache.camel.k.Constants; import org.apache.camel.k.ContextCustomizer; -import org.apache.camel.k.RoutesLoader; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; import org.apache.camel.util.ObjectHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -153,7 +153,7 @@ public static Set lookupCustomizerIDs(CamelContext context) { // // ********************************* - public static RoutesLoader loaderFor(CamelContext context, Source source) { + public static SourceLoader loaderFor(CamelContext context, Source source) { return source.getLoader().map( loaderId -> lookupLoaderById(context, loaderId) ).orElseGet( @@ -162,10 +162,10 @@ public static RoutesLoader loaderFor(CamelContext context, Source source) { } - public static RoutesLoader lookupLoaderById(CamelContext context, String loaderId) { + public static SourceLoader lookupLoaderById(CamelContext context, String loaderId) { LOGGER.info("Looking up loader for id: {}", loaderId); - RoutesLoader loader = context.getRegistry().findByTypeWithName(RoutesLoader.class).get(loaderId); + SourceLoader loader = context.getRegistry().findByTypeWithName(SourceLoader.class).get(loaderId); if (loader != null) { LOGGER.info("Found loader {} with id {} from the registry", loader, loaderId); return loader; @@ -174,10 +174,10 @@ public static RoutesLoader lookupLoaderById(CamelContext context, String loaderI return lookupLoaderFromResource(context, loaderId); } - public static RoutesLoader lookupLoaderByLanguage(CamelContext context, String loaderId) { + public static SourceLoader lookupLoaderByLanguage(CamelContext context, String loaderId) { LOGGER.info("Looking up loader for language: {}", loaderId); - for (RoutesLoader loader: context.getRegistry().findByType(RoutesLoader.class)) { + for (SourceLoader loader: context.getRegistry().findByType(SourceLoader.class)) { if (loader.getSupportedLanguages().contains(loaderId)) { LOGGER.info("Found loader {} for language {} from the registry", loader, loaderId); return loader; @@ -187,13 +187,13 @@ public static RoutesLoader lookupLoaderByLanguage(CamelContext context, String l return lookupLoaderFromResource(context, loaderId); } - public static RoutesLoader lookupLoaderFromResource(CamelContext context, String loaderId) { - RoutesLoader loader; + public static SourceLoader lookupLoaderFromResource(CamelContext context, String loaderId) { + SourceLoader loader; try { loader = context.adapt(ExtendedCamelContext.class) .getFactoryFinder(Constants.ROUTES_LOADER_RESOURCE_PATH) - .newInstance(loaderId, RoutesLoader.class) + .newInstance(loaderId, SourceLoader.class) .orElseThrow(() -> new RuntimeException("Error creating instance of loader: " + loaderId)); LOGGER.info("Found loader {} for language {} from service definition", loader, loaderId); diff --git a/camel-k-runtime-knative/src/test/java/org/apache/camel/k/knative/yaml/parser/KnativeConverterTest.java b/camel-k-runtime-knative/src/test/java/org/apache/camel/k/knative/yaml/parser/KnativeConverterTest.java index 15a152522..628fada4e 100644 --- a/camel-k-runtime-knative/src/test/java/org/apache/camel/k/knative/yaml/parser/KnativeConverterTest.java +++ b/camel-k-runtime-knative/src/test/java/org/apache/camel/k/knative/yaml/parser/KnativeConverterTest.java @@ -16,14 +16,17 @@ */ package org.apache.camel.k.knative.yaml.parser; +import java.util.ArrayList; import java.util.List; -import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.CamelContext; +import org.apache.camel.RoutesBuilder; import org.apache.camel.impl.DefaultCamelContext; -import org.apache.camel.k.RoutesLoader; +import org.apache.camel.k.Runtime; import org.apache.camel.k.Source; +import org.apache.camel.k.SourceLoader; import org.apache.camel.k.Sources; -import org.apache.camel.k.loader.yaml.YamlRoutesLoader; +import org.apache.camel.k.loader.yaml.YamlSourceLoader; import org.apache.camel.k.support.RuntimeSupport; import org.apache.camel.model.FromDefinition; import org.apache.camel.model.ProcessorDefinition; @@ -37,17 +40,18 @@ public class KnativeConverterTest { @Test public void testLoadRoutes() throws Exception { - DefaultCamelContext context = new DefaultCamelContext(); + TestRuntime runtime = new TestRuntime(); Source source = Sources.fromURI("classpath:route.yaml"); - RoutesLoader loader = RuntimeSupport.loaderFor(context, source); - RouteBuilder builder = loader.load(context, source); + SourceLoader loader = RuntimeSupport.loaderFor(runtime.camelContext, source); - assertThat(loader).isInstanceOf(YamlRoutesLoader.class); - assertThat(builder).isNotNull(); + loader.load(runtime, source); - context.addRoutes(builder); + assertThat(loader).isInstanceOf(YamlSourceLoader.class); + assertThat(runtime.builders).hasSize(1); - List routes = context.getRouteDefinitions(); + runtime.camelContext.addRoutes(runtime.builders.get(0)); + + List routes = runtime.camelContext.getRouteDefinitions(); assertThat(routes).hasSize(1); // definition @@ -90,4 +94,24 @@ private static void validateSteps(RouteDefinition definition) { assertThat(t.getEndpointUri()).isEqualTo("knative:endpoint/to"); }); } + + static class TestRuntime implements Runtime { + private final DefaultCamelContext camelContext; + private final List builders; + + public TestRuntime() { + this.camelContext = new DefaultCamelContext(); + this.builders = new ArrayList<>(); + } + + @Override + public CamelContext getCamelContext() { + return this.camelContext; + } + + @Override + public void addRoutes(RoutesBuilder builder) { + this.builders.add(builder); + } + } } diff --git a/camel-k-runtime-main/src/main/java/org/apache/camel/k/main/ApplicationRuntime.java b/camel-k-runtime-main/src/main/java/org/apache/camel/k/main/ApplicationRuntime.java index b91f7d56d..470d0c524 100644 --- a/camel-k-runtime-main/src/main/java/org/apache/camel/k/main/ApplicationRuntime.java +++ b/camel-k-runtime-main/src/main/java/org/apache/camel/k/main/ApplicationRuntime.java @@ -79,6 +79,11 @@ public void addRoutes(RoutesBuilder builder) { this.main.addRoutesBuilder(builder); } + @Override + public void addConfiguration(Object configuration) { + this.main.addConfiguration(configuration); + } + @Override public void setProperties(Properties properties) { this.main.setOverrideProperties(properties); diff --git a/camel-k-runtime-main/src/test/java/org/apache/camel/k/main/RuntimeTest.java b/camel-k-runtime-main/src/test/java/org/apache/camel/k/main/RuntimeTest.java index ffa89e2fd..b5256e56c 100644 --- a/camel-k-runtime-main/src/test/java/org/apache/camel/k/main/RuntimeTest.java +++ b/camel-k-runtime-main/src/test/java/org/apache/camel/k/main/RuntimeTest.java @@ -93,12 +93,13 @@ void testLoadRouteWithExpression() throws Exception { } @Test - public void testLoadJavaSourceWithBeans() throws Exception { + public void testLoadJavaSource() throws Exception { ApplicationRuntime runtime = new ApplicationRuntime(); - runtime.addListener(RoutesConfigurer.forRoutes("classpath:MyRoutesWithBeans.java")); + runtime.addListener(RoutesConfigurer.forRoutes("classpath:MyRoutesWithBeans.java", "classpath:MyRoutesConfig.java")); runtime.addListener(Runtime.Phase.Started, r -> runtime.stop()); runtime.run(); + assertThat(runtime.getRegistry().lookupByName("my-processor")).isNotNull(); assertThat(runtime.getRegistry().lookupByName("my-bean")).isInstanceOfSatisfying(MyBean.class, b -> { assertThat(b).hasFieldOrPropertyWithValue("name", "my-bean-name"); }); diff --git a/camel-k-runtime-main/src/test/resources/MyRoutesConfig.java b/camel-k-runtime-main/src/test/resources/MyRoutesConfig.java new file mode 100644 index 000000000..65f8a0572 --- /dev/null +++ b/camel-k-runtime-main/src/test/resources/MyRoutesConfig.java @@ -0,0 +1,33 @@ +/* + * 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. + */ +import org.apache.camel.BindToRegistry; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; + +public class MyRoutesConfig { + @BindToRegistry("my-processor") + public static MyProcessor myProcessor() { + return new MyProcessor(); + } + + public static class MyProcessor implements Processor { + @Override + public void process(Exchange exchange) throws Exception { + } + } +} \ No newline at end of file diff --git a/tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java b/tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java index b94c3dc4b..89ea1e649 100644 --- a/tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java +++ b/tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java @@ -24,5 +24,5 @@ @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface Loader { - String value(); + String[] value(); } diff --git a/tooling/camel-k-apt/src/main/java/org/apache/camel/k/tooling/apt/CamelProcessor.java b/tooling/camel-k-apt/src/main/java/org/apache/camel/k/tooling/apt/CamelProcessor.java index cb40d65e2..269bf4541 100644 --- a/tooling/camel-k-apt/src/main/java/org/apache/camel/k/tooling/apt/CamelProcessor.java +++ b/tooling/camel-k-apt/src/main/java/org/apache/camel/k/tooling/apt/CamelProcessor.java @@ -53,10 +53,14 @@ public boolean process(Set annotations, RoundEnvironment for (TypeElement annotation : annotations) { Set ae = roundEnv.getElementsAnnotatedWith(annotation); for (Element element: ae) { - on(element, Loader.class, (e, a) -> service( - output("META-INF/services/org/apache/camel/k/loader/%s", a.value()), - e - )); + on(element, Loader.class, (e, a) -> { + for (String loader: a.value()) { + service( + output("META-INF/services/org/apache/camel/k/loader/%s", loader), + e + ); + } + }); on(element, YAMLStepParser.class, (e, a) -> { for (String id: a.value()) { service(