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
commit 7da47e324e9126c61a1c2fc9c9bb40d7b95fd4e2 Author: lburgazzoli <lburgazz...@gmail.com> AuthorDate: Tue Dec 18 14:26:44 2018 +0100 support resources as env var --- examples/resources-route.groovy | 2 +- pkg/trait/knative.go | 23 +++++ pkg/trait/knative_test.go | 32 +++++++ runtime/camel-k-runtime-jvm/pom.xml | 15 ++++ .../java/org/apache/camel/k/jvm/Application.java | 7 ++ .../org/apache/camel/k/jvm/RuntimeSupport.java | 98 ++++++++++++++++++++++ .../java/org/apache/camel/k/jvm/RuntimeTest.java | 24 ++++++ .../src/test/resources/my-resource.txt | 1 + .../apache/camel/k/kotlin/KotlinRoutesLoader.kt | 2 +- .../apache/camel/k/spring/boot/Application.java | 9 ++ 10 files changed, 211 insertions(+), 2 deletions(-) diff --git a/examples/resources-route.groovy b/examples/resources-route.groovy index e87c930..4c7d61b 100644 --- a/examples/resources-route.groovy +++ b/examples/resources-route.groovy @@ -7,5 +7,5 @@ from('timer:resources') .routeId('resources') .setBody() - .simple("resource:classpath:resources-data.txt") + .simple("resource:platform:resources-data.txt") .log('file content is: ${body}') diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go index b31ef07..ae2e30d 100644 --- a/pkg/trait/knative.go +++ b/pkg/trait/knative.go @@ -156,6 +156,29 @@ func (t *knativeTrait) getServiceFor(e *Environment) *serving.Service { sources = append(sources, src) } + for i, r := range e.Integration.Spec.Resources { + envName := fmt.Sprintf("CAMEL_K_RESOURCE_%03d", i) + envvar.SetVal(&environment, envName, r.Content) + + params := make([]string, 0) + if r.Compression { + params = append(params, "compression=true") + } + + envValue := fmt.Sprintf("env:%s", envName) + if len(params) > 0 { + envValue = fmt.Sprintf("%s?%s", envValue, strings.Join(params, "&")) + } + + envName = r.Name + envName = strings.ToUpper(envName) + envName = strings.Replace(envName, "-", "_", -1) + envName = strings.Replace(envName, ".", "_", -1) + envName = strings.Replace(envName, " ", "_", -1) + + envvar.SetVal(&environment, envName, envValue) + } + // set env vars needed by the runtime envvar.SetVal(&environment, "JAVA_MAIN_CLASS", "org.apache.camel.k.jvm.Application") diff --git a/pkg/trait/knative_test.go b/pkg/trait/knative_test.go index 2d50e48..9827ef9 100644 --- a/pkg/trait/knative_test.go +++ b/pkg/trait/knative_test.go @@ -58,6 +58,22 @@ func TestKnativeTraitWithCompressedSources(t *testing.T) { Language: v1alpha1.LanguageJavaScript, }, }, + Resources: []v1alpha1.ResourceSpec{ + { + DataSpec: v1alpha1.DataSpec{ + Name: "my-resource.txt", + Content: content, + Compression: false, + }, + }, + { + DataSpec: v1alpha1.DataSpec{ + Name: "my-resource.gz", + Content: content, + Compression: true, + }, + }, + }, }, }, Platform: &v1alpha1.IntegrationPlatform{ @@ -94,6 +110,22 @@ func TestKnativeTraitWithCompressedSources(t *testing.T) { route := util.LookupEnvVar(vars, "CAMEL_K_ROUTE_000") assert.NotNil(t, route) assert.Equal(t, content, route.Value) + + resource := util.LookupEnvVar(vars, "MY_RESOURCE_TXT") + assert.NotNil(t, resource) + assert.Equal(t, "env:CAMEL_K_RESOURCE_000", resource.Value) + + resource = util.LookupEnvVar(vars, "CAMEL_K_RESOURCE_000") + assert.NotNil(t, resource) + assert.Equal(t, content, resource.Value) + + resource = util.LookupEnvVar(vars, "MY_RESOURCE_GZ") + assert.NotNil(t, resource) + assert.Equal(t, "env:CAMEL_K_RESOURCE_001?compression=true", resource.Value) + + resource = util.LookupEnvVar(vars, "CAMEL_K_RESOURCE_001") + assert.NotNil(t, resource) + assert.Equal(t, content, resource.Value) }) assert.True(t, services > 0) diff --git a/runtime/camel-k-runtime-jvm/pom.xml b/runtime/camel-k-runtime-jvm/pom.xml index aa48603..a4d1832 100644 --- a/runtime/camel-k-runtime-jvm/pom.xml +++ b/runtime/camel-k-runtime-jvm/pom.xml @@ -96,4 +96,19 @@ </dependency> </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <environmentVariables> + <CAMEL_K_RESOURCE_001>value from env</CAMEL_K_RESOURCE_001> + <MY_OTHER_RESOURCE_TXT>env:CAMEL_K_RESOURCE_001</MY_OTHER_RESOURCE_TXT> + </environmentVariables> + </configuration> + </plugin> + </plugins> + </build> + </project> diff --git a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/Application.java b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/Application.java index 682609c..b98c95b 100644 --- a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/Application.java +++ b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/Application.java @@ -34,6 +34,13 @@ public class Application { // We now support setting the logging level only // RuntimeSupport.configureLogging(); + + // + // Install a custom protocol handler to support discovering resources + // from the platform i.e. in knative, resources are provided through + // env var as it is not possible to mount config maps / secrets. + // + RuntimeSupport.configureStreamHandler(); } // ******************************* diff --git a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/RuntimeSupport.java b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/RuntimeSupport.java index 700d70d..60d1cf9 100644 --- a/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/RuntimeSupport.java +++ b/runtime/camel-k-runtime-jvm/src/main/java/org/apache/camel/k/jvm/RuntimeSupport.java @@ -16,8 +16,15 @@ */ package org.apache.camel.k.jvm; +import java.io.ByteArrayInputStream; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.io.Reader; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; @@ -25,8 +32,11 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; +import java.util.Base64; +import java.util.Map; import java.util.Objects; import java.util.Properties; +import java.util.zip.GZIPInputStream; import org.apache.camel.CamelContext; import org.apache.camel.NoFactoryAvailableException; @@ -38,7 +48,9 @@ import org.apache.camel.k.Source; import org.apache.camel.spi.FactoryFinder; import org.apache.camel.util.IntrospectionSupport; import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.URISupport; import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.LoggerContext; @@ -203,4 +215,90 @@ public final class RuntimeSupport { return loader; } + + public static void configureStreamHandler() { + URL.setURLStreamHandlerFactory(protocol -> "platform".equals(protocol) ? new PlatformStreamHandler() : null); + } + + // *************************************** + // + // + // + // *************************************** + + private static class PlatformStreamHandler extends URLStreamHandler { + @Override + protected URLConnection openConnection(URL url) throws IOException { + return new URLConnection(url) { + @Override + public void connect() throws IOException { + } + + @Override + public InputStream getInputStream() throws IOException { + InputStream is = null; + + // check if the file exists + Path path = Paths.get(url.getPath()); + if (Files.exists(path)) { + is = Files.newInputStream(path); + } + + // check if the file exists in classpath + if (is == null) { + is = ObjectHelper.loadResourceAsStream(url.getPath()); + } + + if (is == null) { + String name = getURL().getPath().toUpperCase(); + name = name.replace(" ", "_"); + name = name.replace(".", "_"); + name = name.replace("-", "_"); + + String envName = System.getenv(name); + String envType = StringUtils.substringBefore(envName, ":"); + String envQuery = StringUtils.substringAfter(envName, "?"); + + envName = StringUtils.substringAfter(envName, ":"); + envName = StringUtils.substringBefore(envName, "?"); + + if (envName != null) { + try { + final Map<String, Object> params = URISupport.parseQuery(envQuery); + final boolean compression = Boolean.valueOf((String) params.get("compression")); + + if (StringUtils.equals(envType, "env")) { + String data = System.getenv(envName); + + if (data == null) { + throw new IllegalArgumentException("Unknown env var: " + envName); + } + + is = new ByteArrayInputStream(data.getBytes()); + } else if (StringUtils.equals(envType, "file")) { + Path data = Paths.get(envName); + + if (!Files.exists(data)) { + throw new FileNotFoundException(envName); + } + + is = Files.newInputStream(data); + } else if (StringUtils.equals(envType, "classpath")) { + is = ObjectHelper.loadResourceAsStream(envName); + } + + if (is != null && compression) { + is = new GZIPInputStream(Base64.getDecoder().wrap(is)); + } + } catch (URISyntaxException e) { + throw new IOException(e); + } + } + } + + return is; + } + }; + } + } } diff --git a/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/RuntimeTest.java b/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/RuntimeTest.java index 909ae23..e434c26 100644 --- a/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/RuntimeTest.java +++ b/runtime/camel-k-runtime-jvm/src/test/java/org/apache/camel/k/jvm/RuntimeTest.java @@ -16,11 +16,15 @@ */ package org.apache.camel.k.jvm; +import java.io.InputStream; +import java.nio.charset.Charset; import java.util.List; import org.apache.camel.CamelContext; import org.apache.camel.Route; import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.ResourceHelper; +import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Java6Assertions.assertThat; @@ -48,4 +52,24 @@ public class RuntimeTest { runtime.stop(); } } + + + @Test + void testLoadResource() throws Exception { + RuntimeSupport.configureStreamHandler(); + + CamelContext context = new Runtime().getCamelContext(); + + try (InputStream is = ResourceHelper.resolveMandatoryResourceAsInputStream(context, "platform:my-resource.txt")) { + String content = IOUtils.toString(is, Charset.defaultCharset()); + + assertThat(content).isEqualTo("value from file resource"); + } + + try (InputStream is = ResourceHelper.resolveMandatoryResourceAsInputStream(context, "platform:my-other-resource.txt")) { + String content = IOUtils.toString(is, Charset.defaultCharset()); + + assertThat(content).isEqualTo("value from env"); + } + } } diff --git a/runtime/camel-k-runtime-jvm/src/test/resources/my-resource.txt b/runtime/camel-k-runtime-jvm/src/test/resources/my-resource.txt new file mode 100644 index 0000000..817b31f --- /dev/null +++ b/runtime/camel-k-runtime-jvm/src/test/resources/my-resource.txt @@ -0,0 +1 @@ +value from file resource \ No newline at end of file diff --git a/runtime/camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/KotlinRoutesLoader.kt b/runtime/camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/KotlinRoutesLoader.kt index 7902539..d72bb60 100644 --- a/runtime/camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/KotlinRoutesLoader.kt +++ b/runtime/camel-k-runtime-kotlin/src/main/kotlin/org/apache/camel/k/kotlin/KotlinRoutesLoader.kt @@ -21,7 +21,7 @@ import org.apache.camel.k.Language import org.apache.camel.k.RoutesLoader import org.apache.camel.k.RuntimeRegistry import org.apache.camel.k.Source -import org.apache.camel.k.jvm.* +import org.apache.camel.k.jvm.URIResolver import org.apache.camel.k.kotlin.dsl.IntegrationConfiguration import org.slf4j.Logger import org.slf4j.LoggerFactory diff --git a/runtime/camel-k-runtime-spring-boot/src/main/java/org/apache/camel/k/spring/boot/Application.java b/runtime/camel-k-runtime-spring-boot/src/main/java/org/apache/camel/k/spring/boot/Application.java index 427dd9e..a6fbb5a 100644 --- a/runtime/camel-k-runtime-spring-boot/src/main/java/org/apache/camel/k/spring/boot/Application.java +++ b/runtime/camel-k-runtime-spring-boot/src/main/java/org/apache/camel/k/spring/boot/Application.java @@ -42,6 +42,15 @@ import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; public class Application { private static final Logger LOGGER = LoggerFactory.getLogger(Application.class); + static { + // + // Install a custom protocol handler to support discovering resources + // from the platform i.e. in knative, resources are provided through + // env var as it is not possible to mount config maps / secrets. + // + RuntimeSupport.configureStreamHandler(); + } + public static void main(String[] args) { SpringApplication.run(Application.class, args); }