You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by cd...@apache.org on 2024/03/15 13:18:00 UTC
(camel) branch camel-4.4.x updated: CAMEL-20517 camel-jbang-plugin-k doesn't recognize command (#13397)
This is an automated email from the ASF dual-hosted git repository.
cdeppisch pushed a commit to branch camel-4.4.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.4.x by this push:
new 22bd4374faf CAMEL-20517 camel-jbang-plugin-k doesn't recognize command (#13397)
22bd4374faf is described below
commit 22bd4374fafd3043f22e212061a21679f3c4938a
Author: Claudio Miranda <cl...@claudius.com.br>
AuthorDate: Tue Mar 12 11:26:17 2024 -0300
CAMEL-20517 camel-jbang-plugin-k doesn't recognize command (#13397)
(cherry picked from commit cc8a3f85356a535e2a5dc2c6c5326607c30aea24)
---
.../camel/dsl/jbang/core/common/PluginHelper.java | 127 +++++++--------------
1 file changed, 43 insertions(+), 84 deletions(-)
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginHelper.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginHelper.java
index 303cbce1574..0470aad1cc2 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginHelper.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginHelper.java
@@ -20,19 +20,22 @@ package org.apache.camel.dsl.jbang.core.common;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Optional;
+import java.util.Properties;
import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.catalog.CamelCatalog;
-import org.apache.camel.catalog.DefaultCamelCatalog;
+import org.apache.camel.catalog.VersionHelper;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
import org.apache.camel.impl.engine.DefaultClassResolver;
import org.apache.camel.impl.engine.DefaultFactoryFinder;
+import org.apache.camel.main.download.DependencyDownloader;
+import org.apache.camel.main.download.DependencyDownloaderClassLoader;
+import org.apache.camel.main.download.MavenDependencyDownloader;
import org.apache.camel.spi.FactoryFinder;
+import org.apache.camel.support.ObjectHelper;
import org.apache.camel.util.IOHelper;
import org.apache.camel.util.json.JsonObject;
import org.apache.camel.util.json.Jsoner;
@@ -73,95 +76,51 @@ public final class PluginHelper {
String command = properties.getOrDefault("command", name).toString();
Optional<Plugin> plugin = FACTORY_FINDER.newInstance("camel-jbang-plugin-" + command, Plugin.class);
+ if (plugin.isEmpty()) {
+ plugin = downloadPlugin(command, main);
+ }
if (plugin.isPresent()) {
plugin.get().customize(commandLine, main);
} else {
- String description = properties.getOrDefault("description", "").toString();
- String dependency = properties.getOrDefault("dependency",
- "org.apache.camel:camel-jbang-plugin-%s:${camel-version}".formatted(command)).toString();
- createSubCommand(commandLine, name, command, dependency, description, main);
+ main.getOut().println("camel-jbang-plugin-" + command + " not found. Exit");
+ main.quit(1);
}
}
}
}
- /**
- * Create sub-command as a placeholder for calling a plugin. When the command gets executed the plugin is added to
- * the classpath and a new JBang process is spawned with the same arguments. The factory finder mechanism will be
- * able to resolve the actual plugin from the classpath so the real plugin command is run.
- *
- * @param commandLine to receive the new command
- * @param name the plugin name
- * @param command the plugin command
- * @param dependency the Maven dependency for the plugin
- * @param description optional description of the plugin command
- * @param main current Camel JBang main
- */
- private static void createSubCommand(
- CommandLine commandLine, String name, String command,
- String dependency, String description, CamelJBangMain main) {
- commandLine.addSubcommand(command, CommandLine.Model.CommandSpec.wrapWithoutInspection(
- (Runnable) () -> {
- List<String> args = commandLine.getParseResult().originalArgs();
- if (args.contains("--help") || args.contains("--h")) {
- main.getOut().printf("Loading plugin %s for command %s%n", name, command);
- }
-
- String gav = dependency;
- if (gav.endsWith(":${camel-version}")) {
- gav = gav.substring(0, gav.length() - "${camel-version}".length()) + getCamelVersion(args);
- }
-
- // need to use jbang command to call plugin
- List<String> jbangArgs = new ArrayList<>();
- jbangArgs.add("jbang");
- // Add plugin dependency, so it is present on the classpath for the new JBang process
- jbangArgs.add("--deps=" + gav);
-
- jbangArgs.add("camel");
- jbangArgs.addAll(args);
-
- try {
- ProcessBuilder pb = new ProcessBuilder();
- pb.command(jbangArgs);
-
- 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
- int exitCode = p.waitFor();
- main.quit(exitCode);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- main.getOut().printf("Interrupted while spawning JBang process");
- main.quit(1);
- } catch (IOException e) {
- main.getOut().printf("Unable to spawn JBang process - %s%n", e.getMessage());
- main.quit(1);
- }
- })
- .usageMessage(new CommandLine.Model.UsageMessageSpec().description(description))
- .addUnmatchedArgsBinding(CommandLine.Model.UnmatchedArgsBinding
- .forStringArrayConsumer(new CommandLine.Model.ISetter() {
- @Override
- public <T> T set(T value) throws Exception {
- return value;
- }
- })));
- }
-
- private static String getCamelVersion(List<String> args) {
- Optional<String> version = args.stream()
- .filter(arg -> arg.startsWith("--camel.version="))
- .map(arg -> arg.substring("camel.version=".length()))
- .findFirst();
-
- if (version.isPresent()) {
- return version.get();
+ private static Optional<Plugin> downloadPlugin(String command, CamelJBangMain main) {
+ DependencyDownloader downloader = new MavenDependencyDownloader();
+ DependencyDownloaderClassLoader ddlcl = new DependencyDownloaderClassLoader(PluginHelper.class.getClassLoader());
+ downloader.setClassLoader(ddlcl);
+ downloader.start();
+ String version = new VersionHelper().getVersion();
+ // downloads and adds to the classpath
+ downloader.downloadDependency("org.apache.camel", "camel-jbang-plugin-" + command, version);
+ Optional<Plugin> instance = Optional.empty();
+ InputStream in = null;
+ String path = FactoryFinder.DEFAULT_PATH + "camel-jbang-plugin/camel-jbang-plugin-" + command;
+ try {
+ // reads the class name from the plugin dependency
+ in = ddlcl.getResourceAsStream(path);
+ if (in != null) {
+ Properties prop = new Properties();
+ prop.load(in);
+ String pluginClassName = prop.getProperty("class");
+ DefaultClassResolver resolver = new DefaultClassResolver();
+ Class<?> pluginClass = resolver.resolveClass(pluginClassName, ddlcl);
+ instance = Optional.of(Plugin.class.cast(ObjectHelper.newInstance(pluginClass)));
+ } else {
+ String gav = String.join(":", "org.apache.camel", "camel-jbang-plugin-" + command, version);
+ main.getOut().printf(String.format("ERROR: Failed to read file %s in dependency %s.\n", path, gav));
+ }
+ } catch (IOException e) {
+ throw new RuntimeCamelException(String.format("Failed to read the file %s.", path), e);
+ } finally {
+ downloader.stop();
+ IOHelper.close(in);
}
-
- CamelCatalog catalog = new DefaultCamelCatalog();
- return catalog.getCatalogVersion();
+ return instance;
}
public static JsonObject getOrCreatePluginConfig() {