package org.opennms.netmgt.poller.monitors;
import groovy.lang.GroovyClassLoader;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Level;
import org.codehaus.groovy.control.CompilationFailedException;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.opennms.core.utils.TimeoutTracker;
import org.opennms.netmgt.junit.runner.SeleniumComputer;
import org.opennms.netmgt.model.PollStatus;
import org.opennms.netmgt.poller.MonitoredService;
public class SeleniumMonitor extends AbstractServiceMonitor {
public static class BaseUrlUtils{
private static Pattern s_ipAddrPattern = Pattern.compile("\\$\\{ipAddr\\}");
public static String replaceIpAddr(String baseUrl, String monSvcIpAddr) {
if(!baseUrl.contains("${ipAddr}")) {
return baseUrl;
}
String finalUrl = "";
Matcher matcher = s_ipAddrPattern.matcher(baseUrl);
finalUrl = matcher.replaceAll(monSvcIpAddr);
return finalUrl;
}
}
private static final int DEFAULT_SEQUENCE_RETRY = 0;
private static final int DEFAULT_TIMEOUT = 3000;
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters)
{
PollStatus serviceStatus = PollStatus.unavailable("Poll not completed yet");
TimeoutTracker tracker = new TimeoutTracker(parameters, DEFAULT_SEQUENCE_RETRY, DEFAULT_TIMEOUT);
for(tracker.reset(); tracker.shouldRetry() && !serviceStatus.isAvailable(); tracker.nextAttempt()) {
String seleniumTestFilename = getGroovyFilename( parameters );
try {
Map<String, Number> responseTimes = new HashMap<String, Number>();
responseTimes.put("response-time", Double.NaN);
tracker.startAttempt();
Result result = runTest( getBaseUrl(parameters, svc), getTimeout(parameters), createGroovyClass( seleniumTestFilename ) );
double responseTime = tracker.elapsedTimeInMillis();
responseTimes.put("response-time", responseTime);
if(result.wasSuccessful()) {
serviceStatus = PollStatus.available();
serviceStatus.setProperties(responseTimes);
}else {
serviceStatus = PollStatus.unavailable( getFailureMessage( result, svc ));
}
} catch (CompilationFailedException e) {
serviceStatus = PollStatus.unavailable("Selenium page sequence attempt on:" + svc.getIpAddr() + " failed : selenium-test compilation error " + e.getMessage());
logDown(Level.DEBUG, "Selenium sequence failed: CompilationFailedException" + e.getMessage());
} catch (IOException e) {
serviceStatus = PollStatus.unavailable("Selenium page sequence attempt on " + svc.getIpAddr() + " failed: IOException occurred, failed to find selenium-test: " + seleniumTestFilename);
logDown(Level.DEBUG, "Selenium sequence failed: IOException: " + e.getMessage());
} catch (Exception e) {
serviceStatus = PollStatus.unavailable("Selenium page sequence attempt on " + svc.getIpAddr() + " failed:\n" + e.getMessage());
logDown(Level.DEBUG, "Selenium sequence failed: Exception: " + e.getMessage());
}
}
return serviceStatus;
}
private int getTimeout(Map<String, Object> parameters) {
if(parameters.containsKey("timeout")) {
return Integer.parseInt("" + parameters.get("timeout"));
}else {
return 3;
}
}
private String getBaseUrl(Map<String, Object> parameters, MonitoredService svc)
{
if(parameters.containsKey("base-url")) {
String baseUrl = (String) parameters.get("base-url");
if(!baseUrl.contains("http")) {
baseUrl = "http://" + baseUrl;
}
if(baseUrl.contains("${ipAddr}")) {
baseUrl = BaseUrlUtils.replaceIpAddr(baseUrl, svc.getIpAddr());
}
if(parameters.containsKey("port")) {
String port = (String) parameters.get("port");
baseUrl = baseUrl + ":" + port;
}
return baseUrl;
}else {
return null;
}
}
private String getFailureMessage(Result result, MonitoredService svc)
{
StringBuffer stringBuilder = new StringBuffer();
stringBuilder.append("Failed: ");
for(Failure failure : result.getFailures()) {
stringBuilder.append(" " + failure.getMessage() + "\n");
}
logDown(Level.DEBUG, "Selenium sequence failed: " + stringBuilder.toString());
return stringBuilder.toString();
}
private Result runTest(String baseUrl, int timeoutInSeconds, Class<?> clazz)
{
return JUnitCore.runClasses(new SeleniumComputer(baseUrl, timeoutInSeconds), clazz);
}
private String getGroovyFilename(Map<String, Object> parameters)
{
if(parameters.containsKey("selenium-test")) {
return (String) parameters.get("selenium-test");
}else {
return "";
}
}
private Class<?> createGroovyClass(String filename) throws CompilationFailedException, IOException
{
GroovyClassLoader gcl = new GroovyClassLoader();
String file = System.getProperty("opennms.home") + "/etc/selenium/" + filename;
System.err.println("File name: " + file);
return gcl.parseClass( new File( file ) );
}
}