package org.jboss.web.loadbalancer.monitor;
import java.io.IOException;
import java.util.ArrayList;
import javax.management.ObjectName;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.jboss.logging.Logger;
import org.jboss.mx.util.MBeanProxyExt;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.web.loadbalancer.scheduler.AbstractSchedulerMBean;
import org.jboss.web.loadbalancer.scheduler.Host;
import org.jboss.web.loadbalancer.util.Constants;
public abstract class AbstractMonitor
extends ServiceMBeanSupport
implements AbstractMonitorMBean, Runnable
{
protected boolean keepRunning = true;
protected long interval = 15000;
protected AbstractSchedulerMBean scheduler;
protected Logger log = Logger.getLogger(this.getClass());
protected ObjectName schedulerObjectName;
protected int timeout;
protected String path;
protected Thread monitorThread;
protected void startService() throws java.lang.Exception
{
scheduler = (AbstractSchedulerMBean)
MBeanProxyExt.create(AbstractSchedulerMBean.class,
schedulerObjectName);
this.setKeepRunning(true);
monitorThread = new Thread(this, "LoadbalancerMonitor");
monitorThread.setDaemon(true);
monitorThread.start();
}
protected void stopService() throws java.lang.Exception
{
this.setKeepRunning(false);
monitorThread.interrupt();
monitorThread.join();
}
protected void destroyService() throws java.lang.Exception
{
monitorThread = null;
}
protected abstract boolean checkHostStatus(HttpMethod method);
protected void monitorHosts()
{
ArrayList list = (ArrayList) scheduler.getHostsDown().clone();
for (int i = 0; i < list.size(); ++i)
{
Host checkHost = (Host) list.get(i);
if (checkHost.getState()==Constants.STATE_NODE_FORCED_DOWN)
{
log.debug("Ignoring Host "+checkHost+" because it is forced down");
continue;
}
if (checkHost(checkHost))
{
log.info("Host " + checkHost + " is up again - adding to up list");
checkHost.markNodeUp();
}
}
list = (ArrayList) scheduler.getHostsUp().clone();
for (int i = 0; i < list.size(); ++i)
{
Host checkHost = (Host) list.get(i);
if (checkHost.getState()==Constants.STATE_NODE_FORCED_DOWN)
{
log.debug("Ignoring Host "+checkHost+" because it is forced down");
continue;
}
if (!checkHost(checkHost))
{
log.error("Host " + checkHost + " is DOWN - adding to down list");
checkHost.markNodeDown();
}
}
}
protected boolean checkHost(Host host)
{
log.debug("Checking host " + host.getUrl() + path);
HttpClient httpClient = new HttpClient();
httpClient.setConnectionTimeout(this.getTimeout());
httpClient.setTimeout(this.getTimeout());
GetMethod method = new GetMethod(host.getUrl().toExternalForm() + path);
method.setFollowRedirects(false);
method.setDoAuthentication(false);
try
{
httpClient.executeMethod(method);
if (method.getStatusCode() >= HttpServletResponse.SC_BAD_REQUEST)
{
log.error("Server is up but sends error: " + method.getStatusLine());
return false;
}
return checkHostStatus(method);
}
catch (IOException ex)
{
log.error("Check for host " + host.getUrl() + " failed", ex);
return false;
}
finally
{
method.recycle();
}
}
public void run()
{
while (keepRunning)
{
try
{
Thread.sleep(interval);
monitorHosts();
}
catch (InterruptedException ex)
{
}
}
}
public boolean isKeepRunning()
{
return keepRunning;
}
public void setKeepRunning(boolean keepRunning)
{
this.keepRunning = keepRunning;
}
public void setPath(String path)
{
if (path.startsWith("/"))
{
this.path = path.substring(1);
}
else
{
this.path = path;
}
}
public String getPath()
{
return "/" + path;
}
public void setInterval(long interval)
{
this.interval = interval;
}
public long getInterval()
{
return interval;
}
public int getTimeout()
{
return timeout;
}
public void setTimeout(int timeout)
{
this.timeout = timeout;
}
public ObjectName getScheduler()
{
return schedulerObjectName;
}
public void setScheduler(ObjectName schedulerObjectName)
{
this.schedulerObjectName = schedulerObjectName;
}
}