package io.vertx.core.impl.launcher.commands;
import io.vertx.core.cli.annotations.*;
import io.vertx.core.spi.launcher.DefaultCommand;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Name("stop")
@Summary("Stop a vert.x application")
@Description("This command stops a vert.x application started with the `start` command. The command requires the " +
"application id as argument. Use the `list` command to get the list of applications")
public class StopCommand extends DefaultCommand {
private String id;
private boolean redeploy;
private static final Pattern PS = Pattern.compile("([0-9]+)\\s.*-Dvertx.id=.*");
@Argument(index = 0, argName = "vertx.id", required = false)
@Description("The vert.x application id")
public void setApplicationId(String id) {
this.id = id;
}
@Option(longName = "redeploy", flag = true)
@Hidden
public void setRedeploy(boolean redeploy) {
this.redeploy = redeploy;
}
@Override
public void run() {
if (id == null) {
out.println("Application id not specified...");
executionContext.execute("list");
return;
}
out.println("Stopping vert.x application '" + id + "'");
if (ExecUtils.isWindows()) {
terminateWindowsApplication();
} else {
terminateLinuxApplication();
}
}
private void terminateLinuxApplication() {
String pid = pid();
if (pid == null) {
out.println("Cannot find process for application using the id '" + id + "'.");
if (!redeploy) {
ExecUtils.exitBecauseOfProcessIssue();
}
return;
}
List<String> cmd = new ArrayList<>();
cmd.add("kill");
cmd.add(pid);
try {
int result = new ProcessBuilder(cmd).start().waitFor();
out.println("Application '" + id + "' terminated with status " + result);
if (!redeploy) {
ExecUtils.exit(result);
}
} catch (Exception e) {
out.println("Failed to stop application '" + id + "'");
e.printStackTrace(out);
if (!redeploy) {
ExecUtils.exitBecauseOfProcessIssue();
}
}
}
private void terminateWindowsApplication() {
List<String> cmd = Arrays.asList(
"WMIC",
"PROCESS",
"WHERE",
"CommandLine like '%vertx.id=" + id + "%'",
"CALL",
"TERMINATE"
);
try {
final Process process = new ProcessBuilder(cmd).start();
int result = process.waitFor();
out.println("Application '" + id + "' terminated with status " + result);
if (!redeploy) {
ExecUtils.exit(result);
}
} catch (Exception e) {
out.println("Failed to stop application '" + id + "'");
e.printStackTrace(out);
if (!redeploy) {
ExecUtils.exitBecauseOfProcessIssue();
}
}
}
private String pid() {
try {
final Process process = new ProcessBuilder(Arrays.asList("sh", "-c", "ps ax | grep \"" + id + "\"")).start();
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
final Matcher matcher = PS.matcher(line);
if (matcher.find()) {
return matcher.group(1);
}
}
process.waitFor();
reader.close();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace(out);
} catch (Exception e) {
e.printStackTrace(out);
}
return null;
}
}