blob: 3bf79ff25c0923b40af09b043496ef392465461d [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.service;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.vmware.gemfire.tools.pulse.internal.controllers.PulseController;
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.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.util.StringUtils;
import com.vmware.gemfire.tools.pulse.internal.util.TimeUtils;
/**
* Class ClusterSelectedRegionService
*
* This class contains implementations of getting Cluster's selected region details
*
* @author Riya Bhandekar
* @since version 7.5 cedar 2014-03-01
*/
@Component
@Service("ClusterSelectedRegion")
@Scope("singleton")
public class ClusterSelectedRegionService implements PulseService {
// String constants used for forming a json response
private final String ENTRY_SIZE = "entrySize";
// Comparator based upon regions entry count
private static Comparator<Cluster.Member> memberCurrentHeapUsageComparator = new Comparator<Cluster.Member>() {
@Override
public int compare(Cluster.Member m1, Cluster.Member m2) {
long m1HeapUsage = m1.getCurrentHeapSize();
long m2HeapUsage = m2.getCurrentHeapSize();
if (m1HeapUsage < m2HeapUsage) {
return -1;
} else if (m1HeapUsage > m2HeapUsage) {
return 1;
} else {
return 0;
}
}
};
@Override
public JSONObject execute(final HttpServletRequest request) throws Exception {
String userName = request.getUserPrincipal().getName();
String pulseData = request.getParameter("pulseData");
JSONObject parameterMap = new JSONObject(pulseData);
String selectedRegionFullPath = parameterMap.getJSONObject("ClusterSelectedRegion").getString("regionFullPath");
// get cluster object
Cluster cluster = Repository.get().getCluster();
// json object to be sent as response
JSONObject responseJSON = new JSONObject();
try {
// getting cluster's Regions
responseJSON.put("clusterName", cluster.getServerName());
responseJSON.put("userName", userName);
responseJSON.put("selectedRegion", getSelectedRegionJson(cluster, selectedRegionFullPath));
// Send json response
return responseJSON;
} catch (JSONException e) {
throw new Exception(e);
}
}
/**
* Create JSON for selected cluster region
*
* @param cluster
* @return JSONObject Array List
*/
private JSONObject getSelectedRegionJson(Cluster cluster, String selectedRegionFullPath) throws JSONException {
PulseLogWriter LOGGER = PulseLogWriter.getLogger();
Long totalHeapSize = cluster.getTotalHeapSize();
Long totalDiskUsage = cluster.getTotalBytesOnDisk();
Cluster.Region reg = cluster.getClusterRegion(selectedRegionFullPath);
if(reg != null){
JSONObject regionJSON = new JSONObject();
regionJSON.put("name", reg.getName());
regionJSON.put("path", reg.getFullPath());
regionJSON.put("totalMemory", totalHeapSize);
regionJSON.put("systemRegionEntryCount", reg.getSystemRegionEntryCount());
regionJSON.put("memberCount", reg.getMemberCount());
final String regionType = reg.getRegionType();
regionJSON.put("type", regionType);
regionJSON.put("getsRate", reg.getGetsRate());
regionJSON.put("putsRate", reg.getPutsRate());
regionJSON.put("lruEvictionRate", reg.getLruEvictionRate());
DecimalFormat df2 = new DecimalFormat(
PulseConstants.DECIMAL_FORMAT_PATTERN);
Cluster.Member[] clusterMembersList = cluster.getMembers();
// collect members of this region
List<Cluster.Member> clusterMembersL = new ArrayList<Cluster.Member>();
for (String memberName : reg.getMemberName()) {
for (Cluster.Member member : clusterMembersList) {
String name = member.getName();
name = name.replace(":", "-");
String id = member.getId();
id = id.replace(":", "-");
if ((memberName.equals(id)) || (memberName.equals(name))) {
clusterMembersL.add(member);
}
}
}
// sort members of this region
Collections.sort(clusterMembersL, memberCurrentHeapUsageComparator);
// return sorted member list by heap usage
JSONArray memberArray = new JSONArray();
for (Cluster.Member member : clusterMembersL) {
JSONObject regionMember = new JSONObject();
regionMember.put("memberId", member.getId());
regionMember.put("name", member.getName());
regionMember.put("host", member.getHost());
long usedHeapSize = cluster.getUsedHeapSize();
long currentHeap = member.getCurrentHeapSize();
if (usedHeapSize > 0) {
float heapUsage = ((float) currentHeap / (float) usedHeapSize) * 100;
regionMember.put("heapUsage", Double.valueOf(df2.format(heapUsage)));
} else {
regionMember.put("heapUsage", 0);
}
Float currentCPUUsage = member.getCpuUsage();
regionMember.put("cpuUsage", Float.valueOf(df2.format(currentCPUUsage)));
regionMember.put("currentHeapUsage", member.getCurrentHeapSize());
regionMember.put("isManager", member.isManager());
regionMember.put("uptime", TimeUtils.convertTimeSecondsToHMS(member.getUptime()));
regionMember.put("loadAvg", member.getLoadAverage());
regionMember.put("sockets", member.getTotalFileDescriptorOpen());
regionMember.put("threads", member.getNumThreads());
if (PulseController.getPulseProductSupport().equalsIgnoreCase(
PulseConstants.PRODUCT_NAME_SQLFIRE)){
regionMember.put("clients", member.getNumSqlfireClients());
}else{
regionMember.put("clients", member.getMemberClientsHMap().size());
}
regionMember.put("queues", member.getQueueBacklog());
memberArray.put(regionMember);
}
regionJSON.put("members", memberArray);
regionJSON.put("entryCount", reg.getSystemRegionEntryCount());
Boolean persistent = reg.getPersistentEnabled();
if (persistent) {
regionJSON.put("persistence", PulseService.VALUE_ON);
} else {
regionJSON.put("persistence", PulseService.VALUE_OFF);
}
Boolean isEnableOffHeapMemory = reg.isEnableOffHeapMemory();
if (isEnableOffHeapMemory) {
regionJSON.put("isEnableOffHeapMemory", PulseService.VALUE_ON);
} else {
regionJSON.put("isEnableOffHeapMemory", PulseService.VALUE_OFF);
}
Boolean isHDFSWriteOnly = reg.isHdfsWriteOnly();
if (regionType.startsWith("HDFS")) {
if (isHDFSWriteOnly) {
regionJSON.put("isHDFSWriteOnly", PulseService.VALUE_ON);
} else {
regionJSON.put("isHDFSWriteOnly", PulseService.VALUE_OFF);
}
} else {
regionJSON.put("isHDFSWriteOnly", PulseService.VALUE_NA);
}
String regCompCodec = reg.getCompressionCodec();
if (StringUtils.isNotNullNotEmptyNotWhiteSpace(regCompCodec)) {
regionJSON.put("compressionCodec", reg.getCompressionCodec());
} else {
regionJSON.put("compressionCodec", PulseService.VALUE_NA);
}
if (PulseConstants.PRODUCT_NAME_SQLFIRE.equalsIgnoreCase(PulseController
.getPulseProductSupport())) {
// Convert region path to dot separated region path
regionJSON.put("regionPath",
StringUtils.getTableNameFromRegionName(reg.getFullPath()));
} else {
regionJSON.put("regionPath", reg.getFullPath());
}
regionJSON
.put(
"memoryReadsTrend",
new JSONArray(
reg.getRegionStatisticTrend(Cluster.Region.REGION_STAT_GETS_PER_SEC_TREND)));
regionJSON
.put(
"memoryWritesTrend",
new JSONArray(
reg.getRegionStatisticTrend(Cluster.Region.REGION_STAT_PUTS_PER_SEC_TREND)));
regionJSON
.put(
"diskReadsTrend",
new JSONArray(
reg.getRegionStatisticTrend(Cluster.Region.REGION_STAT_DISK_READS_PER_SEC_TREND)));
regionJSON
.put(
"diskWritesTrend",
new JSONArray(
reg.getRegionStatisticTrend(Cluster.Region.REGION_STAT_DISK_WRITES_PER_SEC_TREND)));
regionJSON.put("emptyNodes", reg.getEmptyNode());
Long entrySize = reg.getEntrySize();
DecimalFormat form = new DecimalFormat(
PulseConstants.DECIMAL_FORMAT_PATTERN_2);
String entrySizeInMB = form.format(entrySize / (1024f * 1024f));
if (entrySize < 0) {
regionJSON.put(this.ENTRY_SIZE, PulseService.VALUE_NA);
} else {
regionJSON.put(this.ENTRY_SIZE, entrySizeInMB);
}
regionJSON.put("dataUsage", reg.getDiskUsage());
regionJSON.put("wanEnabled", reg.getWanEnabled());
regionJSON.put("totalDataUsage", totalDiskUsage);
regionJSON.put("memoryUsage", entrySizeInMB);
LOGGER.fine("calling getSelectedRegionJson :: regionJSON = " + regionJSON);
return regionJSON;
} else {
JSONObject responseJSON = new JSONObject();
responseJSON.put("errorOnRegion", "Region [" + selectedRegionFullPath
+ "] is not available");
return responseJSON;
}
}
}