Package com.baasbox.controllers

Source Code of com.baasbox.controllers.Root

/*
* Copyright (c) 2014.
*
* BaasBox - info-at-baasbox.com
*
* 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.baasbox.controllers;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipInputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.exception.ExceptionUtils;

import play.Logger;
import play.libs.Json;
import play.mvc.Controller;
import play.mvc.Http;
import play.mvc.Http.MultipartFormData;
import play.mvc.Http.MultipartFormData.FilePart;
import play.mvc.Result;
import play.mvc.With;

import com.baasbox.BBConfiguration;
import com.baasbox.controllers.actions.filters.ConnectToDBFilter;
import com.baasbox.controllers.actions.filters.RootCredentialWrapFilter;
import com.baasbox.dao.exception.FileNotFoundException;
import com.baasbox.dao.exception.SqlInjectionException;
import com.baasbox.exception.OpenTransactionException;
import com.baasbox.exception.UserNotFoundException;
import com.baasbox.metrics.BaasBoxMetric;
import com.baasbox.service.dbmanager.DbManagerService;
import com.baasbox.service.user.UserService;
import com.codahale.metrics.json.MetricsModule;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;


public class Root extends Controller {

  @With({RootCredentialWrapFilter.class,ConnectToDBFilter.class})
  public static Result resetAdminPassword(){
    Http.RequestBody body = request().body();

    JsonNode bodyJson= body.asJson();
    if (Logger.isDebugEnabled()) Logger.debug("resetAdminPassword bodyJson: " + bodyJson);
    //check and validate input
    if (bodyJson==null) return badRequest("The body payload cannot be empty.");   
    if (!bodyJson.has("password"))  return badRequest("The 'password' field is missing into the body");
    JsonNode passwordNode=bodyJson.findValue("password");
   
    if (passwordNode==null) return badRequest("The body payload doesn't contain password field");
    String password=passwordNode.asText();  
    try{
      UserService.changePassword("admin", password);
    } catch (SqlInjectionException e) {
      return badRequest("The password is not valid");
    } catch (UserNotFoundException e) {
      Logger.error("User 'admin' not found!");
        return internalServerError("User 'admin' not found!");
    } catch (OpenTransactionException e) {
      Logger.error (ExceptionUtils.getFullStackTrace(e));
      throw new RuntimeException(e);
    }
    return ok("Admin password reset");
  }
 
    
    @With(RootCredentialWrapFilter.class)
    public static Result timers() throws JsonProcessingException {
      if (!BaasBoxMetric.isActivate()) return status(SERVICE_UNAVAILABLE,"The metrics service are disabled");
      ObjectMapper mapper = new ObjectMapper().registerModule(new MetricsModule(TimeUnit.SECONDS, TimeUnit.MILLISECONDS, false));
      return ok(mapper.writeValueAsString(BaasBoxMetric.registry.getTimers()));
      }

    @With(RootCredentialWrapFilter.class)
      public static Result counters() throws JsonProcessingException {
      if (!BaasBoxMetric.isActivate()) return status(SERVICE_UNAVAILABLE,"The metrics service are disabled");
        ObjectMapper mapper = new ObjectMapper().registerModule(new MetricsModule(TimeUnit.SECONDS, TimeUnit.SECONDS, false));
          return ok(mapper.writeValueAsString(BaasBoxMetric.registry.getCounters()));
      }

    @With(RootCredentialWrapFilter.class)
      public static Result meters() throws JsonProcessingException {
      if (!BaasBoxMetric.isActivate()) return status(SERVICE_UNAVAILABLE,"The metrics service are disabled");
        ObjectMapper mapper = new ObjectMapper().registerModule(new MetricsModule(TimeUnit.SECONDS, TimeUnit.SECONDS, false));
          return ok(mapper.writeValueAsString(BaasBoxMetric.registry.getMeters()));
      }
   
    @With(RootCredentialWrapFilter.class)
      public static Result gauges() throws JsonProcessingException {
      if (!BaasBoxMetric.isActivate()) return status(SERVICE_UNAVAILABLE,"The metrics service are disabled");
        ObjectMapper mapper = new ObjectMapper().registerModule(new MetricsModule(TimeUnit.SECONDS, TimeUnit.SECONDS, false));
          return ok(mapper.writeValueAsString(BaasBoxMetric.registry.getGauges()));
      }
   
    @With(RootCredentialWrapFilter.class)
      public static Result histograms() throws JsonProcessingException {
      if (!BaasBoxMetric.isActivate()) return status(SERVICE_UNAVAILABLE,"The metrics service is disabled");
        ObjectMapper mapper = new ObjectMapper().registerModule(new MetricsModule(TimeUnit.SECONDS, TimeUnit.SECONDS, false));
          return ok(mapper.writeValueAsString(BaasBoxMetric.registry.getHistograms()));
      }
   
    @With(RootCredentialWrapFilter.class)
      public static Result uptime() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        HashMap <String,Object> ret = new HashMap<String, Object>();
        ret.put("start_time", BaasBoxMetric.Track.getStartTime());
        ret.put("time_zone", "UTC");
        ret.put("uptime", BaasBoxMetric.Track.getUpTimeinMillis());
        ret.put("time_unit", "ms");
          return ok(mapper.writeValueAsString(ret));
      }
   
    @With(RootCredentialWrapFilter.class)
      public static Result startMetrics() throws JsonProcessingException {
      BaasBoxMetric.start();
          return ok("Metrics service started");
      }
   
    @With(RootCredentialWrapFilter.class)
      public static Result stopMetrics() throws JsonProcessingException {
      BaasBoxMetric.stop();
          return ok("Metrics service stopped");
      }
   
    //backup & restore
    /**
     * /root/db/export (POST)
     *
     * the method generate a full dump of the db in an asyncronus task.
     * the response returns a 202 code (ACCEPTED) and the filename of the
     * file that will be generated.
     *
     * The async nature of the method DOES NOT ensure the creation of the file
     * so, querying for the file name with the /admin/db/:filename could return a 404
     * @return a 202 accepted code and a json representation containing the filename of the generated file
     */
    @With({RootCredentialWrapFilter.class,ConnectToDBFilter.class})
    public static Result exportDb(){
      String appcode = (String)ctx().args.get("appcode");
      String fileName="";
      try {
        fileName = DbManagerService.exportDb(appcode);
      } catch (FileNotFoundException e) {
        return internalServerError(e.getMessage());
      }
      return status(202,Json.toJson(fileName));
    }
   
    /**
     * /root/db/export/:filename (GET)
     *
     * the method returns the stream of the export file named after :filename parameter.
     *
     * if the file is not present a 404 code is returned to the client
     *
     * @return a 200 ok code and the stream of the file
     */
    @With({RootCredentialWrapFilter.class,ConnectToDBFilter.class})
    public static Result getExport(String filename){
      java.io.File file = new java.io.File(DbManagerService.backupDir+DbManagerService.fileSeparator+filename);
      if(!file.exists()){
        return notFound();
      }else{
        response().setContentType("application/zip"); //added in Play 2.2.1. it is very strange because the content type should be set by the framework
        return ok(file);
      }

    }
   
    /**
     * /root/db/export/:filename (DELETE)
     *
     * Deletes an export file from the db backup folder, if it exists
     *
     *
     * @param fileName the name of the file to be deleted
     * @return a 200 code if the file is deleted correctly or a 404.If the file could not
     * be deleted a 500 error code is returned
     */
    @With({RootCredentialWrapFilter.class,ConnectToDBFilter.class})
    public static Result deleteExport(String filename){
      try {
        DbManagerService.deleteExport(filename);
      } catch (FileNotFoundException e1) {
        return notFound();
      } catch (IOException e1) {
        return internalServerError("Unable to delete export.It will be deleted on the next reboot."+filename);
      }
      return ok();
    }
   
    /**
     * /root/db/export (GET)
     *
     * the method returns the list as a json array of all the export files
     * stored into the db export folder ({@link BBConfiguration#getDBBackupDir()})
     *
     * @return a 200 ok code and a json representation containing the list of files stored in the db backup folder
     */
    @With({RootCredentialWrapFilter.class,ConnectToDBFilter.class})
    public static Result getExports(){
      List<String> fileNames = DbManagerService.getExports();
      return ok(Json.toJson(fileNames));
    }
   
    /**
     * /admin/db/import (POST)
     *
     * the method allows to upload a json export file and apply it to the db.
     * WARNING: all data on the db will be wiped out before importing
     *
     * @return a 200 Status code when the import is successfull,a 500 status code otherwise
     */
    @With({RootCredentialWrapFilter.class,ConnectToDBFilter.class})
    public static Result importDb(){
      String appcode = (String)ctx().args.get("appcode");
      MultipartFormData  body = request().body().asMultipartFormData();
      if (body==null) return badRequest("missing data: is the body multipart/form-data?");
      FilePart fp = body.getFile("file");

      if (fp!=null){
        ZipInputStream zis = null;
        try{
          java.io.File multipartFile=fp.getFile();
          java.util.UUID uuid = java.util.UUID.randomUUID();
          File zipFile = File.createTempFile(uuid.toString(), ".zip");
          FileUtils.copyFile(multipartFile,zipFile);
          zis =   new ZipInputStream(new FileInputStream(zipFile));
          DbManagerService.importDb(appcode, zis);
          zipFile.delete();
          return ok();   
        }catch(Exception e){
          Logger.error(ExceptionUtils.getStackTrace(e));
          return internalServerError(ExceptionUtils.getStackTrace(e));
        }finally{
          try {
            if(zis!=null){
              zis.close();
            }
          } catch (IOException e) {
            // Nothing to do here
          }
        }
      }else{
        return badRequest("The form was submitted without a multipart file field.");
      }
    }
   
    //DB size and alert thresholds
    /**
     * /root/configuration (POST)
     *
     * this method allows to set (or override) just two configuration parameter (at the moment)
     * the db size Threshold in bytes:
     *     baasbox.db.size
     * A percentage needed by the console to show alerts on dashboard when DB size is near the defined Threshold
     *     baasbox.db.alert
     *
     * @return a 200 OK with the new values
     */
    @With({RootCredentialWrapFilter.class})
    public static Result overrideConfiguration(){
      Http.RequestBody body = request().body();
      JsonNode bodyJson= body.asJson();
      JsonNode newDBAlert = bodyJson.get(BBConfiguration.DB_ALERT_THRESHOLD);
      JsonNode newDBSize = bodyJson.get(BBConfiguration.DB_SIZE_THRESHOLD);
      try{
        if (newDBAlert!=null && !newDBAlert.isInt() && newDBAlert.asInt()<1) throw new IllegalArgumentException(BBConfiguration.DB_ALERT_THRESHOLD + " must be a positive integer value");
        if (newDBSize!=null && !newDBSize.isLong() && newDBSize.asInt()<0) throw new IllegalArgumentException(BBConfiguration.DB_SIZE_THRESHOLD + " must be a positive integer value, or 0 to disable it");
      }catch (Throwable e){
        return badRequest(e.getMessage());
      }
      if (newDBAlert!=null) BBConfiguration.setDBAlertThreshold(newDBAlert.asInt());
      if (newDBSize!=null) BBConfiguration.setDBSizeThreshold(BigInteger.valueOf(newDBSize.asLong()));
      HashMap returnMap = new HashMap();
      returnMap.put(BBConfiguration.DB_ALERT_THRESHOLD, BBConfiguration.getDBAlertThreshold());
      returnMap.put(BBConfiguration.DB_SIZE_THRESHOLD, BBConfiguration.getDBSizeThreshold());
      try {
        return ok(new ObjectMapper().writeValueAsString(returnMap));
      } catch (JsonProcessingException e) {
        return internalServerError(e.getMessage());
      }
    }
   
    @With({RootCredentialWrapFilter.class})
    public static Result getOverridableConfiguration(){
      HashMap returnMap = new HashMap();
      returnMap.put(BBConfiguration.DB_ALERT_THRESHOLD, BBConfiguration.getDBAlertThreshold());
      returnMap.put(BBConfiguration.DB_SIZE_THRESHOLD, BBConfiguration.getDBSizeThreshold());
      try {
        return ok(new ObjectMapper().writeValueAsString(returnMap));
      } catch (JsonProcessingException e) {
        return internalServerError(e.getMessage());
      }
    }
   
}
TOP

Related Classes of com.baasbox.controllers.Root

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.