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 b4dc6d3f9cdda8ee26067509a9c8bdd3230ab0a2
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Sat Jan 7 10:46:01 2023 +0100

    CAMEL-18674: camel-jbang - Run in background
---
 .../dsl/jbang/core/commands/CamelJBangMain.java    |   1 +
 .../dsl/jbang/core/commands/ExportBaseCommand.java |   4 +-
 .../apache/camel/dsl/jbang/core/commands/Run.java  |  69 ++++++++++---
 .../dsl/jbang/core/commands/RunBackground.java     | 111 +++++++++++++++++++++
 .../camel/dsl/jbang/core/common/RuntimeUtil.java   |   5 +-
 .../main/resources/log4j2-background.properties    |  31 ++++++
 6 files changed, 203 insertions(+), 18 deletions(-)

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 5176926abe2..fd989e523d8 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
@@ -73,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("run-background", new CommandLine(new 
RunBackground(main)))
                 .addSubcommand("log", new CommandLine(new 
CamelLogAction(main)))
                 .addSubcommand("ps", new CommandLine(new ListProcess(main)))
                 .addSubcommand("stop", new CommandLine(new StopProcess(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..c31689c3abe 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
@@ -143,9 +143,9 @@ abstract class ExportBaseCommand extends CamelCommand {
     public Integer call() throws Exception {
         // configure logging first
         if (logging) {
-            RuntimeUtil.configureLog(loggingLevel, false, false, false, true);
+            RuntimeUtil.configureLog(loggingLevel, false, false, false, true, 
false);
         } else {
-            RuntimeUtil.configureLog("off", false, false, false, true);
+            RuntimeUtil.configureLog("off", false, false, false, true, false);
         }
         // export
         return export();
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 5dabdaed640..ce7d3fe78d1 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
@@ -39,6 +39,7 @@ import java.util.Properties;
 import java.util.Set;
 import java.util.Stack;
 import java.util.StringJoiner;
+import java.util.concurrent.Callable;
 import java.util.function.Supplier;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -92,6 +93,7 @@ class Run extends CamelCommand {
 
     private boolean silentRun;
     private boolean pipeRun;
+    private boolean backgroundRun;
 
     private File logFile;
 
@@ -102,6 +104,9 @@ class Run extends CamelCommand {
 
     List<String> files = new ArrayList<>();
 
+    @Option(names = { "--background" }, defaultValue = "false", description = 
"Run in the background")
+    boolean background;
+
     @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;
@@ -222,6 +227,11 @@ class Run extends CamelCommand {
         return run();
     }
 
+    protected Integer runBackground() throws Exception {
+        backgroundRun = true;
+        return run();
+    }
+
     private void writeSetting(KameletMain main, Properties existing, String 
key, String value) {
         String val = existing != null ? existing.getProperty(key, value) : 
value;
         if (val != null) {
@@ -262,9 +272,11 @@ class Run extends CamelCommand {
     }
 
     private int run() throws Exception {
-        File work = new File(WORK_DIR);
-        removeDir(work);
-        work.mkdirs();
+        if (!backgroundRun) {
+            File work = new File(WORK_DIR);
+            removeDir(work);
+            work.mkdirs();
+        }
 
         Properties profileProperties = null;
         File profilePropertiesFile = new File(getProfile() + ".properties");
@@ -277,7 +289,7 @@ class Run extends CamelCommand {
             loggingJson
                     = 
"true".equals(profileProperties.getProperty("loggingJson", loggingJson ? "true" 
: "false"));
             if (propertiesFiles == null) {
-                propertiesFiles = "file:" + profilePropertiesFile.getName();
+                propertiesFiles = "file:" + getProfile() + ".properties";
             } else {
                 propertiesFiles = propertiesFiles + ",file:" + 
profilePropertiesFile.getName();
             }
@@ -286,6 +298,7 @@ class Run extends CamelCommand {
             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"));
+            background = 
"true".equals(profileProperties.getProperty("camel.jbang.background", 
background ? "true" : "false"));
         }
 
         // generate open-api early
@@ -393,7 +406,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(",");
@@ -559,15 +572,17 @@ class Run extends CamelCommand {
             writeSettings("camel.component.properties.location", loc);
         }
 
-        main.start();
-        main.run();
-
-        // cleanup and delete log file
-        if (logFile != null) {
-            FileUtil.deleteFile(logFile);
+        RunMainTask run = new RunMainTask(main, logFile);
+        if (background) {
+            // run as background
+            ProcessBuilder pb = new ProcessBuilder();
+            pb.command("camel", "run-background");
+            Process p = pb.start();
+            System.out.println("Running Camel integration: " + name + " in 
background with PID: " + p.pid());
+            return 0;
+        } else {
+            return run.call();
         }
-
-        return main.getExitCode();
     }
 
     private String loadFromCode(String code) throws IOException {
@@ -704,7 +719,7 @@ class Run extends CamelCommand {
         if (silentRun) {
             // do not configure logging
         } else if (logging) {
-            RuntimeUtil.configureLog(loggingLevel, loggingColor, loggingJson, 
pipeRun, false);
+            RuntimeUtil.configureLog(loggingLevel, loggingColor, loggingJson, 
pipeRun, false, background);
             writeSettings("loggingLevel", loggingLevel);
             writeSettings("loggingColor", loggingColor ? "true" : "false");
             writeSettings("loggingJson", loggingJson ? "true" : "false");
@@ -716,7 +731,7 @@ class Run extends CamelCommand {
                 logFile.deleteOnExit();
             }
         } else {
-            RuntimeUtil.configureLog("off", false, false, false, false);
+            RuntimeUtil.configureLog("off", false, false, false, false, false);
             writeSettings("loggingLevel", "off");
         }
     }
@@ -921,4 +936,28 @@ class Run extends CamelCommand {
         }
     }
 
+    static class RunMainTask implements Callable<Integer> {
+
+        private final KameletMain main;
+        private final File logFile;
+
+        public RunMainTask(KameletMain main, File logFile) {
+            this.main = main;
+            this.logFile = logFile;
+        }
+
+        @Override
+        public Integer call() throws Exception {
+            main.start();
+            main.run();
+
+            // cleanup and delete log file
+            if (logFile != null) {
+                FileUtil.deleteFile(logFile);
+            }
+
+            return main.getExitCode();
+        }
+    }
+
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/RunBackground.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/RunBackground.java
new file mode 100644
index 00000000000..0ed5ec865b1
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/RunBackground.java
@@ -0,0 +1,111 @@
+/*
+ * 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.StringJoiner;
+
+import org.apache.camel.dsl.jbang.core.common.RuntimeUtil;
+import org.apache.camel.util.CamelCaseOrderedProperties;
+import picocli.CommandLine;
+
+@CommandLine.Command(name = "run-background", description = "Run Camel 
integration in background")
+public class RunBackground extends CamelCommand {
+
+    public RunBackground(CamelJBangMain main) {
+        super(main);
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        return run();
+    }
+
+    private int run() throws Exception {
+        File source = new File(Run.WORK_DIR + "/" + Run.RUN_SETTINGS_FILE);
+        Properties settings = loadProfileProperties(source);
+        if (settings.isEmpty()) {
+            System.err.println("Cannot load settings. Use camel run 
--background instead!");
+            return 1;
+        }
+
+        Run run = new Run(getMain());
+        return runBackground(run, settings);
+    }
+
+    private Properties loadProfileProperties(File source) throws Exception {
+        Properties prop = new CamelCaseOrderedProperties();
+        RuntimeUtil.loadProperties(prop, source);
+
+        // special for routes include pattern that we need to "fix" after 
reading from properties
+        // to make this work in run command
+        String value = prop.getProperty("camel.main.routesIncludePattern");
+        if (value != null) {
+            // if not scheme then must use file: as this is what run command 
expects
+            StringJoiner sj = new StringJoiner(",");
+            for (String part : value.split(",")) {
+                if (!part.contains(":")) {
+                    part = "file:" + part;
+                }
+                sj.add(part);
+            }
+            value = sj.toString();
+            prop.setProperty("camel.main.routesIncludePattern", value);
+        }
+
+        return prop;
+    }
+
+    protected Integer runBackground(Run cmd, Properties settings) throws 
Exception {
+        cmd.profile = Run.WORK_DIR + "/camel-jbang-run";
+        cmd.loggingLevel = settings.getProperty("loggingLevel", "INFO");
+        cmd.loggingColor = "true".equals(settings.getProperty("loggingColor", 
"true"));
+        cmd.loggingJson = "true".equals(settings.getProperty("loggingJson", 
"false"));
+        cmd.loggingLevel = settings.getProperty("loggingLevel");
+        cmd.name = settings.getProperty("camel.main.name", "CamelJBang");
+        cmd.dev = 
"true".equals(settings.getProperty("camel.main.sourceLocationEnabled"));
+        cmd.trace = "true".equals(settings.getProperty("camel.main.tracing"));
+        cmd.modeline = 
"true".equals(settings.getProperty("camel.main.modeline"));
+        cmd.openapi = settings.getProperty("camel.jbang.openApi");
+        cmd.repos = settings.getProperty("camel.jbang.repos");
+        cmd.health = "true".equals(settings.getProperty("camel.jbang.health"));
+        cmd.console = 
"true".equals(settings.getProperty("camel.jbang.console"));
+        String s = settings.getProperty("camel.main.durationMaxMessages");
+        if (s != null) {
+            cmd.maxMessages = Integer.parseInt(s);
+        }
+        s = settings.getProperty("camel.main.durationMaxSeconds");
+        if (s != null) {
+            cmd.maxSeconds = Integer.parseInt(s);
+        }
+        s = settings.getProperty("camel.main.durationMaxIdleSeconds");
+        if (s != null) {
+            cmd.maxIdleSeconds = Integer.parseInt(s);
+        }
+        s = settings.getProperty("camel.jbang.platform-http.port");
+        if (s != null) {
+            cmd.port = Integer.parseInt(s);
+        }
+        cmd.jfr = 
"jfr".equals(settings.getProperty("camel.jbang.jfr-profile"));
+        cmd.jfrProfile = settings.getProperty("camel.jbang.jfr-profile");
+        cmd.propertiesFiles = 
settings.getProperty("camel.component.properties.location");
+
+        return cmd.runBackground();
+    }
+
+}
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 4dc5f495950..905d3ddf58b 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,13 +32,16 @@ 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, boolean background) {
         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 (background) {
+                Configurator.initialize("CamelJBang", 
"log4j2-background.properties");
             } else if (pipe) {
                 Configurator.initialize("CamelJBang", 
"log4j2-pipe.properties");
             } else if (json) {
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-background.properties
 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-background.properties
new file mode 100644
index 00000000000..5e700f81157
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/log4j2-background.properties
@@ -0,0 +1,31 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+# 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.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
+

Reply via email to