This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 905310472c9 CAMEL-22283: camel-jbang - infra stop to be similar to 
camel stop (#18748)
905310472c9 is described below

commit 905310472c96e943951713277c2be51a126fc7d3
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Mon Jul 28 16:45:34 2025 +0200

    CAMEL-22283: camel-jbang - infra stop to be similar to camel stop (#18748)
    
    * CAMEL-22283: camel-jbang - infra stop to have kill option
    
    * CAMEL-22283: camel-jbang - infra stop to be similar to camel stop
---
 .../dsl/jbang/core/commands/infra/InfraRun.java    | 58 +++++++-------
 .../dsl/jbang/core/commands/infra/InfraStop.java   | 89 +++++++++++++++-------
 .../dsl/jbang/core/commands/infra/InfraTest.java   |  2 +-
 3 files changed, 94 insertions(+), 55 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraRun.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraRun.java
index 713b7b3c64e..a8eda7bd083 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraRun.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraRun.java
@@ -165,7 +165,7 @@ public class InfraRun extends InfraBaseCommand {
             if (testServiceImplementation != null) {
                 prefix = " with implementation " + testServiceImplementation;
             }
-            printer().println("Starting service " + testService + prefix);
+            printer().println("Starting service " + testService + prefix + " 
(PID: " + RuntimeUtil.getPid() + ")");
         }
         actualService.getClass().getMethod("initialize").invoke(actualService);
 
@@ -207,46 +207,52 @@ public class InfraRun extends InfraBaseCommand {
         // use shutdown hook as fallback to shut-down and delete files
         Runtime.getRuntime().addShutdownHook(new Thread(() -> 
shutdownInfra(closed, logFile, jsonFile, actualService)));
 
+        final CountDownLatch latch = new CountDownLatch(1);
+
         // running in foreground then wait for user to exit
         final Console c = System.console();
         if (c != null) {
             if (!jsonOutput) {
                 printer().println("Press ENTER to stop the execution");
             }
-            boolean quit = false;
-            do {
-                String line = c.readLine();
-                if (line != null) {
-                    quit = true;
-                }
-            } while (!quit);
-        } else {
-            final CountDownLatch latch = new CountDownLatch(1);
-            // headless (running in background so wait until being signalled 
to stop)
             Thread t = new Thread(() -> {
-                while (latch.getCount() > 0) {
-                    try {
-                        Thread.sleep(1000);
-                    } catch (Exception e) {
-                        // ignore
-                    }
-                    File f = jsonFile.toFile();
-                    if (!f.exists()) {
+                boolean quit = false;
+                do {
+                    String line = c.readLine();
+                    if (line != null) {
+                        quit = true;
                         latch.countDown();
                     }
-                }
-            }, "InfraWait");
+                } while (!quit);
+            }, "WaitEnter");
             t.start();
-
+        } else {
             // wait for this process to be stopped
             printer().println("Running (use camel infra stop "
                               + testService + (testServiceImplementation != 
null ? " " + testServiceImplementation : "")
                               + " to stop the execution)");
-            try {
-                latch.await();
-            } catch (Exception e) {
-                // ignore
+        }
+
+        // always wait for external signal to stop if the json-file is deleted
+        Thread t = new Thread(() -> {
+            while (latch.getCount() > 0) {
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                    // ignore
+                }
+                File f = jsonFile.toFile();
+                if (!f.exists()) {
+                    latch.countDown();
+                }
             }
+        }, "WaitShutdownSignal");
+        t.start();
+
+        try {
+            latch.await();
+        } catch (Exception e) {
+            // ignore
         }
 
         shutdownInfra(closed, logFile, jsonFile, actualService);
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraStop.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraStop.java
index 73a4e611794..38b6620731b 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraStop.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraStop.java
@@ -16,21 +16,28 @@
  */
 package org.apache.camel.dsl.jbang.core.commands.infra;
 
-import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
 import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
+import org.apache.camel.dsl.jbang.core.common.PathUtils;
+import org.apache.camel.support.PatternHelper;
 import picocli.CommandLine;
 
 @CommandLine.Command(name = "stop",
-                     description = "Stop an external service")
+                     description = "Shuts down running infrastructure 
services", sortOptions = false, showDefaultValues = true)
 public class InfraStop extends InfraBaseCommand {
 
-    @CommandLine.Parameters(description = "Service name", arity = "1")
-    private List<String> serviceName;
+    @CommandLine.Parameters(description = "Name or pid of running service(s)", 
arity = "0..1")
+    String name = "*";
+
+    @CommandLine.Option(names = { "--kill" },
+                        description = "To force killing the process (SIGKILL)")
+    boolean kill;
 
     public InfraStop(CamelJBangMain main) {
         super(main);
@@ -38,35 +45,61 @@ public class InfraStop extends InfraBaseCommand {
 
     @Override
     public Integer doCall() throws Exception {
-        String serviceToStop = serviceName.get(0);
-
-        boolean serviceStopped = false;
-        String pid = null;
-        try {
-            List<Path> pidFiles = Files.list(CommandLineHelper.getCamelDir())
-                    .filter(p -> 
p.getFileName().toString().startsWith("infra-" + serviceToStop + "-"))
-                    .toList();
-
-            for (Path pidFile : pidFiles) {
-                String name = pidFile.getFileName().toString();
-                pid = name.substring(name.lastIndexOf("-") + 1, 
name.lastIndexOf('.'));
-
-                Files.deleteIfExists(pidFile);
-                serviceStopped = true;
-                break;
+
+        Map<Long, Path> pids = findPids(name);
+
+        // stop by deleting the pid file
+        for (var entry : pids.entrySet()) {
+            Path pidFile = entry.getValue();
+            if (Files.exists(pidFile)) {
+                printer().println("Shutting down infrastructure services (PID: 
" + entry.getKey() + ")");
+                PathUtils.deleteFile(pidFile);
+            }
+        }
+        if (kill) {
+            for (Long pid : pids.keySet()) {
+                ProcessHandle.of(pid).ifPresent(ph -> {
+                    printer().println("Killing infrastructure service (PID: " 
+ pid + ")");
+                    ph.destroyForcibly();
+                });
             }
-        } catch (IOException e) {
-            // ignore
         }
 
-        if (!serviceStopped) {
-            printer().println("No Camel Infrastructure found with name " + 
serviceToStop);
-            return 0;
+        return 0;
+    }
+
+    private Map<Long, Path> findPids(String name) throws Exception {
+        Map<Long, Path> pids = new HashMap<>();
+
+        // we need to know the pids of the running camel integrations
+        if (!name.matches("\\d+")) {
+            if (name.endsWith("!")) {
+                // exclusive this name only
+                name = name.substring(0, name.length() - 1);
+            } else if (!name.endsWith("*")) {
+                // lets be open and match all that starts with this pattern
+                name = name + "*";
+            }
         }
 
-        printer().println("Shutting down service " + serviceToStop + " (PID: " 
+ pid + ")");
-        
ProcessHandle.of(Long.parseLong(pid)).ifPresent(ProcessHandle::destroy);
+        final String pattern = name;
 
-        return 0;
+        List<Path> pidFiles = Files.list(CommandLineHelper.getCamelDir())
+                .filter(p -> {
+                    var n = p.getFileName().toString();
+                    return n.startsWith("infra-") && n.endsWith(".json");
+                })
+                .toList();
+        for (Path pidFile : pidFiles) {
+            String fn = pidFile.getFileName().toString();
+            String sn = fn.substring(fn.indexOf("-") + 1, fn.lastIndexOf('-'));
+            String pid = fn.substring(fn.lastIndexOf("-") + 1, 
fn.lastIndexOf('.'));
+            if (pid.equals(pattern) || PatternHelper.matchPattern(sn, 
pattern)) {
+                pids.put(Long.valueOf(pid), pidFile);
+            }
+        }
+
+        return pids;
     }
+
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java
index d74bace585a..a3cc24b7af5 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java
@@ -48,7 +48,7 @@ public class InfraTest extends CamelCommandBaseTest {
 
         Awaitility.await().untilAsserted(() -> {
             List<String> lines = printer.getLines();
-            Assertions.assertThat(lines).contains("Starting service ftp");
+            Assertions.assertThat(lines).anyMatch(l -> l.startsWith("Starting 
service ftp"));
             // because we run headless unit test then you would see this 
message instead of press ENTER to stop
             Assertions.assertThat(lines).contains("Running (use camel infra 
stop ftp to stop the execution)");
         });

Reply via email to