All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.airlift.http.server.JettyWebServer Maven / Gradle / Ivy

There is a newer version: 0.0.6
Show newest version
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