Package com.twosigma.beaker.core.rest

Source Code of com.twosigma.beaker.core.rest.UtilRest

/*
*  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.rest;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.twosigma.beaker.core.module.config.BeakerConfig;
import com.twosigma.beaker.shared.module.util.GeneralUtils;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

/**
* RESTful API for general utilities
*/
@Path("util")
@Produces(MediaType.APPLICATION_JSON)
@Singleton
public class UtilRest {

  private final BeakerConfig bkConfig;
  private final GeneralUtils utils;

  @Inject
  public UtilRest(BeakerConfig bkConfig, GeneralUtils generalUtils) {
    this.bkConfig = bkConfig;
    this.utils = generalUtils;
    resetConfig();
  }

  @GET
  @Path("whoami")
  @Produces(MediaType.TEXT_PLAIN)
  public String whoami(@Context HttpServletRequest request) {
    return "\"" + System.getProperty("user.name") + "\"";
  }

  @GET
  @Path("getVersionInfo")
  @Produces(MediaType.APPLICATION_JSON)
  public String getVersionInfo(@Context HttpServletRequest request) {
    return "{\"buildTime\": \"" + this.bkConfig.getBuildTime() + "\","
        + " \"version\":\"" + this.bkConfig.getVersion() + "\"}";
  }

  @GET
  @Path("allStackTraces")
  public List<Map<String, Object>> getAllStackTraces() {
    List<Map<String, Object>> out = new ArrayList<>();
    Map<Thread, StackTraceElement[]> allStackTraces = Thread.getAllStackTraces();

    for (Thread t : allStackTraces.keySet()) {
      Map<String, Object> map = new HashMap<>();
      map.put("thread", t);
      map.put("stackTraces", allStackTraces.get(t));
      out.add(map);
    }

    return out;
  }

  private static String clean(String js) {
    // Remove slash-star comments. This regexp is not correct
    // since it removes comments that are in a string
    // constant. Should really parse. This is why we don't remove
    // double-slash comments, because they are likely to appear
    // (think http://). XXX
    js = js.replaceAll("/\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/", "");
    int i, j;
    String tripleQuote = "\"\"\"";
    while ((i = js.indexOf(tripleQuote)) > 0) {
      if ((j = js.indexOf(tripleQuote, i + 1)) < 0) {
        break;
      }
      String pre = js.substring(0, i);
      String lines = js.substring(i + 3, j);
      String post = js.substring(j + 3);
      lines = lines.replaceAll("\n", "\\\\n");
      js = pre + "\"" + lines + "\"" + post;
    }
    return js;
  }

  @GET
  @Path("getDefaultNotebook")
  @Produces(MediaType.TEXT_PLAIN)
  public String getDefaultNotebook() {
    final String defaultNotebookUrl = this.bkConfig.getDefaultNotebookUrl();

    // TODO, assume the url is a file path for now.
    java.nio.file.Path defaultNotebookFile = Paths.get(defaultNotebookUrl);
    String content = this.utils.readFile(defaultNotebookFile);
    if (content == null) {
      System.out.println("Warning, default notebook is empty");
      return "";
    }

    return clean(content);
  }

  /**
   * This function returns a Boolean setting as string. If the setting is null in the preference,
   * it will use the setting in the config, otherwise, what is set in preference is used.
   * @param settingsListName
   * @param configs
   * @param prefs
   * @return
   */
  private static String mergeBooleanSetting(
      String settingName,
      JSONObject configs,
      JSONObject prefs) {
      Boolean sc = (Boolean) configs.get(settingName);
      Boolean sp = (Boolean) prefs.get(settingName);
      Boolean s = (sp != null) ? sp : sc;
      String setting = null;
      if (s != null) {
        if (s.equals(Boolean.TRUE)) {
          setting = "true";
        } else if (s.equals(Boolean.FALSE)) {
          setting = "false";
        }
      }
      return setting;
  }

