package org.myrobotlab.framework; import java.io.File; import java.io.Serializable; import java.util.ArrayList; import org.myrobotlab.logging.LoggerFactory; import org.myrobotlab.service.interfaces.Invoker; import org.slf4j.Logger; /** * Simple class representing an operating system mrl process * * @author GroG * */ public class ProcessData implements Serializable { public final static Logger log = LoggerFactory.getLogger(ProcessData.class); private static final long serialVersionUID = 1L; public static final String STATE_RUNNING = "running"; public static final String STATE_STOPPED = "stopped"; public static final String STATE_UNKNOWN = "unknown"; // TODO - need to start using id public Integer id; public String branch; public String name; public String version; public Long startTs = null; public Long stopTs = null; public String jarPath = null; public String javaExe = null; public String jniLibraryPath = null; public String jnaLibraryPath = null; public String Xmx = null; boolean userDefinedServices = false; public String state = STATE_STOPPED; transient public Process process; transient public Monitor monitor; static transient public Invoker service; ArrayList<String> in = null; public static class Monitor extends Thread { ProcessData data; public Monitor(ProcessData pd) { super(String.format("%s.monitor", pd.name)); this.data = pd; } @Override public void run() { try { if (data.process != null) { // data.isRunning = true; data.state = STATE_RUNNING; data.state = "running"; // don't wait if there is no agent if (service != null) { data.process.waitFor(); } } } catch (Exception e) { } data.state = STATE_STOPPED; data.state = "stopped"; if (ProcessData.service != null){ ProcessData.service.invoke("publishTerminated", data.id); } } } public ProcessData(Invoker service, Integer id, String branch, String version, String name, Process process) { this.id = id; ProcessData.service = service; this.name = name; this.branch = branch; this.version = version; this.process = process; } /** * copy of a ProcessData - threaded data will not be copied * * @param pd */ public ProcessData(ProcessData pd) { this.id = pd.id; this.name = pd.name; this.branch = pd.branch; this.version = pd.version; this.javaExe = pd.javaExe; this.jniLibraryPath = pd.jniLibraryPath; this.version = pd.version; this.jnaLibraryPath = pd.jnaLibraryPath; this.userDefinedServices = pd.userDefinedServices; if (pd.in != null) { this.in = new ArrayList<String>(); for (int i = 0; i < pd.in.size(); ++i) { this.in.add(pd.in.get(i)); } } // this.process = pd.process; // this.startTs = System.currentTimeMillis(); // monitor = new Monitor(this); // monitor.start(); } /** * FIXME - is too much catering to mrl execution ... * * convert an String[] into a valid ProcessData * * @param inCmdLine * @param defaultBranch * @param defaultVersion */ public ProcessData(Invoker service, String jarPath, String[] inCmdLine, String defaultBranch, String defaultVersion) { ProcessData.service = service; this.jarPath = jarPath; // String protectedDomain = // URLDecoder.decode(Agent.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath(), // "UTF-8"); // log.info("protected domain {}", protectedDomain); // convert to ArrayList to process in = new ArrayList<String>(); for (int i = 0; i < inCmdLine.length; ++i) { String cmd = inCmdLine[i]; if (cmd.equals("-runtimeName")) { name = inCmdLine[i + 1]; continue; } if (cmd.equals("-branch")) { branch = inCmdLine[i + 1]; continue; } if (cmd.equals("-service")) { userDefinedServices = true; } // additional parameters in.add(inCmdLine[i]); } name = (name == null) ? "runtime" : name; branch = (branch == null) ? defaultBranch : branch; version = (version == null) ? defaultVersion : version; // step 1 - get current env data // String ps = File.pathSeparator; String fs = File.separator; Platform platform = Platform.getLocalInstance(); String exeName = platform.isWindows() ? "javaw" : "java"; javaExe = String.format("%s%sbin%s%s", System.getProperty("java.home"), fs, fs, exeName); jniLibraryPath = "-Djava.library.path=libraries/native"; jnaLibraryPath = "-Djna.library.path=libraries/native"; } public boolean isRunning() { return STATE_RUNNING.equals(state); } public String[] buildCmdLine() { ArrayList<String> cmd = new ArrayList<String>(); cmd.add(javaExe); cmd.add(jniLibraryPath); cmd.add(jnaLibraryPath); cmd.add("-cp"); // step 1 - get current env data String ps = File.pathSeparator; // bogus jython.jar added as a hack to support - jython's 'more' fragile // 2.7.0 interface :( // http://www.jython.org/archive/21/docs/registry.html // http://bugs.jython.org/issue2355 String classpath = String.format("%s%s./libraries/jar/jython.jar%s./libraries/jar/*%s./bin%s./build/classes", jarPath,ps, ps, ps, ps); cmd.add(classpath); cmd.add("org.myrobotlab.service.Runtime"); if (!userDefinedServices) { cmd.add("-service"); cmd.add("webgui"); cmd.add("WebGui"); cmd.add("log"); cmd.add("Log"); cmd.add("cli"); cmd.add("Cli"); cmd.add("gui"); cmd.add("GUIService"); cmd.add("python"); cmd.add("Python"); } cmd.add("-fromAgent"); if (in != null) { for (int i = 0; i < in.size(); ++i) { cmd.add(in.get(i)); } } return cmd.toArray(new String[cmd.size()]); } }