You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/02/02 14:56:03 UTC
[camel] branch camel-3.20.x updated: CAMEL-19001: camel-jbang - Backport 3.21 fixes and others to 3.20.x
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch camel-3.20.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-3.20.x by this push:
new e649884dc95 CAMEL-19001: camel-jbang - Backport 3.21 fixes and others to 3.20.x
e649884dc95 is described below
commit e649884dc9589819de6ac8c3dc651cd3923a6bc9
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Feb 2 15:49:30 2023 +0100
CAMEL-19001: camel-jbang - Backport 3.21 fixes and others to 3.20.x
---
.../apache/camel/dsl/jbang/core/commands/Bind.java | 18 +-
.../dsl/jbang/core/commands/CamelJBangMain.java | 11 +-
.../dsl/jbang/core/commands/CodeRestGenerator.java | 19 +-
.../CamelTop.java => DependencyCommand.java} | 17 +-
.../dsl/jbang/core/commands/DependencyCopy.java | 107 +++++
.../{DependencyTree.java => DependencyList.java} | 6 +-
.../dsl/jbang/core/commands/ExportBaseCommand.java | 63 +--
.../dsl/jbang/core/commands/ExportQuarkus.java | 61 +++
.../apache/camel/dsl/jbang/core/commands/Init.java | 2 +-
.../apache/camel/dsl/jbang/core/commands/Run.java | 250 ++++++++++--
.../core/commands/action/ActionBaseCommand.java | 4 -
.../ActionWatchCommand.java} | 38 +-
.../jbang/core/commands/action/CamelLogAction.java | 449 +++++++++++++++++++++
.../jbang/core/commands/action/CamelSourceTop.java | 5 +-
.../core/commands/action/CamelThreadDump.java | 5 +-
.../commands/action/RouteControllerAction.java | 5 +-
.../core/commands/catalog/CatalogBaseCommand.java | 1 +
.../jbang/core/commands/catalog/CatalogDoc.java | 2 +-
.../core/commands/catalog/CatalogKamelet.java | 2 +-
.../core/commands/process/CamelContextStatus.java | 4 +-
.../core/commands/process/CamelContextTop.java | 4 +-
.../jbang/core/commands/process/CamelCount.java | 4 +-
.../commands/process/CamelProcessorStatus.java | 4 +-
.../core/commands/process/CamelRouteStatus.java | 4 +-
.../jbang/core/commands/process/CamelStatus.java | 9 +-
.../dsl/jbang/core/commands/process/CamelTop.java | 9 +-
.../dsl/jbang/core/commands/process/Hawtio.java | 4 +-
.../jbang/core/commands/process/ListBlocked.java | 4 +-
.../core/commands/process/ListCircuitBreaker.java | 4 +-
...{CamelEndpointStatus.java => ListEndpoint.java} | 6 +-
.../dsl/jbang/core/commands/process/ListEvent.java | 4 +-
.../jbang/core/commands/process/ListHealth.java | 4 +-
.../jbang/core/commands/process/ListInflight.java | 4 +-
.../jbang/core/commands/process/ListMetric.java | 4 +-
.../jbang/core/commands/process/ListProcess.java | 5 +-
.../jbang/core/commands/process/ListService.java | 4 +-
.../dsl/jbang/core/commands/process/ListVault.java | 4 +-
.../{CamelStatus.java => ProcessWatchCommand.java} | 40 +-
.../camel/dsl/jbang/core/common/RuntimeUtil.java | 14 +-
.../catalog => common}/VersionHelper.java | 4 +-
.../camel/dsl/jbang/core/common/XmlHelper.java | 5 +
...ipe.properties => log4j2-background.properties} | 11 +-
.../src/main/resources/log4j2-export.properties | 2 +-
.../src/main/resources/log4j2-no-color.properties | 2 +-
.../src/main/resources/log4j2-pipe.properties | 2 +-
.../src/main/resources/log4j2.properties | 15 +-
.../templates/run-custom-camel-version.tmpl} | 33 +-
47 files changed, 1094 insertions(+), 184 deletions(-)
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Bind.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Bind.java
index 4f8d25739f5..6741b8019f9 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Bind.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Bind.java
@@ -27,6 +27,7 @@ import java.util.Stack;
import org.apache.camel.github.GitHubResourceResolver;
import org.apache.camel.impl.engine.DefaultResourceResolvers;
import org.apache.camel.spi.Resource;
+import org.apache.camel.spi.ResourceResolver;
import org.apache.camel.util.FileUtil;
import org.apache.camel.util.IOHelper;
import org.snakeyaml.engine.v2.api.LoadSettings;
@@ -131,15 +132,26 @@ class Bind extends CamelCommand {
InputStream is;
String loc;
+ Resource res;
// try local disk first before github
- Resource res = new DefaultResourceResolvers.FileResolver().resolve("file:" + kamelet + ".kamelet.yaml");
+ ResourceResolver resolver = new DefaultResourceResolvers.FileResolver();
+ try {
+ res = resolver.resolve("file:" + kamelet + ".kamelet.yaml");
+ } finally {
+ resolver.close();
+ }
if (res.exists()) {
is = res.getInputStream();
loc = res.getLocation();
} else {
- res = new GitHubResourceResolver().resolve(
- "github:apache:camel-kamelets:main:kamelets/" + kamelet + ".kamelet.yaml");
+ resolver = new GitHubResourceResolver();
+ try {
+ res = resolver.resolve(
+ "github:apache:camel-kamelets:main:kamelets/" + kamelet + ".kamelet.yaml");
+ } finally {
+ resolver.close();
+ }
loc = res.getLocation();
URL u = new URL(loc);
is = u.openStream();
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
index 49ed050991b..5176926abe2 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
@@ -22,6 +22,7 @@ import org.apache.camel.catalog.CamelCatalog;
import org.apache.camel.catalog.DefaultCamelCatalog;
import org.apache.camel.dsl.jbang.core.commands.action.CamelAction;
import org.apache.camel.dsl.jbang.core.commands.action.CamelGCAction;
+import org.apache.camel.dsl.jbang.core.commands.action.CamelLogAction;
import org.apache.camel.dsl.jbang.core.commands.action.CamelReloadAction;
import org.apache.camel.dsl.jbang.core.commands.action.CamelResetStatsAction;
import org.apache.camel.dsl.jbang.core.commands.action.CamelRouteStartAction;
@@ -41,7 +42,6 @@ import org.apache.camel.dsl.jbang.core.commands.catalog.CatalogOther;
import org.apache.camel.dsl.jbang.core.commands.process.CamelContextStatus;
import org.apache.camel.dsl.jbang.core.commands.process.CamelContextTop;
import org.apache.camel.dsl.jbang.core.commands.process.CamelCount;
-import org.apache.camel.dsl.jbang.core.commands.process.CamelEndpointStatus;
import org.apache.camel.dsl.jbang.core.commands.process.CamelProcessorStatus;
import org.apache.camel.dsl.jbang.core.commands.process.CamelProcessorTop;
import org.apache.camel.dsl.jbang.core.commands.process.CamelRouteStatus;
@@ -52,6 +52,7 @@ import org.apache.camel.dsl.jbang.core.commands.process.Hawtio;
import org.apache.camel.dsl.jbang.core.commands.process.Jolokia;
import org.apache.camel.dsl.jbang.core.commands.process.ListBlocked;
import org.apache.camel.dsl.jbang.core.commands.process.ListCircuitBreaker;
+import org.apache.camel.dsl.jbang.core.commands.process.ListEndpoint;
import org.apache.camel.dsl.jbang.core.commands.process.ListEvent;
import org.apache.camel.dsl.jbang.core.commands.process.ListHealth;
import org.apache.camel.dsl.jbang.core.commands.process.ListInflight;
@@ -72,6 +73,7 @@ public class CamelJBangMain implements Callable<Integer> {
commandLine = new CommandLine(main)
.addSubcommand("init", new CommandLine(new Init(main)))
.addSubcommand("run", new CommandLine(new Run(main)))
+ .addSubcommand("log", new CommandLine(new CamelLogAction(main)))
.addSubcommand("ps", new CommandLine(new ListProcess(main)))
.addSubcommand("stop", new CommandLine(new StopProcess(main)))
.addSubcommand("get", new CommandLine(new CamelStatus(main))
@@ -80,7 +82,7 @@ public class CamelJBangMain implements Callable<Integer> {
.addSubcommand("processor", new CommandLine(new CamelProcessorStatus(main)))
.addSubcommand("count", new CommandLine(new CamelCount(main)))
.addSubcommand("health", new CommandLine(new ListHealth(main)))
- .addSubcommand("endpoint", new CommandLine(new CamelEndpointStatus(main)))
+ .addSubcommand("endpoint", new CommandLine(new ListEndpoint(main)))
.addSubcommand("event", new CommandLine(new ListEvent(main)))
.addSubcommand("inflight", new CommandLine(new ListInflight(main)))
.addSubcommand("blocked", new CommandLine(new ListBlocked(main)))
@@ -103,6 +105,9 @@ public class CamelJBangMain implements Callable<Integer> {
.addSubcommand("thread-dump", new CommandLine(new CamelThreadDump(main)))
.addSubcommand("logger", new CommandLine(new LoggerAction(main)))
.addSubcommand("gc", new CommandLine(new CamelGCAction(main))))
+ .addSubcommand("dependency", new CommandLine(new DependencyCommand(main))
+ .addSubcommand("list", new CommandLine(new DependencyList(main)))
+ .addSubcommand("copy", new CommandLine(new DependencyCopy(main))))
.addSubcommand("generate", new CommandLine(new CodeGenerator(main))
.addSubcommand("rest", new CommandLine(new CodeRestGenerator(main))))
.addSubcommand("catalog", new CommandLine(new CatalogCommand(main))
@@ -116,7 +121,7 @@ public class CamelJBangMain implements Callable<Integer> {
.addSubcommand("hawtio", new CommandLine(new Hawtio(main)))
.addSubcommand("bind", new CommandLine(new Bind(main)))
.addSubcommand("pipe", new CommandLine(new Pipe(main)))
- .addSubcommand("dependencies", new CommandLine(new DependencyTree(main)))
+ .addSubcommand("dependencies", new CommandLine(new DependencyList(main)))
.addSubcommand("export", new CommandLine(new Export(main)))
.addSubcommand("completion", new CommandLine(new Complete(main)));
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CodeRestGenerator.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CodeRestGenerator.java
index 7db7d0785d7..41787ebfe36 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CodeRestGenerator.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CodeRestGenerator.java
@@ -56,7 +56,8 @@ public class CodeRestGenerator extends CamelCommand {
private boolean generateRoutes;
@CommandLine.Option(names = { "-d", "--dto" }, description = "Data Objects")
private boolean generateDataObjects;
- @CommandLine.Option(names = { "-run", "--runtime" }, description = "Runtime (quarkus, spring-boot)", defaultValue = "quarkus")
+ @CommandLine.Option(names = { "-run", "--runtime" }, description = "Runtime (quarkus, spring-boot)",
+ defaultValue = "quarkus")
private String runtime;
@CommandLine.Option(names = { "-p", "--package" }, description = "Package for generated models", defaultValue = "model")
private String packageName;
@@ -104,14 +105,14 @@ public class CodeRestGenerator extends CamelCommand {
}
private void generateDto() throws IOException {
- final String CODE = "code";
- final String GENERATOR_NAME = "quarkus".equals(runtime) ? "jaxrs-spec" : "java-camel";
- final String LIBRARY = "quarkus".equals(runtime) ? "quarkus" : "spring-boot";
+ final String code = "code";
+ final String generatorName = "quarkus".equals(runtime) ? "jaxrs-spec" : "java-camel";
+ final String library = "quarkus".equals(runtime) ? "quarkus" : "spring-boot";
File output = Files.createTempDirectory("gendto").toFile();
final CodegenConfigurator configurator = new CodegenConfigurator()
- .setGeneratorName(GENERATOR_NAME)
- .setLibrary(LIBRARY)
+ .setGeneratorName(generatorName)
+ .setLibrary(library)
.setInputSpec(input)
.setModelPackage(packageName)
.setAdditionalProperties(
@@ -122,14 +123,12 @@ public class CodeRestGenerator extends CamelCommand {
GENERATE_MODELS, "true",
"generatePom", "false",
"generateApis", "false",
- "sourceFolder", CODE
- )
- )
+ "sourceFolder", code))
.setOutputDir(output.getAbsolutePath());
final ClientOptInput clientOptInput = configurator.toClientOptInput();
new DefaultGenerator().opts(clientOptInput).generate();
- File generated = new File(Paths.get(output.getAbsolutePath(), CODE, packageName).toUri());
+ File generated = new File(Paths.get(output.getAbsolutePath(), code, packageName).toUri());
generated.renameTo(new File(packageName));
}
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyCommand.java
similarity index 64%
copy from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java
copy to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyCommand.java
index 9f0b3b8c1a0..e34619741ec 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyCommand.java
@@ -14,24 +14,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.dsl.jbang.core.commands.process;
+package org.apache.camel.dsl.jbang.core.commands;
-import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
-import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
import picocli.CommandLine;
-@CommandLine.Command(name = "top",
- description = "Top status of Camel integrations (use top --help to see sub commands)")
-public class CamelTop extends CamelCommand {
+@CommandLine.Command(name = "dependency",
+ description = "Displays all Camel dependencies required to run (use dependency --help to see sub commands)")
+public class DependencyCommand extends CamelCommand {
- public CamelTop(CamelJBangMain main) {
+ public DependencyCommand(CamelJBangMain main) {
super(main);
}
@Override
public Integer call() throws Exception {
- // default to top the integrations
- new CommandLine(new CamelContextTop(getMain())).execute();
+ // default to list
+ new CommandLine(new DependencyList(getMain())).execute();
return 0;
}
+
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyCopy.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyCopy.java
new file mode 100644
index 00000000000..bd033fa954f
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyCopy.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.commands;
+
+import java.io.File;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.dsl.jbang.core.common.RuntimeUtil;
+import org.apache.camel.util.CamelCaseOrderedProperties;
+import org.apache.camel.util.FileUtil;
+import picocli.CommandLine;
+
+@CommandLine.Command(name = "copy",
+ description = "Copies all Camel dependencies required to run to a specific directory")
+public class DependencyCopy extends Export {
+
+ protected static final String EXPORT_DIR = ".camel-jbang/export";
+
+ @CommandLine.Option(names = { "--output-directory" }, description = "Directory where dependencies should be copied",
+ defaultValue = "lib", required = true)
+ protected String outputDirectory;
+
+ public DependencyCopy(CamelJBangMain main) {
+ super(main);
+ }
+
+ @Override
+ protected Integer export() throws Exception {
+ this.quiet = true; // be quiet and generate from fresh data to ensure the output is up-to-date
+
+ Integer answer = doExport();
+ if (answer == 0) {
+ File buildDir = new File(EXPORT_DIR);
+ Process p = Runtime.getRuntime()
+ .exec("mvn dependency:copy-dependencies -DincludeScope=compile -DexcludeGroupIds=org.fusesource.jansi,org.apache.logging.log4j -DoutputDirectory=../../"
+ + outputDirectory,
+ null,
+ buildDir);
+ boolean done = p.waitFor(30, TimeUnit.SECONDS);
+ if (!done) {
+ answer = 1;
+ }
+ // cleanup dir after complete
+ FileUtil.removeDir(buildDir);
+ }
+ return answer;
+ }
+
+ protected Integer doExport() throws Exception {
+ // read runtime and gav from profile if not configured
+ File profile = new File(getProfile() + ".properties");
+ if (profile.exists()) {
+ Properties prop = new CamelCaseOrderedProperties();
+ RuntimeUtil.loadProperties(prop, profile);
+ if (this.runtime == null) {
+ this.runtime = prop.getProperty("camel.jbang.runtime");
+ }
+ if (this.gav == null) {
+ this.gav = prop.getProperty("camel.jbang.gav");
+ }
+ // allow configuring versions from profile
+ this.javaVersion = prop.getProperty("camel.jbang.javaVersion", this.javaVersion);
+ this.kameletsVersion = prop.getProperty("camel.jbang.kameletsVersion", this.kameletsVersion);
+ this.localKameletDir = prop.getProperty("camel.jbang.localKameletDir", this.localKameletDir);
+ this.quarkusGroupId = prop.getProperty("camel.jbang.quarkusGroupId", this.quarkusGroupId);
+ this.quarkusArtifactId = prop.getProperty("camel.jbang.quarkusArtifactId", this.quarkusArtifactId);
+ this.quarkusVersion = prop.getProperty("camel.jbang.quarkusVersion", this.quarkusVersion);
+ this.springBootVersion = prop.getProperty("camel.jbang.springBootVersion", this.springBootVersion);
+ }
+
+ // use temporary export dir
+ exportDir = EXPORT_DIR;
+ if (gav == null) {
+ gav = "org.apache.camel:camel-jbang-dummy:1.0";
+ }
+ if (runtime == null) {
+ runtime = "camel-main";
+ }
+
+ if ("spring-boot".equals(runtime) || "camel-spring-boot".equals(runtime)) {
+ return export(new ExportSpringBoot(getMain()));
+ } else if ("quarkus".equals(runtime) || "camel-quarkus".equals(runtime)) {
+ return export(new ExportQuarkus(getMain()));
+ } else if ("main".equals(runtime) || "camel-main".equals(runtime)) {
+ return export(new ExportCamelMain(getMain()));
+ } else {
+ System.err.println("Unknown runtime: " + runtime);
+ return 1;
+ }
+ }
+
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyTree.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyList.java
similarity index 98%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyTree.java
rename to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyList.java
index 040150d1123..3dc475b2cad 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyTree.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyList.java
@@ -35,16 +35,16 @@ import org.apache.camel.util.CamelCaseOrderedProperties;
import org.apache.camel.util.FileUtil;
import picocli.CommandLine;
-@CommandLine.Command(name = "dependencies",
+@CommandLine.Command(name = "list",
description = "Displays all Camel dependencies required to run")
-public class DependencyTree extends Export {
+public class DependencyList extends Export {
protected static final String EXPORT_DIR = ".camel-jbang/export";
@CommandLine.Option(names = { "--output" }, description = "Output format (gav or maven)", defaultValue = "gav")
protected String output;
- public DependencyTree(CamelJBangMain main) {
+ public DependencyList(CamelJBangMain main) {
super(main);
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java
index 54139ce6228..4016c4cc556 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java
@@ -79,7 +79,7 @@ abstract class ExportBaseCommand extends CamelCommand {
protected String javaVersion;
@CommandLine.Option(names = {
- "--kamelets-version" }, description = "Apache Camel Kamelets version", defaultValue = "3.20.0")
+ "--kamelets-version" }, description = "Apache Camel Kamelets version", defaultValue = "3.20.1.1")
protected String kameletsVersion;
@CommandLine.Option(names = { "--local-kamelet-dir" },
@@ -370,13 +370,16 @@ abstract class ExportBaseCommand extends CamelCommand {
if (profile.exists()) {
RuntimeUtil.loadProperties(prop2, profile);
}
+ prop2.putAll(prop);
+ prepareApplicationProperties(prop2);
for (Map.Entry<Object, Object> entry : prop.entrySet()) {
String key = entry.getKey().toString();
- boolean skip = "camel.main.routesCompileDirectory".equals(key)
+ boolean skip = !key.startsWith("camel.main")
+ || "camel.main.routesCompileDirectory".equals(key)
|| "camel.main.routesReloadEnabled".equals(key);
- if (!skip && key.startsWith("camel.main")) {
- prop2.put(entry.getKey(), entry.getValue());
+ if (skip) {
+ prop2.remove(key);
}
}
@@ -385,33 +388,39 @@ abstract class ExportBaseCommand extends CamelCommand {
}
FileOutputStream fos = new FileOutputStream(new File(targetDir, "application.properties"), false);
- for (Map.Entry<Object, Object> entry : prop2.entrySet()) {
- String k = entry.getKey().toString();
- String v = entry.getValue().toString();
+ try {
+ for (Map.Entry<Object, Object> entry : prop2.entrySet()) {
+ String k = entry.getKey().toString();
+ String v = entry.getValue().toString();
- boolean skip = k.startsWith("camel.jbang.") || k.startsWith("jkube.");
- if (skip) {
- continue;
- }
+ boolean skip = k.startsWith("camel.jbang.") || k.startsWith("jkube.");
+ if (skip) {
+ continue;
+ }
- // files are now loaded in classpath
- v = v.replaceAll("file:", "classpath:");
- if ("camel.main.routesIncludePattern".equals(k)) {
- // camel.main.routesIncludePattern should remove all .java as we use spring boot
- // to load them
- // camel.main.routesIncludePattern should remove all file: classpath: as we copy
- // them to src/main/resources/camel where camel auto-load from
- v = Arrays.stream(v.split(","))
- .filter(n -> !n.endsWith(".java") && !n.startsWith("file:") && !n.startsWith("classpath:"))
- .collect(Collectors.joining(","));
- }
- if (!v.isBlank()) {
- String line = applicationPropertyLine(k, v);
- fos.write(line.getBytes(StandardCharsets.UTF_8));
- fos.write("\n".getBytes(StandardCharsets.UTF_8));
+ // files are now loaded in classpath
+ v = v.replaceAll("file:", "classpath:");
+ if ("camel.main.routesIncludePattern".equals(k)) {
+ // camel.main.routesIncludePattern should remove all .java as we use move them to regular src/main/java
+ // camel.main.routesIncludePattern should remove all file: classpath: as we copy
+ // them to src/main/resources/camel where camel autoload from
+ v = Arrays.stream(v.split(","))
+ .filter(n -> !n.endsWith(".java") && !n.startsWith("file:") && !n.startsWith("classpath:"))
+ .collect(Collectors.joining(","));
+ }
+ if (!v.isBlank()) {
+ String line = applicationPropertyLine(k, v);
+ fos.write(line.getBytes(StandardCharsets.UTF_8));
+ fos.write("\n".getBytes(StandardCharsets.UTF_8));
+ }
}
+ } finally {
+ IOHelper.close(fos);
}
- IOHelper.close(fos);
+ }
+
+ protected void prepareApplicationProperties(Properties properties) {
+ // noop
}
protected void copyMavenWrapper() throws Exception {
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
index cc44f627417..bdfcda47383 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
@@ -20,9 +20,13 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -143,6 +147,63 @@ class ExportQuarkus extends Export {
return 0;
}
+ @Override
+ protected void prepareApplicationProperties(Properties properties) {
+ // quarkus native compilation only works if we specify each resource explicit
+
+ StringJoiner sj = new StringJoiner(",");
+ StringJoiner sj2 = new StringJoiner(",");
+ for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+ String k = entry.getKey().toString();
+ String v = entry.getValue().toString();
+
+ if ("camel.main.routesIncludePattern".equals(k)) {
+ v = Arrays.stream(v.split(","))
+ .map(ExportQuarkus::removeScheme) // remove scheme and routes are in camel sub-folder
+ .map(s -> "camel/" + s)
+ .collect(Collectors.joining(","));
+ sj.add(v);
+ }
+ // extra classpath files
+ if ("camel.jbang.classpathFiles".equals(k)) {
+ v = Arrays.stream(v.split(","))
+ .map(ExportQuarkus::removeScheme) // remove scheme
+ .collect(Collectors.joining(","));
+ sj2.add(v);
+ }
+ }
+
+ String routes = sj.length() > 0 ? sj.toString() : null;
+ String extra = sj2.length() > 0 ? sj2.toString() : null;
+
+ if (routes != null || extra != null) {
+ sj = new StringJoiner(",");
+ String e = properties.getProperty("quarkus.native.resources.includes");
+ if (e != null) {
+ sj.add(e);
+ }
+ if (routes != null) {
+ sj.add(routes);
+ }
+ if (extra != null) {
+ sj.add(extra);
+ }
+ if (sj.length() > 0) {
+ properties.setProperty("quarkus.native.resources.includes", sj.toString());
+ }
+ if (routes != null) {
+ properties.setProperty("camel.main.routes-include-pattern", routes);
+ }
+ }
+ }
+
+ private static String removeScheme(String s) {
+ if (s.contains(":")) {
+ return StringHelper.after(s, ":");
+ }
+ return s;
+ }
+
private void createGradleProperties(File output) throws Exception {
InputStream is = ExportQuarkus.class.getClassLoader().getResourceAsStream("templates/quarkus-gradle-properties.tmpl");
String context = IOHelper.loadText(is);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Init.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Init.java
index 85ee118ff2b..1d3ce0d93e4 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Init.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Init.java
@@ -59,7 +59,7 @@ class Init extends CamelCommand {
private String fromKamelet;
@Option(names = {
- "--kamelets-version" }, description = "Apache Camel Kamelets version", defaultValue = "3.20.0")
+ "--kamelets-version" }, description = "Apache Camel Kamelets version", defaultValue = "3.20.1.1")
private String kameletsVersion;
@Option(names = {
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 dd59b5d4eb5..a543981cd9f 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
@@ -49,7 +49,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import io.apicurio.datamodels.Library;
import io.apicurio.datamodels.openapi.models.OasDocument;
import org.apache.camel.CamelContext;
+import org.apache.camel.catalog.DefaultCamelCatalog;
import org.apache.camel.dsl.jbang.core.common.RuntimeUtil;
+import org.apache.camel.dsl.jbang.core.common.VersionHelper;
import org.apache.camel.generator.openapi.RestDslGenerator;
import org.apache.camel.impl.lw.LightweightCamelContext;
import org.apache.camel.main.KameletMain;
@@ -93,6 +95,8 @@ class Run extends CamelCommand {
private boolean silentRun;
private boolean pipeRun;
+ private File logFile;
+
//CHECKSTYLE:OFF
@Parameters(description = "The Camel file(s) to run. If no files specified then application.properties is used as source for which files to run.",
arity = "0..9", paramLabel = "<files>", parameterConsumer = FilesConsumer.class)
@@ -100,6 +104,12 @@ class Run extends CamelCommand {
List<String> files = new ArrayList<>();
+ @Option(names = { "--background" }, defaultValue = "false", description = "Run in the background")
+ boolean background;
+
+ @Option(names = { "--camel-version" }, description = "To run using a different Camel version than the default version.")
+ String camelVersion;
+
@Option(names = { "--profile" }, scope = CommandLine.ScopeType.INHERIT, defaultValue = "application",
description = "Profile to use, which refers to loading properties file with the given profile name. By default application.properties is loaded.")
String profile;
@@ -264,32 +274,12 @@ class Run extends CamelCommand {
removeDir(work);
work.mkdirs();
- Properties profileProperties = null;
- File profilePropertiesFile = new File(getProfile() + ".properties");
- if (profilePropertiesFile.exists()) {
- profileProperties = loadProfileProperties(profilePropertiesFile);
- // logging level/color may be configured in the properties file
- loggingLevel = profileProperties.getProperty("loggingLevel", loggingLevel);
- loggingColor
- = "true".equals(profileProperties.getProperty("loggingColor", loggingColor ? "true" : "false"));
- loggingJson
- = "true".equals(profileProperties.getProperty("loggingJson", loggingJson ? "true" : "false"));
- if (propertiesFiles == null) {
- propertiesFiles = "file:" + profilePropertiesFile.getName();
- } else {
- propertiesFiles = propertiesFiles + ",file:" + profilePropertiesFile.getName();
- }
- repos = profileProperties.getProperty("camel.jbang.repos", repos);
- mavenSettings = profileProperties.getProperty("camel.jbang.maven-settings", mavenSettings);
- mavenSettingsSecurity = profileProperties.getProperty("camel.jbang.maven-settings-security", mavenSettingsSecurity);
- openapi = profileProperties.getProperty("camel.jbang.openApi", openapi);
- download = "true".equals(profileProperties.getProperty("camel.jbang.download", download ? "true" : "false"));
- }
-
- // generate open-api early
+ Properties profileProperties = loadProfileProperties();
+ configureLogging();
if (openapi != null) {
generateOpenApi();
}
+
// route code as option
if (code != null) {
// store code in temporary file
@@ -303,7 +293,9 @@ class Run extends CamelCommand {
String routes = profileProperties != null ? profileProperties.getProperty("camel.main.routesIncludePattern") : null;
if (routes == null) {
if (!silentRun) {
- System.out.println("Cannot run because " + getProfile() + ".properties file does not exist");
+ System.out
+ .println("Cannot run because " + getProfile()
+ + ".properties file does not exist or camel.main.routesIncludePattern is not configured");
return 1;
} else {
// silent-run then auto-detect all files (except properties as they are loaded explicit or via profile)
@@ -319,11 +311,7 @@ class Run extends CamelCommand {
files = files.stream().distinct().collect(Collectors.toList());
}
- // configure logging first
- configureLogging();
-
final KameletMain main = createMainInstance();
-
main.setRepos(repos);
main.setDownload(download);
main.setFresh(fresh);
@@ -344,11 +332,12 @@ class Run extends CamelCommand {
if (modeline) {
writeSetting(main, profileProperties, "camel.main.modeline", "true");
}
- writeSetting(main, profileProperties, "camel.jbang.openApi", openapi);
+ writeSetting(main, profileProperties, "camel.jbang.open-api", openapi);
writeSetting(main, profileProperties, "camel.jbang.repos", repos);
writeSetting(main, profileProperties, "camel.jbang.health", health ? "true" : "false");
writeSetting(main, profileProperties, "camel.jbang.console", console ? "true" : "false");
- writeSetting(main, profileProperties, "camel.main.routesCompileDirectory", WORK_DIR);
+ // the runtime version of Camel is what is loaded via the catalog
+ writeSetting(main, profileProperties, "camel.jbang.camel-version", new DefaultCamelCatalog().getCatalogVersion());
// merge existing dependencies with --deps
String deps = RuntimeUtil.getDependencies(profileProperties);
if (deps.isBlank()) {
@@ -391,7 +380,7 @@ class Run extends CamelCommand {
() -> maxIdleSeconds > 0 ? String.valueOf(maxIdleSeconds) : null);
writeSetting(main, profileProperties, "camel.jbang.platform-http.port",
() -> port > 0 ? String.valueOf(port) : null);
- writeSetting(main, profileProperties, "camel.jbang.jfr", jfr || jfrProfile != null ? "jfr" : null);
+ writeSetting(main, profileProperties, "camel.jbang.jfr", jfr || jfrProfile != null ? "jfr" : null); // TODO: "true" instead of "jfr" ?
writeSetting(main, profileProperties, "camel.jbang.jfr-profile", jfrProfile != null ? jfrProfile : null);
StringJoiner js = new StringJoiner(",");
@@ -481,7 +470,6 @@ class Run extends CamelCommand {
sjReload.add(file.substring(5));
}
}
-
writeSetting(main, profileProperties, "camel.main.name", name);
if (js.length() > 0) {
@@ -557,9 +545,198 @@ class Run extends CamelCommand {
writeSettings("camel.component.properties.location", loc);
}
+ // okay we have validated all input and are ready to run
+ if (camelVersion != null) {
+ // run in another JVM with different camel version (foreground or background)
+ boolean custom = camelVersion.contains("-");
+ if (custom) {
+ // custom camel distribution
+ return runCustomCamelVersion(main);
+ } else {
+ // apache camel distribution
+ return runCamelVersion(main);
+ }
+ } else if (background) {
+ // spawn new JVM to run in background
+ return runBackground(main);
+ } else {
+ // run default in current JVM with same camel version
+ return runKameletMain(main);
+ }
+ }
+
+ private Properties loadProfileProperties() throws Exception {
+ Properties answer = null;
+
+ File profilePropertiesFile = new File(getProfile() + ".properties");
+ if (profilePropertiesFile.exists()) {
+ answer = loadProfileProperties(profilePropertiesFile);
+ // logging level/color may be configured in the properties file
+ loggingLevel = answer.getProperty("loggingLevel", loggingLevel);
+ loggingColor
+ = "true".equals(answer.getProperty("loggingColor", loggingColor ? "true" : "false"));
+ loggingJson
+ = "true".equals(answer.getProperty("loggingJson", loggingJson ? "true" : "false"));
+ if (propertiesFiles == null) {
+ propertiesFiles = "file:" + getProfile() + ".properties";
+ } else {
+ propertiesFiles = propertiesFiles + ",file:" + profilePropertiesFile.getName();
+ }
+ repos = answer.getProperty("camel.jbang.repos", repos);
+ mavenSettings = answer.getProperty("camel.jbang.maven-settings", mavenSettings);
+ mavenSettingsSecurity = answer.getProperty("camel.jbang.maven-settings-security", mavenSettingsSecurity);
+ openapi = answer.getProperty("camel.jbang.open-api", openapi);
+ download = "true".equals(answer.getProperty("camel.jbang.download", download ? "true" : "false"));
+ background = "true".equals(answer.getProperty("camel.jbang.background", background ? "true" : "false"));
+ camelVersion = answer.getProperty("camel.jbang.camel-version", camelVersion);
+ }
+ return answer;
+ }
+
+ protected int runCamelVersion(KameletMain main) throws Exception {
+ String cmd = ProcessHandle.current().info().commandLine().orElse(null);
+ if (cmd != null) {
+ cmd = StringHelper.after(cmd, "main.CamelJBang ");
+ }
+ if (cmd == null) {
+ System.err.println("No Camel integration files to run");
+ return 1;
+ }
+ if (background) {
+ cmd = cmd.replaceFirst("--background=true", "");
+ cmd = cmd.replaceFirst("--background", "");
+ }
+ cmd = cmd.replaceFirst("--camel-version=" + camelVersion, "");
+ // need to use jbang command to specify camel version
+ String jbang = "jbang run -Dcamel.jbang.version=" + camelVersion;
+ if (repos != null) {
+ jbang += " --repos=" + repos;
+ }
+ cmd = jbang + " camel@apache/camel " + cmd;
+
+ ProcessBuilder pb = new ProcessBuilder();
+ String[] arr = cmd.split("\\s+"); // TODO: safe split
+ List<String> args = Arrays.asList(arr);
+ pb.command(args);
+ if (background) {
+ Process p = pb.start();
+ System.out.println("Running Camel integration: " + name + " (version: " + camelVersion
+ + ") in background with PID: " + p.pid());
+ return 0;
+ } else {
+ pb.inheritIO(); // run in foreground (with IO so logs are visible)
+ Process p = pb.start();
+ // wait for that process to exit as we run in foreground
+ return p.waitFor();
+ }
+ }
+
+ protected int runBackground(KameletMain main) throws Exception {
+ String cmd = ProcessHandle.current().info().commandLine().orElse(null);
+ if (cmd != null) {
+ cmd = StringHelper.after(cmd, "main.CamelJBang ");
+ }
+ if (cmd == null) {
+ System.err.println("No Camel integration files to run");
+ return 1;
+ }
+ cmd = cmd.replaceFirst("--background=true", "");
+ cmd = cmd.replaceFirst("--background", "");
+ cmd = "camel " + cmd;
+
+ ProcessBuilder pb = new ProcessBuilder();
+ String[] arr = cmd.split("\\s+"); // TODO: safe split
+ List<String> args = Arrays.asList(arr);
+ pb.command(args);
+ Process p = pb.start();
+ System.out.println("Running Camel integration: " + name + " in background with PID: " + p.pid());
+ return 0;
+ }
+
+ protected int runCustomCamelVersion(KameletMain main) throws Exception {
+ InputStream is = Run.class.getClassLoader().getResourceAsStream("templates/run-custom-camel-version.tmpl");
+ String content = IOHelper.loadText(is);
+ IOHelper.close(is);
+
+ content = content.replaceFirst("\\{\\{ \\.JavaVersion }}", "11"); // TODO: java 11 or 17
+ if (repos != null) {
+ content = content.replaceFirst("\\{\\{ \\.MavenRepositories }}", "//REPOS " + repos);
+ }
+
+ // use custom distribution of camel
+ StringBuilder sb = new StringBuilder();
+ sb.append(String.format("//DEPS org.apache.camel:camel-bom:%s@pom\n", camelVersion));
+ sb.append(String.format("//DEPS org.apache.camel:camel-core:%s\n", camelVersion));
+ sb.append(String.format("//DEPS org.apache.camel:camel-core-engine:%s\n", camelVersion));
+ sb.append(String.format("//DEPS org.apache.camel:camel-main:%s\n", camelVersion));
+ sb.append(String.format("//DEPS org.apache.camel:camel-java-joor-dsl:%s\n", camelVersion));
+ sb.append(String.format("//DEPS org.apache.camel:camel-kamelet:%s\n", camelVersion));
+ content = content.replaceFirst("\\{\\{ \\.CamelDependencies }}", sb.toString());
+
+ // use apache distribution of camel-jbang
+ String v = camelVersion.substring(0, camelVersion.lastIndexOf('.'));
+ sb = new StringBuilder();
+ sb.append(String.format("//DEPS org.apache.camel:camel-jbang-core:%s\n", v));
+ sb.append(String.format("//DEPS org.apache.camel:camel-kamelet-main:%s\n", v));
+ sb.append(String.format("//DEPS org.apache.camel:camel-resourceresolver-github:%s\n", v));
+ if (VersionHelper.isGE(v, "3.19.0")) {
+ sb.append(String.format("//DEPS org.apache.camel:camel-cli-connector:%s\n", v));
+ }
+ content = content.replaceFirst("\\{\\{ \\.CamelJBangDependencies }}", sb.toString());
+
+ String fn = WORK_DIR + "/CustomCamelJBang.java";
+ Files.write(Paths.get(fn), content.getBytes(StandardCharsets.UTF_8));
+
+ String cmd = ProcessHandle.current().info().commandLine().orElse(null);
+ if (cmd != null) {
+ cmd = StringHelper.after(cmd, "main.CamelJBang ");
+ }
+ if (cmd == null) {
+ System.err.println("No Camel integration files to run");
+ return 1;
+ }
+ if (background) {
+ cmd = cmd.replaceFirst("--background=true", "");
+ cmd = cmd.replaceFirst("--background", "");
+ }
+ if (repos != null) {
+ if (!VersionHelper.isGE(v, "3.18.1")) {
+ // --repos is not supported in 3.18.0 or older, so remove
+ cmd = cmd.replaceFirst("--repos=" + repos, "");
+ }
+ }
+
+ cmd = cmd.replaceFirst("--camel-version=" + camelVersion, "");
+ // need to use jbang command to specify camel version
+ String jbang = "jbang " + WORK_DIR + "/CustomCamelJBang.java ";
+ cmd = jbang + cmd;
+
+ ProcessBuilder pb = new ProcessBuilder();
+ String[] arr = cmd.split("\\s+"); // TODO: safe split
+ List<String> args = Arrays.asList(arr);
+ pb.command(args);
+ if (background) {
+ Process p = pb.start();
+ System.out.println("Running Camel integration: " + name + " (version: " + camelVersion
+ + ") in background with PID: " + p.pid());
+ return 0;
+ } else {
+ pb.inheritIO(); // run in foreground (with IO so logs are visible)
+ Process p = pb.start();
+ // wait for that process to exit as we run in foreground
+ return p.waitFor();
+ }
+ }
+
+ protected int runKameletMain(KameletMain main) throws Exception {
main.start();
main.run();
+ // cleanup and delete log file
+ if (logFile != null) {
+ FileUtil.deleteFile(logFile);
+ }
+
return main.getExitCode();
}
@@ -667,7 +844,7 @@ class Run extends CamelCommand {
return file;
}
- private KameletMain createMainInstance() throws Exception {
+ private KameletMain createMainInstance() {
KameletMain main;
if (localKameletDir == null || localKameletDir.isEmpty()) {
main = new KameletMain();
@@ -701,6 +878,13 @@ class Run extends CamelCommand {
writeSettings("loggingLevel", loggingLevel);
writeSettings("loggingColor", loggingColor ? "true" : "false");
writeSettings("loggingJson", loggingJson ? "true" : "false");
+ if (!pipeRun) {
+ // remember log file
+ File dir = new File(System.getProperty("user.home"), ".camel");
+ String name = RuntimeUtil.getPid() + ".log";
+ logFile = new File(dir, name);
+ logFile.deleteOnExit();
+ }
} else {
RuntimeUtil.configureLog("off", false, false, false, false);
writeSettings("loggingLevel", "off");
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionBaseCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionBaseCommand.java
index 4381965d9d6..ff2f019c13e 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionBaseCommand.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionBaseCommand.java
@@ -20,7 +20,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
-import java.util.regex.Pattern;
import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
@@ -33,9 +32,6 @@ import org.apache.camel.util.json.Jsoner;
abstract class ActionBaseCommand extends CamelCommand {
- private static final String[] DSL_EXT = new String[] { "groovy", "java", "js", "jsh", "kts", "xml", "yaml" };
- private static final Pattern PATTERN = Pattern.compile("([\\w|\\-.])+");
-
public ActionBaseCommand(CamelJBangMain main) {
super(main);
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionWatchCommand.java
similarity index 51%
copy from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelStatus.java
copy to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionWatchCommand.java
index 3f3c44df414..8fbd5421db5 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelStatus.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionWatchCommand.java
@@ -14,24 +14,44 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.dsl.jbang.core.commands.process;
+package org.apache.camel.dsl.jbang.core.commands.action;
-import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.fusesource.jansi.Ansi;
+import org.fusesource.jansi.AnsiConsole;
import picocli.CommandLine;
-@CommandLine.Command(name = "get",
- description = "Get status of Camel integrations (use get --help to see sub commands)")
-public class CamelStatus extends CamelCommand {
+abstract class ActionWatchCommand extends ActionBaseCommand {
- public CamelStatus(CamelJBangMain main) {
+ @CommandLine.Option(names = { "--watch" },
+ description = "Execute periodically and showing output fullscreen")
+ boolean watch;
+
+ public ActionWatchCommand(CamelJBangMain main) {
super(main);
}
@Override
public Integer call() throws Exception {
- // default to get the integrations
- new CommandLine(new CamelContextStatus(getMain())).execute();
- return 0;
+ int exit;
+ if (watch) {
+ do {
+ exit = doCall();
+ if (exit == 0) {
+ // use 2-sec delay in watch mode
+ Thread.sleep(2000);
+ }
+ } while (exit == 0);
+ } else {
+ exit = doCall();
+ }
+ return exit;
+ }
+
+ protected void clearScreen() {
+ AnsiConsole.out().print(Ansi.ansi().eraseScreen().cursor(1, 1));
}
+
+ protected abstract Integer doCall() throws Exception;
+
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java
new file mode 100644
index 00000000000..75d934dadc6
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java
@@ -0,0 +1,449 @@
+/*
+ * 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.action;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.regex.Pattern;
+
+import org.apache.camel.catalog.impl.TimePatternConverter;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.ProcessHelper;
+import org.apache.camel.util.StopWatch;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.json.JsonObject;
+import org.fusesource.jansi.Ansi;
+import org.fusesource.jansi.AnsiConsole;
+import picocli.CommandLine;
+
+@CommandLine.Command(name = "log",
+ description = "Tail logs from running Camel integrations")
+public class CamelLogAction extends ActionBaseCommand {
+
+ private static final int NAME_MAX_WIDTH = 25;
+ private static final int NAME_MIN_WIDTH = 10;
+
+ @CommandLine.Parameters(description = "Name or pid of running Camel integration. (default selects all)", arity = "0..1")
+ String name = "*";
+
+ @CommandLine.Option(names = { "--logging-color" }, defaultValue = "true", description = "Use colored logging")
+ boolean loggingColor = true;
+
+ @CommandLine.Option(names = { "--timestamp" }, defaultValue = "true",
+ description = "Print timestamp.")
+ boolean timestamp = true;
+
+ @CommandLine.Option(names = { "--follow" }, defaultValue = "true",
+ description = "Keep following and outputting new log lines (use ctrl + c to exit).")
+ boolean follow = true;
+
+ @CommandLine.Option(names = { "--prefix" }, defaultValue = "true",
+ description = "Print prefix with running Camel integration name.")
+ boolean prefix = true;
+
+ @CommandLine.Option(names = { "--tail" },
+ description = "The number of lines from the end of the logs to show. Defaults to showing all logs.")
+ int tail;
+
+ @CommandLine.Option(names = { "--since" },
+ description = "Return logs newer than a relative duration like 5s, 2m, or 1h. The value is in seconds if no unit specified.")
+ String since;
+
+ @CommandLine.Option(names = { "--find" },
+ description = "Find and highlight matching text (ignore case).", arity = "0..*")
+ String[] find;
+
+ @CommandLine.Option(names = { "--grep" },
+ description = "Filter logs to only output lines matching text (ignore case).", arity = "0..*")
+ String[] grep;
+
+ String findAnsi;
+
+ private int nameMaxWidth;
+
+ private final Map<String, Ansi.Color> colors = new HashMap<>();
+
+ public CamelLogAction(CamelJBangMain main) {
+ super(main);
+ }
+
+ @Override
+ public Integer call() throws Exception {
+ Map<Long, Row> rows = new LinkedHashMap<>();
+
+ // find new pids
+ updatePids(rows);
+ if (!rows.isEmpty()) {
+ // read existing log files (skip by tail/since)
+ if (find != null) {
+ findAnsi = Ansi.ansi().fg(Ansi.Color.BLACK).bg(Ansi.Color.YELLOW).a("$0").reset().toString();
+ for (int i = 0; i < find.length; i++) {
+ String f = find[i];
+ f = Pattern.quote(f);
+ find[i] = f;
+ }
+ }
+ if (grep != null) {
+ findAnsi = Ansi.ansi().fg(Ansi.Color.BLACK).bg(Ansi.Color.YELLOW).a("$0").reset().toString();
+ for (int i = 0; i < grep.length; i++) {
+ String f = grep[i];
+ f = Pattern.quote(f);
+ grep[i] = f;
+ }
+ }
+ Date limit = null;
+ if (since != null) {
+ long millis;
+ if (StringHelper.isDigit(since)) {
+ // is in seconds by default
+ millis = TimePatternConverter.toMilliSeconds(since) * 1000;
+ } else {
+ millis = TimePatternConverter.toMilliSeconds(since);
+ }
+ limit = new Date(System.currentTimeMillis() - millis);
+ }
+
+ // dump existing log lines
+ tailLogFiles(rows, tail, limit);
+ dumpLogFiles(rows, tail);
+ }
+
+ if (follow) {
+ boolean waitMessage = true;
+ StopWatch watch = new StopWatch();
+ do {
+ if (rows.isEmpty()) {
+ if (waitMessage) {
+ System.out.println("Waiting for logs ...");
+ waitMessage = false;
+ }
+ Thread.sleep(500);
+ updatePids(rows);
+ } else {
+ waitMessage = true;
+ if (watch.taken() > 500) {
+ // check for new logs
+ updatePids(rows);
+ watch.restart();
+ }
+ int lines = readLogFiles(rows);
+ if (lines > 0) {
+ dumpLogFiles(rows, 0);
+ } else {
+ Thread.sleep(100);
+ }
+ }
+ } while (true);
+ }
+
+ return 0;
+ }
+
+ private void updatePids(Map<Long, Row> rows) {
+ List<Long> pids = findPids(name);
+ ProcessHandle.allProcesses()
+ .filter(ph -> pids.contains(ph.pid()))
+ .forEach(ph -> {
+ JsonObject root = loadStatus(ph.pid());
+ if (root != null) {
+ Row row = new Row();
+ row.pid = "" + ph.pid();
+ JsonObject context = (JsonObject) root.get("context");
+ if (context == null) {
+ return;
+ }
+ row.name = context.getString("name");
+ if ("CamelJBang".equals(row.name)) {
+ row.name = ProcessHelper.extractName(root, ph);
+ }
+ int len = row.name.length();
+ if (len < NAME_MIN_WIDTH) {
+ len = NAME_MIN_WIDTH;
+ }
+ if (len > NAME_MAX_WIDTH) {
+ len = NAME_MAX_WIDTH;
+ }
+ if (len > nameMaxWidth) {
+ nameMaxWidth = len;
+ }
+ if (!rows.containsKey(ph.pid())) {
+ rows.put(ph.pid(), row);
+ }
+ }
+ });
+
+ // remove pids that are no long active from the rows
+ Set<Long> remove = new HashSet<>();
+ for (long pid : rows.keySet()) {
+ if (!pids.contains(pid)) {
+ remove.add(pid);
+ }
+ }
+ for (long pid : remove) {
+ rows.remove(pid);
+ }
+ }
+
+ private int readLogFiles(Map<Long, Row> rows) throws Exception {
+ int lines = 0;
+
+ for (Row row : rows.values()) {
+ if (row.reader == null) {
+ File log = logFile(row.pid);
+ if (log.exists()) {
+ row.reader = new LineNumberReader(new FileReader(log));
+ }
+ }
+ if (row.reader != null) {
+ String line;
+ do {
+ try {
+ line = row.reader.readLine();
+ if (line != null) {
+ boolean valid = true;
+ if (grep != null) {
+ valid = isValidGrep(line);
+ }
+ if (valid) {
+ lines++;
+ // switch fifo to be unlimited as we use it for new log lines
+ if (row.fifo == null || row.fifo instanceof ArrayBlockingQueue) {
+ row.fifo = new ArrayDeque<>();
+ }
+ row.fifo.offer(line);
+ }
+ }
+ } catch (IOException e) {
+ // ignore
+ line = null;
+ }
+ } while (line != null);
+ }
+ }
+
+ return lines;
+ }
+
+ private void dumpLogFiles(Map<Long, Row> rows, int tail) {
+ List<String> lines = new ArrayList<>();
+ for (Row row : rows.values()) {
+ Queue<String> queue = row.fifo;
+ if (queue != null) {
+ for (String l : queue) {
+ lines.add(row.name + "| " + l);
+ }
+ row.fifo.clear();
+ }
+ }
+ // sort lines
+ lines.sort(this::compareLogLine);
+ if (tail > 0) {
+ // cut according to tail
+ int pos = lines.size() - tail;
+ if (pos > 0) {
+ lines = lines.subList(pos, lines.size());
+ }
+ }
+ lines.forEach(l -> {
+ String name = StringHelper.before(l, "| ");
+ String line = StringHelper.after(l, "| ");
+ printLine(name, line);
+ });
+ }
+
+ private int compareLogLine(String l1, String l2) {
+ l1 = unescapeAnsi(l1);
+ l2 = unescapeAnsi(l2);
+
+ String t1 = StringHelper.after(l1, "| ");
+ t1 = StringHelper.before(t1, " ");
+ String t2 = StringHelper.after(l2, "| ");
+ t2 = StringHelper.before(t2, " ");
+ return t1.compareTo(t2);
+ }
+
+ protected void printLine(String name, String line) {
+ if (!prefix) {
+ name = null;
+ }
+ if (!timestamp) {
+ // after timestamp is after 2 sine-space
+ int pos = line.indexOf(' ');
+ pos = line.indexOf(' ', pos + 1);
+ if (pos != -1) {
+ line = line.substring(pos + 1);
+ }
+ }
+ if (loggingColor) {
+ if (name != null) {
+ Ansi.Color color = colors.get(name);
+ if (color == null) {
+ // grab a new color
+ int idx = (colors.size() % 6) + 1;
+ color = Ansi.Color.values()[idx];
+ colors.put(name, color);
+ }
+ String n = String.format("%-" + nameMaxWidth + "s", name);
+ AnsiConsole.out().print(Ansi.ansi().fg(color).a(n).a("| ").reset());
+ }
+ } else {
+ line = unescapeAnsi(line);
+ if (name != null) {
+ String n = String.format("%-" + nameMaxWidth + "s", name);
+ System.out.print(n);
+ System.out.print("| ");
+ }
+ }
+ if (find != null || grep != null) {
+ String before = StringHelper.before(line, "---");
+ String after = StringHelper.after(line, "---");
+ if (find != null) {
+ for (String f : find) {
+ after = after.replaceAll("(?i)" + f, findAnsi);
+ }
+ }
+ if (grep != null) {
+ for (String g : grep) {
+ after = after.replaceAll("(?i)" + g, findAnsi);
+ }
+ }
+ line = before + "---" + after;
+ }
+ if (loggingColor) {
+ AnsiConsole.out().println(line);
+ } else {
+ System.out.println(line);
+ }
+ }
+
+ private static File logFile(String pid) {
+ File dir = new File(System.getProperty("user.home"), ".camel");
+ String name = pid + ".log";
+ return new File(dir, name);
+ }
+
+ private void tailLogFiles(Map<Long, Row> rows, int tail, Date limit) throws Exception {
+ for (Row row : rows.values()) {
+ File log = logFile(row.pid);
+ if (log.exists()) {
+ row.reader = new LineNumberReader(new FileReader(log));
+ String line;
+ if (tail == 0) {
+ row.fifo = new ArrayDeque<>();
+ } else {
+ row.fifo = new ArrayBlockingQueue<>(tail);
+ }
+ do {
+ line = row.reader.readLine();
+ if (line != null) {
+ boolean valid = isValidSince(limit, line);
+ if (valid && grep != null) {
+ valid = isValidGrep(line);
+ }
+ if (valid) {
+ while (!row.fifo.offer(line)) {
+ row.fifo.poll();
+ }
+ }
+ }
+ } while (line != null);
+ }
+ }
+ }
+
+ private boolean isValidSince(Date limit, String line) {
+ if (limit == null) {
+ return true;
+ }
+ // the log can be in color or not so we need to unescape always
+ line = unescapeAnsi(line);
+ String ts = StringHelper.before(line, " ");
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ try {
+ Date row = sdf.parse(ts);
+ return row.compareTo(limit) >= 0;
+ } catch (ParseException e) {
+ // ignore
+ }
+ return false;
+ }
+
+ private boolean isValidGrep(String line) {
+ if (grep == null) {
+ return true;
+ }
+ // the log can be in color or not so we need to unescape always
+ line = unescapeAnsi(line);
+ String after = StringHelper.after(line, "---");
+ for (String g : grep) {
+ boolean m = Pattern.compile("(?i)" + g).matcher(after).find();
+ if (m) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private String unescapeAnsi(String line) {
+ // unescape ANSI colors
+ StringBuilder sb = new StringBuilder();
+ boolean escaping = false;
+ char[] arr = line.toCharArray();
+ for (int i = 0; i < arr.length; i++) {
+ char ch = arr[i];
+ if (escaping) {
+ if (ch == 'm') {
+ escaping = false;
+ }
+ continue;
+ }
+ char ch2 = i < arr.length - 1 ? arr[i + 1] : 0;
+ if (ch == 27 && ch2 == '[') {
+ escaping = true;
+ continue;
+ }
+
+ sb.append(ch);
+ }
+ return sb.toString();
+ }
+
+ private static class Row {
+ String pid;
+ String name;
+ Queue<String> fifo;
+ LineNumberReader reader;
+
+ }
+
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelSourceTop.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelSourceTop.java
index 5c6a4215591..bda0bb38c11 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelSourceTop.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelSourceTop.java
@@ -33,7 +33,7 @@ import picocli.CommandLine;
import picocli.CommandLine.Command;
@Command(name = "source", description = "List top processors (source) in a running Camel integration")
-public class CamelSourceTop extends ActionBaseCommand {
+public class CamelSourceTop extends ActionWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "1")
String name;
@@ -53,7 +53,7 @@ public class CamelSourceTop extends ActionBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
@@ -140,6 +140,7 @@ public class CamelSourceTop extends ActionBaseCommand {
// sort rows
rows.sort(this::sortRow);
+ clearScreen();
if (!rows.isEmpty()) {
printSource(rows);
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelThreadDump.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelThreadDump.java
index e12dbd2dda0..1ee5b4c147f 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelThreadDump.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelThreadDump.java
@@ -38,7 +38,7 @@ import picocli.CommandLine;
import picocli.CommandLine.Command;
@Command(name = "thread-dump", description = "List threads in a running Camel integration")
-public class CamelThreadDump extends ActionBaseCommand {
+public class CamelThreadDump extends ActionWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "1")
String name;
@@ -66,7 +66,7 @@ public class CamelThreadDump extends ActionBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
@@ -132,6 +132,7 @@ public class CamelThreadDump extends ActionBaseCommand {
// sort rows
rows.sort(this::sortRow);
+ clearScreen();
if (!rows.isEmpty()) {
int total = jo.getInteger("threadCount");
int peak = jo.getInteger("peakThreadCount");
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/RouteControllerAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/RouteControllerAction.java
index 5412738ce7e..f5e0a85acfd 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/RouteControllerAction.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/RouteControllerAction.java
@@ -39,7 +39,7 @@ import picocli.CommandLine;
import picocli.CommandLine.Command;
@Command(name = "route-controller", description = "List status of route controller in a running Camel integration")
-public class RouteControllerAction extends ActionBaseCommand {
+public class RouteControllerAction extends ActionWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "1")
String name;
@@ -67,7 +67,7 @@ public class RouteControllerAction extends ActionBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
@@ -134,6 +134,7 @@ public class RouteControllerAction extends ActionBaseCommand {
// sort rows
rows.sort(this::sortRow);
+ clearScreen();
if (!rows.isEmpty()) {
if (supervising) {
if (header) {
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogBaseCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogBaseCommand.java
index 448bba7a364..5cb43bfe1ae 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogBaseCommand.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogBaseCommand.java
@@ -28,6 +28,7 @@ import org.apache.camel.catalog.CamelCatalog;
import org.apache.camel.catalog.DefaultCamelCatalog;
import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.VersionHelper;
import org.apache.camel.main.download.MavenGav;
import org.apache.camel.tooling.model.ArtifactModel;
import picocli.CommandLine;
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogDoc.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogDoc.java
index c5866b117fb..33297b470f2 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogDoc.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogDoc.java
@@ -70,7 +70,7 @@ public class CatalogDoc extends CamelCommand {
boolean headers;
@CommandLine.Option(names = {
- "--kamelets-version" }, description = "Apache Camel Kamelets version", defaultValue = "3.20.0")
+ "--kamelets-version" }, description = "Apache Camel Kamelets version", defaultValue = "3.20.1.1")
String kameletsVersion;
final CamelCatalog catalog = new DefaultCamelCatalog(true);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogKamelet.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogKamelet.java
index 0d9903a6ef0..bf8af192b3c 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogKamelet.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogKamelet.java
@@ -52,7 +52,7 @@ public class CatalogKamelet extends CamelCommand {
String filterName;
@CommandLine.Option(names = {
- "--kamelets-version" }, description = "Apache Camel Kamelets version", defaultValue = "3.20.0")
+ "--kamelets-version" }, description = "Apache Camel Kamelets version", defaultValue = "3.20.1.1")
String kameletsVersion;
public CatalogKamelet(CamelJBangMain main) {
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java
index 1a331516dba..eb87dc1f2fb 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextStatus.java
@@ -35,7 +35,7 @@ import picocli.CommandLine.Command;
@Command(name = "context",
description = "Get status of Camel integrations")
-public class CamelContextStatus extends ProcessBaseCommand {
+public class CamelContextStatus extends ProcessWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1")
String name = "*";
@@ -49,7 +49,7 @@ public class CamelContextStatus extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextTop.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextTop.java
index 9cdbcc8c334..ed36eb58b8e 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextTop.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelContextTop.java
@@ -34,7 +34,7 @@ import picocli.CommandLine.Command;
@Command(name = "context",
description = "Top status of Camel integrations")
-public class CamelContextTop extends ProcessBaseCommand {
+public class CamelContextTop extends ProcessWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1")
String name = "*";
@@ -48,7 +48,7 @@ public class CamelContextTop extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelCount.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelCount.java
index 69515307887..f43d3f6819c 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelCount.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelCount.java
@@ -34,7 +34,7 @@ import picocli.CommandLine.Command;
@Command(name = "count",
description = "Get total and failed exchanges for running integrations")
-public class CamelCount extends ProcessBaseCommand {
+public class CamelCount extends ProcessWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1")
String name = "*";
@@ -56,7 +56,7 @@ public class CamelCount extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java
index 39a30060c69..f752d71da1d 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelProcessorStatus.java
@@ -35,7 +35,7 @@ import picocli.CommandLine;
import picocli.CommandLine.Command;
@Command(name = "processor", description = "Get status of Camel processors")
-public class CamelProcessorStatus extends ProcessBaseCommand {
+public class CamelProcessorStatus extends ProcessWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1")
String name = "*";
@@ -61,7 +61,7 @@ public class CamelProcessorStatus extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java
index f5cb0545a34..2e65d9ec7a3 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelRouteStatus.java
@@ -34,7 +34,7 @@ import picocli.CommandLine;
import picocli.CommandLine.Command;
@Command(name = "route", description = "Get status of Camel routes")
-public class CamelRouteStatus extends ProcessBaseCommand {
+public class CamelRouteStatus extends ProcessWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1")
String name = "*";
@@ -64,7 +64,7 @@ public class CamelRouteStatus extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelStatus.java
index 3f3c44df414..596cd72c7b8 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelStatus.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelStatus.java
@@ -24,6 +24,10 @@ import picocli.CommandLine;
description = "Get status of Camel integrations (use get --help to see sub commands)")
public class CamelStatus extends CamelCommand {
+ @CommandLine.Option(names = { "--watch" },
+ description = "Execute periodically and showing output fullscreen")
+ boolean watch;
+
public CamelStatus(CamelJBangMain main) {
super(main);
}
@@ -31,7 +35,8 @@ public class CamelStatus extends CamelCommand {
@Override
public Integer call() throws Exception {
// default to get the integrations
- new CommandLine(new CamelContextStatus(getMain())).execute();
- return 0;
+ CamelContextStatus cmd = new CamelContextStatus(getMain());
+ cmd.watch = watch;
+ return new CommandLine(cmd).execute();
}
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java
index 9f0b3b8c1a0..5a3af05e8f3 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java
@@ -24,6 +24,10 @@ import picocli.CommandLine;
description = "Top status of Camel integrations (use top --help to see sub commands)")
public class CamelTop extends CamelCommand {
+ @CommandLine.Option(names = { "--watch" },
+ description = "Execute periodically and showing output fullscreen")
+ boolean watch;
+
public CamelTop(CamelJBangMain main) {
super(main);
}
@@ -31,7 +35,8 @@ public class CamelTop extends CamelCommand {
@Override
public Integer call() throws Exception {
// default to top the integrations
- new CommandLine(new CamelContextTop(getMain())).execute();
- return 0;
+ CamelContextTop cmd = new CamelContextTop(getMain());
+ cmd.watch = watch;
+ return new CommandLine(cmd).execute();
}
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/Hawtio.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/Hawtio.java
index b5d925231fa..8d9e1dcd1ff 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/Hawtio.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/Hawtio.java
@@ -37,8 +37,8 @@ public class Hawtio extends CamelCommand {
String name;
@CommandLine.Option(names = { "--version" },
- description = "Version of the Hawtio web console", defaultValue = "2.16.2")
- String version = "2.16.2";
+ description = "Version of the Hawtio web console", defaultValue = "2.17.0")
+ String version = "2.17.0";
// use port 8888 as 8080 is too commonly used
@CommandLine.Option(names = { "--port" },
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListBlocked.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListBlocked.java
index 5cc8ac73359..800eba36ca3 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListBlocked.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListBlocked.java
@@ -34,7 +34,7 @@ import picocli.CommandLine.Command;
@Command(name = "blocked",
description = "Get blocked messages of Camel integrations")
-public class ListBlocked extends ProcessBaseCommand {
+public class ListBlocked extends ProcessWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1")
String name = "*";
@@ -48,7 +48,7 @@ public class ListBlocked extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListCircuitBreaker.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListCircuitBreaker.java
index d91051babaa..9d79ed9568e 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListCircuitBreaker.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListCircuitBreaker.java
@@ -34,7 +34,7 @@ import picocli.CommandLine.Command;
@Command(name = "circuit-breaker",
description = "Get status of Circuit Breaker EIPs")
-public class ListCircuitBreaker extends ProcessBaseCommand {
+public class ListCircuitBreaker extends ProcessWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1")
String name = "*";
@@ -48,7 +48,7 @@ public class ListCircuitBreaker extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelEndpointStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListEndpoint.java
similarity index 98%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelEndpointStatus.java
rename to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListEndpoint.java
index 53d2c44192f..e3205346c86 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelEndpointStatus.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListEndpoint.java
@@ -34,7 +34,7 @@ import picocli.CommandLine;
import picocli.CommandLine.Command;
@Command(name = "endpoint", description = "Get usage of Camel endpoints")
-public class CamelEndpointStatus extends ProcessBaseCommand {
+public class ListEndpoint extends ProcessWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1")
String name = "*";
@@ -63,12 +63,12 @@ public class CamelEndpointStatus extends ProcessBaseCommand {
description = "List endpoint URI without query parameters (short)")
boolean shortUri;
- public CamelEndpointStatus(CamelJBangMain main) {
+ public ListEndpoint(CamelJBangMain main) {
super(main);
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
// make it easier to filter
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListEvent.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListEvent.java
index 9f201aecc24..fca78be3c4a 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListEvent.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListEvent.java
@@ -34,7 +34,7 @@ import picocli.CommandLine.Command;
@Command(name = "event",
description = "Get latest events of Camel integrations")
-public class ListEvent extends ProcessBaseCommand {
+public class ListEvent extends ProcessWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1")
String name = "*";
@@ -52,7 +52,7 @@ public class ListEvent extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListHealth.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListHealth.java
index 5ba23909a2a..8d69917ba7b 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListHealth.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListHealth.java
@@ -40,7 +40,7 @@ import picocli.CommandLine;
import picocli.CommandLine.Command;
@Command(name = "health", description = "Get health check status of running Camel integrations")
-public class ListHealth extends ProcessBaseCommand {
+public class ListHealth extends ProcessWatchCommand {
@CommandLine.Option(names = { "--sort" },
description = "Sort by pid, name or age", defaultValue = "pid")
@@ -75,7 +75,7 @@ public class ListHealth extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
final List<Row> rows = new ArrayList<>();
// include stack-traces
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListInflight.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListInflight.java
index ce0ae54e0c5..941431dce9e 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListInflight.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListInflight.java
@@ -34,7 +34,7 @@ import picocli.CommandLine.Command;
@Command(name = "inflight",
description = "Get inflight messages of Camel integrations")
-public class ListInflight extends ProcessBaseCommand {
+public class ListInflight extends ProcessWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1")
String name = "*";
@@ -48,7 +48,7 @@ public class ListInflight extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListMetric.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListMetric.java
index b4252053865..b69b646b1d9 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListMetric.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListMetric.java
@@ -34,7 +34,7 @@ import picocli.CommandLine.Command;
@Command(name = "metric",
description = "Get metrics (micrometer) of running Camel integrations")
-public class ListMetric extends ProcessBaseCommand {
+public class ListMetric extends ProcessWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1")
String name = "*";
@@ -60,7 +60,7 @@ public class ListMetric extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java
index 85a9475e3e8..8d67cfff03b 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProcess.java
@@ -32,7 +32,7 @@ import picocli.CommandLine;
import picocli.CommandLine.Command;
@Command(name = "ps", description = "List running Camel integrations")
-public class ListProcess extends ProcessBaseCommand {
+public class ListProcess extends ProcessWatchCommand {
@CommandLine.Option(names = { "--sort" },
description = "Sort by pid, name or age", defaultValue = "pid")
@@ -46,8 +46,7 @@ public class ListProcess extends ProcessBaseCommand {
super(main);
}
- @Override
- public Integer call() throws Exception {
+ protected Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids("*");
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListService.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListService.java
index 3a45113de8b..9b56a84ef15 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListService.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListService.java
@@ -34,7 +34,7 @@ import picocli.CommandLine.Command;
@Command(name = "service",
description = "Get services of Camel integrations")
-public class ListService extends ProcessBaseCommand {
+public class ListService extends ProcessWatchCommand {
@CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "0..1")
String name = "*";
@@ -48,7 +48,7 @@ public class ListService extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids(name);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVault.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVault.java
index d6092254a00..8ce83a353cb 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVault.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVault.java
@@ -34,7 +34,7 @@ import picocli.CommandLine.Command;
@Command(name = "vault",
description = "List secrets from security vaults used by running Camel integrations")
-public class ListVault extends ProcessBaseCommand {
+public class ListVault extends ProcessWatchCommand {
@CommandLine.Option(names = { "--sort" },
description = "Sort by pid, name", defaultValue = "pid")
@@ -45,7 +45,7 @@ public class ListVault extends ProcessBaseCommand {
}
@Override
- public Integer call() throws Exception {
+ public Integer doCall() throws Exception {
List<Row> rows = new ArrayList<>();
List<Long> pids = findPids("*");
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelStatus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ProcessWatchCommand.java
similarity index 52%
copy from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelStatus.java
copy to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ProcessWatchCommand.java
index 3f3c44df414..cb8c6dbb560 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelStatus.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ProcessWatchCommand.java
@@ -16,22 +16,46 @@
*/
package org.apache.camel.dsl.jbang.core.commands.process;
-import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.fusesource.jansi.Ansi;
+import org.fusesource.jansi.AnsiConsole;
import picocli.CommandLine;
-@CommandLine.Command(name = "get",
- description = "Get status of Camel integrations (use get --help to see sub commands)")
-public class CamelStatus extends CamelCommand {
+/**
+ * Base class for commands that can run in watch mode.
+ */
+abstract class ProcessWatchCommand extends ProcessBaseCommand {
+
+ @CommandLine.Option(names = { "--watch" },
+ description = "Execute periodically and showing output fullscreen")
+ boolean watch;
- public CamelStatus(CamelJBangMain main) {
+ public ProcessWatchCommand(CamelJBangMain main) {
super(main);
}
@Override
public Integer call() throws Exception {
- // default to get the integrations
- new CommandLine(new CamelContextStatus(getMain())).execute();
- return 0;
+ int exit;
+ if (watch) {
+ do {
+ clearScreen();
+ exit = doCall();
+ if (exit == 0) {
+ // use 2-sec delay in watch mode
+ Thread.sleep(2000);
+ }
+ } while (exit == 0);
+ } else {
+ exit = doCall();
+ }
+ return exit;
+ }
+
+ protected void clearScreen() {
+ AnsiConsole.out().print(Ansi.ansi().eraseScreen().cursor(1, 1));
}
+
+ protected abstract Integer doCall() throws Exception;
+
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/RuntimeUtil.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/RuntimeUtil.java
index edd832c98f8..837e698ef7e 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/RuntimeUtil.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/RuntimeUtil.java
@@ -32,8 +32,12 @@ public final class RuntimeUtil {
private RuntimeUtil() {
}
- public static void configureLog(String level, boolean color, boolean json, boolean pipe, boolean export) {
+ public static void configureLog(
+ String level, boolean color, boolean json, boolean pipe, boolean export) {
if (INIT_DONE.compareAndSet(false, true)) {
+ long pid = ProcessHandle.current().pid();
+ System.setProperty("pid", "" + pid);
+
if (export) {
Configurator.initialize("CamelJBang", "log4j2-export.properties");
} else if (pipe) {
@@ -99,4 +103,12 @@ public final class RuntimeUtil {
return deps;
}
+ public static String getPid() {
+ try {
+ return "" + ProcessHandle.current().pid();
+ } catch (Throwable e) {
+ return null;
+ }
+ }
+
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/VersionHelper.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/VersionHelper.java
similarity index 95%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/VersionHelper.java
rename to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/VersionHelper.java
index 587a56b70d8..cc22c2985e5 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/VersionHelper.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/VersionHelper.java
@@ -14,11 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.dsl.jbang.core.commands.catalog;
+package org.apache.camel.dsl.jbang.core.common;
import org.apache.camel.util.StringHelper;
-final class VersionHelper {
+public final class VersionHelper {
private VersionHelper() {
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/XmlHelper.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/XmlHelper.java
index afc58f99cd9..452307af4cd 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/XmlHelper.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/XmlHelper.java
@@ -42,6 +42,11 @@ public final class XmlHelper {
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
} catch (ParserConfigurationException e) {
}
+ try {
+ // Disable the external-parameter-entities by default
+ factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+ } catch (ParserConfigurationException e) {
+ }
// setup the SecurityManager by default if it's apache xerces
try {
Class<?> smClass = ObjectHelper.loadClass("org.apache.xerces.util.SecurityManager");
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-pipe.properties b/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-background.properties
similarity index 76%
copy from dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-pipe.properties
copy to dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-background.properties
index f6ed178ad0d..5e700f81157 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-pipe.properties
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-background.properties
@@ -15,16 +15,17 @@
## limitations under the License.
## ---------------------------------------------------------------------------
+# file logger
appender.file.type = File
appender.file.name = file
-appender.file.fileName = ${sys:user.home}/.camel/camel-pipe.log
+appender.file.fileName = ${sys:user.home}/.camel/${sys:pid}.log
appender.file.createOnDemand = true
appender.file.append = false
-
appender.file.layout.type = PatternLayout
-# logging style that is similar to spring boot (no color)
-appender.file.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} %5p %pid --- [%15.15t] %-40.40c : %m%n
+# logging style that is similar to spring boot
+appender.file.layout.pattern = %style{%d{yyyy-MM-dd HH:mm:ss.SSS}}{Dim} %highlight{%5p} %style{%pid}{Magenta} %style{---}{Dim} %style{[%15.15t]}{Dim} %style{%-35.35c}{Cyan} : %m%n
+# log to file
+rootLogger = INFO,file
rootLogger.level = INFO
-rootLogger.appenderRef.out.ref = file
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-export.properties b/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-export.properties
index c09e2c668a4..730ef1eb162 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-export.properties
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-export.properties
@@ -23,7 +23,7 @@ appender.file.append = false
appender.file.layout.type = PatternLayout
# logging style that is similar to spring boot (no color)
-appender.file.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} %5p %pid --- [%15.15t] %-40.40c : %m%n
+appender.file.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} %5p %pid --- [%15.15t] %-35.35c : %m%n
rootLogger.level = INFO
rootLogger.appenderRef.out.ref = file
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-no-color.properties b/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-no-color.properties
index 2bb0c0ddc93..6dcdec667d3 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-no-color.properties
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-no-color.properties
@@ -20,7 +20,7 @@ appender.stdout.name = out
appender.stdout.layout.type = PatternLayout
# logging style that is similar to spring boot (no color)
-appender.stdout.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} %5p %pid --- [%15.15t] %-40.40c : %m%n
+appender.stdout.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} %5p %pid --- [%15.15t] %-35.35c : %m%n
rootLogger.level = INFO
rootLogger.appenderRef.out.ref = out
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-pipe.properties b/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-pipe.properties
index f6ed178ad0d..1349f98ad8d 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-pipe.properties
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-pipe.properties
@@ -23,7 +23,7 @@ appender.file.append = false
appender.file.layout.type = PatternLayout
# logging style that is similar to spring boot (no color)
-appender.file.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} %5p %pid --- [%15.15t] %-40.40c : %m%n
+appender.file.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} %5p %pid --- [%15.15t] %-35.35c : %m%n
rootLogger.level = INFO
rootLogger.appenderRef.out.ref = file
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2.properties b/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2.properties
index bd77ce59db0..5561cfee4a4 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2.properties
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2.properties
@@ -15,13 +15,24 @@
## limitations under the License.
## ---------------------------------------------------------------------------
+# console logger
appender.stdout.type = Console
appender.stdout.name = out
appender.stdout.layout.type = PatternLayout
+# logging style that is similar to spring boot
+appender.stdout.layout.pattern = %style{%d{yyyy-MM-dd HH:mm:ss.SSS}}{Dim} %highlight{%5p} %style{%pid}{Magenta} %style{---}{Dim} %style{[%15.15t]}{Dim} %style{%-35.35c}{Cyan} : %m%n
+# file logger
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = ${sys:user.home}/.camel/${sys:pid}.log
+appender.file.createOnDemand = true
+appender.file.append = false
+appender.file.layout.type = PatternLayout
# logging style that is similar to spring boot
-appender.stdout.layout.pattern = %style{%d{yyyy-MM-dd HH:mm:ss.SSS}}{Dim} %highlight{%5p} %style{%pid}{Magenta} %style{---}{Dim} %style{[%15.15t]}{Dim} %style{%-40.40c}{Cyan} : %m%n
+appender.file.layout.pattern = %style{%d{yyyy-MM-dd HH:mm:ss.SSS}}{Dim} %highlight{%5p} %style{%pid}{Magenta} %style{---}{Dim} %style{[%15.15t]}{Dim} %style{%-35.35c}{Cyan} : %m%n
+# log to console and file
+rootLogger = INFO,out,file
rootLogger.level = INFO
-rootLogger.appenderRef.out.ref = out
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/run-custom-camel-version.tmpl
similarity index 56%
copy from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java
copy to dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/run-custom-camel-version.tmpl
index 9f0b3b8c1a0..cd15762a79f 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/CamelTop.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/run-custom-camel-version.tmpl
@@ -1,3 +1,5 @@
+///usr/bin/env jbang "$0" "$@" ; exit $?
+
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -6,7 +8,7 @@
* (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
+ * 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,
@@ -14,24 +16,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.dsl.jbang.core.commands.process;
-import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
+//JAVA {{ .JavaVersion }}+
+{{ .MavenRepositories }}
+//REPOS mavencentral,apache-snapshot=http://repository.apache.org/content/groups/snapshots/
+{{ .CamelDependencies }}
+{{ .CamelJBangDependencies }}
+//DEPS org.apache.camel.kamelets:camel-kamelets:${camel-kamelets.version:3.20.1.1}
+
+package main;
+
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
-import picocli.CommandLine;
-@CommandLine.Command(name = "top",
- description = "Top status of Camel integrations (use top --help to see sub commands)")
-public class CamelTop extends CamelCommand {
+/**
+ * Main to run CamelJBang
+ */
+public class CustomCamelJBang {
- public CamelTop(CamelJBangMain main) {
- super(main);
+ public static void main(String... args) {
+ CamelJBangMain.run(args);
}
- @Override
- public Integer call() throws Exception {
- // default to top the integrations
- new CommandLine(new CamelContextTop(getMain())).execute();
- return 0;
- }
}