This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit b929b1b6986d088e0f15959c41ce25a046a21aa5 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Sun May 8 07:48:23 2022 +0200 CAMEL-18077: camel-jbang - Run from gist --- .../apache/camel/github/GistResourceResolver.java | 16 +-- .../camel/github/GistResourceResolverTest.java | 4 +- .../camel/dsl/jbang/core/commands/GistHelper.java | 119 +++++++++++++++++++++ .../apache/camel/dsl/jbang/core/commands/Run.java | 25 +++++ 4 files changed, 156 insertions(+), 8 deletions(-) diff --git a/components/camel-resourceresolver-github/src/main/java/org/apache/camel/github/GistResourceResolver.java b/components/camel-resourceresolver-github/src/main/java/org/apache/camel/github/GistResourceResolver.java index b1a3f51eaad..d3e1cf683a5 100644 --- a/components/camel-resourceresolver-github/src/main/java/org/apache/camel/github/GistResourceResolver.java +++ b/components/camel-resourceresolver-github/src/main/java/org/apache/camel/github/GistResourceResolver.java @@ -24,9 +24,9 @@ import org.apache.camel.support.service.ServiceSupport; @ResourceResolver("gist") public class GistResourceResolver extends ServiceSupport implements org.apache.camel.spi.ResourceResolver { - // gist:davsclaus:477ddff5cdeb1ae03619aa544ce47e92 - // https://gist.githubusercontent.com/davsclaus/477ddff5cdeb1ae03619aa544ce47e92/raw - private static final String GIST_URL = "https://gist.githubusercontent.com/%s/%s/raw"; + // gist:davsclaus:477ddff5cdeb1ae03619aa544ce47e92:cd1be96034748e42e43879a4d27ed297752b6115:mybeer.xml + // https://gist.githubusercontent.com/davsclaus/477ddff5cdeb1ae03619aa544ce47e92/raw/cd1be96034748e42e43879a4d27ed297752b6115/mybeer.xml + private static final String GIST_URL = "https://gist.githubusercontent.com/%s/%s/raw/%s/%s"; private CamelContext camelContext; @@ -51,16 +51,20 @@ public class GistResourceResolver extends ServiceSupport implements org.apache.c // scheme not in use as its gist String user = null; String gid = null; + String gid2 = null; + String fileName = null; - if (parts.length == 3) { + if (parts.length == 5) { user = parts[1]; gid = parts[2]; + gid2 = parts[3]; + fileName = parts[4]; } - if (user == null || gid == null) { + if (user == null || gid == null || gid2 == null || fileName == null) { throw new IllegalArgumentException(location); } - String target = String.format(GIST_URL, user, gid); + String target = String.format(GIST_URL, user, gid, gid2, fileName); return new GistResource(camelContext, target); } } diff --git a/components/camel-resourceresolver-github/src/test/java/org/apache/camel/github/GistResourceResolverTest.java b/components/camel-resourceresolver-github/src/test/java/org/apache/camel/github/GistResourceResolverTest.java index 8f84784927f..fe24b4a8365 100644 --- a/components/camel-resourceresolver-github/src/test/java/org/apache/camel/github/GistResourceResolverTest.java +++ b/components/camel-resourceresolver-github/src/test/java/org/apache/camel/github/GistResourceResolverTest.java @@ -30,10 +30,10 @@ public class GistResourceResolverTest extends CamelTestSupport { @Test public void testGist() throws Exception { ExtendedCamelContext ecc = context.adapt(ExtendedCamelContext.class); - Resource res = ecc.getResourceLoader().resolveResource("gist:davsclaus:123"); + Resource res = ecc.getResourceLoader().resolveResource("gist:davsclaus:123:456:beer.xml"); assertNotNull(res); assertFalse(res.exists()); - assertEquals("https://gist.githubusercontent.com/davsclaus/123/raw", res.getLocation()); + assertEquals("https://gist.githubusercontent.com/davsclaus/123/raw/456/beer.xml", res.getLocation()); } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/GistHelper.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/GistHelper.java new file mode 100644 index 00000000000..bba81f4cc16 --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/GistHelper.java @@ -0,0 +1,119 @@ +/* + * 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.dsl.jbang.core.commands; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.StringJoiner; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.camel.util.FileUtil; + +public final class GistHelper { + + private GistHelper() { + } + + public static String asGistSingleUrl(String url) throws Exception { + if (url.startsWith("https://gist.githubusercontent.com/")) { + url = url.substring(35); + } else if (url.startsWith("https://gist.github.com/")) { + url = url.substring(24); + } + + // https://gist.github.com/davsclaus/477ddff5cdeb1ae03619aa544ce47e92 + // https://gist.githubusercontent.com/davsclaus/477ddff5cdeb1ae03619aa544ce47e92/raw/cd1be96034748e42e43879a4d27ed297752b6115/mybeer.xml + url = url.replaceFirst("/", ":"); + url = url.replaceFirst("/raw/", ":"); + url = url.replaceFirst("/", ":"); + return "gist:" + url; + } + + public static void fetchGistUrls(String url, StringJoiner routes, StringJoiner kamelets, StringJoiner properties) + throws Exception { + doFetchGistUrls(url, routes, kamelets, properties, null); + } + + private static void doFetchGistUrls( + String url, StringJoiner routes, StringJoiner kamelets, StringJoiner properties, + StringJoiner all) + throws Exception { + + // a gist can have one or more files + // https://gist.github.com/davsclaus/477ddff5cdeb1ae03619aa544ce47e92 + + // strip https://gist.github.com/ + url = url.substring(24); + + String[] parts = url.split("/"); + if (parts.length < 2) { + return; + } + String user = parts[0]; + String gid = parts[1]; + + url = "https://api.github.com/gists/" + gid; + + resolveGistAsRawFiles(url, routes, kamelets, properties, all); + } + + private static void resolveGistAsRawFiles( + String url, StringJoiner routes, StringJoiner kamelets, StringJoiner properties, StringJoiner all) + throws Exception { + + // use JDK http client to call github api + HttpClient hc = HttpClient.newHttpClient(); + HttpResponse<String> res = hc.send(HttpRequest.newBuilder(new URI(url)).timeout(Duration.ofSeconds(20)).build(), + HttpResponse.BodyHandlers.ofString()); + + if (res.statusCode() == 200) { + ObjectMapper mapper = new ObjectMapper(); + JsonNode root = mapper.readTree(res.body()); + for (JsonNode c : root.get("files")) { + String name = c.get("filename").asText(); + String ext = FileUtil.onlyExt(name, false); + if (kamelets != null && "kamelet.yaml".equalsIgnoreCase(ext)) { + String rawUrl = c.get("raw_url").asText(); + String u = asGistSingleUrl(rawUrl); + kamelets.add(u); + } else if (properties != null && "properties".equalsIgnoreCase(ext)) { + String rawUrl = c.get("raw_url").asText(); + String u = asGistSingleUrl(rawUrl); + properties.add(u); + } else if (routes != null) { + if ("java".equalsIgnoreCase(ext) || "xml".equalsIgnoreCase(ext) + || "yaml".equalsIgnoreCase(ext) + || "groovy".equalsIgnoreCase(ext) || "js".equalsIgnoreCase(ext) || "jsh".equalsIgnoreCase(ext) + || "kts".equalsIgnoreCase(ext)) { + String rawUrl = c.get("raw_url").asText(); + String u = asGistSingleUrl(rawUrl); + routes.add(u); + } + } else if (all != null) { + String rawUrl = c.get("raw_url").asText(); + String u = asGistSingleUrl(rawUrl); + all.add(u); + } + } + } + } + +} diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java index 5a98598343f..3b9e035bae4 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java @@ -59,6 +59,7 @@ import picocli.CommandLine.Command; import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; +import static org.apache.camel.dsl.jbang.core.commands.GistHelper.fetchGistUrls; import static org.apache.camel.dsl.jbang.core.commands.GitHubHelper.asGithubSingleUrl; import static org.apache.camel.dsl.jbang.core.commands.GitHubHelper.fetchGithubUrls; @@ -458,6 +459,30 @@ class Run implements Callable<Integer> { } } + if (file.startsWith("https://gist.github.com/")) { + StringJoiner routes = new StringJoiner(","); + StringJoiner kamelets = new StringJoiner(","); + StringJoiner properties = new StringJoiner(","); + fetchGistUrls(file, routes, kamelets, properties); + + if (routes.length() > 0) { + file = routes.toString(); + } + if (properties.length() > 0) { + main.addInitialProperty("camel.component.properties.location", properties.toString()); + } + if (kamelets.length() > 0) { + String loc = main.getInitialProperties().getProperty("camel.component.kamelet.location"); + if (loc != null) { + // local kamelets first + loc = kamelets + "," + loc; + } else { + loc = kamelets.toString(); + } + main.addInitialProperty("camel.component.kamelet.location", loc); + } + } + js.add(file); if (dev && file.startsWith("file:")) { // we can only reload if file based