package org.infinispan.server.test.util.arquillian.extensions;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.logging.Logger;
import org.jboss.arquillian.container.spi.Container;
import org.jboss.arquillian.container.spi.ServerKillProcessor;
/**
* Handles calls to {@link org.jboss.arquillian.container.test.api.ContainerController#kill(String)}
*
* @author <a href="mailto:mgencur@redhat.com">Martin Gencur</a>
* @author <a href="mailto:tsykora@redhat.com">Tomas Sykora</a>
*/
public class InfinispanServerKillProcessor implements ServerKillProcessor {
private final Logger log = Logger.getLogger(InfinispanServerKillProcessor.class.getName());
private static final long TIMEOUT = 1000;
public void kill(Container container) throws Exception {
String osName = System.getProperty("os.name", "");
String killSequence = null;
Process p = null;
if (osName.startsWith("Linux")) {
killSequence = "kill -9 `ps aux | grep -v 'grep' | grep 'jboss.home.dir=[jbossHome] ' | sed -re '1,$s/[ \\t]+/ /g' | cut -d ' ' -f 2`";
killSequence = killSequence.replace("[jbossHome]", container.getContainerConfiguration().getContainerProperties()
.get("jbossHome"));
p = Runtime.getRuntime().exec(new String[]{"sh", "-c", killSequence});
executeKill(p, killSequence);
} else if (osName.startsWith("Mac OS X")) {
killSequence = "ps aux | grep -v grep | grep 'jboss.home.dir=[jbossHome]' | awk '{ print $2 }' |xargs kill -9";
killSequence = killSequence.replace("[jbossHome]", container.getContainerConfiguration().getContainerProperties()
.get("jbossHome"));
p = Runtime.getRuntime().exec(new String[]{"sh", "-c", killSequence});
executeKill(p, killSequence);
} else if (osName.startsWith("SunOS")) {
killSequence = "jps | grep jboss-modules.jar | cut -f 1 -d ' ' | head -1 | xargs kill -9";
p = Runtime.getRuntime().exec(new String[]{"sh", "-c", killSequence});
executeKill(p, killSequence);
} else if (osName.startsWith("HP-UX")) {
// port-offset: node0=0, node0=100, node0=200
String port = "8080";
String vmArguments = container.getContainerConfiguration().getContainerProperties().get("javaVmArguments");
if (vmArguments.contains("jboss.node.name=node1")) {
port = "8180";
}
if (vmArguments.contains("jboss.node.name=node2")) {
port = "8280";
}
killSequence = "lsof | grep '" + port + " (LISTEN)' | awk '{print $2}' | xargs kill -9";
p = Runtime.getRuntime().exec(new String[]{"sh", "-c", killSequence});
executeKill(p, killSequence);
} else if (osName.startsWith("Windows")) {
// port-offset: node0=0, node0=100, node0=200
String port = "8080";
String vmArguments = container.getContainerConfiguration().getContainerProperties().get("javaVmArguments");
if (vmArguments.contains("jboss.node.name=node1")) {
port = "8180";
}
if (vmArguments.contains("jboss.node.name=node2")) {
port = "8280";
}
Process ptemp = Runtime.getRuntime().exec(
new String[]{"cmd", "/c", "netstat -aon | findstr LISTENING | findstr 127.0.0.1:" + port});
ptemp.waitFor();
log.info("Exit value of finding process (0 = ok, else num. unexpected): " + ptemp.exitValue());
if (ptemp.exitValue() == 0) {
String idForKill = getPidForKill(ptemp.getInputStream());
log.info("Process ID for kill: " + idForKill + " (port: " + port + ")");
killSequence = "taskkill /F /T /PID " + idForKill;
p = Runtime.getRuntime().exec(new String[]{"cmd", "/c", killSequence});
executeKill(p, killSequence);
} else {
throw new RuntimeException("Finding sequence failed => server not killed. (Exit value of finding process: "
+ p.exitValue() + " OS=" + System.getProperty("os.name") + ")");
}
} else {
throw new RuntimeException("System was probably NOT properly decided. Property os.name = "
+ System.getProperty("os.name"));
}
}
private void executeKill(Process p, String logKillSequence) throws Exception {
log.info("Issuing kill sequence (on " + System.getProperty("os.name") + "): " + logKillSequence);
p.waitFor();
if (p.exitValue() != 0) {
throw new RuntimeException("Kill sequence failed => server not killed. (Exit value of killing process: "
+ p.exitValue() + " OS=" + System.getProperty("os.name") + ")");
}
Thread.sleep(TIMEOUT);
log.info("Kill sequence successfully completed. \n");
}
/**
* Get ID of process listening on 127.0.0.1:8080 (or 8180 or 8280). Used on Windows.
* Note! This method is closing InputStream.
*/
private String getPidForKill(InputStream is) throws IOException {
String line = null;
String lineForSplit = null;
BufferedReader in = new BufferedReader(new InputStreamReader(is));
lineForSplit = in.readLine(); // returns null if end of stream was reached
log.info("Getting process id from: " + lineForSplit);
while ((line = in.readLine()) != null) {
log.warning("There is another line here! : " + line);
}
in.close();
// Expected: [white spaces] TCP 127.0.0.1:8080 0.0.0.0:0 LISTENING 3468
if (lineForSplit != null) {
String[] output = lineForSplit.split("\\s+");
return output[5];
} else {
throw new RuntimeException(
"Finding sequence failed => server not killed. (Unexpected problem in reading process InputStream)");
}
}
}