  /**
   * This function returns a list of settings from the result of merging setting gotten from
   * both the config and preference files and having to-remove items specified in the preference
   * file removed
   * @param settingsListName
   * @param configs
   * @param prefs
   * @return
   */
  private static final String TO_REMOVE_PREFIX = "remove--";
  private static Set<String> mergeListSetting(
      String settingsListName,
      JSONObject configs,
      JSONObject prefs) {
    Set<String> settings = new LinkedHashSet<>();
    Set<String> settingsToRemove = new HashSet<>();
    { // settings from config
      JSONArray s = (JSONArray) configs.get(settingsListName);
      if (s != null) {
        @SuppressWarnings("unchecked")
        Iterator<String> iterator = s.iterator();
        while (iterator.hasNext()) {
          settings.add(iterator.next());
        }
      }
    }
    { // settings from preference
      JSONArray s = (JSONArray) prefs.get(settingsListName);
      if (s != null) {
        @SuppressWarnings("unchecked")
        Iterator<String> iterator = s.iterator();
        while (iterator.hasNext()) {
          settings.add(iterator.next());
        }
      }
    }
    { // to-remove settings from preference
      JSONArray s = (JSONArray) prefs.get(TO_REMOVE_PREFIX + settingsListName);
      if (s != null) {
        @SuppressWarnings("unchecked")
        Iterator<String> iterator = s.iterator();
        while (iterator.hasNext()) {
          settingsToRemove.add(iterator.next());
        }
      }
    }
    settings.removeAll(settingsToRemove);
    return settings;
  }

  private void resetConfig() {
    final String configFileUrl = this.bkConfig.getConfigFileUrl();
    final String preferenceFileUrl = this.bkConfig.getPreferenceFileUrl();

    // TODO, assume the url is a file path for now.
    java.nio.file.Path configFile = Paths.get(configFileUrl);
    java.nio.file.Path preferenceFile = Paths.get(preferenceFileUrl);
    try {
      JSONParser parser = new JSONParser();
      JSONObject configJsonObject =
          (JSONObject) parser.parse(this.utils.readFile(configFile));
      JSONObject preferenceJsonObject =
          (JSONObject) parser.parse(this.utils.readFile(preferenceFile));

      String isAllowTracking = mergeBooleanSetting(
          "allow-anonymous-usage-tracking",
          configJsonObject,
          preferenceJsonObject);
      setAllowAnonymousTracking(isAllowTracking);

      String isUseAdvancedMode = mergeBooleanSetting(
          "advanced-mode",
          configJsonObject,
          preferenceJsonObject);
      setUseAdvancedMode(isUseAdvancedMode);

      this.initPlugins.addAll(
          mergeListSetting("init", configJsonObject, preferenceJsonObject));
      this.controlPanelMenuPlugins.addAll(
          mergeListSetting("control-panel-menu-plugins", configJsonObject, preferenceJsonObject));
      this.menuPlugins.addAll(
          mergeListSetting("notebook-app-menu-plugins", configJsonObject, preferenceJsonObject));
      this.cellMenuPlugins.addAll(
          mergeListSetting("notebook-cell-menu-plugins", configJsonObject, preferenceJsonObject));

    } catch (ParseException e) {
      throw new RuntimeException("failed getting beaker configurations from config file", e);
    }
  }

  private Boolean isAllowAnonymousTracking = null;

