public synchronized void run()

in hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java [238:401]


  public synchronized void run() throws Exception {
    Pair<FilterHolder, Class<? extends ServletContainer>> pair =
      loginServerPrincipal(userProvider, conf);
    FilterHolder authFilter = pair.getFirst();
    Class<? extends ServletContainer> containerClass = pair.getSecond();
    RESTServlet servlet = RESTServlet.getInstance(conf, userProvider);

    // set up the Jersey servlet container for Jetty
    ResourceConfig application = new ResourceConfig().packages("org.apache.hadoop.hbase.rest")
      .register(JacksonJaxbJsonProvider.class);
    // Using our custom ServletContainer is tremendously important. This is what makes sure the
    // UGI.doAs() is done for the remoteUser, and calls are not made as the REST server itself.
    ServletContainer servletContainer = ReflectionUtils.newInstance(containerClass, application);
    ServletHolder sh = new ServletHolder(servletContainer);

    // Set the default max thread number to 100 to limit
    // the number of concurrent requests so that REST server doesn't OOM easily.
    // Jetty set the default max thread number to 250, if we don't set it.
    //
    // Our default min thread number 2 is the same as that used by Jetty.
    int maxThreads = servlet.getConfiguration().getInt(REST_THREAD_POOL_THREADS_MAX, 100);
    int minThreads = servlet.getConfiguration().getInt(REST_THREAD_POOL_THREADS_MIN, 2);
    // Use the default queue (unbounded with Jetty 9.3) if the queue size is negative, otherwise use
    // bounded {@link ArrayBlockingQueue} with the given size
    int queueSize = servlet.getConfiguration().getInt(REST_THREAD_POOL_TASK_QUEUE_SIZE, -1);
    int idleTimeout =
      servlet.getConfiguration().getInt(REST_THREAD_POOL_THREAD_IDLE_TIMEOUT, 60000);
    QueuedThreadPool threadPool = queueSize > 0
      ? new QueuedThreadPool(maxThreads, minThreads, idleTimeout,
        new ArrayBlockingQueue<>(queueSize))
      : new QueuedThreadPool(maxThreads, minThreads, idleTimeout);

    this.server = new Server(threadPool);

    // Setup JMX
    MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
    server.addEventListener(mbContainer);
    server.addBean(mbContainer);

    String host = servlet.getConfiguration().get("hbase.rest.host", "0.0.0.0");
    int servicePort = servlet.getConfiguration().getInt("hbase.rest.port", 8080);
    int httpHeaderCacheSize =
      servlet.getConfiguration().getInt(HTTP_HEADER_CACHE_SIZE, DEFAULT_HTTP_HEADER_CACHE_SIZE);
    HttpConfiguration httpConfig = new HttpConfiguration();
    httpConfig.setSecureScheme("https");
    httpConfig.setSecurePort(servicePort);
    httpConfig.setHeaderCacheSize(httpHeaderCacheSize);
    httpConfig.setRequestHeaderSize(DEFAULT_HTTP_MAX_HEADER_SIZE);
    httpConfig.setResponseHeaderSize(DEFAULT_HTTP_MAX_HEADER_SIZE);
    httpConfig.setSendServerVersion(false);
    httpConfig.setSendDateHeader(false);

    ServerConnector serverConnector;
    boolean isSecure = false;
    if (conf.getBoolean(REST_SSL_ENABLED, false)) {
      isSecure = true;
      HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
      httpsConfig.addCustomizer(new SecureRequestCustomizer());

      SslContextFactory.Server sslCtxFactory = new SslContextFactory.Server();
      String keystore = conf.get(REST_SSL_KEYSTORE_STORE);
      String keystoreType = conf.get(REST_SSL_KEYSTORE_TYPE);
      String password = HBaseConfiguration.getPassword(conf, REST_SSL_KEYSTORE_PASSWORD, null);
      String keyPassword =
        HBaseConfiguration.getPassword(conf, REST_SSL_KEYSTORE_KEYPASSWORD, password);
      sslCtxFactory.setKeyStorePath(keystore);
      if (StringUtils.isNotBlank(keystoreType)) {
        sslCtxFactory.setKeyStoreType(keystoreType);
      }
      sslCtxFactory.setKeyStorePassword(password);
      sslCtxFactory.setKeyManagerPassword(keyPassword);

      String trustStore = conf.get(REST_SSL_TRUSTSTORE_STORE);
      if (StringUtils.isNotBlank(trustStore)) {
        sslCtxFactory.setTrustStorePath(trustStore);
      }
      String trustStorePassword =
        HBaseConfiguration.getPassword(conf, REST_SSL_TRUSTSTORE_PASSWORD, null);
      if (StringUtils.isNotBlank(trustStorePassword)) {
        sslCtxFactory.setTrustStorePassword(trustStorePassword);
      }
      String trustStoreType = conf.get(REST_SSL_TRUSTSTORE_TYPE);
      if (StringUtils.isNotBlank(trustStoreType)) {
        sslCtxFactory.setTrustStoreType(trustStoreType);
      }

      String[] excludeCiphers = servlet.getConfiguration()
        .getStrings(REST_SSL_EXCLUDE_CIPHER_SUITES, ArrayUtils.EMPTY_STRING_ARRAY);
      if (excludeCiphers.length != 0) {
        sslCtxFactory.setExcludeCipherSuites(excludeCiphers);
      }
      String[] includeCiphers = servlet.getConfiguration()
        .getStrings(REST_SSL_INCLUDE_CIPHER_SUITES, ArrayUtils.EMPTY_STRING_ARRAY);
      if (includeCiphers.length != 0) {
        sslCtxFactory.setIncludeCipherSuites(includeCiphers);
      }

      String[] excludeProtocols = servlet.getConfiguration().getStrings(REST_SSL_EXCLUDE_PROTOCOLS,
        ArrayUtils.EMPTY_STRING_ARRAY);
      if (excludeProtocols.length != 0) {
        sslCtxFactory.setExcludeProtocols(excludeProtocols);
      }
      String[] includeProtocols = servlet.getConfiguration().getStrings(REST_SSL_INCLUDE_PROTOCOLS,
        ArrayUtils.EMPTY_STRING_ARRAY);
      if (includeProtocols.length != 0) {
        sslCtxFactory.setIncludeProtocols(includeProtocols);
      }

      serverConnector = new ServerConnector(server,
        new SslConnectionFactory(sslCtxFactory, HttpVersion.HTTP_1_1.toString()),
        new HttpConnectionFactory(httpsConfig));
    } else {
      serverConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
    }

    int acceptQueueSize = servlet.getConfiguration().getInt(REST_CONNECTOR_ACCEPT_QUEUE_SIZE, -1);
    if (acceptQueueSize >= 0) {
      serverConnector.setAcceptQueueSize(acceptQueueSize);
    }

    serverConnector.setPort(servicePort);
    serverConnector.setHost(host);

    server.addConnector(serverConnector);
    server.setStopAtShutdown(true);

    // set up context
    ServletContextHandler ctxHandler =
      new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
    ctxHandler.addServlet(sh, PATH_SPEC_ANY);
    if (authFilter != null) {
      ctxHandler.addFilter(authFilter, PATH_SPEC_ANY, EnumSet.of(DispatcherType.REQUEST));
    }

    // Load filters from configuration.
    String[] filterClasses =
      servlet.getConfiguration().getStrings(FILTER_CLASSES, GzipFilter.class.getName());
    for (String filter : filterClasses) {
      filter = filter.trim();
      ctxHandler.addFilter(filter, PATH_SPEC_ANY, EnumSet.of(DispatcherType.REQUEST));
    }
    addCSRFFilter(ctxHandler, conf);
    HttpServerUtil.addClickjackingPreventionFilter(ctxHandler, conf, PATH_SPEC_ANY);
    HttpServerUtil.addSecurityHeadersFilter(ctxHandler, conf, isSecure, PATH_SPEC_ANY);
    HttpServerUtil.constrainHttpMethods(ctxHandler, servlet.getConfiguration()
      .getBoolean(REST_HTTP_ALLOW_OPTIONS_METHOD, REST_HTTP_ALLOW_OPTIONS_METHOD_DEFAULT));

    // Put up info server.
    int port = conf.getInt("hbase.rest.info.port", 8085);
    if (port >= 0) {
      final long startCode = EnvironmentEdgeManager.currentTime();
      conf.setLong("startcode", startCode);
      this.serverName = ServerName.valueOf(getHostName(conf), servicePort, startCode);

      String addr = conf.get("hbase.rest.info.bindAddress", "0.0.0.0");
      this.infoServer = new InfoServer(REST_SERVER, addr, port, false, conf);
      this.infoServer.addPrivilegedServlet("dump", "/dump", RESTDumpServlet.class);
      this.infoServer.setAttribute(REST_SERVER, this);
      this.infoServer.setAttribute("hbase.conf", conf);
      this.infoServer.start();
    }
    // start server
    server.start();
  }