Package com.twosigma.beaker.core

Source Code of com.twosigma.beaker.core.Main

/*
*  Copyright 2014 TWO SIGMA OPEN SOURCE, LLC
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*         http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.twosigma.beaker.core;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.twosigma.beaker.shared.module.GuiceCometdModule;
import com.twosigma.beaker.core.module.SerializerModule;
import com.twosigma.beaker.core.module.URLConfigModule;
import com.twosigma.beaker.core.module.WebServerModule;
import com.twosigma.beaker.core.module.config.DefaultBeakerConfigModule;
import com.twosigma.beaker.core.module.config.BeakerConfig;
import com.twosigma.beaker.core.module.config.BeakerConfigPref;
import com.twosigma.beaker.core.rest.PluginServiceLocatorRest;
import com.twosigma.beaker.shared.module.util.GeneralUtils;
import com.twosigma.beaker.shared.module.util.GeneralUtilsModule;
import com.twosigma.beaker.shared.module.config.DefaultWebServerConfigModule;
import com.twosigma.beaker.shared.module.config.WebAppConfigPref;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.eclipse.jetty.server.Server;

/**
* In the main function, create modules and perform initialization.
*/
public class Main {

  private static final Logger GuiceComponentProviderFactoryLogger =
          Logger.getLogger(com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory.class.getName());
  private static final Logger WebApplicationImplLogger =
          Logger.getLogger(com.sun.jersey.server.impl.application.WebApplicationImpl.class.getName());
  private static final Logger JerseyLogger = Logger.getLogger("com.sun.jersey");

  static {
    GuiceComponentProviderFactoryLogger.setLevel(Level.WARNING);
    WebApplicationImplLogger.setLevel(Level.WARNING);
    JerseyLogger.setLevel(Level.OFF);
  }

  private static final Integer PORT_BASE_START_DEFAULT = 8800;
  private static final Boolean OPEN_BROWSER_DEFAULT = Boolean.TRUE;
  private static final Boolean USE_HTTPS_DEFAULT = Boolean.FALSE;
  private static final Boolean PUBLIC_SERVER_DEFAULT = Boolean.FALSE;
  private static final Boolean NO_PASSWORD_DEFAULT = Boolean.FALSE;
  private static final Boolean USE_KERBEROS_DEFAULT = Boolean.FALSE;
  private static final Integer CLEAR_PORT_OFFSET = 1;
  private static final Integer BEAKER_SERVER_PORT_OFFSET = 2;

  private static CommandLine parseCommandLine(String[] args)
    throws ParseException
  {
    CommandLineParser parser = new GnuParser();
    Options opts = new Options();
    opts.addOption("h", "help", false, "print this message");
    opts.addOption(null, "disable-kerberos", false, "do not require kerberos authentication");
    opts.addOption(null, "open-browser", true, "open a web browser connected to the Beaker server");
    opts.addOption(null, "port-base", true, "main port number to use, other ports are allocated starting here");
    opts.addOption(null, "default-notebook", true, "file name to find default notebook");
    opts.addOption(null, "plugin-option", true, "pass option on to plugin");
    opts.addOption(null, "public-server", false, "allow connections from external computers");
    opts.addOption(null, "no-password", false, "do not require a password from external connections " +
                   "(warning: for advanced users only!)");
    CommandLine line = parser.parse(opts, args);
    if (line.hasOption("help")) {
      new HelpFormatter().printHelp("beaker.command", opts);
      System.exit(0);
    }
    return line;
  }

  private static boolean parseBoolean(String arg) {
    switch (arg.toLowerCase()) {
      case "true":
      case "t":
      case "yes":
      case "y":
        return true;
      case "false":
      case "f":
      case "no":
      case "n":
        return false;
      default:
        throw new RuntimeException("unrecognized boolean command line argument: " + arg);
    }
  }

  private static Map<String, String> getPluginOptions(CommandLine options) {
    Map<String, String> result = new HashMap<>();
    if (options.hasOption("plugin-option")) {
      for (String param: options.getOptionValues("plugin-option")) {
        int x = param.indexOf(':');
        if (x < 0) {
          throw new RuntimeException("plugin option requires colon (':')");
        }
        result.put(param.substring(0, x), param.substring(x + 1, param.length()));
      }
    }
    return result;
  }

