This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch CAMEL-23667-stub-remote-flag in repository https://gitbox.apache.org/repos/asf/camel.git
commit 3129bcf35a101a387c76ea2617a4d898e29cb8a1 Author: Claus Ibsen <[email protected]> AuthorDate: Tue Jun 2 19:06:54 2026 +0200 CAMEL-23667: Add --stub=remote flag to stub only remote components via catalog Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .../modules/ROOT/pages/camel-jbang.adoc | 12 ++++++++- .../pages/jbang-commands/camel-jbang-debug.adoc | 2 +- .../ROOT/pages/jbang-commands/camel-jbang-dev.adoc | 2 +- .../ROOT/pages/jbang-commands/camel-jbang-run.adoc | 2 +- .../META-INF/camel-jbang-commands-metadata.json | 6 ++--- .../apache/camel/dsl/jbang/core/commands/Run.java | 30 +++++++++++++--------- .../jbang/core/commands/tui/RunOptionsForm.java | 2 +- .../DependencyDownloaderComponentResolver.java | 6 +++++ 8 files changed, 42 insertions(+), 20 deletions(-) diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc index b4768b3db61b..1bc9df3dc041 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc @@ -464,6 +464,16 @@ Then only the `jms:inbox` endpoint is stubbed. TIP: You can stub multiple components separated by comma, such as `--stub=jms,sql` +You can also use `--stub=all` to stub all components, or `--stub=remote` to stub only +remote components (components that connect to external systems such as messaging brokers, databases, cloud services, etc.). +The `remote` flag uses the Camel catalog to determine which components are remote, so it automatically +handles new components without needing a hardcoded list. + +[source,bash] +---- +camel run syncToDatabase.java --stub=remote +---- + Camel JBang comes with the `camel cmd stub` command that allows to list all endpoints that has been stubbed, and also browse any messages that are currently present in their internal queues. A stub endpoint is based on the `seda` component. @@ -4292,7 +4302,7 @@ The camel.jbang supports 48 options, which are listed below. | *camel.jbang.scriptFiles* | Additional shell script files to export to src/main/scripts directory | | String | *camel.jbang.sourceDir* | Source directory for dynamically loading Camel file(s) to run. When using this, then files cannot be specified at the same time. | | String | *camel.jbang.springBootVersion* | Spring Boot version | | String -| *camel.jbang.stub* | Stubs all the matching endpoint with the given component name or pattern. Multiple names can be separated by comma. (all = everything). | | String +| *camel.jbang.stub* | Stubs all the matching endpoint with the given component name or pattern. Multiple names can be separated by comma. (all = stub all endpoints, remote = stub only remote components). | | String | *camel.jbang.tlsFiles* | Additional SSL/TLS files to export to src/main/tls directory | | String | *camel.jbang.verbose* | Verbose output of startup activity (dependency resolution and downloading | false | boolean |=== diff --git a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-debug.adoc b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-debug.adoc index ce2a1538e161..1a81efa627e8 100644 --- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-debug.adoc +++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-debug.adoc @@ -91,7 +91,7 @@ camel debug [options] | `--source-dir` | Source directory for dynamically loading Camel file(s) to run. When using this, then files cannot be specified at the same time. | | String | `--spring-boot-version` | Spring Boot version | RuntimeType.SPRING_BOOT_VERSION | String | `--stop-on-exit` | Whether to stop the running Camel on exit | true | boolean -| `--stub` | Stubs all the matching endpoint uri with the given component name or pattern. Multiple names can be separated by comma. (all = stub all endpoints). | | String +| `--stub` | Stubs all the matching endpoint uri with the given component name or pattern. Multiple names can be separated by comma. (all = stub all endpoints, remote = stub only remote components). | | String | `--timestamp` | Print timestamp. | true | boolean | `--trace` | Enables trace logging of the routed messages | false | boolean | `--verbose` | Verbose output of startup activity (dependency resolution and downloading | false | boolean diff --git a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dev.adoc b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dev.adoc index b5fc0208c2b1..88a9443a4fc3 100644 --- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dev.adoc +++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dev.adoc @@ -77,7 +77,7 @@ camel dev [options] | `--skip-plugins` | Skip resolving plugin dependencies | false | boolean | `--source-dir` | Source directory for dynamically loading Camel file(s) to run. When using this, then files cannot be specified at the same time. | | String | `--spring-boot-version` | Spring Boot version | RuntimeType.SPRING_BOOT_VERSION | String -| `--stub` | Stubs all the matching endpoint uri with the given component name or pattern. Multiple names can be separated by comma. (all = stub all endpoints). | | String +| `--stub` | Stubs all the matching endpoint uri with the given component name or pattern. Multiple names can be separated by comma. (all = stub all endpoints, remote = stub only remote components). | | String | `--trace` | Enables trace logging of the routed messages | false | boolean | `--verbose` | Verbose output of startup activity (dependency resolution and downloading | false | boolean | `-h,--help` | Display the help and sub-commands | | boolean diff --git a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-run.adoc b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-run.adoc index 189ae3be182b..74ba2ea80773 100644 --- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-run.adoc +++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-run.adoc @@ -77,7 +77,7 @@ camel run [options] | `--skip-plugins` | Skip resolving plugin dependencies | false | boolean | `--source-dir` | Source directory for dynamically loading Camel file(s) to run. When using this, then files cannot be specified at the same time. | | String | `--spring-boot-version` | Spring Boot version | RuntimeType.SPRING_BOOT_VERSION | String -| `--stub` | Stubs all the matching endpoint uri with the given component name or pattern. Multiple names can be separated by comma. (all = stub all endpoints). | | String +| `--stub` | Stubs all the matching endpoint uri with the given component name or pattern. Multiple names can be separated by comma. (all = stub all endpoints, remote = stub only remote components). | | String | `--trace` | Enables trace logging of the routed messages | false | boolean | `--verbose` | Verbose output of startup activity (dependency resolution and downloading | false | boolean | `-h,--help` | Display the help and sub-commands | | boolean diff --git a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json index b573203b8850..024b48cdbcaa 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json +++ b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json @@ -6,9 +6,9 @@ { "name": "cmd", "fullName": "cmd", "description": "Performs commands in the running Camel integrations, such as start\/stop route, or change logging levels.", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.action.CamelAction", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": "browse", "fullName": "cmd browse", "description": "Browse pending messages on endpoints [...] { "name": "completion", "fullName": "completion", "description": "Generate completion script for bash\/zsh", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Complete", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ] }, { "name": "config", "fullName": "config", "description": "Get and set user configuration values", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.config.ConfigCommand", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": "get", "fullName": "config get", "description": "Display user configuration value", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.config. [...] - { "name": "debug", "fullName": "debug", "description": "Debug local Camel integration", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Debug", "options": [ { "names": "--ago", "description": "Use ago instead of yyyy-MM-dd HH:mm:ss in timestamp.", "javaType": "boolean", "type": "boolean" }, { "names": "--background", "description": "Run in the background", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "--background-wait", "description": "To [...] + { "name": "debug", "fullName": "debug", "description": "Debug local Camel integration", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Debug", "options": [ { "names": "--ago", "description": "Use ago instead of yyyy-MM-dd HH:mm:ss in timestamp.", "javaType": "boolean", "type": "boolean" }, { "names": "--background", "description": "Run in the background", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "--background-wait", "description": "To [...] { "name": "dependency", "fullName": "dependency", "description": "Displays all Camel dependencies required to run", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.DependencyCommand", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": "copy", "fullName": "dependency copy", "description": "Copies all Camel dependencies required to run to a specific directory", "sourc [...] - { "name": "dev", "fullName": "dev", "description": "Run in dev mode with live reload", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Dev", "options": [ { "names": "--background", "description": "Run in the background", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "--background-wait", "description": "To wait for run in background to startup successfully, before returning", "defaultValue": "true", "javaType": "boolean", "type": "boolean" }, [...] + { "name": "dev", "fullName": "dev", "description": "Run in dev mode with live reload", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Dev", "options": [ { "names": "--background", "description": "Run in the background", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "--background-wait", "description": "To wait for run in background to startup successfully, before returning", "defaultValue": "true", "javaType": "boolean", "type": "boolean" }, [...] { "name": "dirty", "fullName": "dirty", "description": "Check if there are dirty files from previous Camel runs that did not terminate gracefully", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.process.Dirty", "options": [ { "names": "--clean", "description": "Clean dirty files which are no longer in use", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", " [...] { "name": "doc", "fullName": "doc", "description": "Shows documentation for kamelet, component, and other Camel resources", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.catalog.CatalogDoc", "options": [ { "names": "--camel-version", "description": "To use a different Camel version than the default version", "javaType": "java.lang.String", "type": "string" }, { "names": "--download", "description": "Whether to allow automatic downloading JAR dependencies (over the internet [...] { "name": "doctor", "fullName": "doctor", "description": "Checks the environment and reports potential issues", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Doctor", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ] }, @@ -26,7 +26,7 @@ { "name": "plugin", "fullName": "plugin", "description": "Manage plugins that add sub-commands to this CLI", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.plugin.PluginCommand", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": "add", "fullName": "plugin add", "description": "Add new plugin", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.plugin.PluginA [...] { "name": "ps", "fullName": "ps", "description": "List running Camel integrations", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.process.ListProcess", "options": [ { "names": "--json", "description": "Output in JSON Format", "javaType": "boolean", "type": "boolean" }, { "names": "--pid", "description": "List only pid in the output", "javaType": "boolean", "type": "boolean" }, { "names": "--remote", "description": "Break down counters into remote\/total pairs", "javaType": [...] { "name": "restart", "fullName": "restart", "description": "Restarts running Camel integrations (stop + re-launch)", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.process.RestartProcess", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ] }, - { "name": "run", "fullName": "run", "description": "Run as local Camel integration", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Run", "options": [ { "names": "--background", "description": "Run in the background", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "--background-wait", "description": "To wait for run in background to startup successfully, before returning", "defaultValue": "true", "javaType": "boolean", "type": "boolean" }, { [...] + { "name": "run", "fullName": "run", "description": "Run as local Camel integration", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Run", "options": [ { "names": "--background", "description": "Run in the background", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "--background-wait", "description": "To wait for run in background to startup successfully, before returning", "defaultValue": "true", "javaType": "boolean", "type": "boolean" }, { [...] { "name": "sbom", "fullName": "sbom", "description": "Generate a CycloneDX or SPDX SBOM for a specific project", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.SBOMGenerator", "options": [ { "names": "--build-property", "description": "Maven build properties, ex. --build-property=prop1=foo", "javaType": "java.util.List", "type": "array" }, { "names": "--camel-spring-boot-version", "description": "Camel version to use with Spring Boot", "javaType": "java.lang.String", "type" [...] { "name": "script", "fullName": "script", "description": "Run Camel integration as shell script for terminal scripting", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Script", "options": [ { "names": "--logging", "description": "Can be used to turn on logging (logs to file in <user home>\/.camel directory)", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "--logging-level", "description": "Logging level (ERROR, WARN, INFO, DEBUG, TRACE)", "d [...] { "name": "shell", "fullName": "shell", "description": "Interactive Camel JBang shell.", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Shell", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ] }, 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 96ccca6b7ede..169d12ea8b64 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 @@ -283,7 +283,8 @@ public class Run extends CamelCommand { public String[] property; @Option(names = { "--stub" }, description = "Stubs all the matching endpoint uri with the given component name or pattern." - + " Multiple names can be separated by comma. (all = stub all endpoints).") + + " Multiple names can be separated by comma." + + " (all = stub all endpoints, remote = stub only remote components).") String stub; // jfr and jfrProfile options are in DebugOptions @ArgGroup @@ -734,19 +735,24 @@ public class Run extends CamelCommand { if ("all".equals(stub)) { // stub all components only stub = "component:*"; - } - // we need to match by wildcard, to make it easier - StringJoiner sj = new StringJoiner(","); - for (String n : stub.split(",")) { - // you can either refer to a name or a specific endpoint - // if there is a colon then we assume it's a specific endpoint then we should not add wildcard - boolean colon = n.contains(":"); - if (!colon && !n.endsWith("*")) { - n = "component:" + n + "*"; + } else if ("remote".equals(stub)) { + // stub only remote components (resolved via catalog) + stub = "component:remote"; + } + if (!"component:remote".equals(stub)) { + // we need to match by wildcard, to make it easier + StringJoiner sj = new StringJoiner(","); + for (String n : stub.split(",")) { + // you can either refer to a name or a specific endpoint + // if there is a colon then we assume it's a specific endpoint then we should not add wildcard + boolean colon = n.contains(":"); + if (!colon && !n.endsWith("*")) { + n = "component:" + n + "*"; + } + sj.add(n); } - sj.add(n); + stub = sj.toString(); } - stub = sj.toString(); writeSetting(main, profileProperties, STUB, stub); main.setStubPattern(stub); } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java index 12b4a05df719..cbfc5e124b25 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java @@ -190,7 +190,7 @@ class RunOptionsForm { args.add("--backlog-trace"); } if (stubMode) { - args.add("--stub=all"); + args.add("--stub=remote"); } if (properties != null) { for (PropertyEntry pe : properties) { diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderComponentResolver.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderComponentResolver.java index acb48a2350ea..a6bb583d4e02 100644 --- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderComponentResolver.java +++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderComponentResolver.java @@ -152,6 +152,12 @@ public final class DependencyDownloaderComponentResolver extends DefaultComponen return true; } + // stub only remote components (resolved via catalog) + if ("component:remote".equals(stubPattern)) { + ComponentModel model = catalog.componentModel(name); + return model == null || !model.isRemote(); + } + boolean stubbed = false; for (String n : stubPattern.split(",")) { if (n.startsWith("component:")) {
