This is an automated email from the ASF dual-hosted git repository. lburgazzoli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-k-runtime.git
commit 638040cca4bb754a536f48c3c9c02e06e4796234 Author: lburgazzoli <lburgazz...@gmail.com> AuthorDate: Mon Aug 5 18:28:00 2019 +0200 knative: add custom loader for sources --- camel-k-loader-knative/pom.xml | 186 +++++++++++++++++++++ .../loader/knative/KnativeSourceRoutesLoader.java | 101 +++++++++++ .../org/apache/camel/k/loader/knative-source | 18 ++ .../apache/camel/k/loader/knative-source-groovy | 18 ++ .../org/apache/camel/k/loader/knative-source-java | 18 ++ .../org/apache/camel/k/loader/knative-source-js | 18 ++ .../org/apache/camel/k/loader/knative-source-kts | 18 ++ .../org/apache/camel/k/loader/knative-source-xml | 18 ++ .../org/apache/camel/k/loader/knative-source-yaml | 18 ++ .../knative/KnativeSourceRoutesLoaderTest.java | 157 +++++++++++++++++ .../src/test/resources/log4j2-test.xml | 36 ++++ .../src/test/resources/routes.groovy | 19 +++ .../src/test/resources/routes.java | 32 ++++ .../src/test/resources/routes.js | 19 +++ .../src/test/resources/routes.kts | 20 +++ .../src/test/resources/routes.xml | 28 ++++ .../src/test/resources/routes.yaml | 23 +++ camel-k-runtime-bom/pom.xml | 5 + .../src/main/java/org/apache/camel/k/Source.java | 15 +- .../org/apache/camel/k/support/RuntimeSupport.java | 28 +++- camel-k-runtime-knative/pom.xml | 5 + .../component/knative/KnativeEnvironment.java | 25 +++ pom.xml | 8 +- .../maven/processors/CatalogProcessor3x.java | 16 ++ 24 files changed, 840 insertions(+), 9 deletions(-) diff --git a/camel-k-loader-knative/pom.xml b/camel-k-loader-knative/pom.xml new file mode 100644 index 0000000..aed021c --- /dev/null +++ b/camel-k-loader-knative/pom.xml @@ -0,0 +1,186 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <groupId>org.apache.camel.k</groupId> + <artifactId>camel-k-runtime-parent</artifactId> + <version>1.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>camel-k-loader-knative</artifactId> + + <dependencies> + <dependency> + <groupId>org.apache.camel.k</groupId> + <artifactId>camel-k-runtime-core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-core-engine</artifactId> + <scope>provided</scope> + </dependency> + + <!-- ****************************** --> + <!-- --> + <!-- TESTS --> + <!-- --> + <!-- ****************************** --> + + <dependency> + <groupId>org.apache.camel.k</groupId> + <artifactId>camel-knative</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel.k</groupId> + <artifactId>camel-k-loader-yaml</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel.k</groupId> + <artifactId>camel-k-loader-xml</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel.k</groupId> + <artifactId>camel-k-loader-groovy</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel.k</groupId> + <artifactId>camel-k-loader-kotlin</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel.k</groupId> + <artifactId>camel-k-loader-js</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel.k</groupId> + <artifactId>camel-k-loader-java</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-properties</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-direct</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-log</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-mock</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-undertow</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-cloud</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-endpointdsl</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.codehaus.groovy</groupId> + <artifactId>groovy</artifactId> + <version>${groovy.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-params</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <version>${assertj.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j-impl</artifactId> + <version>${log4j2.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.codehaus.gmavenplus</groupId> + <artifactId>gmavenplus-plugin</artifactId> + <version>${gmavenplus-plugin.version}</version> + <executions> + <execution> + <goals> + <goal>addTestSources</goal> + <goal>compileTests</goal> + </goals> + </execution> + </executions> + <configuration> + <invokeDynamic>true</invokeDynamic> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <useSystemClassLoader>false</useSystemClassLoader> + <forkCount>0</forkCount> + </configuration> + </plugin> + </plugins> + </build> + +</project> 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 new file mode 100644 index 0000000..7b106b5 --- /dev/null +++ b/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoader.java @@ -0,0 +1,101 @@ +/* + * 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.builder.RouteBuilder; +import org.apache.camel.impl.engine.AbstractCamelContext; +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<String> 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<RouteDefinition> definitions = builder.configureRoutes(context).getRoutes(); + + if (definitions.size() > 1) { + throw new IllegalArgumentException("Cannot determine route top enrich"); + } + + final String sink = context.resolvePropertyPlaceholders("{{env:KNATIVE_SYNC: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)); + + //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(AbstractCamelContext.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 new file mode 100644 index 0000000..6245d34 --- /dev/null +++ b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source @@ -0,0 +1,18 @@ +# +# 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 new file mode 100644 index 0000000..6245d34 --- /dev/null +++ b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-groovy @@ -0,0 +1,18 @@ +# +# 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 new file mode 100644 index 0000000..6245d34 --- /dev/null +++ b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-java @@ -0,0 +1,18 @@ +# +# 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 new file mode 100644 index 0000000..6245d34 --- /dev/null +++ b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-js @@ -0,0 +1,18 @@ +# +# 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 new file mode 100644 index 0000000..6245d34 --- /dev/null +++ b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-kts @@ -0,0 +1,18 @@ +# +# 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 new file mode 100644 index 0000000..6245d34 --- /dev/null +++ b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-xml @@ -0,0 +1,18 @@ +# +# 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 new file mode 100644 index 0000000..6245d34 --- /dev/null +++ b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-yaml @@ -0,0 +1,18 @@ +# +# 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 new file mode 100644 index 0000000..a7d8f2a --- /dev/null +++ b/camel-k-loader-knative/src/test/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoaderTest.java @@ -0,0 +1,157 @@ +/* + * 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.List; +import java.util.UUID; +import java.util.stream.Stream; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.knative.KnativeComponent; +import org.apache.camel.component.knative.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.Source; +import org.apache.camel.k.support.RuntimeSupport; +import org.apache.camel.model.ModelCamelContext; +import org.apache.camel.model.RouteDefinition; +import org.apache.camel.test.AvailablePortFinder; +import org.junit.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.assertj.core.api.Assertions.assertThat; + +public class KnativeSourceRoutesLoaderTest { + private static final Logger LOGGER = LoggerFactory.getLogger(KnativeSourceRoutesLoaderTest.class); + + static Stream<Arguments> parameters() { + return Stream.of( + Arguments.arguments("classpath:routes.yaml?loader=knative-source"), + Arguments.arguments("classpath:routes.yaml?language=knative-source-yaml"), + Arguments.arguments("classpath:routes.xml?loader=knative-source"), + Arguments.arguments("classpath:routes.xml?language=knative-source-xml"), + Arguments.arguments("classpath:routes.groovy?loader=knative-source"), + Arguments.arguments("classpath:routes.groovy?language=knative-source-groovy"), + Arguments.arguments("classpath:routes.kts?loader=knative-source"), + Arguments.arguments("classpath:routes.kts?language=knative-source-kts"), + Arguments.arguments("classpath:routes.js?loader=knative-source"), + Arguments.arguments("classpath:routes.js?language=knative-source-js"), + Arguments.arguments("classpath:routes.java?name=MyRoutes.java&loader=knative-source"), + Arguments.arguments("classpath:routes.java?name=MyRoutes.java&language=knative-source-java") + ).sequential(); + } + + @ParameterizedTest + @MethodSource("parameters") + public void testWrapLoader(String uri) throws Exception { + LOGGER.info("uri: {}", uri); + + final int port = AvailablePortFinder.getNextAvailable(); + final String data = UUID.randomUUID().toString(); + + KnativeComponent component = new KnativeComponent(); + component.setEnvironment(KnativeEnvironment.on( + KnativeEnvironment.httpEndpoint("sink", "localhost", port) + )); + + CamelContext context = new DefaultCamelContext(); + context.disableJMX(); + context.setStreamCaching(true); + context.addComponent("knative", component); + + Source source = Source.create(uri); + RoutesLoader loader = RuntimeSupport.loaderFor(context, source); + RouteBuilder builder = loader.load(context, source); + + assertThat(loader).isInstanceOf(KnativeSourceRoutesLoader.class); + assertThat(builder).isNotNull(); + + try { + context.addRoutes(builder); + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + fromF("undertow:http://localhost:%d", port) + .routeId("http") + .to("mock:result"); + } + }); + context.start(); + + List<RouteDefinition> definitions = context.adapt(ModelCamelContext.class).getRouteDefinitions(); + + assertThat(definitions).hasSize(2); + assertThat(definitions).first().satisfies(d -> { + assertThat(d.getOutputs()).last().hasFieldOrPropertyWithValue( + "endpointUri", + "knative://endpoint/sink" + ); + }); + + MockEndpoint mock = context.getEndpoint("mock:result", MockEndpoint.class); + mock.expectedMessageCount(1); + mock.expectedBodiesReceived(data); + + context.createProducerTemplate().sendBodyAndHeader( + "direct:start", + "", + "MyHeader", + data); + + mock.assertIsSatisfied(); + } finally { + context.stop(); + } + } + + @Test + public void testWrapLoaderWithBeanRegistration() throws Exception { + final int port = AvailablePortFinder.getNextAvailable(); + + KnativeComponent component = new KnativeComponent(); + component.setEnvironment(KnativeEnvironment.on( + KnativeEnvironment.httpEndpoint("sink", "localhost", port) + )); + + CamelContext context = new DefaultCamelContext(); + context.disableJMX(); + context.setStreamCaching(true); + context.addComponent("knative", component); + + Source source = Source.create("classpath:routes.java?name=MyRoutes.java&loader=knative-source"); + RoutesLoader loader = RuntimeSupport.loaderFor(context, source); + RouteBuilder builder = loader.load(context, source); + + assertThat(loader).isInstanceOf(KnativeSourceRoutesLoader.class); + assertThat(builder).isNotNull(); + + try { + context.addRoutes(builder); + context.start(); + + assertThat(context.getRegistry().lookupByName("my-bean")).isInstanceOfSatisfying(String.class, "my-bean-string"::equals); + } finally { + context.stop(); + } + } +} diff --git a/camel-k-loader-knative/src/test/resources/log4j2-test.xml b/camel-k-loader-knative/src/test/resources/log4j2-test.xml new file mode 100644 index 0000000..42e5526 --- /dev/null +++ b/camel-k-loader-knative/src/test/resources/log4j2-test.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<Configuration status="INFO"> + <Appenders> + <Console name="STDOUT" target="SYSTEM_OUT"> + <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}|%-5level|%t|%c{1} - %msg%n"/> + </Console> + <Null name="NONE"/> + </Appenders> + + + <Loggers> + <Root level="INFO"> + <!--<AppenderRef ref="STDOUT"/>--> + <AppenderRef ref="NONE"/> + </Root> + </Loggers> + +</Configuration> \ No newline at end of file diff --git a/camel-k-loader-knative/src/test/resources/routes.groovy b/camel-k-loader-knative/src/test/resources/routes.groovy new file mode 100644 index 0000000..d4e7b78 --- /dev/null +++ b/camel-k-loader-knative/src/test/resources/routes.groovy @@ -0,0 +1,19 @@ +/* + * 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. + */ +from('direct:start') + .setBody().simple('${header[MyHeader]}') + .to('log:knative') \ No newline at end of file diff --git a/camel-k-loader-knative/src/test/resources/routes.java b/camel-k-loader-knative/src/test/resources/routes.java new file mode 100644 index 0000000..ffa38de --- /dev/null +++ b/camel-k-loader-knative/src/test/resources/routes.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.apache.camel.BindToRegistry; +import org.apache.camel.builder.RouteBuilder; + +public class MyRoutes extends RouteBuilder { + @Override + public void configure() throws Exception { + from("direct:start") + .setBody().simple("${header[MyHeader]}") + .to("log:knative"); + } + + @BindToRegistry("my-bean") + public static String myBean() { + return "my-bean-string"; + } +} \ No newline at end of file diff --git a/camel-k-loader-knative/src/test/resources/routes.js b/camel-k-loader-knative/src/test/resources/routes.js new file mode 100644 index 0000000..75de4de --- /dev/null +++ b/camel-k-loader-knative/src/test/resources/routes.js @@ -0,0 +1,19 @@ +/* + * 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. + */ +from('direct:start') + .setBody().simple('${header[MyHeader]}') + .to('log:knative'); \ No newline at end of file diff --git a/camel-k-loader-knative/src/test/resources/routes.kts b/camel-k-loader-knative/src/test/resources/routes.kts new file mode 100644 index 0000000..48b8b1c --- /dev/null +++ b/camel-k-loader-knative/src/test/resources/routes.kts @@ -0,0 +1,20 @@ +/* + * 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. + */ +from("direct:start") + .setBody().simple("\${header[MyHeader]}") + .to("log:knative") + diff --git a/camel-k-loader-knative/src/test/resources/routes.xml b/camel-k-loader-knative/src/test/resources/routes.xml new file mode 100644 index 0000000..f0d953a --- /dev/null +++ b/camel-k-loader-knative/src/test/resources/routes.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<routes xmlns="http://camel.apache.org/schema/spring"> + <route> + <from uri="direct:start"/> + <setBody> + <simple>${header[MyHeader]}</simple> + </setBody> + <to uri="log:knative"/> + </route> +</routes> \ No newline at end of file diff --git a/camel-k-loader-knative/src/test/resources/routes.yaml b/camel-k-loader-knative/src/test/resources/routes.yaml new file mode 100644 index 0000000..b1fd1f8 --- /dev/null +++ b/camel-k-loader-knative/src/test/resources/routes.yaml @@ -0,0 +1,23 @@ +# +# 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. +# + +- from: + uri: "direct:start" + steps: + - set-body: + simple: "${header[MyHeader]}" + - to: "log:knative" diff --git a/camel-k-runtime-bom/pom.xml b/camel-k-runtime-bom/pom.xml index eab16f3..bf06606 100644 --- a/camel-k-runtime-bom/pom.xml +++ b/camel-k-runtime-bom/pom.xml @@ -163,6 +163,11 @@ <artifactId>camel-k-loader-java</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.camel.k</groupId> + <artifactId>camel-k-loader-knative</artifactId> + <version>${project.version}</version> + </dependency> <!-- legacy --> <dependency> diff --git a/camel-k-runtime-core/src/main/java/org/apache/camel/k/Source.java b/camel-k-runtime-core/src/main/java/org/apache/camel/k/Source.java index 6f34870..83e94f9 100644 --- a/camel-k-runtime-core/src/main/java/org/apache/camel/k/Source.java +++ b/camel-k-runtime-core/src/main/java/org/apache/camel/k/Source.java @@ -17,6 +17,7 @@ package org.apache.camel.k; import java.util.Map; +import java.util.Optional; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.URISupport; @@ -26,12 +27,14 @@ public final class Source { private final String name; private final String location; private final String language; + private final String loader; private final boolean compressed; - private Source(String name, String location, String language, boolean compression) { + private Source(String name, String location, String language, String loader, boolean compression) { this.name = name; this.location = location; this.language = language; + this.loader = loader; this.compressed = compression; } @@ -51,12 +54,17 @@ public final class Source { return compressed; } + public Optional<String> getLoader() { + return Optional.ofNullable(loader); + } + @Override public String toString() { return "Source{" + "location='" + location + '\'' + ", language=" + language - + " , compressed=" + compressed + + ", loader=" + loader + + ", compressed=" + compressed + '}'; } @@ -71,6 +79,7 @@ public final class Source { final Map<String, Object> params = URISupport.parseQuery(query); final String languageName = (String) params.get("language"); final String compression = (String) params.get("compression"); + final String loader = (String) params.get("loader"); String language = languageName; @@ -92,6 +101,6 @@ public final class Source { } } - return new Source(name, location, language, Boolean.valueOf(compression)); + return new Source(name, location, language, loader, Boolean.valueOf(compression)); } } 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 8f9a6b4..796b96e 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 @@ -152,21 +152,39 @@ public final class RuntimeSupport { // ********************************* public static RoutesLoader loaderFor(CamelContext context, Source source) { + return source.getLoader().map( + loaderId -> lookupLoaderById(context, loaderId) + ).orElseGet( + () -> lookupLoaderByLanguage(context, source.getLanguage()) + ); + } + + public static RoutesLoader lookupLoaderById(CamelContext context, String loaderId) { + RoutesLoader answer = context.getRegistry().findByTypeWithName(RoutesLoader.class).get(loaderId); + if (answer == null) { + return lookupLoaderFromResource(context, loaderId); + } + + return answer; + } + + public static RoutesLoader lookupLoaderByLanguage(CamelContext context, String language) { return context.getRegistry().findByType(RoutesLoader.class).stream() - .filter(rl -> rl.getSupportedLanguages().contains(source.getLanguage())) + .filter(rl -> rl.getSupportedLanguages().contains(language)) .findFirst() - .orElseGet(() -> lookupLoaderFromResource(context, source)); + .orElseGet(() -> lookupLoaderFromResource(context, language)); + } - public static RoutesLoader lookupLoaderFromResource(CamelContext context, Source source) { + public static RoutesLoader lookupLoaderFromResource(CamelContext context, String loaderId) { final FactoryFinder finder; final RoutesLoader loader; try { finder = context.adapt(ExtendedCamelContext.class).getFactoryFinder(Constants.ROUTES_LOADER_RESOURCE_PATH); - loader = (RoutesLoader)finder.newInstance(source.getLanguage()); + loader = (RoutesLoader)finder.newInstance(loaderId); } catch (NoFactoryAvailableException e) { - throw new IllegalArgumentException("Unable to find loader for: " + source, e); + throw new IllegalArgumentException("Unable to find loader for: " + loaderId, e); } return loader; diff --git a/camel-k-runtime-knative/pom.xml b/camel-k-runtime-knative/pom.xml index e11407d..ab1bfb1 100644 --- a/camel-k-runtime-knative/pom.xml +++ b/camel-k-runtime-knative/pom.xml @@ -41,6 +41,11 @@ <artifactId>camel-k-loader-yaml</artifactId> <optional>true</optional> </dependency> + <dependency> + <groupId>org.apache.camel.k</groupId> + <artifactId>camel-k-loader-knative</artifactId> + <optional>true</optional> + </dependency> <dependency> <groupId>org.apache.camel</groupId> diff --git a/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeEnvironment.java b/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeEnvironment.java index 19c11af..814740a 100644 --- a/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeEnvironment.java +++ b/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeEnvironment.java @@ -20,6 +20,7 @@ import java.io.InputStream; import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -170,6 +171,30 @@ public class KnativeEnvironment { } } + public static KnativeServiceDefinition httpEndpoint(String name, String host, int port) { + return new KnativeEnvironment.KnativeServiceDefinition( + Knative.Type.endpoint, + Knative.Protocol.http, + name, + host, + port, + Collections.emptyMap()); + } + + public static KnativeServiceDefinition httpChannel(String name, String host, int port) { + return new KnativeEnvironment.KnativeServiceDefinition( + Knative.Type.channel, + Knative.Protocol.http, + name, + host, + port, + Collections.emptyMap()); + } + + public static KnativeEnvironment on(KnativeServiceDefinition... definitions) { + return new KnativeEnvironment(Arrays.asList(definitions)); + } + // ************************ // // Types diff --git a/pom.xml b/pom.xml index 9458562..8feca0b 100644 --- a/pom.xml +++ b/pom.xml @@ -173,7 +173,7 @@ </sourceDirectories> <headerLocation>header-java.txt</headerLocation> <includes>**/*.java,**/*.groovy,**/*.scala,**/*.properties,**/*.xml,**/*.xsd</includes> - <excludes>**/MyRoutes*.java</excludes> + <excludes>**/MyRoutes*.java,**/routes*.java</excludes> </configuration> <goals> <goal>checkstyle</goal> @@ -197,6 +197,7 @@ <module>camel-k-loader-js</module> <module>camel-k-loader-xml</module> <module>camel-k-loader-java</module> + <module>camel-k-loader-knative</module> <module>camel-k-runtime-health</module> <module>camel-k-runtime-servlet</module> @@ -321,6 +322,11 @@ <artifactId>camel-k-loader-java</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.camel.k</groupId> + <artifactId>camel-k-loader-knative</artifactId> + <version>${project.version}</version> + </dependency> <!-- legacy --> <dependency> diff --git a/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/k/tooling/maven/processors/CatalogProcessor3x.java b/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/k/tooling/maven/processors/CatalogProcessor3x.java index 5fa5398..49b0adb 100644 --- a/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/k/tooling/maven/processors/CatalogProcessor3x.java +++ b/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/k/tooling/maven/processors/CatalogProcessor3x.java @@ -182,6 +182,21 @@ public class CatalogProcessor3x implements CatalogProcessor { // ************************ // + // camel-k-loader-knative + // + // ************************ + + { + CamelArtifact artifact = new CamelArtifact(); + artifact.setGroupId("org.apache.camel.k"); + artifact.setArtifactId("camel-k-loader-knative"); + artifact.setVersion(project.getVersion()); + + artifacts.put(artifact.getArtifactId(), artifact); + } + + // ************************ + // // camel-knative // // ************************ @@ -243,6 +258,7 @@ public class CatalogProcessor3x implements CatalogProcessor { artifact.addDependency("org.apache.camel", "camel-cloud"); artifact.addDependency("org.apache.camel", "camel-http-common"); artifact.addDependency("org.apache.camel.k", "camel-k-loader-yaml"); + artifact.addDependency("org.apache.camel.k", "camel-k-loader-knative"); artifact.addDependency("org.apache.camel.k", "camel-knative"); artifact.addDependency("org.apache.camel.k", "camel-knative-http");