package com.cloudera.util;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.BindException;
import java.net.InetSocketAddress;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.util.ReflectionUtils;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;
import org.mortbay.util.MultiException;
import com.google.common.base.Preconditions;
private Server webServer;
private SelectChannelConnector channelConnector;
private SslSocketConnector sslConnector;
private boolean findPort;
private WebAppContext webAppContext;
private static final Log LOG = LogFactory.getLog(StatusHttpServer.class
.getName());
int port, boolean findPort) throws IOException {
webServer = new org.mortbay.jetty.Server();
this.findPort = findPort;
channelConnector = new SelectChannelConnector();
channelConnector.setPort(port);
channelConnector.setHost(bindAddress);
webServer.addConnector(channelConnector);
String appDir = webAppsPath;
String webapp = new File(appDir, name).getAbsolutePath();
LOG.info("starting web app in directory: " + webapp);
webAppContext = new WebAppContext(webapp, "/");
webServer.setHandler(webAppContext);
addServlet("stacks", "/stacks", StackServlet.class);
}
webAppContext.setAttribute(name, value);
}
public <T
extends HttpServlet>
void addServlet(String name, String pathSpec,
Class<T> servletClass) {
WebAppContext context = webAppContext;
if (name == null) {
context.addServlet(pathSpec, servletClass.getName());
} else {
context.addServlet(servletClass, pathSpec);
}
}
return webAppContext.getAttribute(name);
}
return channelConnector.getPort();
}
String storPass, String keyPass) throws IOException {
if (sslConnector != null || webServer.isStarted()) {
throw new IOException("Failed to add ssl listener");
}
sslConnector = new SslSocketConnector();
sslConnector.setHost(addr.getHostName());
sslConnector.setPort(addr.getPort());
sslConnector.setKeystore(keystore);
sslConnector.setPassword(storPass);
sslConnector.setKeyPassword(keyPass);
webServer.addConnector(sslConnector);
}
public void start()
throws IOException {
try {
while (true) {
try {
webServer.start();
break;
} catch (MultiException ex) {
boolean needNewPort = false;
if (ex.size() == 1) {
Throwable sub = ex.getThrowable(0);
if (sub instanceof BindException) {
if (!findPort)
throw (BindException) sub;
needNewPort = true;
}
}
if (!needNewPort)
throw ex;
channelConnector.setPort(channelConnector.getPort() + 1);
}
}
} catch (IOException ie) {
throw ie;
} catch (Exception e) {
IOException ie = new IOException("Problem starting http server");
ie.initCause(e);
throw ie;
}
}
public void stop()
throws Exception {
webServer.stop();
}
private static final long serialVersionUID = -6284183679759467039L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
OutputStream outStream = response.getOutputStream();
ReflectionUtils.printThreadInfo(new PrintWriter(outStream), "");
outStream.close();
ReflectionUtils.logThreadInfo(LOG, "jsp requested", 1);
}
}
public static void main(String[] argv) {
Preconditions.checkArgument(argv.length == 3);
String name = argv[0];
String path = argv[1];
int port = Integer.parseInt(argv[2]);
try {
StatusHttpServer http = new StatusHttpServer(name, path, "0.0.0.0", port,
false);
http.start();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}