#10 Daemon Mode umsetzen

This commit is contained in:
Penski, Andreas 2019-03-04 08:42:21 +01:00
parent 87a05cb456
commit d1d3d25f36
35 changed files with 17482 additions and 25 deletions

View file

@ -20,12 +20,12 @@
package de.kosit.validationtool.cmd;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.stream.Collectors;
@ -37,6 +37,7 @@ import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import lombok.extern.slf4j.Slf4j;
@ -50,20 +51,21 @@ import de.kosit.validationtool.impl.ObjectFactory;
/**
* Commandline Version des Prüftools. Parsed die Kommandozeile und führt die konfigurierten Aktionen aus.
*
*
* @author Andreas Penski
*/
@Slf4j
public class CommandLineApplication {
private static final Option HELP = Option.builder("?").longOpt("help").argName("Help").desc("Displays this help").build();
private static final Option SCENARIOS = Option.builder("s").required().longOpt("scenarios").hasArg()
.desc("Location of scenarios.xml e.g.").build();
private static final Option REPOSITORY = Option.builder("r").longOpt("repository").hasArg()
.desc("Directory containing scenario content").build();
private static final Option PRINT = Option.builder("p").longOpt("print").desc("Prints the check result to stdout").build();
private static final Option OUTPUT = Option.builder("o").longOpt("output-directory")
@ -76,6 +78,17 @@ public class CommandLineApplication {
private static final Option CHECK_ASSERTIONS = Option.builder("c").longOpt("check-assertions").hasArg()
.desc("Check the result using defined assertions").argName("assertions-file").build();
private static final Option SERVER = Option.builder("D").longOpt("daemon").desc("Starts a daemon listing for validation requests").build();
private static final Option HOST = Option.builder("H").longOpt("host").hasArg()
.desc("The hostname / IP address to bind the daemon. Default is localhost").build();
private static final Option PORT = Option.builder("P").longOpt("port").hasArg()
.desc("The port to bind the daemon. Default is 8080").build();
private static final Option WORKER_COUNT = Option.builder("T").longOpt("threads").hasArg().desc("Number of threads processing validation requests").build();
public static final int DAEMON_SIGNAL = 100;
private static final Option PRINT_MEM_STATS = Option.builder("m").longOpt("memory-stats").desc("Prints some memory stats").build();
@ -90,15 +103,19 @@ public class CommandLineApplication {
*/
public static void main(String[] args) {
final int resultStatus = mainProgram(args);
System.exit(resultStatus);
if (DAEMON_SIGNAL != resultStatus) {
System.exit(resultStatus);
}
}
/**
* Hauptprogramm für die Kommandozeilen-Applikation.
*
* @param args die Eingabe-Argumente
*/
static int mainProgram(String[] args) {
int returnValue = 0;
Options options = createOptions();
if (isHelpRequested(args)) {
printHelp(options);
@ -106,10 +123,12 @@ public class CommandLineApplication {
try {
CommandLineParser parser = new DefaultParser();
final CommandLine cmd = parser.parse(options, args);
if (cmd.getArgList().isEmpty()) {
if (cmd.hasOption(SERVER.getOpt())) {
returnValue = startDaemonMode(cmd);
} else if (cmd.getArgList().isEmpty()) {
printHelp(createOptions());
} else {
return processActions(cmd);
returnValue = processActions(cmd);
}
} catch (ParseException e) {
log.error("Error processing command line arguments: " + e.getMessage());
@ -119,6 +138,46 @@ public class CommandLineApplication {
return 0;
}
private static int determinePort(CommandLine cmd) {
int port = 8080;
if (checkOptionWithValue(PORT, cmd)) {
port = Integer.parseInt(cmd.getOptionValue(PORT.getOpt()));
}
return port;
}
private static int determineThreads(CommandLine cmd) {
int threads = Runtime.getRuntime().availableProcessors();
if (checkOptionWithValue(WORKER_COUNT, cmd)) {
threads = Integer.parseInt(cmd.getOptionValue(WORKER_COUNT.getOpt()));
}
return threads;
}
private static String determineHost(CommandLine cmd) {
String host = "localhost";
if (checkOptionWithValue(HOST, cmd)) {
host = cmd.getOptionValue(HOST.getOpt());
}
return host;
}
private static int startDaemonMode(CommandLine cmd) {
Option[] unavailable = new Option[]{PRINT, CHECK_ASSERTIONS, DEBUG, OUTPUT, EXTRACT_HTML};
warnUnusedOptions(cmd, unavailable, true);
Daemon validDaemon = new Daemon(determineDefinition(cmd), determineRepository(cmd), determineHost(cmd), determinePort(cmd), determineThreads(cmd));
validDaemon.startServer();
return DAEMON_SIGNAL;
}
private static void warnUnusedOptions(CommandLine cmd, Option[] unavailable, boolean daemon) {
Arrays.stream(cmd.getOptions()).filter(o -> ArrayUtils.contains(unavailable, o)).map(o -> "The option " + o.getLongOpt() + " is not available in daemon mode").forEach(log::error);
if (daemon && !cmd.getArgList().isEmpty()) {
log.info("Ignoring test targets in daemon mode");
}
}
private static boolean isHelpRequested(String[] args) {
Options helpOptions = createHelpOptions();
try {
@ -137,6 +196,8 @@ public class CommandLineApplication {
try {
long start = System.currentTimeMillis();
Option[] unavailable = new Option[]{HOST, PORT, WORKER_COUNT};
warnUnusedOptions(cmd, unavailable, false);
CheckConfiguration d = new CheckConfiguration(determineDefinition(cmd));
d.setScenarioRepository(determineRepository(cmd));
InternalCheck check = new InternalCheck(d);
@ -149,6 +210,7 @@ public class CommandLineApplication {
if (cmd.hasOption(PRINT.getOpt())) {
check.getCheckSteps().add(new PrintReportAction());
}
if (cmd.hasOption(CHECK_ASSERTIONS.getOpt())) {
Assertions assertions = loadAssertions(cmd.getOptionValue(CHECK_ASSERTIONS.getOpt()));
check.getCheckSteps().add(new CheckAssertionAction(assertions, ObjectFactory.createProcessor()));
@ -236,7 +298,7 @@ public class CommandLineApplication {
}
private static URI determineRepository(CommandLine cmd) throws MalformedURLException {
private static URI determineRepository(CommandLine cmd) {
if (checkOptionWithValue(REPOSITORY, cmd)) {
Path d = Paths.get(cmd.getOptionValue(REPOSITORY.getOpt()));
if (Files.isDirectory(d)) {
@ -249,7 +311,7 @@ public class CommandLineApplication {
return null;
}
private static URI determineDefinition(CommandLine cmd) throws MalformedURLException {
private static URI determineDefinition(CommandLine cmd) {
checkOptionWithValue(SCENARIOS, cmd);
Path f = Paths.get(cmd.getOptionValue(SCENARIOS.getOpt()));
if (Files.isRegularFile(f)) {
@ -291,6 +353,9 @@ public class CommandLineApplication {
private static Options createOptions() {
Options options = new Options();
options.addOption(HELP);
options.addOption(SERVER);
options.addOption(HOST);
options.addOption(PORT);
options.addOption(SCENARIOS);
options.addOption(REPOSITORY);
options.addOption(PRINT);
@ -299,6 +364,7 @@ public class CommandLineApplication {
options.addOption(DEBUG);
options.addOption(CHECK_ASSERTIONS);
options.addOption(PRINT_MEM_STATS);
options.addOption(WORKER_COUNT);
return options;
}
}