You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by or...@apache.org on 2021/07/27 13:02:20 UTC
[camel] branch main updated: Preliminary support for initializing
kamelets from templates (#5865)
This is an automated email from the ASF dual-hosted git repository.
orpiske 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 fb44eaf Preliminary support for initializing kamelets from templates (#5865)
fb44eaf is described below
commit fb44eaf03196dd7286703e56faec1dd6addd04a5
Author: Otavio Rodolfo Piske <or...@users.noreply.github.com>
AuthorDate: Tue Jul 27 15:01:56 2021 +0200
Preliminary support for initializing kamelets from templates (#5865)
---
.../camel/github/GitHubResourceResolver.java | 9 +-
dsl/camel-jbang/camel-jbang-core/pom.xml | 6 +-
.../camel/dsl/jbang/core/api/TemplateParser.java | 26 +++++
.../jbang/core/commands/AbstractInitKamelet.java | 100 +++++++++++++++++++
.../common/exceptions/ResourceAlreadyExists.java | 28 ++++++
.../core/templates/VelocityTemplateParser.java | 107 +++++++++++++++++++++
.../camel-jbang-main/dist/CamelJBang.java | 107 ++++++++++++++++++++-
dsl/camel-jbang/camel-jbang-main/pom.xml | 9 ++
.../src/main/jbang/main/CamelJBang.java | 107 ++++++++++++++++++++-
9 files changed, 495 insertions(+), 4 deletions(-)
diff --git a/components/camel-resourceresolver-github/src/main/java/org/apache/camel/github/GitHubResourceResolver.java b/components/camel-resourceresolver-github/src/main/java/org/apache/camel/github/GitHubResourceResolver.java
index e694d5d..af6760c 100644
--- a/components/camel-resourceresolver-github/src/main/java/org/apache/camel/github/GitHubResourceResolver.java
+++ b/components/camel-resourceresolver-github/src/main/java/org/apache/camel/github/GitHubResourceResolver.java
@@ -28,8 +28,12 @@ public class GitHubResourceResolver extends ServiceSupport implements org.apache
// github:apache:camel:aws-ddb-streams-source.kamelet.yaml
// https://raw.githubusercontent.com/apache/camel-kamelets/main/aws-ddb-streams-source.kamelet.yaml
private static final String GITHUB_URL = "https://raw.githubusercontent.com/%s/%s/%s/%s";
+ private static final String DEFAULT_BRANCH = "main";
+
private CamelContext camelContext;
+ private String branch = DEFAULT_BRANCH;
+
@Override
public CamelContext getCamelContext() {
return camelContext;
@@ -40,6 +44,10 @@ public class GitHubResourceResolver extends ServiceSupport implements org.apache
this.camelContext = camelContext;
}
+ public void setBranch(String branch) {
+ this.branch = branch;
+ }
+
@Override
public String getSupportedScheme() {
return "github";
@@ -51,7 +59,6 @@ public class GitHubResourceResolver extends ServiceSupport implements org.apache
// scheme not in use as its github
String org = null;
String rep = null;
- String branch = "main"; // default branch is main
String name = null;
if (parts.length == 3) {
diff --git a/dsl/camel-jbang/camel-jbang-core/pom.xml b/dsl/camel-jbang/camel-jbang-core/pom.xml
index 5ff6dac..3b2ce54 100644
--- a/dsl/camel-jbang/camel-jbang-core/pom.xml
+++ b/dsl/camel-jbang/camel-jbang-core/pom.xml
@@ -38,11 +38,15 @@
<groupId>org.apache.camel</groupId>
<artifactId>camel-kamelet-main</artifactId>
</dependency>
-
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity-engine-core</artifactId>
+ <version>${velocity-version}</version>
+ </dependency>
</dependencies>
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/api/TemplateParser.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/api/TemplateParser.java
new file mode 100644
index 0000000..28e79e9
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/api/TemplateParser.java
@@ -0,0 +1,26 @@
+/*
+ * 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.api;
+
+import java.io.Writer;
+
+import org.apache.camel.CamelException;
+
+public interface TemplateParser {
+ void parse(String templateFileName, Writer writer) throws CamelException;
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/AbstractInitKamelet.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/AbstractInitKamelet.java
new file mode 100644
index 0000000..fc93aa1
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/AbstractInitKamelet.java
@@ -0,0 +1,100 @@
+/*
+ * 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.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelException;
+import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceAlreadyExists;
+import org.apache.camel.github.GitHubResourceResolver;
+import org.apache.camel.main.KameletMain;
+import org.apache.camel.spi.Resource;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractInitKamelet {
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractInitKamelet.class);
+
+ private String resourceLocation;
+ private String branch;
+
+ protected void setResourceLocation(String baseResourceLocation, String resourcePath) {
+ this.resourceLocation = baseResourceLocation + ":" + resourcePath;
+ LOG.debug("Resource location is: {}", resourceLocation);
+ }
+
+ public void setBranch(String branch) {
+ this.branch = branch;
+ }
+
+ protected File resolveResource(File destinationDirectory) throws IOException, CamelException {
+ KameletMain main = new KameletMain();
+ main.start();
+ CamelContext context = main.getCamelContext();
+
+ try (GitHubResourceResolver resolver = new GitHubResourceResolver()) {
+ resolver.setCamelContext(context);
+ resolver.setBranch(branch);
+
+ Resource resource = resolver.resolve(resourceLocation);
+
+ if (!resource.exists()) {
+ throw new CamelException("The resource does not exist");
+ }
+
+ String fileName = FilenameUtils.getName(resource.getURL().getPath());
+
+ LOG.debug("Destination directory for the downloaded resources: {}", destinationDirectory.getAbsolutePath());
+ LOG.debug("Downloaded resource file name: {}", fileName);
+ File outputFile = new File(destinationDirectory, fileName);
+
+ File parentDir = outputFile.getParentFile();
+ if (!parentDir.exists()) {
+
+ if (!parentDir.mkdirs()) {
+ LOG.warn("Failed to create the output directory: {}. It may have been created already", parentDir);
+ }
+ }
+
+ if (outputFile.exists()) {
+ throw new ResourceAlreadyExists(outputFile);
+ } else {
+ try (FileOutputStream fo = new FileOutputStream(outputFile)) {
+ IOUtils.copy(resource.getInputStream(), fo);
+ }
+ }
+
+ return outputFile;
+ }
+ }
+
+ protected void bootstrap(String branch, String baseResourceLocation, String destination)
+ throws IOException, CamelException {
+
+ setBranch(branch);
+ setResourceLocation(baseResourceLocation, "camel-kamelets:templates/init-template.properties");
+
+ resolveResource(new File(destination));
+
+ }
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/exceptions/ResourceAlreadyExists.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/exceptions/ResourceAlreadyExists.java
new file mode 100644
index 0000000..a5def19
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/exceptions/ResourceAlreadyExists.java
@@ -0,0 +1,28 @@
+/*
+ * 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.common.exceptions;
+
+import java.io.File;
+
+import org.apache.camel.CamelException;
+
+public class ResourceAlreadyExists extends CamelException {
+ public ResourceAlreadyExists(File resource) {
+ super("The destination file already exits: " + resource.getAbsolutePath());
+ }
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/templates/VelocityTemplateParser.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/templates/VelocityTemplateParser.java
new file mode 100644
index 0000000..d6004b9
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/templates/VelocityTemplateParser.java
@@ -0,0 +1,107 @@
+/*
+ * 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.templates;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Properties;
+
+import org.apache.camel.CamelException;
+import org.apache.camel.dsl.jbang.core.api.TemplateParser;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.exception.MethodInvocationException;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.runtime.RuntimeConstants;
+
+public class VelocityTemplateParser implements TemplateParser {
+ private final File propertiesFile;
+
+ public VelocityTemplateParser(File templateDir, String propertiesFile) {
+ this(templateDir, new File(propertiesFile));
+ }
+
+ public VelocityTemplateParser(File templateDir, File propertiesFile) {
+ this.propertiesFile = propertiesFile;
+ initializeTemplateEngine(templateDir);
+ }
+
+ private void initializeTemplateEngine(File templateDir) {
+ Properties props = new Properties();
+
+ props.setProperty(RuntimeConstants.RESOURCE_LOADER, "file");
+
+ props.put("resource.loader.file.path", templateDir.getAbsolutePath());
+
+ Velocity.init(props);
+ }
+
+ private void overridePropertyList(VelocityContext context, Properties properties, String requiredKameletProperties) {
+ String requiredPropertyList = properties.getProperty(requiredKameletProperties);
+
+ if (ObjectHelper.isNotEmpty(requiredPropertyList)) {
+ context.put(requiredKameletProperties, requiredPropertyList.split(","));
+ }
+ }
+
+ @Override
+ public void parse(String templateFileName, Writer writer) throws CamelException {
+ VelocityContext context = new VelocityContext();
+
+ try {
+ loadTemplateProperties(context);
+ } catch (IOException e) {
+ throw new CamelException("Unable to load the template properties", e);
+ }
+
+ try {
+ Template template = Velocity.getTemplate(templateFileName);
+
+ template.merge(context, writer);
+ } catch (ResourceNotFoundException rnfe) {
+ throw new CamelException("Could not find the template to parse", rnfe);
+ } catch (ParseErrorException pee) {
+ throw new CamelException("Failed parsing the template", pee);
+ } catch (MethodInvocationException mie) {
+ throw new CamelException("Method call within the templated has failed", mie);
+ } catch (Exception e) {
+ throw new CamelException("Unspecified error while loading, parsing or processing the template", e);
+ }
+ }
+
+ private void loadTemplateProperties(VelocityContext context) throws IOException {
+ Properties properties = new Properties();
+
+ try (FileReader propertiesReader = new FileReader(propertiesFile)) {
+ properties.load(propertiesReader);
+ }
+
+ properties.forEach((k, v) -> context.put(k.toString(), v));
+
+ overridePropertyList(context, properties, "kameletProperties");
+ overridePropertyList(context, properties, "requiredKameletProperties");
+ overridePropertyList(context, properties, "kameletBeans");
+ overridePropertyList(context, properties, "fromParameters");
+ overridePropertyList(context, properties, "toParameters");
+ }
+}
diff --git a/dsl/camel-jbang/camel-jbang-main/dist/CamelJBang.java b/dsl/camel-jbang/camel-jbang-main/dist/CamelJBang.java
index 6c6eb3e..1119563 100755
--- a/dsl/camel-jbang/camel-jbang-main/dist/CamelJBang.java
+++ b/dsl/camel-jbang/camel-jbang-main/dist/CamelJBang.java
@@ -30,19 +30,24 @@
//DEPS org.apache.logging.log4j:log4j-api:2.13.3
//DEPS org.apache.logging.log4j:log4j-core:2.13.3
//DEPS org.apache.logging.log4j:log4j-slf4j-impl:2.13.3
+//DEPS org.apache.velocity:velocity-engine-core:2.3
//DEPS info.picocli:picocli:4.5.0
package main;
import java.io.File;
+import java.io.FileWriter;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.regex.Pattern;
import org.apache.camel.CamelContext;
+import org.apache.camel.CamelException;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.dsl.jbang.core.commands.AbstractInitKamelet;
import org.apache.camel.dsl.jbang.core.commands.AbstractSearch;
import org.apache.camel.dsl.jbang.core.common.MatchExtractor;
+import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceAlreadyExists;
import org.apache.camel.dsl.jbang.core.components.ComponentConverter;
import org.apache.camel.dsl.jbang.core.components.ComponentDescriptionMatching;
import org.apache.camel.dsl.jbang.core.components.ComponentPrinter;
@@ -55,6 +60,7 @@ import org.apache.camel.dsl.jbang.core.languages.LanguagePrinter;
import org.apache.camel.dsl.jbang.core.others.OtherConverter;
import org.apache.camel.dsl.jbang.core.others.OtherDescriptionMatching;
import org.apache.camel.dsl.jbang.core.others.OtherPrinter;
+import org.apache.camel.dsl.jbang.core.templates.VelocityTemplateParser;
import org.apache.camel.dsl.jbang.core.types.Component;
import org.apache.camel.dsl.jbang.core.types.Kamelet;
import org.apache.camel.dsl.jbang.core.types.Language;
@@ -410,6 +416,103 @@ class SearchOthers extends AbstractSearch implements Callable<Integer> {
}
}
+@Command(name = "init", description = "Provide init templates for kamelets and bindings")
+class Init implements Callable<Integer> {
+ @Option(names = { "-h", "--help" }, usageHelp = true, description = "Display the help and sub-commands")
+ private boolean helpRequested = false;
+
+ @Override
+ public Integer call() throws Exception {
+ new CommandLine(this).execute("--help");
+
+ return 0;
+ }
+}
+
+@Command(name = "kamelet", description = "Provide init templates for kamelets")
+class InitKamelet extends AbstractInitKamelet implements Callable<Integer> {
+ @Option(names = { "-h", "--help" }, usageHelp = true, description = "Display the help and sub-commands")
+ private boolean helpRequested = false;
+
+ @CommandLine.ArgGroup(exclusive = true, multiplicity = "1")
+ private ProcessOptions processOptions;
+
+ static class ProcessOptions {
+ @Option(names = { "--bootstrap" },
+ description = "Bootstrap the Kamelet template generator - download the properties file for editing")
+ private boolean bootstrap = false;
+
+ @Option(names = { "--properties-path" }, defaultValue = "", description = "Kamelet name")
+ private String propertiesPath;
+ }
+
+ @Option(names = { "--base-resource-location" }, defaultValue = "github:apache", hidden = true,
+ description = "Where to download the resources from (used for development/testing)")
+ private String baseResourceLocation;
+
+ @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
+ description = "The branch to use when downloading resources from (used for development/testing)")
+ private String branch;
+
+ @Option(names = { "--destination" }, defaultValue = "work",
+ description = "The destination directory where to download the files")
+ private String destination;
+
+ @Override
+ public Integer call() throws Exception {
+ if (processOptions.bootstrap) {
+ bootstrap();
+ } else {
+ generateTemplate();
+ }
+
+ return 0;
+ }
+
+ private int generateTemplate() throws IOException, CamelException {
+ setBranch(branch);
+ setResourceLocation(baseResourceLocation, "camel-kamelets:templates/init-template.kamelet.yaml.vm");
+
+ File workDirectory = new File(destination);
+
+ File localTemplateFile;
+ try {
+ localTemplateFile = resolveResource(workDirectory);
+ } catch (ResourceAlreadyExists e) {
+ System.err.println(e.getMessage());
+ return 1;
+ }
+
+ localTemplateFile.deleteOnExit();
+
+ VelocityTemplateParser templateParser = new VelocityTemplateParser(
+ localTemplateFile.getParentFile(),
+ processOptions.propertiesPath);
+
+ String outputFileName = localTemplateFile.getName().replace(".vm", "");
+ File outputFile = new File(localTemplateFile.getParentFile(), outputFileName);
+
+ try (FileWriter fw = new FileWriter(outputFile)) {
+ templateParser.parse(localTemplateFile.getName(), fw);
+ System.out.println("Template file was written to " + outputFile);
+ }
+
+ return 0;
+ }
+
+ private int bootstrap() throws IOException, CamelException {
+ try {
+ super.bootstrap(branch, baseResourceLocation, destination);
+ return 0;
+ } catch (ResourceAlreadyExists e) {
+ System.err.println(e.getMessage());
+
+ return 1;
+ }
+ }
+
+}
+
@Command(name = "CamelJBang", mixinStandardHelpOptions = true, version = "CamelJBang 3.12.0-SNAPSHOT",
description = "A JBang-based Camel app for running Kamelets")
class CamelJBang implements Callable<Integer> {
@@ -426,7 +529,9 @@ class CamelJBang implements Callable<Integer> {
.addSubcommand("kamelets", new SearchKamelets())
.addSubcommand("components", new SearchComponents())
.addSubcommand("languages", new SearchLanguages())
- .addSubcommand("others", new SearchOthers()));
+ .addSubcommand("others", new SearchOthers()))
+ .addSubcommand("init", new CommandLine(new Init())
+ .addSubcommand("kamelet", new InitKamelet()));
int exitCode = commandLine.execute(args);
System.exit(exitCode);
diff --git a/dsl/camel-jbang/camel-jbang-main/pom.xml b/dsl/camel-jbang/camel-jbang-main/pom.xml
index 696fe50..aadcaf6 100644
--- a/dsl/camel-jbang/camel-jbang-main/pom.xml
+++ b/dsl/camel-jbang/camel-jbang-main/pom.xml
@@ -89,6 +89,12 @@
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity-engine-core</artifactId>
+ <version>${velocity-version}</version>
+ </dependency>
</dependencies>
<build>
@@ -127,6 +133,9 @@
<replace token="${camel.jbang.picocli.version}" value="${picocli-version}" dir="${dist.dir}">
<include name="**/*.java"/>
</replace>
+ <replace token="${camel.jbang.velocity.version}" value="${velocity-version}" dir="${dist.dir}">
+ <include name="**/*.java"/>
+ </replace>
<chmod file="${dist.dir}/*.java" perm="u+x" />
</tasks>
</configuration>
diff --git a/dsl/camel-jbang/camel-jbang-main/src/main/jbang/main/CamelJBang.java b/dsl/camel-jbang/camel-jbang-main/src/main/jbang/main/CamelJBang.java
index 7c067bd..8da4635 100755
--- a/dsl/camel-jbang/camel-jbang-main/src/main/jbang/main/CamelJBang.java
+++ b/dsl/camel-jbang/camel-jbang-main/src/main/jbang/main/CamelJBang.java
@@ -30,19 +30,24 @@
//DEPS org.apache.logging.log4j:log4j-api:${camel.jbang.log4j2.version}
//DEPS org.apache.logging.log4j:log4j-core:${camel.jbang.log4j2.version}
//DEPS org.apache.logging.log4j:log4j-slf4j-impl:${camel.jbang.log4j2.version}
+//DEPS org.apache.velocity:velocity-engine-core:${camel.jbang.velocity.version}
//DEPS info.picocli:picocli:${camel.jbang.picocli.version}
package main;
import java.io.File;
+import java.io.FileWriter;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.regex.Pattern;
import org.apache.camel.CamelContext;
+import org.apache.camel.CamelException;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.dsl.jbang.core.commands.AbstractInitKamelet;
import org.apache.camel.dsl.jbang.core.commands.AbstractSearch;
import org.apache.camel.dsl.jbang.core.common.MatchExtractor;
+import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceAlreadyExists;
import org.apache.camel.dsl.jbang.core.components.ComponentConverter;
import org.apache.camel.dsl.jbang.core.components.ComponentDescriptionMatching;
import org.apache.camel.dsl.jbang.core.components.ComponentPrinter;
@@ -55,6 +60,7 @@ import org.apache.camel.dsl.jbang.core.languages.LanguagePrinter;
import org.apache.camel.dsl.jbang.core.others.OtherConverter;
import org.apache.camel.dsl.jbang.core.others.OtherDescriptionMatching;
import org.apache.camel.dsl.jbang.core.others.OtherPrinter;
+import org.apache.camel.dsl.jbang.core.templates.VelocityTemplateParser;
import org.apache.camel.dsl.jbang.core.types.Component;
import org.apache.camel.dsl.jbang.core.types.Kamelet;
import org.apache.camel.dsl.jbang.core.types.Language;
@@ -410,6 +416,103 @@ class SearchOthers extends AbstractSearch implements Callable<Integer> {
}
}
+@Command(name = "init", description = "Provide init templates for kamelets and bindings")
+class Init implements Callable<Integer> {
+ @Option(names = { "-h", "--help" }, usageHelp = true, description = "Display the help and sub-commands")
+ private boolean helpRequested = false;
+
+ @Override
+ public Integer call() throws Exception {
+ new CommandLine(this).execute("--help");
+
+ return 0;
+ }
+}
+
+@Command(name = "kamelet", description = "Provide init templates for kamelets")
+class InitKamelet extends AbstractInitKamelet implements Callable<Integer> {
+ @Option(names = { "-h", "--help" }, usageHelp = true, description = "Display the help and sub-commands")
+ private boolean helpRequested = false;
+
+ @CommandLine.ArgGroup(exclusive = true, multiplicity = "1")
+ private ProcessOptions processOptions;
+
+ static class ProcessOptions {
+ @Option(names = { "--bootstrap" },
+ description = "Bootstrap the Kamelet template generator - download the properties file for editing")
+ private boolean bootstrap = false;
+
+ @Option(names = { "--properties-path" }, defaultValue = "", description = "Kamelet name")
+ private String propertiesPath;
+ }
+
+ @Option(names = { "--base-resource-location" }, defaultValue = "github:apache", hidden = true,
+ description = "Where to download the resources from (used for development/testing)")
+ private String baseResourceLocation;
+
+ @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
+ description = "The branch to use when downloading resources from (used for development/testing)")
+ private String branch;
+
+ @Option(names = { "--destination" }, defaultValue = "work",
+ description = "The destination directory where to download the files")
+ private String destination;
+
+ @Override
+ public Integer call() throws Exception {
+ if (processOptions.bootstrap) {
+ bootstrap();
+ } else {
+ generateTemplate();
+ }
+
+ return 0;
+ }
+
+ private int generateTemplate() throws IOException, CamelException {
+ setBranch(branch);
+ setResourceLocation(baseResourceLocation, "camel-kamelets:templates/init-template.kamelet.yaml.vm");
+
+ File workDirectory = new File(destination);
+
+ File localTemplateFile;
+ try {
+ localTemplateFile = resolveResource(workDirectory);
+ } catch (ResourceAlreadyExists e) {
+ System.err.println(e.getMessage());
+ return 1;
+ }
+
+ localTemplateFile.deleteOnExit();
+
+ VelocityTemplateParser templateParser = new VelocityTemplateParser(
+ localTemplateFile.getParentFile(),
+ processOptions.propertiesPath);
+
+ String outputFileName = localTemplateFile.getName().replace(".vm", "");
+ File outputFile = new File(localTemplateFile.getParentFile(), outputFileName);
+
+ try (FileWriter fw = new FileWriter(outputFile)) {
+ templateParser.parse(localTemplateFile.getName(), fw);
+ System.out.println("Template file was written to " + outputFile);
+ }
+
+ return 0;
+ }
+
+ private int bootstrap() throws IOException, CamelException {
+ try {
+ super.bootstrap(branch, baseResourceLocation, destination);
+ return 0;
+ } catch (ResourceAlreadyExists e) {
+ System.err.println(e.getMessage());
+
+ return 1;
+ }
+ }
+
+}
+
@Command(name = "CamelJBang", mixinStandardHelpOptions = true, version = "CamelJBang ${camel.jbang.version}",
description = "A JBang-based Camel app for running Kamelets")
class CamelJBang implements Callable<Integer> {
@@ -426,7 +529,9 @@ class CamelJBang implements Callable<Integer> {
.addSubcommand("kamelets", new SearchKamelets())
.addSubcommand("components", new SearchComponents())
.addSubcommand("languages", new SearchLanguages())
- .addSubcommand("others", new SearchOthers()));
+ .addSubcommand("others", new SearchOthers()))
+ .addSubcommand("init", new CommandLine(new Init())
+ .addSubcommand("kamelet", new InitKamelet()));
int exitCode = commandLine.execute(args);
System.exit(exitCode);