  @POST
  @Path("setAllowAnonymousTracking")
  public void setAllowAnonymousTracking(
      @FormParam("allow") String allow) {

    if (allow == null) {
      this.isAllowAnonymousTracking = null;
    } else if (allow.equals("true")) {
      this.isAllowAnonymousTracking = Boolean.TRUE;
    } else if (allow.equals("false")) {
      this.isAllowAnonymousTracking = Boolean.FALSE;
    } else {
      this.isAllowAnonymousTracking = null;
    }
    final String preferenceFileUrl = this.bkConfig.getPreferenceFileUrl();

    // TODO, assume the url is a file path for now.
    java.nio.file.Path preferenceFile = Paths.get(preferenceFileUrl);
    try {
      ObjectMapper om = new ObjectMapper();
      TypeReference readType = new TypeReference<HashMap<String, Object>>() {
      };
      Map<String, Object> prefs = om.readValue(preferenceFile.toFile(), readType);
      Boolean oldValue = (Boolean) prefs.get("allow-anonymous-usage-tracking");
      // If value changed, write it to the file too
      if ((this.isAllowAnonymousTracking == null && oldValue != null)
              || (this.isAllowAnonymousTracking != null && !(this.isAllowAnonymousTracking.equals(oldValue)))) {
        prefs.put("allow-anonymous-usage-tracking", this.isAllowAnonymousTracking);
        om.writerWithDefaultPrettyPrinter().writeValue(preferenceFile.toFile(), prefs);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @GET
  @Path("isAllowAnonymousTracking")
  public Boolean isAllowAnonymousTracking() {
    return this.isAllowAnonymousTracking;
  }


  private Boolean isUseAdvancedMode = null;

  @POST
  @Path("setUseAdvancedMode")
  public void setUseAdvancedMode(
      @FormParam("advancedmode") String advancedMode) {

    if (advancedMode == null) {
      this.isUseAdvancedMode = null;
    } else if (advancedMode.equals("true")) {
      this.isUseAdvancedMode = Boolean.TRUE;
    } else if (advancedMode.equals("false")) {
      this.isUseAdvancedMode = Boolean.FALSE;
    } else {
      this.isUseAdvancedMode = null;
    }
    final String preferenceFileUrl = this.bkConfig.getPreferenceFileUrl();

    // TODO, assume the url is a file path for now.
    java.nio.file.Path preferenceFile = Paths.get(preferenceFileUrl);
    try {
      ObjectMapper om = new ObjectMapper();
      TypeReference readType = new TypeReference<HashMap<String, Object>>() {
      };
      Map<String, Object> prefs = om.readValue(preferenceFile.toFile(), readType);
      Boolean oldValue = (Boolean) prefs.get("advanced-mode");
      // If value changed, write it to the file too
      if ((this.isUseAdvancedMode == null && oldValue != null)
              || (this.isUseAdvancedMode != null && !(this.isUseAdvancedMode.equals(oldValue)))) {
        prefs.put("advanced-mode", this.isUseAdvancedMode);
        om.writerWithDefaultPrettyPrinter().writeValue(preferenceFile.toFile(), prefs);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @GET
  @Path("isUseAdvancedMode")
  public Boolean isUseAdvancedMode() {
    return this.isUseAdvancedMode;
  }

  /* Init Plugins */
  private final Set<String> initPlugins = new LinkedHashSet<>();

  @GET
  @Path("getInitPlugins")
  public Set<String> getInitPlugins() {
    return this.initPlugins;
  }

  /* bkApp Menu Plugins */
  private final Set<String> menuPlugins = new LinkedHashSet<>();

  @POST
  @Path("addMenuPlugin")
  public void addMenuPlugin(
          @FormParam("url") String urlAsString) {
    this.menuPlugins.add(urlAsString);
  }

  @GET
  @Path("getMenuPlugins")
  public Set<String> getMenuPlugins() {
    return this.menuPlugins;
  }

  /* bkControl Menu Plugins */
  private final Set<String> controlPanelMenuPlugins = new LinkedHashSet<>();

  @POST
  @Path("addControlMenuPlugin")
  public void addControlPanelMenuPlugin(
          @FormParam("url") String urlAsString) {
    this.controlPanelMenuPlugins.add(urlAsString);
  }

  @GET
  @Path("getControlPanelMenuPlugins")
  public Set<String> getControlPanelMenuPlugins() {
    return this.controlPanelMenuPlugins;
  }

  /* bkCell Menu Plugins */
  private final Set<String> cellMenuPlugins = new LinkedHashSet<>();

  @POST
  @Path("addCellMenuPlugin")
  public void addCellMenuPlugin(String p) {
    this.cellMenuPlugins.add(p);
  }

  @GET
  @Path("getCellMenuPlugins")
  public Set<String> getCellMenuPlugins() {
    return this.cellMenuPlugins;
  }
 
  @GET
  @Path("getMainPage")
  @Produces(MediaType.TEXT_HTML)
  public String getMainPage(@Context HttpServletRequest request) {
    String data = utils.readFile(bkConfig.getMainPageFileName());
    data = data.replace("URL-HASH-TO-REPLACE", bkConfig.getHash());
    return data;
  }

}
TOP

Related Classes of com.twosigma.beaker.core.rest.UtilRest

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.