package org.radargun.service; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.radargun.Directories; import org.radargun.Service; import org.radargun.config.Property; import org.radargun.traits.ProvidesTrait; import org.radargun.utils.ArgsConverter; import org.radargun.utils.EnvsConverter; import org.radargun.utils.TimeConverter; /** * @author Radim Vansa <rvansa@redhat.com> */ @Service(doc = "Generic process control") public class ProcessService { @Property(doc = "Command for starting the process") protected String command; @Property(doc = "Configuration file used as the last argument.") protected String file; @Property(doc = "Additional arguments. Empty by default.", converter = ArgsConverter.class) protected List<String> args = Collections.emptyList(); @Property(doc = "Environment arguments. Empty by default.", converter = EnvsConverter.class) protected Map<String,String> env = Collections.emptyMap(); @Property(doc = "Current operating system. Default is UNIX.") protected String os = "unix"; @Property(doc = "Timeout to start the service. Default is 1 minute.", converter = TimeConverter.class) public long startTimeout = 60000; @Property(doc = "Timeout to stop the service. Default is 1 minute.", converter = TimeConverter.class) public long stopTimeout = 60000; @Property(doc = "Process standard error as standard output. Default is false.") public boolean stderrToStdout = false; private CopyOnWriteArrayList<Action> actions = new CopyOnWriteArrayList<Action>(); protected ProcessLifecycle<?> lifecycle; @ProvidesTrait public ProcessLifecycle<?> createLifecycle() { return lifecycle; } protected List<String> getCommand() { ArrayList<String> command = new ArrayList<String>(args.size() + 2); command.add(this.command); command.addAll(args); if (file != null) { command.add(file); } return command; } public String getCommandPrefix() { return Directories.PLUGINS_DIR + File.separator + "process" + File.separator + "bin" + File.separator + os + "-"; } public String getCommandSuffix() { if (!"unix".equals(os)) throw new IllegalArgumentException("Only unix is supported as OS."); return ".sh"; } public Map<String, String> getEnvironment() { return env; } public void registerAction(Pattern pattern, OutputListener action) { actions.add(new Action(pattern, action)); } public void unregisterAction(Pattern pattern) { for (Action a : actions) { if (a.pattern.equals(pattern)) actions.remove(a); } } public void reportOutput(String line) { System.out.println(line); for (Action action : actions) { Matcher m = action.pattern.matcher(line); if (m.matches()) { action.listener.run(m); } } } public void reportError(String line) { if (stderrToStdout) { reportOutput(line); } else { System.err.println(line); } } public interface OutputListener { void run(Matcher matcher); } private static class Action { public final Pattern pattern; public final OutputListener listener; private Action(Pattern pattern, OutputListener listener) { this.pattern = pattern; this.listener = listener; } } }