Package com.elastisys.scale.commons.server

Source Code of com.elastisys.scale.commons.server.BaseServerBuilder

package com.elastisys.scale.commons.server;

import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.util.ssl.SslContextFactory;

import com.elastisys.scale.commons.net.ssl.KeyStoreType;

/**
* A flexible Builder for creating embedded HTTP(S) {@link Server}s with a range
* of possible configuration combinations.
* <p/>
* The created {@link Server} can be considered a "base server", without any
* registered request {@link Handler}s. Any request handlers need to be added by
* the client.
*
*
*
*/
public class BaseServerBuilder {

  /**
   * The {@link Server}'s HTTP listen port. May be <code>null</code>, in which
   * case the server won't listen to HTTP requests.
   */
  private Integer httpPort = null;
  /**
   * The {@link Server}'s HTTPS listen port. May be <code>null</code>, in
   * which case the server won't listen to HTTPS requests. <i>Note: setting a
   * HTTPS port requires an SSL key store to be set for server
   * authentication.</i>
   */
  private Integer httpsPort = null;

  /**
   * File system path or URI to a SSL key store, which stores the server's SSL
   * certificate that it will use to authenticate to clients. <i>Note: this
   * option is only relevant for {@link Server}s with an HTTPS port.</i>
   */
  private String sslKeyStorePath = null;

  /**
   * The type of the SSL key store. Defaults to {@link KeyStoreType#PKCS12}.
   * <i>Note: this option is only relevant for {@link Server}s with an HTTPS
   * port.</i>
   */
  private KeyStoreType sslKeyStoreType = KeyStoreType.PKCS12;

  /**
   * Password used to protect SSL key store. <i>Note: this option is only
   * relevant for HTTPS {@link Server}s with an HTTPS port.</i>
   */
  private String sslKeyStorePassword = null;

  /**
   * The password (if any) used to protect the specific server key within the
   * key store. <i>Note: this option is only relevant for {@link Server}s with
   * an HTTPS port.</i>
   */
  private String sslKeyPassword = null;

  /**
   * File system path or URI to SSL trust store, which stores trusted client
   * certificates. <i>Note: this option is only relevant for {@link Server}s
   * with an HTTPS port that require client certificate authentication.</i>
   */
  private String sslTrustStorePath = null;
  /**
   * The type of the SSL trust store. Defaults to {@link KeyStoreType#JKS}.
   * <i>Note: this option is only relevant for {@link Server}s with an HTTPS
   * port that require client certificate authentication.</i>
   */
  private KeyStoreType sslTrustStoreType = KeyStoreType.JKS;
  /**
   * Password used to protect the SSL trust store. <i>Note: this option is
   * only relevant for {@link Server}s with an HTTPS port that require client
   * certificate authentication.</i>
   */
  private String sslTrustStorePassword = null;
  /**
   * If set to <code>true</code>, requires SSL clients to authenticate with a
   * certificate. <i>Note: this option is only relevant for {@link Server}s
   * with an HTTPS port. If set, a trust store with trusted client
   * certificates should be configured for the {@link Server}.</i>
   */
  private boolean sslRequireClientCert = false;

  protected BaseServerBuilder() {
  }

  /**
   * Creates a new {@link BaseServerBuilder}.
   *
   * @return
   */
  public static BaseServerBuilder create() {
    return new BaseServerBuilder();
  }

  /**
   * Builds a {@link Server} object from the parameters passed to the
   * {@link BaseServerBuilder}.
   *
   * @return
   */
  public Server build() {
    Server server = new Server();

    // set up HTTP connector
    if (this.httpPort != null) {
      HttpConfiguration httpConfig = new HttpConfiguration();
      if (this.httpsPort != null) {
        httpConfig.setSecureScheme("https");
        // set redirect port for those pages requiring confidential
        // (SSL) access
        httpConfig.setSecurePort(this.httpsPort);
      }
      httpConfig.setOutputBufferSize(32768);
      ServerConnector http = new ServerConnector(server,
          new HttpConnectionFactory(httpConfig));
      http.setPort(this.httpPort);

      server.addConnector(http);
    }

    // set up HTTPS connector with SSL key store (and optionally a trust
    // store)
    if (this.httpsPort != null) {
      checkArgument(this.sslKeyStoreType != null,
          "https configuration missing key store type is null");
      checkArgument(this.sslKeyStorePath != null,
          "https configuration missing SSL key store path");
      checkArgument(this.sslKeyStorePassword != null,
          "https configuration missing SSL key store password");

      SslContextFactory sslContextFactory = new SslContextFactory();
      sslContextFactory.setKeyStoreType(this.sslKeyStoreType.name());
      sslContextFactory.setKeyStorePath(this.sslKeyStorePath);
      sslContextFactory.setKeyStorePassword(this.sslKeyStorePassword);
      if (this.sslKeyPassword != null) {
        sslContextFactory.setKeyManagerPassword(this.sslKeyPassword);
      } else {
        sslContextFactory
            .setKeyManagerPassword(this.sslKeyStorePassword);
      }

      if (this.sslTrustStorePath != null) {
        checkArgument(this.sslTrustStoreType != null,
            "missing trust store type for trust store");
        checkArgument(this.sslTrustStorePassword != null,
            "missing password for trust store");

        sslContextFactory.setTrustStoreType(this.sslTrustStoreType
            .name());
        sslContextFactory.setTrustStorePath(this.sslTrustStorePath);
        sslContextFactory
            .setTrustStorePassword(this.sslTrustStorePassword);
      }
      if (this.sslRequireClientCert) {
        checkArgument(this.sslTrustStorePath != null,
            "Client certificate authentication specified without "
                + "specifying a trust store");
        checkArgument(this.sslTrustStorePassword != null,
            "Client certificate authentication specified without "
                + "specifying a trust store password");
      }
      // if true: requires client to authenticate with certificate
      sslContextFactory.setNeedClientAuth(this.sslRequireClientCert);
      // if true: authenticates client certificate if provided
      sslContextFactory.setWantClientAuth(false);

      // HTTPS config
      HttpConfiguration httpsConfig = new HttpConfiguration();
      httpsConfig.addCustomizer(new SecureRequestCustomizer());
      httpsConfig.setOutputBufferSize(32768);
      // HTTPS connector
      ServerConnector https = new ServerConnector(server,
          new SslConnectionFactory(sslContextFactory, "http/1.1"),
          new HttpConnectionFactory(httpsConfig));
      https.setPort(this.httpsPort);

      server.addConnector(https);
    }

    return server;
  }

