package com.comandante.stickypunch.http;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.sun.jersey.api.core.PackagesResourceConfig;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import com.yammer.metrics.jetty.InstrumentedHandler;
import com.yammer.metrics.jetty.InstrumentedQueuedThreadPool;
import com.yammer.metrics.jetty.InstrumentedSelectChannelConnector;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.NCSARequestLog;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.server.handler.StatisticsHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import java.lang.management.ManagementFactory;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class JettyService {
private static final String STICKYPUNCH_RESOURCE = "com.comandante.stickypunch.http.resource";
private static final String INJECT_JERSEY_PACKAGE = "com.comandante.stickypunch.http.inject";
public static Server create(HttpConfiguration configuration) throws Exception {
Server server = new Server();
SelectChannelConnector connector = new InstrumentedSelectChannelConnector(configuration.listenAddress.getPort());
connector.setHost(configuration.listenAddress.getHostName());
QueuedThreadPool queuedThreadPool = new InstrumentedQueuedThreadPool();
queuedThreadPool.setMaxThreads(configuration.numHttpWorkers);
connector.setThreadPool(queuedThreadPool);
queuedThreadPool.start();
server.setConnectors(new Connector[]{connector});
server.setSendServerVersion(true);
server.setSendDateHeader(true);
server.setStopAtShutdown(true);
server.setGracefulShutdown((int) TimeUnit.SECONDS.toMillis(5));
ServletContextHandler root = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
root.setContextPath("/");
server.setHandler(new InstrumentedHandler(root));
// Jersey
root.addServlet(buildJerseyServlet(), "/*");
NCSARequestLog requestLog = new NCSARequestLog(configuration.httpLogFileName);
requestLog.setRetainDays(90);
requestLog.setAppend(true);
requestLog.setExtended(true);
requestLog.setLogTimeZone("GMT");
requestLog.setLogLatency(true);
requestLog.setLogDispatch(true);
RequestLogHandler requestLogHandler = new RequestLogHandler();
requestLogHandler.setRequestLog(requestLog);
root.setHandler(requestLogHandler);
connector.setStatsOn(true);
StatisticsHandler statisticsHandler = new StatisticsHandler();
statisticsHandler.setServer(server);
requestLogHandler.setHandler(statisticsHandler);
// Setup JMX
MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
server.getContainer().addEventListener(mbContainer);
mbContainer.addBean(statisticsHandler);
return server;
}
private static ServletHolder buildJerseyServlet() {
Set<String> jerseyPackages = Sets.newHashSet();
jerseyPackages.add(STICKYPUNCH_RESOURCE);
jerseyPackages.add(INJECT_JERSEY_PACKAGE);
ImmutableMap.Builder<String, Object> propsBuilder = ImmutableMap.builder();
propsBuilder.put(PackagesResourceConfig.PROPERTY_PACKAGES, jerseyPackages.toArray(new String[jerseyPackages.size()]));
PackagesResourceConfig jerseyResourceConfig = new PackagesResourceConfig(propsBuilder.build());
return new ServletHolder(new ServletContainer(jerseyResourceConfig));
}
}