/* * Copyright 1999-2012 Alibaba Group. * * 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.alibaba.cobar.manager.web.ajax; import static com.alibaba.cobar.manager.util.ConstantDefine.*; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.apache.commons.beanutils.PropertyUtilsBean; import org.apache.log4j.Logger; import org.springframework.beans.factory.InitializingBean; import org.springframework.web.HttpRequestHandler; import com.alibaba.cobar.manager.dao.CobarAdapterDAO; import com.alibaba.cobar.manager.dataobject.cobarnode.CommandStatus; import com.alibaba.cobar.manager.dataobject.cobarnode.ProcessorStatus; import com.alibaba.cobar.manager.dataobject.cobarnode.ServerStatus; import com.alibaba.cobar.manager.dataobject.xml.CobarDO; import com.alibaba.cobar.manager.service.CobarAccesser; import com.alibaba.cobar.manager.service.XmlAccesser; import com.alibaba.cobar.manager.util.ConstantDefine; import com.alibaba.cobar.manager.util.FormatUtil; import com.alibaba.cobar.manager.util.MathUtil; import com.alibaba.cobar.manager.util.Pair; /** * @author wenfeng.cenwf 2011-3-8 * @author haiqing.zhuhq 2011-7-14 */ public class ClusterInstantPerfValueAjax implements HttpRequestHandler, InitializingBean { private XmlAccesser xmlAccesser; private CobarAccesser cobarAccesser; private static final Logger logger = Logger.getLogger(ClusterInstantPerfValueAjax.class); public void setCobarAccesser(CobarAccesser cobarAccesser) { this.cobarAccesser = cobarAccesser; } public void setXmlAccesser(XmlAccesser xmlAccesser) { this.xmlAccesser = xmlAccesser; } @Override public void afterPropertiesSet() throws Exception { if (null == xmlAccesser) { throw new IllegalArgumentException("property 'xmlAccesser' is null!"); } if (null == cobarAccesser) { throw new IllegalArgumentException("property 'cobarAccesser' is null!"); } } private long groupByPList(List<ProcessorStatus> list, int type) { long result = 0; switch (type) { case NET_IN: for (ProcessorStatus p : list) { result += p.getNetIn(); } break; case NET_OUT: for (ProcessorStatus p : list) { result += p.getNetOut(); } break; case CONNECTION: for (ProcessorStatus p : list) { result += p.getConnections(); } break; case REQUEST_COUNT: for (ProcessorStatus p : list) { result += p.getRequestCount(); } break; default: throw new IllegalArgumentException("invalid parameter"); } return result; } private long groupByCList(List<CommandStatus> list, int type) { long result = 0; switch (type) { case REQUEST_COUNT: for (CommandStatus p : list) { result += p.getQuery(); } break; default: throw new IllegalArgumentException("invalid parameter"); } return result; } private List<Pair<Long, Integer>> listCobarMemoryUsage(AjaxParams params) { List<Pair<Long, Integer>> result = new ArrayList<Pair<Long, Integer>>(); List<CobarDO> nodes = xmlAccesser.getCobarDAO().getCobarList(params.getClusterId(), ConstantDefine.ACTIVE); for (CobarDO node : nodes) { CobarAdapterDAO perfAccesser = cobarAccesser.getAccesser(node.getId()); if (!perfAccesser.checkConnection()) { StringBuilder sb = new StringBuilder("listCobarMemoryUsage: cobar connect error for Name:"); sb.append(node.getName()).append(" Host:").append(node.getHost()); logger.error(sb.toString()); continue; } ServerStatus ss = perfAccesser.getServerStatus(); int memoryUsage = 0; if (ss.getTotalMemory() != 0) memoryUsage = Math.round(ss.getUsedMemory() * 100 / ss.getTotalMemory()); result.add(new Pair<Long, Integer>(node.getId(), memoryUsage)); } return result; } @SuppressWarnings("unchecked") private List<Map<String, Object>> getClusterThroughput(AjaxParams params) { List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(); JSONArray array = params.getArray(); JSONObject json = null; Map<Long, JSONObject> cobarRequest = new HashMap<Long, JSONObject>(); for (int i = 0; i < array.size(); i++) { JSONObject js = array.getJSONObject(i); if ("cluster".equals(js.getString("flag"))) { json = js; } else if ("cobar".equals(js.getString("flag"))) { cobarRequest.put(js.getLong("id"), js); } } PropertyUtilsBean util = new PropertyUtilsBean(); long clusterId = params.getClusterId(); List<CobarDO> nodes = xmlAccesser.getCobarDAO().getCobarList(clusterId, ConstantDefine.ACTIVE); AjaxResult cluster = new AjaxResult(); cluster.setId(clusterId); cluster.setFlag("cluster"); long timestamp = 0; for (CobarDO node : nodes) { CobarAdapterDAO perfAccesser = cobarAccesser.getAccesser(node.getId()); if (!perfAccesser.checkConnection()) { StringBuilder sb = new StringBuilder("getClusterThroughput: cobar connect error for Name:"); sb.append(node.getName()).append(" Host:").append(node.getHost()); logger.error(sb.toString()); continue; } AjaxResult re = new AjaxResult(); List<ProcessorStatus> list = perfAccesser.listProccessorStatus(); List<CommandStatus> cmdList = perfAccesser.listCommandStatus(); long cobarNetIn = groupByPList(list, NET_IN); long cobarNetOut = groupByPList(list, NET_OUT); long cobarRequestCount = groupByCList(cmdList, REQUEST_COUNT); cluster.addRequest(cobarRequestCount); cluster.addNetIn(cobarNetIn); cluster.addNetOut(cobarNetOut); re.setId(node.getId()); re.setFlag("cobar"); re.setNetIn(cobarNetIn); re.setNetOut(cobarNetOut); re.setConnection(groupByPList(list, CONNECTION)); re.setRequest(cobarRequestCount); timestamp = list.get(list.size() - 1).getSampleTimeStamp(); re.setTimestamp(timestamp); JSONObject jsonTmp = cobarRequest.get(node.getId()); if (jsonTmp != null) { re.setNetIn_deriv(FormatUtil.formatNetwork(Math.round(MathUtil.getDerivate(cobarNetIn, jsonTmp.getLong("netIn"), timestamp, jsonTmp.getLong("timestamp"), 1000.0)))); re.setNetOut_deriv(FormatUtil.formatNetwork(Math.round(MathUtil.getDerivate(cobarNetOut, jsonTmp.getLong("netOut"), timestamp, jsonTmp.getLong("timestamp"), 1000.0)))); re.setRequest_deriv(FormatUtil.formatNumber(Math.round(MathUtil.getDerivate(cobarRequestCount, jsonTmp.getLong("reCount"), timestamp, jsonTmp.getLong("timestamp"), 1000.0)))); } Map<String, Object> map = null; try { map = util.describe(re); } catch (Exception e) { logger.error(e); throw new RuntimeException(e); } if (null != map) { result.add(map); } } cluster.setTimestamp(timestamp); if (null != json && json.getLong("netIn") != -1) { long o_tiemstamp = json.getLong("timestamp"); cluster.setNetIn_deriv(FormatUtil.formatNetwork(Math.round(MathUtil.getDerivate(cluster.getNetIn(), json.getLong("netIn"), timestamp, o_tiemstamp, 1000.0)))); cluster.setNetOut_deriv(FormatUtil.formatNetwork(Math.round(MathUtil.getDerivate(cluster.getNetOut(), json.getLong("netOut"), timestamp, o_tiemstamp, 1000.0)))); cluster.setRequest_deriv(FormatUtil.formatNumber(Math.round(MathUtil.getDerivate(cluster.getRequest(), json.getLong("reCount"), timestamp, o_tiemstamp, 1000.0)))); } Map<String, Object> m = null; try { m = util.describe(cluster); } catch (Exception e) { logger.error(e); throw new RuntimeException(e); } if (null != m) { result.add(m); } return result; } private AjaxResult getClusterInfo(AjaxParams params) { JSONArray array = params.getArray(); long clusterId = params.getClusterId(); JSONObject json = null; if (array.size() > 0) { json = array.getJSONObject(0); } AjaxResult rs = new AjaxResult(); rs.setId(clusterId); List<CobarDO> nodes = xmlAccesser.getCobarDAO().getCobarList(clusterId); rs.setTotal(nodes.size()); for (CobarDO cobar : nodes) { if (ConstantDefine.IN_ACTIVE.equals(cobar.getStatus())) { continue; } CobarAdapterDAO perfAccesser = cobarAccesser.getAccesser(cobar.getId()); if (!perfAccesser.checkConnection()) { rs.addError(1); StringBuilder sb = new StringBuilder("getClusterInfo : cobar connect error for [ Name:"); sb.append(cobar.getName()).append(" Host:").append(cobar.getHost()).append(" ]"); logger.error(sb.toString()); continue; } rs.addActive(1); rs.setSchema(perfAccesser.listDataBases().size()); List<ProcessorStatus> list = perfAccesser.listProccessorStatus(); rs.addNetIn(groupByPList(list, NET_IN)); rs.addNetOut(groupByPList(list, NET_OUT)); rs.addConnection(groupByPList(list, CONNECTION)); rs.setTimestamp(list.get(list.size() - 1).getSampleTimeStamp()); List<CommandStatus> commandList = perfAccesser.listCommandStatus(); rs.addRequest(groupByCList(commandList, REQUEST_COUNT)); } if (json != null && json.getLong("netIn") != -1) { long o_tiemstamp = json.getLong("timestamp"); rs.setNetIn_deriv(FormatUtil.formatNetwork(Math.round(MathUtil.getDerivate(rs.getNetIn(), json.getLong("netIn"), rs.getTimestamp(), o_tiemstamp, 1000.0)))); rs.setNetOut_deriv(FormatUtil.formatNetwork(Math.round(MathUtil.getDerivate(rs.getNetOut(), json.getLong("netOut"), rs.getTimestamp(), o_tiemstamp, 1000.0)))); rs.setRequest_deriv(FormatUtil.formatNumber(Math.round(MathUtil.getDerivate(rs.getRequest(), json.getLong("reCount"), rs.getTimestamp(), o_tiemstamp, 1000.0)))); } return rs; } private List<Pair<Long, String>> getStatus(AjaxParams params) { List<Pair<Long, String>> result = new ArrayList<Pair<Long, String>>(); List<CobarDO> nodes = xmlAccesser.getCobarDAO().getCobarList(params.getClusterId(), ConstantDefine.ACTIVE); for (CobarDO node : nodes) { if (ConstantDefine.IN_ACTIVE.equals(node.getStatus())) { result.add(new Pair<Long, String>(node.getId(), ConstantDefine.IN_ACTIVE)); continue; } CobarAdapterDAO perfAccesser = cobarAccesser.getAccesser(node.getId()); if (!perfAccesser.checkConnection()) { StringBuilder sb = new StringBuilder("getStatus: cobar connect error for Name:"); sb.append(node.getName()).append(" Host:").append(node.getHost()); logger.error(sb.toString()); result.add(new Pair<Long, String>(node.getId(), ConstantDefine.ERROR)); } else { result.add(new Pair<Long, String>(node.getId(), ConstantDefine.ACTIVE)); } } return result; } @SuppressWarnings("unchecked") @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { AjaxParams params = new AjaxParams(request); String jsonRst = null; String st = params.getValueType(); if (null == st || st.equals("")) { throw new IllegalArgumentException("parameter 'cobarControlValueType' is unknown: " + st); } int type = valueTypeMap.get(st); PropertyUtilsBean util = new PropertyUtilsBean(); switch (type) { case TYPE_COBAR_MEMORY_USAGE: List<Pair<Long, Integer>> mList = listCobarMemoryUsage(params); JSONArray mArray = JSONArray.fromObject(mList); jsonRst = mArray.toString(2); break; case TYPE_CLUSTER_THROUGHPUT_INFO: List<Map<String, Object>> list1 = getClusterThroughput(params); JSONArray arrayMap = JSONArray.fromObject(list1); jsonRst = arrayMap.toString(2); break; case TYPE_CLUSTER_INFO: AjaxResult rs = getClusterInfo(params); Map<String, Object> map = null; try { map = util.describe(rs); } catch (Exception e) { logger.error(e); throw new RuntimeException(e); } jsonRst = JSONObject.fromObject(map).toString(2); break; case TYPE_STATUS: List<Pair<Long, String>> sList = getStatus(params); JSONArray sArray = JSONArray.fromObject(sList); jsonRst = sArray.toString(2); break; default: throw new IllegalArgumentException("parameter 'ValueType' is known: " + params.getValueType()); } response.setHeader("Content-Type", "text/json; charset=utf-8"); OutputStream out = response.getOutputStream(); out.write(jsonRst.getBytes("utf-8")); out.flush(); } private static final Map<String, Integer> valueTypeMap = new HashMap<String, Integer>(); static { valueTypeMap.put("cobarServerLevelMemoryUsage", TYPE_COBAR_MEMORY_USAGE); valueTypeMap.put("cobarClusterLevelThroughput", TYPE_CLUSTER_THROUGHPUT_INFO); valueTypeMap.put("indexInfo", TYPE_INDEX); valueTypeMap.put("clusterInfo", TYPE_CLUSTER_INFO); valueTypeMap.put("status", TYPE_STATUS); } private static final int NET_IN = 1; private static final int NET_OUT = 2; private static final int CONNECTION = 3; private static final int REQUEST_COUNT = 4; }