blob: 22a98057428a02d33f880375469d953ff9acac2a [file] [log] [blame]
/*
* =========================================================================
* Copyright (c) 2012-2014 Pivotal Software, Inc. All Rights Reserved.
* This product is protected by U.S. and international copyright
* and intellectual property laws. Pivotal products are covered by
* more patents listed at http://www.pivotal.io/patents.
* ========================================================================
*/
package com.vmware.gemfire.tools.pulse.internal.controllers;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.vmware.gemfire.tools.pulse.internal.data.Cluster;
import com.vmware.gemfire.tools.pulse.internal.data.PulseConstants;
import com.vmware.gemfire.tools.pulse.internal.data.PulseVersion;
import com.vmware.gemfire.tools.pulse.internal.data.Repository;
import com.vmware.gemfire.tools.pulse.internal.json.JSONArray;
import com.vmware.gemfire.tools.pulse.internal.json.JSONException;
import com.vmware.gemfire.tools.pulse.internal.json.JSONObject;
import com.vmware.gemfire.tools.pulse.internal.log.PulseLogWriter;
import com.vmware.gemfire.tools.pulse.internal.service.PulseService;
import com.vmware.gemfire.tools.pulse.internal.service.PulseServiceFactory;
import com.vmware.gemfire.tools.pulse.internal.service.SystemAlertsService;
import com.vmware.gemfire.tools.pulse.internal.util.StringUtils;
/**
* Class PulseController
*
* This class contains the implementations for all http Ajax requests needs to
* be served in Pulse.
*
* @author azambre
* @since version 7.5
*/
@Controller
public class PulseController {
// CONSTANTS
private final String DEFAULT_EXPORT_FILENAME = "DataBrowserQueryResult.json";
private final String QUERYSTRING_PARAM_ACTION = "action";
private final String QUERYSTRING_PARAM_QUERYID = "queryId";
private final String ACTION_VIEW = "view";
private final String ACTION_DELETE = "delete";
private String STATUS_REPSONSE_SUCCESS = "success";
private String STATUS_REPSONSE_FAIL = "fail";
private String ERROR_REPSONSE_QUERYNOTFOUND = "No queries found";
private String ERROR_REPSONSE_QUERYIDMISSING = "Query id is missing";
private final JSONObject NoDataJSON = new JSONObject();
// Shared object to hold pulse version details
public static PulseVersion pulseVersion = new PulseVersion();
//default is gemfire
private static String pulseProductSupport = PulseConstants.PRODUCT_NAME_GEMFIRE;
@Autowired
PulseServiceFactory pulseServiceFactory;
@RequestMapping(value = "/pulseUpdate", method = RequestMethod.POST)
public void getPulseUpdate(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PulseLogWriter LOGGER = PulseLogWriter.getLogger();
String pulseData = request.getParameter("pulseData");
JSONObject responseMap = new JSONObject();
JSONObject requestMap = null;
try {
requestMap = new JSONObject(pulseData);
Iterator<?> keys = requestMap.keys();
// Execute Services
while (keys.hasNext()) {
String serviceName = keys.next().toString();
try {
PulseService pulseService = pulseServiceFactory
.getPulseServiceInstance(serviceName);
responseMap.put(serviceName, pulseService.execute(request));
} catch (Exception serviceException) {
LOGGER.warning("serviceException [for service "+serviceName+"] = " + serviceException.getMessage());
responseMap.put(serviceName, NoDataJSON);
}
}
} catch (JSONException eJSON) {
LOGGER.logJSONError(new JSONException(eJSON),
new String[] { "requestMap:"
+ ((requestMap == null) ? "" : requestMap) });
} catch (Exception e) {
if (LOGGER.fineEnabled()) {
LOGGER.fine("Exception Occured : " + e.getMessage());
}
}
// Create Response
response.getOutputStream().write(responseMap.toString().getBytes());
}
@RequestMapping(value = "/authenticateUser", method = RequestMethod.GET)
public void authenticateUser(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PulseLogWriter LOGGER = PulseLogWriter.getLogger();
// json object to be sent as response
JSONObject responseJSON = new JSONObject();
try {
responseJSON.put("isUserLoggedIn", this.isUserLoggedIn(request));
// Send json response
response.getOutputStream().write(responseJSON.toString().getBytes());
} catch (JSONException eJSON) {
LOGGER.logJSONError(eJSON, null);
} catch (Exception e) {
if (LOGGER.fineEnabled()) {
LOGGER.fine("Exception Occured : " + e.getMessage());
}
}
}
/**
* Method isUserLoggedIn Check whether user is logged in or not.
*
* @param request
* @return boolean
*/
protected boolean isUserLoggedIn(HttpServletRequest request) {
if (null != request.getUserPrincipal()) {
return true;
} else {
return false;
}
}
@RequestMapping(value = "/clusterLogout", method = RequestMethod.GET)
public void clusterLogout(HttpServletRequest request,
HttpServletResponse response) throws IOException {
HttpSession session = request.getSession(false);
if (session != null) {
// End session and redirect
session.invalidate();
}
response.sendRedirect("../Login.html");
}
@RequestMapping(value = "/pulseVersion", method = RequestMethod.GET)
public void pulseVersion(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PulseLogWriter LOGGER = PulseLogWriter.getLogger();
// json object to be sent as response
JSONObject responseJSON = new JSONObject();
try {
// Reference to repository
Repository repository = Repository.get();
// set pulse web app url
String pulseWebAppUrl = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ request.getContextPath();
repository.setPulseWebAppUrl(pulseWebAppUrl);
// Response
responseJSON.put("pulseVersion",
PulseController.pulseVersion.getPulseVersion());
responseJSON.put("buildId",
PulseController.pulseVersion.getPulseBuildId());
responseJSON.put("buildDate",
PulseController.pulseVersion.getPulseBuildDate());
responseJSON.put("sourceDate",
PulseController.pulseVersion.getPulseSourceDate());
responseJSON.put("sourceRevision",
PulseController.pulseVersion.getPulseSourceRevision());
responseJSON.put("sourceRepository",
PulseController.pulseVersion.getPulseSourceRepository());
} catch (JSONException eJSON) {
LOGGER
.logJSONError(eJSON, new String[] { "pulseVersionData :"
+ PulseController.pulseVersion });
} catch (Exception e) {
if (LOGGER.fineEnabled()) {
LOGGER.fine("Exception Occured : " + e.getMessage());
}
}
// Send json response
response.getOutputStream().write(responseJSON.toString().getBytes());
}
@RequestMapping(value = "/clearAlerts", method = RequestMethod.GET)
public void clearAlerts(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PulseLogWriter LOGGER = PulseLogWriter.getLogger();
int alertType;
JSONObject responseJSON = new JSONObject();
try {
alertType = Integer.valueOf(request.getParameter("alertType"));
} catch (NumberFormatException e) {
// Empty json response
response.getOutputStream().write(responseJSON.toString().getBytes());
if (LOGGER.finerEnabled()) {
LOGGER.finer(e.getMessage());
}
return;
}
try {
boolean isClearAll = Boolean.valueOf(request.getParameter("clearAll"));
// get cluster object
Cluster cluster = Repository.get().getCluster();
cluster.clearAlerts(alertType, isClearAll);
responseJSON.put("status", "deleted");
responseJSON.put(
"systemAlerts", SystemAlertsService.getAlertsJson(cluster,
cluster.getNotificationPageNumber()));
responseJSON.put("pageNumber", cluster.getNotificationPageNumber());
boolean isGFConnected = cluster.isConnectedFlag();
if(isGFConnected){
responseJSON.put("connectedFlag", isGFConnected);
}else{
responseJSON.put("connectedFlag", isGFConnected);
responseJSON.put("connectedErrorMsg", cluster.getConnectionErrorMsg());
}
} catch (JSONException eJSON) {
LOGGER.logJSONError(eJSON, null);
} catch (Exception e) {
if (LOGGER.fineEnabled()) {
LOGGER.fine("Exception Occured : " + e.getMessage());
}
}
// Send json response
response.getOutputStream().write(responseJSON.toString().getBytes());
}
@RequestMapping(value = "/acknowledgeAlert", method = RequestMethod.GET)
public void acknowledgeAlert(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PulseLogWriter LOGGER = PulseLogWriter.getLogger();
int alertId;
JSONObject responseJSON = new JSONObject();
try {
alertId = Integer.valueOf(request.getParameter("alertId"));
} catch (NumberFormatException e) {
// Empty json response
response.getOutputStream().write(responseJSON.toString().getBytes());
if (LOGGER.finerEnabled()) {
LOGGER.finer(e.getMessage());
}
return;
}
try {
// get cluster object
Cluster cluster = Repository.get().getCluster();
// set alert is acknowledged
cluster.acknowledgeAlert(alertId);
responseJSON.put("status", "deleted");
} catch (JSONException eJSON) {
LOGGER.logJSONError(eJSON, null);
} catch (Exception e) {
if (LOGGER.fineEnabled()) {
LOGGER.fine("Exception Occured : " + e.getMessage());
}
}
// Send json response
response.getOutputStream().write(responseJSON.toString().getBytes());
}
@RequestMapping(value = "/dataBrowserRegions", method = RequestMethod.GET)
public void dataBrowserRegions(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PulseLogWriter LOGGER = PulseLogWriter.getLogger();
// get cluster object
Cluster cluster = Repository.get().getCluster();
// json object to be sent as response
JSONObject responseJSON = new JSONObject();
List<JSONObject> regionsData = Collections.emptyList();
try {
// getting cluster's Regions
responseJSON.put("clusterName", cluster.getServerName());
regionsData = getRegionsJson(cluster);
responseJSON.put("clusterRegions", regionsData);
responseJSON.put("connectedFlag", cluster.isConnectedFlag());
responseJSON.put("connectedErrorMsg", cluster.getConnectionErrorMsg());
} catch (JSONException eJSON) {
LOGGER.logJSONError(
eJSON,
new String[] { "clusterName:" + cluster.getServerName(),
"clusterRegions:" + regionsData,
"connectedFlag:" + cluster.isConnectedFlag(),
"connectedErrorMsg:" + cluster.getConnectionErrorMsg() });
} catch (Exception e) {
if (LOGGER.fineEnabled()) {
LOGGER.fine("Exception Occured : " + e.getMessage());
}
}
// Send json response
response.getOutputStream().write(responseJSON.toString().getBytes());
}
/**
* This method creates json for list of cluster regions
*
* @param cluster
* @return JSONObject Array List
*/
private List<JSONObject> getRegionsJson(Cluster cluster) throws JSONException {
Collection<Cluster.Region> clusterRegions = cluster.getClusterRegions()
.values();
List<JSONObject> regionsListJson = new ArrayList<JSONObject>();
if (!clusterRegions.isEmpty()) {
for (Cluster.Region region : clusterRegions) {
JSONObject regionJSON = new JSONObject();
regionJSON.put("name", region.getName());
regionJSON.put("fullPath", region.getFullPath());
regionJSON.put("regionType", region.getRegionType());
if(region.getRegionType().contains("PARTITION")){
regionJSON.put("isPartition", true);
}else{
regionJSON.put("isPartition", false);
}
regionJSON.put("memberCount", region.getMemberCount());
List<String> regionsMembers = region.getMemberName();
JSONArray jsonRegionMembers = new JSONArray();
for (int i = 0; i < regionsMembers.size(); i++) {
Cluster.Member member = cluster.getMembersHMap().get(
regionsMembers.get(i));
JSONObject jsonMember = new JSONObject();
jsonMember.put("key", regionsMembers.get(i));
jsonMember.put("id", member.getId());
jsonMember.put("name", member.getName());
jsonRegionMembers.put(jsonMember);
}
regionJSON.put("members", jsonRegionMembers);
regionsListJson.add(regionJSON);
}
}
return regionsListJson;
}
@RequestMapping(value = "/dataBrowserQuery", method = RequestMethod.GET)
public void dataBrowserQuery(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PulseLogWriter LOGGER = PulseLogWriter.getLogger();
// get query string
String query = request.getParameter("query");
String members = request.getParameter("members");
int limit = 0;
try {
limit = Integer.valueOf(request.getParameter("limit"));
} catch (NumberFormatException e) {
limit = 0;
if (LOGGER.finerEnabled()) {
LOGGER.finer(e.getMessage());
}
}
JSONObject queryResult = new JSONObject();
try {
if (StringUtils.isNotNullNotEmptyNotWhiteSpace(query)) {
// get cluster object
Cluster cluster = Repository.get().getCluster();
String userName = request.getUserPrincipal().getName();
// Call execute query method
queryResult = cluster.executeQuery(query, members, limit);
// Add query in history if query is executed successfully
if (!queryResult.has("error")) {
// Add html escaped query to history
String escapedQuery = StringEscapeUtils.escapeHtml(query);
cluster.addQueryInHistory(escapedQuery, userName);
}
}
} catch (JSONException eJSON) {
LOGGER.logJSONError(eJSON, new String[] { "queryResult:" + queryResult });
} catch (Exception e) {
if (LOGGER.fineEnabled()) {
LOGGER.fine("Exception Occured : " + e.getMessage());
}
}
response.getOutputStream().write(queryResult.toString().getBytes());
}
@RequestMapping(value = "/dataBrowserQueryHistory", method = RequestMethod.GET)
public void dataBrowserQueryHistory(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PulseLogWriter LOGGER = PulseLogWriter.getLogger();
JSONObject responseJSON = new JSONObject();
JSONArray queryResult = null;
String action = "";
try {
// get cluster object
Cluster cluster = Repository.get().getCluster();
String userName = request.getUserPrincipal().getName();
// get query string
action = request.getParameter(QUERYSTRING_PARAM_ACTION);
if (!StringUtils.isNotNullNotEmptyNotWhiteSpace(action)) {
action = ACTION_VIEW;
}
if (action.toLowerCase().equalsIgnoreCase(ACTION_DELETE)) {
String queryId = request.getParameter(QUERYSTRING_PARAM_QUERYID);
if (StringUtils.isNotNullNotEmptyNotWhiteSpace(queryId)) {
boolean deleteStatus = cluster.deleteQueryById(userName, queryId);
if (deleteStatus) {
responseJSON.put("status", STATUS_REPSONSE_SUCCESS);
} else {
responseJSON.put("status", STATUS_REPSONSE_FAIL);
responseJSON.put("error", ERROR_REPSONSE_QUERYNOTFOUND);
}
} else {
responseJSON.put("status", STATUS_REPSONSE_FAIL);
responseJSON.put("error", ERROR_REPSONSE_QUERYIDMISSING);
}
}
// Get list of past executed queries
queryResult = cluster.getQueryHistoryByUserId(userName);
responseJSON.put("queryHistory", queryResult);
} catch (JSONException eJSON) {
LOGGER.logJSONError(eJSON, new String[] { "action:" + action,
"queryResult:" + queryResult });
} catch (Exception e) {
if (LOGGER.fineEnabled()) {
LOGGER.fine("Exception Occured : " + e.getMessage());
}
}
response.getOutputStream().write(responseJSON.toString().getBytes());
}
@RequestMapping(value = "/dataBrowserExport", method = RequestMethod.POST)
public void dataBrowserExport(HttpServletRequest request,
HttpServletResponse response) throws IOException {
// get query string
String filename = request.getParameter("filename");
String resultContent = request.getParameter("content");
response.setHeader("Cache-Control", "");
response.setHeader("Content-type", "text/plain");
if (StringUtils.isNotNullNotEmptyNotWhiteSpace(filename)) {
response.setHeader("Content-Disposition", "attachment; filename="
+ filename);
} else {
response.setHeader("Content-Disposition", "attachment; filename="
+ DEFAULT_EXPORT_FILENAME);
}
if (!StringUtils.isNotNullNotEmptyNotWhiteSpace(resultContent)) {
resultContent = "";
}
response.getOutputStream().write(resultContent.getBytes());
}
@RequestMapping(value = "/pulseProductSupport", method = RequestMethod.GET)
public void getConfiguredPulseProduct(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PulseLogWriter LOGGER = PulseLogWriter.getLogger();
JSONObject responseJSON = new JSONObject();
try {
responseJSON.put("product", pulseProductSupport);
// Send json response
response.getOutputStream().write(responseJSON.toString().getBytes());
} catch (JSONException eJSON) {
LOGGER.logJSONError(eJSON, null);
} catch (Exception e) {
if (LOGGER.fineEnabled()) {
LOGGER.fine("Exception Occured : " + e.getMessage());
}
}
}
@RequestMapping(value = "/getQueryStatisticsGridModel", method = RequestMethod.GET)
public void getQueryStatisticsGridModel(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PulseLogWriter LOGGER = PulseLogWriter.getLogger();
JSONObject responseJSON = new JSONObject();
// get cluster object
Cluster cluster = Repository.get().getCluster();
String userName = request.getUserPrincipal().getName();
try {
String[] arrColNames = Cluster.Statement.getGridColumnNames();
String[] arrColAttribs = Cluster.Statement.getGridColumnAttributes();
int[] arrColWidths = Cluster.Statement.getGridColumnWidths();
JSONArray colNamesList = new JSONArray();
for (int i = 0; i < arrColNames.length; ++i) {
colNamesList.put(arrColNames[i]);
}
JSONArray colModelList = new JSONArray();
JSONObject columnJSON = null;
for (int i = 0; i < arrColAttribs.length; ++i) {
columnJSON = new JSONObject();
columnJSON.put("name", arrColAttribs[i]);
columnJSON.put("index", arrColAttribs[i]);
columnJSON.put("width", arrColWidths[i]);
columnJSON.put("sortable", "true");
columnJSON.put("sorttype", ((i == 0) ? "String" : "integer"));
colModelList.put(columnJSON);
}
responseJSON.put("columnNames", colNamesList);
responseJSON.put("columnModels", colModelList);
responseJSON.put("clusterName", cluster.getServerName());
responseJSON.put("userName", userName);
// Send json response
response.getOutputStream().write(responseJSON.toString().getBytes());
} catch (JSONException eJSON) {
LOGGER.logJSONError(eJSON, null);
} catch (Exception e) {
if (LOGGER.fineEnabled()) {
LOGGER.fine("Exception Occured : " + e.getMessage());
}
}
}
/**
* @return the pulseProductSupport
*/
public static String getPulseProductSupport() {
return pulseProductSupport;
}
/**
* @param pulseProductSupport
* the pulseProductSupport to set
*/
public static void setPulseProductSupport(String pulseProductSupport) {
PulseController.pulseProductSupport = pulseProductSupport;
}
}