
io.airlift.http.server.JettyWebServer Maven / Gradle / Ivy
package io.airlift.http.server;
import java.io.File;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.server.handler.StatisticsHandler;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.webapp.WebAppContext;
import com.google.common.base.Preconditions;
import io.airlift.http.server.helper.NCSARequestLogHandlerProvider;
import io.airlift.http.server.model.FilterDefinition;
import io.airlift.http.server.model.ServletDefinition;
import io.airlift.http.server.model.StaticResourceDefinition;
import io.airlift.http.server.model.WebServerDefinition;
// http://stackoverflow.com/questions/20043097/jetty-9-embedded-adding-handlers-during-runtime
/**
* @author dhanji (Dhanji R. Prasanna)
*/
public class JettyWebServer implements WebServer {
private static final StartListener NOOP = new StartListener() {
@Override
public void started() {}
};
private final Server server;
public JettyWebServer(WebServerDefinition webServerDefinition) {
this.server = build(webServerDefinition);
}
@Override
public void start() {
start(NOOP);
}
@Override
public void start(StartListener listener) {
start(listener, false);
}
@Override
public void startAndWait() {
startAndWait(NOOP);
}
@Override
public void startAndWait(StartListener listener) {
start(NOOP, true);
}
private synchronized void start(StartListener listener, boolean wait) {
Preconditions.checkArgument(listener != null);
try {
server.start();
printConfig();
listener.started();
if (wait) {
server.join();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void printConfig() {}
@Override
public synchronized void stop() {
try {
server.stop();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Server build(WebServerDefinition webServerDefinition) {
/**
* structure is:
*
* server |--- statistics handler |--- context handler | |--- trace token filter | |--- gzip
* response filter | |--- gzip request filter | |--- security handler | |--- user provided
* filters | |--- the servlet (normally GuiceContainer) | |--- resource handlers |--- log
* handler |-- admin context handler \ --- the admin servlet
*/
QueuedThreadPool threadPool = new QueuedThreadPool(webServerDefinition.getMaxThreads());
threadPool.setMinThreads(webServerDefinition.getMinThreads());
// threadPool.setIdleTimeout(Ints.checkedCast(config.getThreadMaxIdleTime().toMillis()));
threadPool.setName("http-worker");
Server server = new Server(threadPool);
HttpConfiguration httpConfiguration = new HttpConfiguration();
httpConfiguration.setSendServerVersion(false);
httpConfiguration.setSendXPoweredBy(false);
ServerConnector httpConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfiguration));
httpConnector.setName("http");
httpConnector.setPort(webServerDefinition.getPort());
// httpConnector.setIdleTimeout(config.getNetworkMaxIdleTime().toMillis());
// httpConnector.setHost(nodeInfo.getBindIp().getHostAddress());
server.addConnector(httpConnector);
HandlerCollection handlerCollection = new HandlerCollection();
//
// Static resources
//
for (StaticResourceDefinition definition : webServerDefinition.getStaticContentDefinitions()) {
String[] welcomeFiles = definition.getWelcomeFiles().toArray(new String[definition.getWelcomeFiles().size()]);
File fileResourcePath = new File(definition.getResource());
if (fileResourcePath.exists()) {
handlerCollection.addHandler(fileResourceHandler(definition));
} else {
handlerCollection.addHandler(classpathResourceHandler(definition.getPath(), definition.getResource(), welcomeFiles));
}
}
ServletContextHandler applicationContext = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
// TODO: need to set the path
construct(webServerDefinition, applicationContext);
handlerCollection.addHandler(applicationContext);
handlerCollection.addHandler(new NCSARequestLogHandlerProvider().get());
StatisticsHandler statisticsHandler = new StatisticsHandler();
statisticsHandler.setHandler(handlerCollection);
server.setHandler(statisticsHandler);
return server;
}
protected void construct(WebServerDefinition webServerDefinition, ServletContextHandler applicationContext) {
//
// Filters
//
for (FilterDefinition filterDefinition : webServerDefinition.getFilterDefintions()) {
applicationContext.addFilter(new FilterHolder(filterDefinition.getFilterClass()), filterDefinition.getPattern(), null);
}
//
// Servlets
//
for (ServletDefinition servletDefinition : webServerDefinition.getServletDefinitions()) {
if (servletDefinition.getWar() != null) {
WebAppContext webapp = new WebAppContext(applicationContext, servletDefinition.getWar().getAbsolutePath(), servletDefinition.getPattern());
} else if (servletDefinition.getServlet() != null) {
ServletHolder servletHolder = new ServletHolder(servletDefinition.getServlet());
applicationContext.addServlet(servletHolder, servletDefinition.getPattern());
} else {
ServletHolder servletHolder = new ServletHolder(servletDefinition.getServletClass());
servletHolder.setInitParameters(servletDefinition.getParameters());
applicationContext.addServlet(servletHolder, servletDefinition.getPattern());
}
}
}
private ContextHandler fileResourceHandler(StaticResourceDefinition definition) {
String[] welcomeFiles = definition.getWelcomeFiles().toArray(new String[definition.getWelcomeFiles().size()]);
ContextHandler contextHandler = new ContextHandler();
ResourceHandler resourceHandler = new ResourceHandler();
File css = new File(definition.getResource(), "jetty-dir.css");
if (css.exists()) {
resourceHandler.setStylesheet(css.getAbsolutePath());
}
resourceHandler.setDirectoriesListed(definition.isListing());
resourceHandler.setWelcomeFiles(welcomeFiles);
contextHandler.setBaseResource(Resource.newResource(new File(definition.getResource())));
contextHandler.setHandler(resourceHandler);
contextHandler.setContextPath(definition.getPath());
return contextHandler;
}
private ContextHandler classpathResourceHandler(String context, String path, String[] welcomeFiles) {
ContextHandler contextHandler = new ContextHandler();
ResourceHandler resourceHandler = new ResourceHandler();
resourceHandler.setDirectoriesListed(false);
resourceHandler.setWelcomeFiles(welcomeFiles);
Resource resourcesClasspath = Resource.newClassPathResource(path);
contextHandler.setBaseResource(resourcesClasspath);
contextHandler.setHandler(resourceHandler);
contextHandler.setContextPath(context);
return contextHandler;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy