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 2022/08/18 16:20:27 UTC

[camel] 01/02: CAMEL-18389: camel-jbang - camel stop to stop running Camel

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

commit 2d463ed2cc17a8b9ba2f1dbb645ee9842a447070
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Aug 18 18:18:06 2022 +0200

    CAMEL-18389: camel-jbang - camel stop to stop running Camel
---
 .../dsl/jbang/core/commands/CamelCommand.java      |  2 +
 .../dsl/jbang/core/commands/CamelJBangMain.java    |  1 +
 .../apache/camel/dsl/jbang/core/commands/Run.java  | 55 +++++++-------
 .../camel/dsl/jbang/core/commands/StopProcess.java | 86 ++++++++++++++++++++++
 4 files changed, 116 insertions(+), 28 deletions(-)

diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelCommand.java
index 150333f31aa..029eadf5f2c 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelCommand.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelCommand.java
@@ -22,6 +22,8 @@ import picocli.CommandLine;
 
 abstract class CamelCommand implements Callable<Integer> {
 
+    public static final String PID_DIR = "${sys:user.home}/.camel";
+
     private final CamelJBangMain main;
 
     //CHECKSTYLE:OFF
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 1f97191f857..3b7911d76cc 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
@@ -32,6 +32,7 @@ public class CamelJBangMain implements Callable<Integer> {
         commandLine = new CommandLine(main)
                 .addSubcommand("run", new CommandLine(new Run(main)))
                 .addSubcommand("ps", new CommandLine(new ListProcess(main)))
+                .addSubcommand("stop", new CommandLine(new StopProcess(main)))
                 .addSubcommand("init", new CommandLine(new Init(main)))
                 .addSubcommand("bind", new CommandLine(new Bind(main)))
                 .addSubcommand("pipe", new CommandLine(new Pipe(main)))
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 137b308fc84..618db4f344b 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
@@ -70,7 +70,7 @@ import static org.apache.camel.dsl.jbang.core.common.GistHelper.fetchGistUrls;
 import static org.apache.camel.dsl.jbang.core.common.GitHubHelper.asGithubSingleUrl;
 import static org.apache.camel.dsl.jbang.core.common.GitHubHelper.fetchGithubUrls;
 
-@Command(name = "run", description = "Run as local Camel application")
+@Command(name = "run", description = "Run as local Camel integration")
 class Run extends CamelCommand {
 
     public static final String WORK_DIR = ".camel-jbang";
@@ -159,8 +159,8 @@ class Run extends CamelCommand {
     String[] property;
 
     @Option(names = { "--file-lock" },
-            description = "Whether to create a temporary file lock, which upon deleting triggers this process to terminate")
-    boolean fileLock;
+            description = "Whether to create a temporary file lock, which upon deleting triggers this process to terminate", defaultValue = "true")
+    boolean fileLock = true;
 
     @Option(names = { "--jfr" },
             description = "Enables Java Flight Recorder saving recording to disk on exit")
@@ -238,21 +238,9 @@ class Run extends CamelCommand {
     }
 
     private int stop() {
-        File currentDir = new File(".");
-
-        File[] lockFiles = currentDir.listFiles(f -> f.getName().endsWith(".camel.lock"));
-
-        for (File lockFile : lockFiles) {
-            if (logging) {
-                System.out.println("Removing file " + lockFile);
-            }
-            if (!lockFile.delete()) {
-                if (logging) {
-                    System.err.println("Failed to remove lock file " + lockFile);
-                }
-            }
+        if (lockFile != null) {
+            FileUtil.deleteFile(lockFile);
         }
-
         return 0;
     }
 
@@ -413,10 +401,6 @@ class Run extends CamelCommand {
 
         if (fileLock) {
             lockFile = createLockFile();
-            if (!lockFile.exists()) {
-                throw new IllegalStateException("Lock file does not exists: " + lockFile);
-            }
-
             // to trigger shutdown on file lock deletion
             executor = Executors.newSingleThreadScheduledExecutor();
             executor.scheduleWithFixedDelay(() -> {
@@ -704,15 +688,30 @@ class Run extends CamelCommand {
     }
 
     public File createLockFile() throws IOException {
-        File lockFile = File.createTempFile(".run", ".camel.lock", new File("."));
-
-        if (logging) {
-            System.out.printf("A new lock file was created, delete the file to stop running:%n%s%n",
-                    lockFile.getAbsolutePath());
+        File answer = null;
+        String pid = getPid();
+        if (pid != null) {
+            File dir = new File(System.getProperty("user.home"), ".camel");
+            try {
+                dir.mkdirs();
+                answer = new File(dir, pid);
+                if (!answer.exists()) {
+                    answer.createNewFile();
+                }
+                answer.deleteOnExit();
+            } catch (Exception e) {
+                answer = null;
+            }
         }
-        lockFile.deleteOnExit();
+        return answer;
+    }
 
-        return lockFile;
+    private static String getPid() {
+        try {
+            return "" + ProcessHandle.current().pid();
+        } catch (Throwable e) {
+            return null;
+        }
     }
 
     private boolean knownFile(String file) throws Exception {
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/StopProcess.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/StopProcess.java
new file mode 100644
index 00000000000..d3d1f4a23c3
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/StopProcess.java
@@ -0,0 +1,86 @@
+/*
+ * 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.ArrayList;
+import java.util.List;
+
+import org.apache.camel.support.PatternHelper;
+import org.apache.camel.util.FileUtil;
+import org.apache.camel.util.StringHelper;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+
+@Command(name = "stop", description = "Stop a running Camel integration")
+class StopProcess extends CamelCommand {
+
+    @CommandLine.Parameters(description = "Name or pid of running Camel integration", arity = "1")
+    private String name;
+
+    public StopProcess(CamelJBangMain main) {
+        super(main);
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        // we need to know the pids of the running camel integrations
+        List<Long> pids;
+        if (name.matches("\\d+")) {
+            pids = List.of(Long.parseLong(name));
+        } else {
+            pids = findPids(name);
+        }
+
+        // stop by deleting the pid file
+        for (Long pid : pids) {
+            File dir = new File(System.getProperty("user.home"), ".camel");
+            File pidFile = new File(dir, "" + pid);
+            System.out.println("Stopping Camel integration (pid: " + pid + ")");
+            FileUtil.deleteFile(pidFile);
+        }
+
+        return 0;
+    }
+
+    private static String extractName(ProcessHandle ph) {
+        String cl = ph.info().commandLine().orElse("");
+        String name = StringHelper.after(cl, "main.CamelJBang run");
+        if (name != null) {
+            name = name.trim();
+        } else {
+            name = "";
+        }
+        return name;
+    }
+
+    private static List<Long> findPids(String pattern) {
+        List<Long> pids = new ArrayList<>();
+
+        ProcessHandle.allProcesses()
+                .forEach(ph -> {
+                    String name = extractName(ph);
+                    // ignore file extension so it is easier to match by name
+                    name = FileUtil.onlyName(name);
+                    if (PatternHelper.matchPattern(name, pattern)) {
+                        pids.add(ph.pid());
+                    }
+                });
+        return pids;
+    }
+
+}