  public static void main(String[] args) throws Exception {
    CommandLine options = parseCommandLine(args);

    final Integer portBase = options.hasOption("port-base") ?
      Integer.parseInt(options.getOptionValue("port-base")) : findPortBase(PORT_BASE_START_DEFAULT);
    final Boolean useKerberos = options.hasOption("disable-kerberos") ?
      !parseBoolean(options.getOptionValue("disable-kerberos")) : USE_KERBEROS_DEFAULT;
    final Boolean openBrowser = options.hasOption("open-browser") ?
      parseBoolean(options.getOptionValue("open-browser")) : OPEN_BROWSER_DEFAULT;
    final Boolean useHttps = options.hasOption("use-https") ?
      parseBoolean(options.getOptionValue("use-https")) : USE_HTTPS_DEFAULT;
    final Boolean publicServer = options.hasOption("public-server");

    // create preferences for beaker core from cli options and others
    // to be used by BeakerCoreConfigModule to initialize its config
    BeakerConfigPref beakerCorePref = createBeakerCoreConfigPref(
        useKerberos,
        publicServer,
        false,
        portBase,
        options.getOptionValue("default-notebook"),
        getPluginOptions(options));

    WebAppConfigPref webAppPref = createWebAppConfigPref(
        portBase + BEAKER_SERVER_PORT_OFFSET,
        System.getProperty("user.dir") + "/src/main/web");

    Injector injector = Guice.createInjector(
        new DefaultBeakerConfigModule(beakerCorePref),
        new DefaultWebServerConfigModule(webAppPref),
        new GeneralUtilsModule(),
        new WebServerModule(),
        new URLConfigModule(),
        new SerializerModule(),
        new GuiceCometdModule());

    PluginServiceLocatorRest processStarter = injector.getInstance(PluginServiceLocatorRest.class);
    processStarter.start();

    BeakerConfig bkConfig = injector.getInstance(BeakerConfig.class);

    Server server = injector.getInstance(Server.class);
    server.start();

    // openBrower and show connection instruction message
    final String initUrl = bkConfig.getBaseURL();
    if (openBrowser) {
      injector.getInstance(GeneralUtils.class).openUrl(initUrl);
      System.out.println("\nConnecting to " + initUrl);
    } else {
      System.out.println("\nConnect to " + initUrl);
    }
    if (publicServer) {
      System.out.println("Submit this password: " + bkConfig.getPassword());
    }
    System.out.println("");
  }

  private static BeakerConfigPref createBeakerCoreConfigPref(
      final Boolean useKerberos,
      final Boolean publicServer,
      final Boolean noPasswordAllowed,
      final Integer portBase,
      final String defaultNotebookUrl,
      final Map<String, String> pluginOptions) {
    return new BeakerConfigPref() {

      @Override
      public Boolean getUseKerberos() {
        return useKerberos;
      }

      @Override
      public Integer getPortBase() {
        return portBase;
      }

      @Override
      public Boolean getPublicServer() {
        return publicServer;
      }

      @Override
      public Boolean getNoPasswordAllowed() {
        return noPasswordAllowed;
      }

      @Override
      public String getDefaultNotebookUrl() {
        return defaultNotebookUrl;
      }

      @Override
      public Map<String, String> getPluginOptions() {
        return pluginOptions;
      }
    };
  }

  private static WebAppConfigPref createWebAppConfigPref(final Integer port, final String staticDir) {
    return new WebAppConfigPref() {
      @Override
      public Integer getPort() {
        return port;
      }

      @Override
      public String getStaticDirectory() {
        return staticDir;
      }
    };
  }

  private static int findPortBase(Integer start) {
    int width = 4;
    int tries = 0;
    int base = start.intValue();
    while (!portRangeAvailable(base, width)) {
      System.out.println("Port range " + base + "-" + (base + width - 1) + " taken, searching...");
      base += width;
      if (tries++ > 10) {
        System.err.println("can't find open port.");
        System.exit(1);
      }
    }
    return base;
  }

  private static boolean portAvailable(int port) {

    ServerSocket ss = null;
    try {
      InetAddress address = InetAddress.getByName("127.0.0.1");
      ss = new ServerSocket(port, 1, address);
      ss.setReuseAddress(true);
      return true;
    } catch (IOException e) {
    } finally {
      if (ss != null) {
        try {
          ss.close();
        } catch (IOException e) {
          /* should not be thrown */
        }
      }
    }

    return false;
  }

  private static boolean portRangeAvailable(int port, int width) {
    for (int p = port; p < port + width; p++) {
      if (!portAvailable(p)) {
        return false;
      }
    }
    return true;
  }
}
TOP

Related Classes of com.twosigma.beaker.core.Main

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.