You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2018/09/12 07:09:36 UTC
[camel-k] branch master updated: Route loaders should derive
language from 'kamel run --language' #46
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git
The following commit(s) were added to refs/heads/master by this push:
new d8bfcac Route loaders should derive language from 'kamel run --language' #46
d8bfcac is described below
commit d8bfcac11d2c2fb0aaf6727a9792cdaa2e49df62
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Wed Sep 12 08:02:41 2018 +0200
Route loaders should derive language from 'kamel run --language' #46
---
pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go | 5 ++
pkg/build/api/types.go | 5 +-
pkg/build/local/local_builder.go | 5 +-
pkg/stub/action/integration/build.go | 5 +-
.../java/org/apache/camel/k/jvm/Application.java | 16 ++--
.../main/java/org/apache/camel/k/jvm/Routes.java | 88 +++++++++++++++++++++
.../java/org/apache/camel/k/jvm/RoutesLoader.java | 15 ++++
.../jvm/{RouteLoaders.java => RoutesLoaders.java} | 91 ++++++++++------------
.../org/apache/camel/k/jvm/ApplicationTest.java | 16 ++++
.../test/java/org/apache/camel/k/jvm/MyRoutes.java | 16 ++++
...outeLoadersTest.java => RoutesLoadersTest.java} | 44 ++++++++---
runtime/jvm/src/test/resources/routes.mytype | 3 +
12 files changed, 234 insertions(+), 75 deletions(-)
diff --git a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
index 8b16b1e..2e4d8d2 100644
--- a/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/camel/v1alpha1/zz_generated.deepcopy.go
@@ -277,6 +277,11 @@ func (in *SourceSpec) DeepCopyInto(out *SourceSpec) {
*out = new(string)
**out = **in
}
+ if in.Language != nil {
+ in, out := &in.Language, &out.Language
+ *out = new(string)
+ **out = **in
+ }
return
}
diff --git a/pkg/build/api/types.go b/pkg/build/api/types.go
index b94a9e7..5fc1395 100644
--- a/pkg/build/api/types.go
+++ b/pkg/build/api/types.go
@@ -29,8 +29,9 @@ type BuildIdentifier struct {
}
type Code struct {
- Name string
- Content string
+ Name string
+ Content string
+ Language string
}
// represents the result of a build
diff --git a/pkg/build/local/local_builder.go b/pkg/build/local/local_builder.go
index 38a9812..f1ed76a 100644
--- a/pkg/build/local/local_builder.go
+++ b/pkg/build/local/local_builder.go
@@ -131,8 +131,9 @@ func (b *localBuilder) execute(source build.BuildSource) (string, error) {
source.Code.Name: source.Code.Content,
},
Env: map[string]string{
- "JAVA_MAIN_CLASS": "org.apache.camel.k.jvm.Application",
- "CAMEL_K_ROUTES_URI": "classpath:" + source.Code.Name,
+ "JAVA_MAIN_CLASS": "org.apache.camel.k.jvm.Application",
+ "CAMEL_K_ROUTES_URI": "classpath:" + source.Code.Name,
+ "CAMEL_K_ROUTES_LANGUAGE": source.Code.Language,
},
}
diff --git a/pkg/stub/action/integration/build.go b/pkg/stub/action/integration/build.go
index 25747cc..22f006a 100644
--- a/pkg/stub/action/integration/build.go
+++ b/pkg/stub/action/integration/build.go
@@ -55,8 +55,9 @@ func (b *BuildAction) Handle(integration *v1alpha1.Integration) error {
b.buildManager.Start(api.BuildSource{
Identifier: buildIdentifier,
Code: api.Code{
- Name: *integration.Spec.Source.Name,
- Content: *integration.Spec.Source.Content,
+ Name: *integration.Spec.Source.Name,
+ Content: *integration.Spec.Source.Content,
+ Language: *integration.Spec.Source.Language,
}, // FIXME possible panic
})
logrus.Info("Build started")
diff --git a/runtime/jvm/src/main/java/org/apache/camel/k/jvm/Application.java b/runtime/jvm/src/main/java/org/apache/camel/k/jvm/Application.java
index dbca9f1..bec284f 100644
--- a/runtime/jvm/src/main/java/org/apache/camel/k/jvm/Application.java
+++ b/runtime/jvm/src/main/java/org/apache/camel/k/jvm/Application.java
@@ -18,23 +18,19 @@ package org.apache.camel.k.jvm;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.main.Main;
+import org.apache.camel.util.ObjectHelper;
public class Application {
- public static final String ENV_CAMEL_K_ROUTES_URI = "CAMEL_K_ROUTES_URI";
- public static final String SCHEME_CLASSPATH = "classpath:";
- public static final String SCHEME_FILE = "file:";
public static void main(String[] args) throws Exception {
- final String resource = System.getenv(ENV_CAMEL_K_ROUTES_URI);
+ final String resource = System.getenv(Routes.ENV_CAMEL_K_ROUTES_URI);
+ final String language = System.getenv(Routes.ENV_CAMEL_K_ROUTES_LANGUAGE);
- if (resource == null || resource.trim().length() == 0) {
- throw new IllegalStateException("No valid resource found in " + ENV_CAMEL_K_ROUTES_URI + " environment variable");
- }
- if (!resource.startsWith(SCHEME_CLASSPATH) && !resource.startsWith(SCHEME_FILE)) {
- throw new IllegalStateException("No valid resource format, expected scheme:path, found " + resource);
+ if (ObjectHelper.isEmpty(resource)) {
+ throw new IllegalStateException("No valid resource found in " + Routes.ENV_CAMEL_K_ROUTES_URI + " environment variable");
}
- RoutesLoader loader = RouteLoaders.loaderFor(resource);
+ RoutesLoader loader = Routes.loaderFor(resource, language);
RouteBuilder routes = loader.load(resource);
if (routes == null) {
diff --git a/runtime/jvm/src/main/java/org/apache/camel/k/jvm/Routes.java b/runtime/jvm/src/main/java/org/apache/camel/k/jvm/Routes.java
new file mode 100644
index 0000000..b2c87d4
--- /dev/null
+++ b/runtime/jvm/src/main/java/org/apache/camel/k/jvm/Routes.java
@@ -0,0 +1,88 @@
+/**
+ * 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.jvm;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import org.apache.camel.util.ObjectHelper;
+import org.apache.commons.lang3.StringUtils;
+
+public final class Routes {
+ public static final String ENV_CAMEL_K_ROUTES_URI = "CAMEL_K_ROUTES_URI";
+ public static final String ENV_CAMEL_K_ROUTES_LANGUAGE = "CAMEL_K_ROUTES_LANGUAGE";
+ public static final String SCHEME_CLASSPATH = "classpath:";
+ public static final String SCHEME_FILE = "file:";
+
+ private Routes() {
+ }
+
+ public static boolean isScripting(String resource) {
+ return resource.endsWith(".java") || resource.endsWith(".js") || resource.endsWith(".groovy");
+ }
+
+ public static RoutesLoader loaderForLanguage(String language) {
+ for (RoutesLoader loader: RoutesLoaders.values()) {
+ if (loader.getSupportedLanguages().contains(language)) {
+ return loader;
+ }
+ }
+
+ throw new IllegalArgumentException("Unable to find loader for language: " + language);
+ }
+
+ public static RoutesLoader loaderForResource(String resource) {
+ if (!resource.startsWith(SCHEME_CLASSPATH) && !resource.startsWith(SCHEME_FILE)) {
+ throw new IllegalArgumentException("No valid resource format, expected scheme:path, found " + resource);
+ }
+
+ for (RoutesLoader loader: RoutesLoaders.values()) {
+ if (loader.test(resource)) {
+ return loader;
+ }
+ }
+
+ throw new IllegalArgumentException("Unable to find loader for: " + resource);
+ }
+
+ public static RoutesLoader loaderFor(String resource, String language) {
+ if (!resource.startsWith(SCHEME_CLASSPATH) && !resource.startsWith(SCHEME_FILE)) {
+ throw new IllegalArgumentException("No valid resource format, expected scheme:path, found " + resource);
+ }
+
+ return ObjectHelper.isEmpty(language)
+ ? loaderForResource(resource)
+ : loaderForLanguage(language);
+ }
+
+ static InputStream loadResourceAsInputStream(String resource) throws IOException {
+ if (resource.startsWith(SCHEME_CLASSPATH)) {
+ String location = StringUtils.removeStart(resource, SCHEME_CLASSPATH);
+ if (!location.startsWith("/")) {
+ location = "/" + location;
+ }
+
+ return Application.class.getResourceAsStream(location);
+ } else {
+ return Files.newInputStream(
+ Paths.get(resource.substring(SCHEME_FILE.length()))
+ );
+ }
+ }
+}
diff --git a/runtime/jvm/src/main/java/org/apache/camel/k/jvm/RoutesLoader.java b/runtime/jvm/src/main/java/org/apache/camel/k/jvm/RoutesLoader.java
index 9589822..1446b55 100644
--- a/runtime/jvm/src/main/java/org/apache/camel/k/jvm/RoutesLoader.java
+++ b/runtime/jvm/src/main/java/org/apache/camel/k/jvm/RoutesLoader.java
@@ -16,10 +16,25 @@
*/
package org.apache.camel.k.jvm;
+import java.util.List;
import java.util.function.Predicate;
import org.apache.camel.builder.RouteBuilder;
public interface RoutesLoader extends Predicate<String> {
+ /**
+ * Provides a list of the languages supported by this loader.
+ *
+ * @return the supported languages.
+ */
+ List<String> getSupportedLanguages();
+
+ /**
+ * Creates a camel {@link RouteBuilder} from the given resource.
+ *
+ * @param resource the location fo the resource to load.
+ * @return the RouteBuilder.
+ * @throws Exception
+ */
RouteBuilder load(String resource) throws Exception;
}
diff --git a/runtime/jvm/src/main/java/org/apache/camel/k/jvm/RouteLoaders.java b/runtime/jvm/src/main/java/org/apache/camel/k/jvm/RoutesLoaders.java
similarity index 74%
rename from runtime/jvm/src/main/java/org/apache/camel/k/jvm/RouteLoaders.java
rename to runtime/jvm/src/main/java/org/apache/camel/k/jvm/RoutesLoaders.java
index 48a3fb6..ab1bc5c 100644
--- a/runtime/jvm/src/main/java/org/apache/camel/k/jvm/RouteLoaders.java
+++ b/runtime/jvm/src/main/java/org/apache/camel/k/jvm/RoutesLoaders.java
@@ -16,12 +16,11 @@
*/
package org.apache.camel.k.jvm;
-import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
-import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
import java.util.function.Function;
import javax.script.Bindings;
import javax.script.ScriptEngine;
@@ -40,16 +39,24 @@ import org.apache.commons.lang3.StringUtils;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.joor.Reflect;
-public enum RouteLoaders implements RoutesLoader {
+import static org.apache.camel.k.jvm.Routes.SCHEME_CLASSPATH;
+
+public enum RoutesLoaders implements RoutesLoader {
JavaClass {
@Override
+ public List<String> getSupportedLanguages() {
+ return Arrays.asList("class");
+ }
+
+ @Override
public boolean test(String resource) {
- return !isScripting(resource) && hasSupportedScheme(resource);
+ //TODO: add support for compiled classes
+ return !Routes.isScripting(resource) && !resource.endsWith(".class");
}
@Override
public RouteBuilder load(String resource) throws Exception {
- String path = resource.substring(Application.SCHEME_CLASSPATH.length());
+ String path = resource.substring(SCHEME_CLASSPATH.length());
Class<?> type = Class.forName(path);
if (!RouteBuilder.class.isAssignableFrom(type)) {
@@ -61,13 +68,21 @@ public enum RouteLoaders implements RoutesLoader {
},
JavaSource {
@Override
+ public List<String> getSupportedLanguages() {
+ return Arrays.asList("java");
+ }
+
+ @Override
public boolean test(String resource) {
- return isScripting(resource, "java") && hasSupportedScheme(resource);
+ String ext = StringUtils.substringAfterLast(resource, ".");
+ List<String> langs = getSupportedLanguages();
+
+ return langs.contains(ext);
}
@Override
public RouteBuilder load(String resource) throws Exception {
- try (InputStream is = is(resource)) {
+ try (InputStream is = Routes.loadResourceAsInputStream(resource)) {
String name = StringUtils.substringAfter(resource, ":");
name = StringUtils.removeEnd(name, ".java");
name = StringUtils.removeStart(name, "/");
@@ -78,8 +93,16 @@ public enum RouteLoaders implements RoutesLoader {
},
JavaScript {
@Override
+ public List<String> getSupportedLanguages() {
+ return Arrays.asList("js");
+ }
+
+ @Override
public boolean test(String resource) {
- return isScripting(resource, "js") && hasSupportedScheme(resource);
+ String ext = StringUtils.substringAfterLast(resource, ".");
+ List<String> langs = getSupportedLanguages();
+
+ return langs.contains(ext);
}
@Override
@@ -98,7 +121,7 @@ public enum RouteLoaders implements RoutesLoader {
bindings.put("components", new Components(context));
bindings.put("from", (Function<String, RouteDefinition>) uri -> from(uri));
- try (InputStream is = is(resource)) {
+ try (InputStream is = Routes.loadResourceAsInputStream(resource)) {
engine.eval(new InputStreamReader(is), bindings);
}
}
@@ -107,8 +130,16 @@ public enum RouteLoaders implements RoutesLoader {
},
Groovy {
@Override
+ public List<String> getSupportedLanguages() {
+ return Arrays.asList("groovy");
+ }
+
+ @Override
public boolean test(String resource) {
- return isScripting(resource, "groovy") && hasSupportedScheme(resource);
+ String ext = StringUtils.substringAfterLast(resource, ".");
+ List<String> langs = getSupportedLanguages();
+
+ return langs.contains(ext);
}
@Override
@@ -122,7 +153,7 @@ public enum RouteLoaders implements RoutesLoader {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
GroovyShell sh = new GroovyShell(cl, new Binding(), cc);
- try (InputStream is = is(resource)) {
+ try (InputStream is = Routes.loadResourceAsInputStream(resource)) {
Reader reader = new InputStreamReader(is);
DelegatingScript script = (DelegatingScript) sh.parse(reader);
@@ -142,42 +173,6 @@ public enum RouteLoaders implements RoutesLoader {
// TODO: move to a dedicate class
// ********************************
- public static boolean isScripting(String resource, String type) {
- return type.startsWith(".") ? resource.endsWith(type) : resource.endsWith("." + type);
- }
-
- public static boolean isScripting(String resource) {
- return resource.endsWith(".java") || resource.endsWith(".js") || resource.endsWith(".groovy");
- }
-
- public static boolean hasSupportedScheme(String resource) {
- return resource.startsWith(Application.SCHEME_CLASSPATH) || resource.startsWith(Application.SCHEME_FILE);
- }
-
- public static RoutesLoader loaderFor(String resource) {
- for (RoutesLoader loader: RouteLoaders.values()) {
- if (loader.test(resource)) {
- return loader;
- }
- }
-
- throw new IllegalArgumentException("Unable to find loader for: " + resource);
- }
-
- private static InputStream is(String resource) throws IOException {
- if (resource.startsWith(Application.SCHEME_CLASSPATH)) {
- String location = StringUtils.removeStart(resource, Application.SCHEME_CLASSPATH);
- if (!location.startsWith("/")) {
- location = "/" + location;
- }
-
- return Application.class.getResourceAsStream(location);
- } else {
- return Files.newInputStream(
- Paths.get(resource.substring(Application.SCHEME_FILE.length()))
- );
- }
- }
public static class Components {
private CamelContext context;
diff --git a/runtime/jvm/src/test/java/org/apache/camel/k/jvm/ApplicationTest.java b/runtime/jvm/src/test/java/org/apache/camel/k/jvm/ApplicationTest.java
index e43d711..0b576dd 100644
--- a/runtime/jvm/src/test/java/org/apache/camel/k/jvm/ApplicationTest.java
+++ b/runtime/jvm/src/test/java/org/apache/camel/k/jvm/ApplicationTest.java
@@ -1,3 +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.
+ */
package org.apache.camel.k.jvm;
import org.junit.Ignore;
diff --git a/runtime/jvm/src/test/java/org/apache/camel/k/jvm/MyRoutes.java b/runtime/jvm/src/test/java/org/apache/camel/k/jvm/MyRoutes.java
index c92f35a..3869f2d 100644
--- a/runtime/jvm/src/test/java/org/apache/camel/k/jvm/MyRoutes.java
+++ b/runtime/jvm/src/test/java/org/apache/camel/k/jvm/MyRoutes.java
@@ -1,3 +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.
+ */
package org.apache.camel.k.jvm;
import org.apache.camel.builder.RouteBuilder;
diff --git a/runtime/jvm/src/test/java/org/apache/camel/k/jvm/RouteLoadersTest.java b/runtime/jvm/src/test/java/org/apache/camel/k/jvm/RoutesLoadersTest.java
similarity index 70%
rename from runtime/jvm/src/test/java/org/apache/camel/k/jvm/RouteLoadersTest.java
rename to runtime/jvm/src/test/java/org/apache/camel/k/jvm/RoutesLoadersTest.java
index 8701558..e083464 100644
--- a/runtime/jvm/src/test/java/org/apache/camel/k/jvm/RouteLoadersTest.java
+++ b/runtime/jvm/src/test/java/org/apache/camel/k/jvm/RoutesLoadersTest.java
@@ -25,15 +25,15 @@ import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
-public class RouteLoadersTest {
+public class RoutesLoadersTest {
@Test
public void testLoadClass() throws Exception {
String resource = "classpath:" + MyRoutes.class.getCanonicalName();
- RoutesLoader loader = RouteLoaders.loaderFor(resource);
+ RoutesLoader loader = Routes.loaderForResource(resource);
RouteBuilder builder = loader.load(resource);
- assertThat(loader).isSameAs(RouteLoaders.JavaClass);
+ assertThat(loader).isSameAs(RoutesLoaders.JavaClass);
assertThat(builder).isNotNull();
builder.configure();
@@ -47,10 +47,10 @@ public class RouteLoadersTest {
@Test
public void testLoadJava() throws Exception {
String resource = "classpath:MyRoutes.java";
- RoutesLoader loader = RouteLoaders.loaderFor(resource);
+ RoutesLoader loader = Routes.loaderForResource(resource);
RouteBuilder builder = loader.load(resource);
- assertThat(loader).isSameAs(RouteLoaders.JavaSource);
+ assertThat(loader).isSameAs(RoutesLoaders.JavaSource);
assertThat(builder).isNotNull();
builder.configure();
@@ -64,10 +64,27 @@ public class RouteLoadersTest {
@Test
public void testLoadJavaScript() throws Exception {
String resource = "classpath:routes.js";
- RoutesLoader loader = RouteLoaders.loaderFor(resource);
+ RoutesLoader loader = Routes.loaderForResource(resource);
RouteBuilder builder = loader.load(resource);
- assertThat(loader).isSameAs(RouteLoaders.JavaScript);
+ assertThat(loader).isSameAs(RoutesLoaders.JavaScript);
+ assertThat(builder).isNotNull();
+
+ builder.configure();
+
+ List<RouteDefinition> routes = builder.getRouteCollection().getRoutes();
+ assertThat(routes).hasSize(1);
+ assertThat(routes.get(0).getInputs().get(0).getEndpointUri()).isEqualTo("timer:tick");
+ assertThat(routes.get(0).getOutputs().get(0)).isInstanceOf(ToDefinition.class);
+ }
+
+ @Test
+ public void testLoadJavaScriptWithCustomExtension() throws Exception {
+ String resource = "classpath:routes.mytype";
+ RoutesLoader loader = Routes.loaderFor(resource, "js");
+ RouteBuilder builder = loader.load(resource);
+
+ assertThat(loader).isSameAs(RoutesLoaders.JavaScript);
assertThat(builder).isNotNull();
builder.configure();
@@ -81,10 +98,10 @@ public class RouteLoadersTest {
@Test
public void testLoadGroovy() throws Exception {
String resource = "classpath:routes.groovy";
- RoutesLoader loader = RouteLoaders.loaderFor(resource);
+ RoutesLoader loader = Routes.loaderForResource(resource);
RouteBuilder builder = loader.load(resource);
- assertThat(loader).isSameAs(RouteLoaders.Groovy);
+ assertThat(loader).isSameAs(RoutesLoaders.Groovy);
assertThat(builder).isNotNull();
builder.configure();
@@ -97,11 +114,16 @@ public class RouteLoadersTest {
@Test(expected = IllegalArgumentException.class)
public void testResourceWithoutScheme() {
- RouteLoaders.loaderFor("routes.js");
+ Routes.loaderForResource("routes.js");
}
@Test(expected = IllegalArgumentException.class)
public void testResourceWithIllegalScheme() {
- RouteLoaders.loaderFor("http:routes.js");
+ Routes.loaderForResource("http:routes.js");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testUnsupportedLanguage() {
+ Routes.loaderForLanguage(" test");
}
}
diff --git a/runtime/jvm/src/test/resources/routes.mytype b/runtime/jvm/src/test/resources/routes.mytype
new file mode 100644
index 0000000..0f5600d
--- /dev/null
+++ b/runtime/jvm/src/test/resources/routes.mytype
@@ -0,0 +1,3 @@
+
+from('timer:tick')
+ .to('log:info')
\ No newline at end of file