  /**
   * Set the {@link Server}'s HTTP listen port. May be <code>null</code>, in
   * which case the server won't listen to HTTP requests.
   *
   * @param port
   * @return
   */
  public BaseServerBuilder httpPort(Integer port) {
    this.httpPort = port;
    return this;
  }

  /**
   * Set the {@link Server}'s HTTPS listen port. May be <code>null</code>, in
   * which case the server won't listen to HTTPS requests. <i>Note: setting a
   * HTTPS port requires an SSL key store to be set for server
   * authentication.</i>
   *
   * @param port
   * @return
   */
  public BaseServerBuilder httpsPort(Integer port) {
    this.httpsPort = port;
    return this;
  }

  /**
   * Set a file system path or URI to a SSL key store, which stores the
   * server's SSL certificate that it will use to authenticate to clients.
   * <i>Note: this option is only relevant for {@link Server}s with an HTTPS
   * port.</i>
   *
   * @param pathOrUri
   * @return
   */
  public BaseServerBuilder sslKeyStorePath(String pathOrUri) {
    this.sslKeyStorePath = pathOrUri;
    return this;
  }

  /**
   * Set the type of the SSL key store. Defaults to
   * {@link KeyStoreType#PKCS12}. <i>Note: this option is only relevant for
   * {@link Server}s with an HTTPS port.</i>
   *
   * @param type
   * @return
   */
  public BaseServerBuilder sslKeyStoreType(KeyStoreType type) {
    this.sslKeyStoreType = type;
    return this;
  }

  /**
   * Set the password used to protect SSL key store. <i>Note: this option is
   * only relevant for HTTPS {@link Server}s with an HTTPS port.</i>
   *
   * @param password
   * @return
   */
  public BaseServerBuilder sslKeyStorePassword(String password) {
    this.sslKeyStorePassword = password;
    return this;
  }

  /**
   * Set the password (if any) used to protect the specific server key within
   * the key store. <i>Note: this option is only relevant for {@link Server}s
   * with an HTTPS port.</i>
   *
   * @param password
   * @return
   */
  public BaseServerBuilder sslKeyPassword(String password) {
    this.sslKeyPassword = password;
    return this;
  }

  /**
   * Set the file system path or URI to the SSL trust store, which stores
   * trusted client certificates. <i>Note: this option is only relevant for
   * {@link Server}s with an HTTPS port that require client certificate
   * authentication.</i>
   *
   * @param pathOrUri
   * @return
   */
  public BaseServerBuilder sslTrustStorePath(String pathOrUri) {
    this.sslTrustStorePath = pathOrUri;
    return this;
  }

  /**
   * Set the type of the SSL trust store. Defaults to {@link KeyStoreType#JKS}
   * . <i>Note: this option is only relevant for {@link Server}s with an HTTPS
   * port that require client certificate authentication.</i>
   *
   * @param type
   * @return
   */
  public BaseServerBuilder sslTrustStoreType(KeyStoreType type) {
    this.sslTrustStoreType = type;
    return this;
  }

  /**
   * Set the password used to protect the SSL trust store. <i>Note: this
   * option is only relevant for {@link Server}s with an HTTPS port that
   * require client certificate authentication.</i>
   *
   * @param password
   * @return
   */
  public BaseServerBuilder sslTrustStorePassword(String password) {
    this.sslTrustStorePassword = password;
    return this;
  }

  /**
   * If set to <code>true</code>, requires SSL clients to authenticate with a
   * certificate.
   *
   * @param requireCertAuthentication
   * @return
   */
  public BaseServerBuilder sslRequireClientCert(
      boolean requireCertAuthentication) {
    this.sslRequireClientCert = requireCertAuthentication;
    return this;
  }

  /**
   * Ensures the truth of an expression involving one or more parameters to
   * the calling method.
   *
   * @param expression
   *            a boolean expression
   * @param errorMessage
   *            the exception message to use if the check fails; will be
   *            converted to a string using {@link String#valueOf(Object)}
   * @throws IllegalArgumentException
   *             if {@code expression} is false
   */
  static void checkArgument(boolean expression, Object errorMessage) {
    if (!expression) {
      throw new IllegalArgumentException(String.valueOf(errorMessage));
    }
  }
}
TOP

Related Classes of com.elastisys.scale.commons.server.BaseServerBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.