diff --git a/src/main/java/ch/ivyteam/ivy/maven/engine/EngineControl.java b/src/main/java/ch/ivyteam/ivy/maven/engine/EngineControl.java index 56dd386f..c7990603 100644 --- a/src/main/java/ch/ivyteam/ivy/maven/engine/EngineControl.java +++ b/src/main/java/ch/ivyteam/ivy/maven/engine/EngineControl.java @@ -27,21 +27,18 @@ import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.nio.file.Files; +import java.util.ArrayList; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.function.Supplier; -import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.ExecuteException; import org.apache.commons.exec.ExecuteResultHandler; -import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.exec.Executor; import org.apache.commons.exec.PumpStreamHandler; -import org.apache.commons.exec.ShutdownHookProcessDestroyer; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.StopWatch; @@ -53,6 +50,7 @@ * Sends commands like start, stop to the ivy Engine */ public class EngineControl { + public static interface Property { String TEST_ENGINE_URL = "test.engine.url"; String TEST_ENGINE_LOG = "test.engine.log"; @@ -76,24 +74,26 @@ public EngineControl(EngineMojoContext context) { this.context = context; } - public Executor start() throws Exception { - CommandLine startCmd = toEngineCommand(Command.start); + public Process start() throws Exception { + var startCmd = toEngineCommand(Command.start); context.log.info("Start Axon Ivy Engine in folder: " + context.engineDirectory); - Executor executor = createEngineExecutor(); - executor.setStreamHandler(createEngineLogStreamForwarder(logLine -> findStartEngineUrl(logLine))); - var watchdog = ExecuteWatchdog.builder() - .setTimeout(ExecuteWatchdog.INFINITE_TIMEOUT_DURATION) - .get(); - executor.setWatchdog(watchdog); - executor.setProcessDestroyer(new ShutdownHookProcessDestroyer()); - executor.execute(startCmd, asynchExecutionHandler()); - waitForEngineStart(executor); - return executor; + //Executor executor = createEngineExecutor(); + //executor.setStreamHandler(createEngineLogStreamForwarder(logLine -> findStartEngineUrl(logLine))); + //var watchdog = ExecuteWatchdog.builder() + // .setTimeout(ExecuteWatchdog.INFINITE_TIMEOUT_DURATION) + // .get(); + //executor.setWatchdog(watchdog); + //executor.setProcessDestroyer(new ShutdownHookProcessDestroyer()); + //executor.execute(startCmd, asynchExecutionHandler()); + + var process = startCmd.start(); + waitForEngineStart(process); + return process; } public void stop() throws Exception { - CommandLine stopCmd = toEngineCommand(Command.stop); + var stopCmd = toEngineCommand(Command.stop); context.log.info("Stopping Axon Ivy Engine in folder: " + context.engineDirectory); executeSynch(stopCmd); @@ -101,12 +101,12 @@ public void stop() throws Exception { } EngineState state() { - CommandLine statusCmd = toEngineCommand(Command.status); + var statusCmd = toEngineCommand(Command.status); String engineOutput = executeSynch(statusCmd); return parseState(engineOutput); } - private CommandLine toEngineCommand(Command command) { + private ProcessBuilder toEngineCommand(Command command) { var classpath = context.engineClasspathJarPath.toString(); if (StringUtils.isNotBlank(context.vmOptions.additionalClasspath())) { classpath += File.pathSeparator + context.vmOptions.additionalClasspath(); @@ -114,22 +114,25 @@ private CommandLine toEngineCommand(Command command) { var osgiDir = context.engineDirectory.resolve(OsgiDir.INSTALL_AREA); - CommandLine cli = new CommandLine(new File(getJavaExec())) - .addArgument("-classpath") - .addArgument(classpath) - .addArgument("-Divy.engine.testheadless=true") - .addArgument("-Djava.awt.headless=true") - .addArgument("-Dosgi.install.area=" + osgiDir.toAbsolutePath()); - + var commands = new ArrayList(); + commands.add(getJavaExec()); + commands.add("-classpath"); + commands.add(classpath); + commands.add("-Divy.engine.testheadless=true"); + commands.add("-Djava.awt.headless=true"); + commands.add("-Dosgi.install.area=" + osgiDir.toAbsolutePath()); if (StringUtils.isNotBlank(context.vmOptions.additionalVmOptions())) { - cli.addArguments(context.vmOptions.additionalVmOptions(), false); + // todo quoting + commands.add(context.vmOptions.additionalVmOptions()); } - EngineModuleHints.loadFromJvmOptionsFile(context, cli); - - cli.addArgument("org.eclipse.equinox.launcher.Main") - .addArgument("-application").addArgument("ch.ivyteam.ivy.server.exec.engine") - .addArgument(command.toString()); - return cli; + //EngineModuleHints.loadFromJvmOptionsFile(context, cli); + + commands.add("org.eclipse.equinox.launcher.Main"); + commands.add("-application"); + commands.add("ch.ivyteam.ivy.server.exec.engine"); + // todo correct= + commands.add(command.toString()); + return new ProcessBuilder(commands); } private Executor createEngineExecutor() { @@ -224,14 +227,15 @@ static String evaluateIvyContextFromUrl(String location) { return StringUtils.substringBefore(StringUtils.removeStart(location, "/"), "sys"); } - private void waitForEngineStart(Executor executor) throws Exception { + private void waitForEngineStart(Process executor) throws Exception { int i = 0; while (!engineStarted.get()) { Thread.sleep(1_000); i++; - if (!executor.getWatchdog().isWatching()) { - throw new RuntimeException("Engine start failed unexpected."); - } + + //if (!executor.getWatchdog().isWatching()) { + // throw new RuntimeException("Engine start failed unexpected."); + //} if (i > context.timeoutInSeconds) { throw new TimeoutException("Timeout while starting engine " + context.timeoutInSeconds + " [s].\n" + "Check the engine log for details or increase the timeout property '" @@ -261,19 +265,20 @@ public void onProcessComplete(int exitValue) { * @param statusCmd * @return the output of the engine command. */ - private String executeSynch(CommandLine statusCmd) { + private String executeSynch(ProcessBuilder statusCmd) { String engineOutput = null; - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream, System.err); - Executor executor = createEngineExecutor(); - executor.setStreamHandler(streamHandler); - executor.setExitValue(-1); + //ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + //PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream, System.err); + //Executor executor = createEngineExecutor(); + //executor.setStreamHandler(streamHandler); + //executor.setExitValue(-1); try { - executor.execute(statusCmd); + statusCmd.start(); + //executor.execute(statusCmd); } catch (IOException ex) { // expected! } finally { - engineOutput = outputStream.toString(); - IOUtils.closeQuietly(outputStream); + //engineOutput = outputStream.toString(); + //IOUtils.closeQuietly(outputStream); } return engineOutput; } diff --git a/src/main/java/ch/ivyteam/ivy/maven/test/StartTestEngineMojo.java b/src/main/java/ch/ivyteam/ivy/maven/test/StartTestEngineMojo.java index 5c498f62..de307a82 100644 --- a/src/main/java/ch/ivyteam/ivy/maven/test/StartTestEngineMojo.java +++ b/src/main/java/ch/ivyteam/ivy/maven/test/StartTestEngineMojo.java @@ -22,7 +22,6 @@ import java.nio.file.StandardCopyOption; import java.util.stream.Stream; -import org.apache.commons.exec.Executor; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; @@ -106,7 +105,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { } } - public Executor startEngine() throws Exception { + public Process startEngine() throws Exception { var engineDir = engineDir(); var vmOptions = new EngineVmOptions(additionalClasspath, additionalVmOptions); var ctx = new EngineMojoContext(engineDir, project, getLog(), engineLogFile, vmOptions, startTimeoutInSeconds); diff --git a/src/test/java/ch/ivyteam/ivy/maven/deploy/TestDeployToRunningEngine.java b/src/test/java/ch/ivyteam/ivy/maven/deploy/TestDeployToRunningEngine.java index 7e0968cf..962624ec 100644 --- a/src/test/java/ch/ivyteam/ivy/maven/deploy/TestDeployToRunningEngine.java +++ b/src/test/java/ch/ivyteam/ivy/maven/deploy/TestDeployToRunningEngine.java @@ -22,7 +22,6 @@ import java.io.PrintStream; import java.nio.file.Path; -import org.apache.commons.exec.Executor; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.settings.Server; @@ -71,7 +70,7 @@ public void canDeployIar() throws Exception { var deployedIar = getTarget(deployMojo.deployFile, deployMojo); var deployedIarFlagFile = deployedIar.resolveSibling(deployedIar.getFileName() + ".deployed"); var deployedIarLogFile = deployedIar.resolveSibling(deployedIar.getFileName() + ".deploymentLog"); - Executor startedProcess = null; + Process startedProcess = null; try { startedProcess = mojo.startEngine(); deployMojo.execute(); @@ -116,7 +115,7 @@ private void deployIarRemoteAndAssert() throws Exception, MojoExecutionException deployMojo.deployToEngineApplication = "test"; deployMojo.deployMethod = DeployMethod.HTTP; - Executor startedProcess = null; + Process startedProcess = null; try { System.setOut(originalOut); startedProcess = mojo.startEngine(); @@ -142,9 +141,9 @@ private static Path getTarget(Path iar, DeployToEngineMojo mojo) { .resolve(iar.getFileName().toString()); } - private static void kill(Executor startedProcess) { + private static void kill(Process startedProcess) { if (startedProcess != null) { - startedProcess.getWatchdog().destroyProcess(); + startedProcess.destroy(); } } diff --git a/src/test/java/ch/ivyteam/ivy/maven/test/TestStartEngine.java b/src/test/java/ch/ivyteam/ivy/maven/test/TestStartEngine.java index 31281074..83c09874 100644 --- a/src/test/java/ch/ivyteam/ivy/maven/test/TestStartEngine.java +++ b/src/test/java/ch/ivyteam/ivy/maven/test/TestStartEngine.java @@ -22,8 +22,6 @@ import java.nio.file.Files; import java.nio.file.Path; -import org.apache.commons.exec.Executor; -import org.apache.commons.exec.ShutdownHookProcessDestroyer; import org.apache.maven.plugin.MojoExecutionException; import org.junit.Rule; import org.junit.Test; @@ -44,7 +42,7 @@ public void canStartEngine() throws Exception { assertThat(getProperty(EngineControl.Property.TEST_ENGINE_URL)).isNull(); assertThat(getProperty(EngineControl.Property.TEST_ENGINE_LOG)).isNull(); - Executor startedProcess = null; + Process startedProcess = null; try { startedProcess = mojo.startEngine(); assertThat(getProperty(EngineControl.Property.TEST_ENGINE_URL)).startsWith("http://") @@ -55,21 +53,20 @@ public void canStartEngine() throws Exception { } } - @Test - public void testKillEngineOnVmExit() throws Exception { - StartTestEngineMojo mojo = rule.getMojo(); - Executor startedProcess = null; - try { - startedProcess = mojo.startEngine(); - assertThat(startedProcess.getProcessDestroyer()).isInstanceOf(ShutdownHookProcessDestroyer.class); - var jvmShutdownHoock = (ShutdownHookProcessDestroyer) startedProcess.getProcessDestroyer(); - assertThat(jvmShutdownHoock.size()) - .as("One started engine process must be killed on VM end.") - .isEqualTo(1); - } finally { - kill(startedProcess); - } - } +// @Test +// public void testKillEngineOnVmExit() throws Exception { +// StartTestEngineMojo mojo = rule.getMojo(); +// Process startedProcess = null; +// try { +// startedProcess = mojo.startEngine(); +// var jvmShutdownHoock = (ShutdownHookProcessDestroyer) startedProcess.getProcessDestroyer(); +// assertThat(jvmShutdownHoock.size()) +// .as("One started engine process must be killed on VM end.") +// .isEqualTo(1); +// } finally { +// kill(startedProcess); +// } +// } /** * MODIFY_EXISTING 1. If engine @@ -146,7 +143,7 @@ public void startEngine_COPY_FROM_CACHE_cacheEngine() throws MojoExecutionExcept @Test public void startEngine_copyEngineToTarget() throws Exception { StartTestEngineMojo mojo = rule.getMojo(); - Executor startedProcess = null; + Process startedProcess = null; try { mojo.testEngine = TestEngineLocation.COPY_FROM_TEMPLATE; var engineDirTarget = mojo.getEngineDir(mojo.project); @@ -166,7 +163,7 @@ public void startEngine_targetDirectoryNotClean() throws Exception { StartTestEngineMojo mojo = rule.getMojo(); mojo.setLog(log); - Executor startedProcess = null; + Process startedProcess = null; try { var engineDirTarget = mojo.getEngineDir(mojo.project); assertThat(engineDirTarget).endsWith(Path.of("/target/ivyEngine")); @@ -191,7 +188,7 @@ public void startEngine_targetDirectoryNotClean() throws Exception { public void startEngine_copiedEngine_executable() throws Exception { StartTestEngineMojo mojo = rule.getMojo(); mojo.testEngine = TestEngineLocation.COPY_FROM_TEMPLATE; - Executor startedProcess = null; + Process startedProcess = null; try { var cacheEngine = mojo.engineDirectory; assertFileExecutable(cacheEngine.resolve("elasticsearch/bin/elasticsearch")); @@ -212,9 +209,9 @@ private void assertFileExecutable(Path file) { .isExecutable(); } - private static void kill(Executor startedProcess) { + private static void kill(Process startedProcess) { if (startedProcess != null) { - startedProcess.getWatchdog().destroyProcess(); + startedProcess.destroy(); } }