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
The following commit(s) were added to refs/heads/main by this push:
new aa9aa35 CAMEL-16585: camel-kamelet - Main class to easily bootstrap
Camel with Kamelets
aa9aa35 is described below
commit aa9aa3575e16623f549313f3145a7d949615353d
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon May 24 21:07:26 2021 +0200
CAMEL-16585: camel-kamelet - Main class to easily bootstrap Camel with
Kamelets
---
.../apache/camel/catalog/docs/kamelet-main.adoc | 26 +++++++-
components/camel-kamelet-main/pom.xml | 10 ++-
.../src/main/docs/kamelet-main.adoc | 26 +++++++-
.../camel/main/KameletDependencyDownloader.java | 40 +++++++++---
.../java/org/apache/camel/main/KameletMain.java | 7 ++-
.../main/java/org/apache/camel/main/MavenGav.java | 73 ++++++++++++++++++++++
.../modules/others/pages/kamelet-main.adoc | 26 +++++++-
7 files changed, 195 insertions(+), 13 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/kamelet-main.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/kamelet-main.adoc
index 2120967..4e196d1 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/kamelet-main.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/kamelet-main.adoc
@@ -22,4 +22,28 @@ camel.main.routes-include-pattern = classpath:camel/*
camel.main.lightweight = true
----
-These settings can be overridden by configuration in `application.properties`.
\ No newline at end of file
+These settings can be overridden by configuration in `application.properties`.
+
+== Automatic dependencies downloading
+
+The Kamelet Main can automatic download Kamelet YAML files from a remote
location over http/https, and from github as well.
+
+The official Kameleets from the Apache Camel Kamelet Catalog is stored on
github and they can be used out of the box as-is.
+
+For example a Camel route can be _coded_ in YAML which uses the Earthquake
Kamelet from the catalog, as shown below:
+
+[source,yaml]
+----
+- route:
+ from: "kamelet:earthquake-source"
+ steps:
+ - unmarshal:
+ json: {}
+ - log: "Earthquake with magnitude ${body[properties][mag]} at
${body[properties][place]}"
+----
+
+In this use-case the earthquake kamelet will be downloaded from github, and as
well its required dependencies.
+
+You can find an example with this at
+https://github.com/apache/camel-examples/tree/main/examples/kamelet-main[kamelet-main].
+
diff --git a/components/camel-kamelet-main/pom.xml
b/components/camel-kamelet-main/pom.xml
index 1cdb924..6fb2a3f 100644
--- a/components/camel-kamelet-main/pom.xml
+++ b/components/camel-kamelet-main/pom.xml
@@ -51,12 +51,20 @@
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
- <artifactId>camel-yaml-dsl</artifactId>
+ <artifactId>camel-jackson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-grape</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-resourceresolver-github</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-yaml-dsl</artifactId>
+ </dependency>
</dependencies>
diff --git a/components/camel-kamelet-main/src/main/docs/kamelet-main.adoc
b/components/camel-kamelet-main/src/main/docs/kamelet-main.adoc
index 2120967..4e196d1 100644
--- a/components/camel-kamelet-main/src/main/docs/kamelet-main.adoc
+++ b/components/camel-kamelet-main/src/main/docs/kamelet-main.adoc
@@ -22,4 +22,28 @@ camel.main.routes-include-pattern = classpath:camel/*
camel.main.lightweight = true
----
-These settings can be overridden by configuration in `application.properties`.
\ No newline at end of file
+These settings can be overridden by configuration in `application.properties`.
+
+== Automatic dependencies downloading
+
+The Kamelet Main can automatic download Kamelet YAML files from a remote
location over http/https, and from github as well.
+
+The official Kameleets from the Apache Camel Kamelet Catalog is stored on
github and they can be used out of the box as-is.
+
+For example a Camel route can be _coded_ in YAML which uses the Earthquake
Kamelet from the catalog, as shown below:
+
+[source,yaml]
+----
+- route:
+ from: "kamelet:earthquake-source"
+ steps:
+ - unmarshal:
+ json: {}
+ - log: "Earthquake with magnitude ${body[properties][mag]} at
${body[properties][place]}"
+----
+
+In this use-case the earthquake kamelet will be downloaded from github, and as
well its required dependencies.
+
+You can find an example with this at
+https://github.com/apache/camel-examples/tree/main/examples/kamelet-main[kamelet-main].
+
diff --git
a/components/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletDependencyDownloader.java
b/components/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletDependencyDownloader.java
index 7709078..1fb3d04 100644
---
a/components/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletDependencyDownloader.java
+++
b/components/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletDependencyDownloader.java
@@ -19,14 +19,20 @@ package org.apache.camel.main;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import groovy.grape.Grape;
+import groovy.lang.GroovyClassLoader;
import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.dsl.yaml.YamlRoutesBuilderLoaderSupport;
+import org.apache.camel.util.StopWatch;
+import org.apache.camel.util.TimeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snakeyaml.engine.v2.nodes.Node;
@@ -45,6 +51,7 @@ public class KameletDependencyDownloader extends
YamlRoutesBuilderLoaderSupport
private CamelContext camelContext;
private final String cp = System.getProperty("java.class.path");
private final Set<String> downloaded = new HashSet<>();
+ private GroovyClassLoader groovyClassLoader;
public KameletDependencyDownloader(String extension) {
super(extension);
@@ -97,16 +104,33 @@ public class KameletDependencyDownloader extends
YamlRoutesBuilderLoaderSupport
String gav = dep;
if (dep.startsWith("camel:")) {
// its a known camel component
- gav = "org.apache.camel:camel-" + dep.substring(6) + ":" +
camelContext.getVersion();
+ gav = "mvn:org.apache.camel:camel-" + dep.substring(6) + ":" +
camelContext.getVersion();
}
if (isValidGav(gav)) {
gavs.add(gav);
}
}
- for (String gav : gavs) {
- LOG.debug("Downloading dependency: {}", gav);
- // TODO: download dependency and add to classpath
+ if (!gavs.isEmpty()) {
+ StopWatch watch = new StopWatch();
+ LOG.info("Downloading {} dependencies (may take some time)",
gavs.size());
+ for (String gav : gavs) {
+ MavenGav mg = MavenGav.parseGav(gav);
+ if (mg.getVersion() == null) {
+ mg.setVersion(camelContext.getVersion());
+ }
+ Map<String, Object> map = new HashMap<>();
+ map.put("classLoader",
camelContext.getApplicationContextClassLoader());
+ map.put("group", mg.getGroupId());
+ map.put("module", mg.getArtifactId());
+ map.put("version", mg.getVersion());
+ map.put("classifier", "");
+
+ LOG.info("Downloading dependency: {}", mg);
+ Grape.grab(map);
+ downloaded.add(gav);
+ }
+ LOG.info("Downloaded {} dependencies took: {}", gavs.size(),
TimeUtils.printDuration(watch.taken()));
}
}
@@ -117,15 +141,15 @@ public class KameletDependencyDownloader extends
YamlRoutesBuilderLoaderSupport
}
// skip camel-core and camel-kamelet as they are already included
- if (gav.startsWith("org.apache.camel:camel-core") ||
gav.startsWith("org.apache.camel:camel-kamelet:")) {
+ if (gav.startsWith("mvn:org.apache.camel:camel-core") ||
gav.startsWith("mvn:org.apache.camel:camel-kamelet:")) {
return false;
}
String[] arr = gav.split(":");
String name = null;
- if (arr.length == 3) {
- String aid = arr[1];
- String v = arr[2];
+ if (arr.length == 4) {
+ String aid = arr[2];
+ String v = arr[3];
name = aid + "-" + v + ".jar";
}
diff --git
a/components/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
b/components/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index dcbf733..1ca8e1b 100644
---
a/components/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++
b/components/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -18,6 +18,7 @@ package org.apache.camel.main;
import java.util.Map;
+import groovy.lang.GroovyClassLoader;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.RuntimeCamelException;
@@ -30,6 +31,7 @@ import org.apache.camel.spi.Registry;
public class KameletMain extends MainCommandLineSupport {
protected static KameletMain instance;
+ private static ClassLoader kameletClassLoader;
protected final MainRegistry registry = new MainRegistry();
private boolean download = true;
@@ -150,7 +152,10 @@ public class KameletMain extends MainCommandLineSupport {
protected CamelContext createCamelContext() {
// do not build/init camel context yet
DefaultCamelContext answer = new DefaultCamelContext(false);
-
answer.setApplicationContextClassLoader(KameletMain.class.getClassLoader());
+ if (kameletClassLoader == null) {
+ kameletClassLoader = new
GroovyClassLoader(KameletMain.class.getClassLoader());
+ }
+ answer.setApplicationContextClassLoader(kameletClassLoader);
answer.setRegistry(registry);
instance.addInitialProperty("camel.component.kamelet.location",
"classpath:/kamelets,github:apache:camel-kamelets");
instance.addInitialProperty("camel.main.routes-include-pattern",
"classpath:camel/*");
diff --git
a/components/camel-kamelet-main/src/main/java/org/apache/camel/main/MavenGav.java
b/components/camel-kamelet-main/src/main/java/org/apache/camel/main/MavenGav.java
new file mode 100644
index 0000000..9801f43
--- /dev/null
+++
b/components/camel-kamelet-main/src/main/java/org/apache/camel/main/MavenGav.java
@@ -0,0 +1,73 @@
+/*
+ * 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.main;
+
+public class MavenGav {
+
+ private String groupId;
+ private String artifactId;
+ private String version;
+
+ public MavenGav() {
+ }
+
+ public static MavenGav parseGav(String gav) {
+ MavenGav answer = new MavenGav();
+ // camel-k style GAV
+ if (gav.startsWith("camel:")) {
+ answer.setGroupId("org.apache.camel");
+ answer.setArtifactId(gav.substring(6));
+ } else {
+ String[] parts = gav.startsWith("mvn:") ?
gav.substring(4).split(":") : gav.split(":");
+ answer.setGroupId(parts[0]);
+ answer.setArtifactId(parts[1]);
+ if (parts.length == 3) {
+ answer.setVersion(parts[2]);
+ }
+ }
+ return answer;
+ }
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ @Override
+ public String toString() {
+ return groupId + ":" + artifactId + ":" + version;
+ }
+}
diff --git a/docs/components/modules/others/pages/kamelet-main.adoc
b/docs/components/modules/others/pages/kamelet-main.adoc
index 3d26044..66ca814 100644
--- a/docs/components/modules/others/pages/kamelet-main.adoc
+++ b/docs/components/modules/others/pages/kamelet-main.adoc
@@ -24,4 +24,28 @@ camel.main.routes-include-pattern = classpath:camel/*
camel.main.lightweight = true
----
-These settings can be overridden by configuration in `application.properties`.
\ No newline at end of file
+These settings can be overridden by configuration in `application.properties`.
+
+== Automatic dependencies downloading
+
+The Kamelet Main can automatic download Kamelet YAML files from a remote
location over http/https, and from github as well.
+
+The official Kameleets from the Apache Camel Kamelet Catalog is stored on
github and they can be used out of the box as-is.
+
+For example a Camel route can be _coded_ in YAML which uses the Earthquake
Kamelet from the catalog, as shown below:
+
+[source,yaml]
+----
+- route:
+ from: "kamelet:earthquake-source"
+ steps:
+ - unmarshal:
+ json: {}
+ - log: "Earthquake with magnitude ${body[properties][mag]} at
${body[properties][place]}"
+----
+
+In this use-case the earthquake kamelet will be downloaded from github, and as
well its required dependencies.
+
+You can find an example with this at
+https://github.com/apache/camel-examples/tree/main/examples/kamelet-main[kamelet-main].
+