diff --git a/src/main/html/webapp/components/admin/settings/server/server.stache b/src/main/html/webapp/components/admin/settings/server/server.stache index f681fe16..437f685d 100644 --- a/src/main/html/webapp/components/admin/settings/server/server.stache +++ b/src/main/html/webapp/components/admin/settings/server/server.stache @@ -95,7 +95,9 @@ {{else}}
{{name}}
- {{{error}}} +
+
{{error}}
+
{{/enabled}} diff --git a/src/main/java/cloudgene/mapred/plugins/docker/DockerBinary.java b/src/main/java/cloudgene/mapred/plugins/docker/DockerBinary.java index 4f0f469f..04101742 100644 --- a/src/main/java/cloudgene/mapred/plugins/docker/DockerBinary.java +++ b/src/main/java/cloudgene/mapred/plugins/docker/DockerBinary.java @@ -38,12 +38,11 @@ public String getVersion() { if (isInstalled()) { String binary = getBinary(); Command command = new Command(binary, "version"); - command.saveStdOut(FileUtil.path("docker-version.txt")); + StringBuffer stdout = new StringBuffer(); + command.writeStdout(stdout); command.setSilent(true); command.execute(); - String version = FileUtil.readFileAsString("docker-version.txt"); - FileUtil.deleteFile("docker-version.txt"); - return version; + return stdout.toString(); } else { return "Docker not installed."; } diff --git a/src/main/java/cloudgene/mapred/plugins/nextflow/NextflowBinary.java b/src/main/java/cloudgene/mapred/plugins/nextflow/NextflowBinary.java index 85347d26..b32aca2e 100644 --- a/src/main/java/cloudgene/mapred/plugins/nextflow/NextflowBinary.java +++ b/src/main/java/cloudgene/mapred/plugins/nextflow/NextflowBinary.java @@ -63,12 +63,11 @@ public boolean isInstalled() { public String getVersion() { if (isInstalled()) { Command command = new Command(binary, "info"); - command.saveStdOut(FileUtil.path("info-version.txt")); + StringBuffer stdout = new StringBuffer(); + command.writeStdout(stdout); command.setSilent(true); command.execute(); - String version = FileUtil.readFileAsString("info-version.txt"); - FileUtil.deleteFile("info-version.txt"); - return version; + return stdout.toString(); } else { return "Nextflow not installed."; } diff --git a/src/main/java/cloudgene/mapred/server/controller/ServerAdminController.java b/src/main/java/cloudgene/mapred/server/controller/ServerAdminController.java index 005bebb8..1490ff63 100644 --- a/src/main/java/cloudgene/mapred/server/controller/ServerAdminController.java +++ b/src/main/java/cloudgene/mapred/server/controller/ServerAdminController.java @@ -14,6 +14,7 @@ import cloudgene.mapred.server.responses.ServerResponse; import cloudgene.mapred.server.responses.StatisticsResponse; import cloudgene.mapred.server.services.ServerService; +import cloudgene.mapred.util.TextUtil; import genepi.io.FileUtil; import io.micronaut.core.annotation.Nullable; import io.micronaut.http.MediaType; @@ -88,8 +89,7 @@ public String getDetails() { public String getLogs() { File file = new File(LOG_FILENAME); if (file.exists()) { - String content = serverService.tail(file, 1000); - return content; + return TextUtil.tail(file, 1000); } else { return "No log file available."; } diff --git a/src/main/java/cloudgene/mapred/server/services/ServerService.java b/src/main/java/cloudgene/mapred/server/services/ServerService.java index 000dd2b4..f2f1af57 100644 --- a/src/main/java/cloudgene/mapred/server/services/ServerService.java +++ b/src/main/java/cloudgene/mapred/server/services/ServerService.java @@ -3,15 +3,12 @@ import java.io.File; import java.io.IOException; import java.net.URL; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Vector; +import java.util.*; import java.util.jar.Attributes; import java.util.jar.Manifest; import cloudgene.mapred.plugins.nextflow.NextflowPlugin; +import cloudgene.mapred.util.command.Command; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -211,6 +208,34 @@ public String getClusterDetails() { plugins.add(pluginObject); } + //check user defined resources + for (Map resource: application.getSettings().getResources()){ + String name = resource.get("name"); + ObjectNode pluginObject = mapper.createObjectNode(); + pluginObject.put("name", name); + if (!resource.containsKey("command")) { + pluginObject.put("error", "Command defined in resource '" + name + "'"); + } + String cmd = resource.get("command"); + String[] tiles = cmd.split(" "); + String[] params = Arrays.copyOfRange(tiles, 1, tiles.length); + Command command = new Command(tiles[0], params); + command.setSilent(true); + StringBuffer output = new StringBuffer(); + StringBuffer error = new StringBuffer(); + command.writeStdout(output); + command.writeStderr(error); + int exitCode = command.execute(); + if (exitCode == 0) { + pluginObject.put("enabled", true); + pluginObject.put("details", output.toString()); + }else { + pluginObject.put("enabled", false); + pluginObject.put("error", output.toString()+ "\n" + error.toString()); + } + plugins.add(pluginObject); + } + // database object.put("db_max_active", application.getDatabase().getDataSource().getMaxActive()); object.put("db_active", application.getDatabase().getDataSource().getNumActive()); @@ -222,53 +247,6 @@ public String getClusterDetails() { return object.toString(); } - public String tail(File file, int lines) { - java.io.RandomAccessFile fileHandler = null; - try { - fileHandler = new java.io.RandomAccessFile(file, "r"); - long fileLength = fileHandler.length() - 1; - StringBuilder sb = new StringBuilder(); - int line = 0; - - for (long filePointer = fileLength; filePointer != -1; filePointer--) { - fileHandler.seek(filePointer); - int readByte = fileHandler.readByte(); - - if (readByte == 0xA) { - line = line + 1; - if (line == lines) { - if (filePointer == fileLength) { - continue; - } - break; - } - } else if (readByte == 0xD) { - line = line + 1; - if (line == lines) { - if (filePointer == fileLength - 1) { - continue; - } - break; - } - } - sb.append((char) readByte); - } - - String lastLine = sb.reverse().toString(); - return lastLine; - } catch (java.io.IOException e) { - log.error("Parsing log file failed.", e); - return null; - } finally { - if (fileHandler != null) - try { - fileHandler.close(); - } catch (IOException e) { - log.error("Parsing log file failed.", e); - } - } - } - public void updateNextflowConfig(String content) { NextflowPlugin plugin = (NextflowPlugin) PluginManager.getInstance().getPlugin(NextflowPlugin.ID); String filename = plugin.getNextflowConfig(); diff --git a/src/main/java/cloudgene/mapred/util/Settings.java b/src/main/java/cloudgene/mapred/util/Settings.java index d2520b6a..32da184e 100644 --- a/src/main/java/cloudgene/mapred/util/Settings.java +++ b/src/main/java/cloudgene/mapred/util/Settings.java @@ -48,6 +48,8 @@ public class Settings { private List> errorHandlers = new Vector>(); + private List> resources = new Vector<>(); + private int autoRetireInterval = 5; private int retireAfter = 6; @@ -389,6 +391,14 @@ public List> getErrorHandlers() { return errorHandlers; } + public void setResources(List> resources) { + this.resources = resources; + } + + public List> getResources() { + return resources; + } + public void setRepository(ApplicationRepository repository) { this.repository = repository; } diff --git a/src/main/java/cloudgene/mapred/util/TextUtil.java b/src/main/java/cloudgene/mapred/util/TextUtil.java new file mode 100644 index 00000000..38d45056 --- /dev/null +++ b/src/main/java/cloudgene/mapred/util/TextUtil.java @@ -0,0 +1,59 @@ +package cloudgene.mapred.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; + +public class TextUtil { + + private static final Logger log = LoggerFactory.getLogger(TextUtil.class); + + public static String tail(File file, int lines) { + java.io.RandomAccessFile fileHandler = null; + try { + fileHandler = new java.io.RandomAccessFile(file, "r"); + long fileLength = fileHandler.length() - 1; + StringBuilder sb = new StringBuilder(); + int line = 0; + + for (long filePointer = fileLength; filePointer != -1; filePointer--) { + fileHandler.seek(filePointer); + int readByte = fileHandler.readByte(); + + if (readByte == 0xA) { + line = line + 1; + if (line == lines) { + if (filePointer == fileLength) { + continue; + } + break; + } + } else if (readByte == 0xD) { + line = line + 1; + if (line == lines) { + if (filePointer == fileLength - 1) { + continue; + } + break; + } + } + sb.append((char) readByte); + } + + String lastLine = sb.reverse().toString(); + return lastLine; + } catch (java.io.IOException e) { + log.error("Parsing log file failed.", e); + return null; + } finally { + if (fileHandler != null) + try { + fileHandler.close(); + } catch (IOException e) { + log.error("Parsing log file failed.", e); + } + } + } +} diff --git a/src/main/java/cloudgene/mapred/util/command/Command.java b/src/main/java/cloudgene/mapred/util/command/Command.java index 5d6df9e8..314b7842 100644 --- a/src/main/java/cloudgene/mapred/util/command/Command.java +++ b/src/main/java/cloudgene/mapred/util/command/Command.java @@ -3,9 +3,6 @@ import java.io.File; import java.util.ArrayList; import java.util.List; -import java.util.Vector; - -import org.apache.commons.codec.digest.DigestUtils; public class Command { @@ -15,19 +12,15 @@ public class Command { private boolean silent = false; - private boolean deleteInput = false; - private String directory = null; - private StringBuffer stout = new StringBuffer(); - private String stdoutFileName = null; private String stderrFileName = null; - private List inputs = new Vector(); + private StringBuffer stdout; - private List outputs = new Vector(); + private StringBuffer stderr; public Command(String cmd, String... params) { this.cmd = cmd; @@ -38,7 +31,7 @@ public Command(String cmd) { this.cmd = cmd; } - public void setParams(String... params) { + public void setArgs(String... params) { this.params = params; } @@ -49,6 +42,15 @@ public void setParams(List params) { } } + public void writeStdout(StringBuffer stdout) { + this.stdout = stdout; + } + + public void writeStderr(StringBuffer stderr) { + this.stderr = stderr; + } + + public void saveStdOut(String filename) { this.stdoutFileName = filename; } @@ -72,19 +74,20 @@ public int execute() { try { ProcessBuilder builder = new ProcessBuilder(command); - // builder.redirectErrorStream(true); + // ensure it works on MacOS + builder.environment().put("PATH", builder.environment().get("PATH") + ":" + "/usr/local/bin/"); if (directory != null) { builder.directory(new File(directory)); } Process process = builder.start(); - CommandStreamHandler handler = new CommandStreamHandler( - process.getInputStream(), stdoutFileName); + CommandStreamHandler handler = new CommandStreamHandler(process.getInputStream(), stdoutFileName); + handler.setStringBuffer(stdout); handler.setSilent(silent); Thread inputStreamHandler = new Thread(handler); - CommandStreamHandler handler2 = new CommandStreamHandler( - process.getErrorStream(), stderrFileName); + CommandStreamHandler handler2 = new CommandStreamHandler(process.getErrorStream(), stderrFileName); + handler2.setStringBuffer(stderr); handler2.setSilent(silent); Thread errorStreamHandler = new Thread(handler2); @@ -104,11 +107,8 @@ public int execute() { process.destroy(); } - if (deleteInput) { - new File(cmd).delete(); - } - return 0; + } catch (Exception e) { e.printStackTrace(); return -1; @@ -123,14 +123,6 @@ public void setSilent(boolean silent) { this.silent = silent; } - public boolean isDeleteInput() { - return deleteInput; - } - - public void setDeleteInput(boolean deleteInput) { - this.deleteInput = deleteInput; - } - public void setDirectory(String directory) { this.directory = directory; } @@ -150,43 +142,6 @@ public String toString() { return result; } - public String getStdOut() { - return stout.toString(); - } - - public void addInput(String input) { - inputs.add(input); - } - - public void addOutput(String output) { - outputs.add(output); - } - - public List getInputs() { - return inputs; - } - - public List getOutputs() { - return outputs; - } - - private boolean isNoFile(String param) { - return !inputs.contains(param) && !outputs.contains(param); - } - - public String getSignature() { - - String fullCommand = cmd; - for (String param : params) { - if (isNoFile(param)) { - fullCommand += param; - } - } - - return DigestUtils.md5Hex(fullCommand); - - } - public String getName() { return cmd; } diff --git a/src/main/java/cloudgene/mapred/util/command/CommandStreamHandler.java b/src/main/java/cloudgene/mapred/util/command/CommandStreamHandler.java index 35e94811..7aae1ba3 100644 --- a/src/main/java/cloudgene/mapred/util/command/CommandStreamHandler.java +++ b/src/main/java/cloudgene/mapred/util/command/CommandStreamHandler.java @@ -1,25 +1,23 @@ package cloudgene.mapred.util.command; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; public class CommandStreamHandler implements Runnable { - private InputStream is; - - //private StringBuffer stdout = new StringBuffer();; + private BufferedReader is; private boolean silent = false; private String filename = null; + private StringBuffer memory; + public CommandStreamHandler(InputStream is) { - this.is = is; + this.is = new BufferedReader(new InputStreamReader(is)); } public CommandStreamHandler(InputStream is, String filename) { - this.is = is; + this.is = new BufferedReader(new InputStreamReader(is)); this.filename = filename; } @@ -27,6 +25,10 @@ public void setSilent(boolean silent) { this.silent = silent; } + public void setStringBuffer(StringBuffer memory) { + this.memory = memory; + } + public void setFilename(String filename) { this.filename = filename; } @@ -37,24 +39,25 @@ public void run() { try { boolean save = (filename != null && !filename.isEmpty()); - FileOutputStream writer = null; + BufferedWriter writer = null; byte[] buffer = new byte[200]; if (save) { - writer = new FileOutputStream(filename); + writer = new BufferedWriter(new FileWriter(filename)); } - int size = 0; - - while ((size = is.read(buffer)) > 0) { - //stdout.append(line); + String line = null; + while ((line = is.readLine()) != null) { + if (memory != null) { + memory.append(line).append("\n"); + } if (!silent) { - String line = new String(buffer, 0, size); - System.out.println(line); + System.out.println(" > " + line); } if (save) { - writer.write(buffer, 0, size); + writer.write(line); + writer.newLine(); } }