Package com.dianping.cat.report.page.dependency

Source Code of com.dianping.cat.report.page.dependency.Handler

package com.dianping.cat.report.page.dependency;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

import javax.servlet.ServletException;

import org.hsqldb.lib.StringUtil;
import org.unidal.lookup.annotation.Inject;
import org.unidal.tuple.Pair;
import org.unidal.web.mvc.PageHandler;
import org.unidal.web.mvc.annotation.InboundActionMeta;
import org.unidal.web.mvc.annotation.OutboundActionMeta;
import org.unidal.web.mvc.annotation.PayloadMeta;

import com.dianping.cat.Constants;
import com.dianping.cat.ServerConfigManager;
import com.dianping.cat.consumer.dependency.DependencyAnalyzer;
import com.dianping.cat.consumer.dependency.DependencyReportMerger;
import com.dianping.cat.consumer.dependency.model.entity.Dependency;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.consumer.dependency.model.entity.Index;
import com.dianping.cat.consumer.dependency.model.entity.Segment;
import com.dianping.cat.consumer.state.StateAnalyzer;
import com.dianping.cat.consumer.state.model.entity.Machine;
import com.dianping.cat.consumer.state.model.entity.StateReport;
import com.dianping.cat.helper.TimeHelper;
import com.dianping.cat.home.dal.report.Event;
import com.dianping.cat.home.dependency.graph.entity.TopologyEdge;
import com.dianping.cat.home.dependency.graph.entity.TopologyGraph;
import com.dianping.cat.home.dependency.graph.entity.TopologyNode;
import com.dianping.cat.home.dependency.graph.transform.DefaultJsonBuilder;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.LineChart;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.dependency.dashboard.ProductLinesDashboard;
import com.dianping.cat.report.page.dependency.graph.LineGraphBuilder;
import com.dianping.cat.report.page.dependency.graph.TopologyGraphManager;
import com.dianping.cat.report.page.model.spi.ModelService;
import com.dianping.cat.service.ModelRequest;
import com.dianping.cat.service.ModelResponse;

public class Handler implements PageHandler<Context> {

  @Inject(type = ModelService.class, value = DependencyAnalyzer.ID)
  private ModelService<DependencyReport> m_dependencyService;

  @Inject(type = ModelService.class, value = StateAnalyzer.ID)
  private ModelService<StateReport> m_stateService;

  @Inject
  private TopologyGraphManager m_graphManager;

  @Inject
  private ExternalInfoBuilder m_externalInfoBuilder;

  @Inject
  private JspViewer m_jspViewer;

  @Inject
  private PayloadNormalizer m_normalizePayload;

  @Inject
  private ServerConfigManager m_configManager;

  public static final String TUAN_TOU = "TuanGou";
 
  private Segment buildAllSegmentsInfo(DependencyReport report) {
    Segment result = new Segment();
    Map<Integer, Segment> segments = report.getSegments();
    DependencyReportMerger merger = new DependencyReportMerger(null);

    for (Segment segment : segments.values()) {
      Map<String, Dependency> dependencies = segment.getDependencies();
      Map<String, Index> indexs = segment.getIndexs();

      for (Index index : indexs.values()) {
        Index temp = result.findOrCreateIndex(index.getName());
        merger.mergeIndex(temp, index);
      }
      for (Dependency dependency : dependencies.values()) {
        Dependency temp = result.findOrCreateDependency(dependency.getKey());

        merger.mergeDependency(temp, dependency);
      }
    }
    return result;
  }

  private String buildCatInfoMessage(StateReport report) {
    int realSize = report.getMachines().size();
    List<Pair<String, Integer>> servers = m_configManager.getConsoleEndpoints();
    int excepeted = servers.size();
    Set<String> errorServers = new HashSet<String>();

    if (realSize != excepeted) {
      for (Pair<String, Integer> server : servers) {
        String serverIp = server.getKey();

        if (report.getMachines().get(serverIp) == null) {
          errorServers.add(serverIp);
        }
      }
    }
    for (Machine machine : report.getMachines().values()) {
      if (machine.getTotalLoss() > 100 * 10000) {
        errorServers.add(machine.getIp());
      }
    }

    if (errorServers.size() > 0) {
      return errorServers.toString();
    } else {
      return null;
    }
  }


  private void buildDependencyDashboard(Model model, Payload payload, Date reportTime) {
    ProductLinesDashboard dashboardGraph = m_graphManager.buildDependencyDashboard(reportTime.getTime());
    Map<String, List<TopologyNode>> dashboardNodes = dashboardGraph.getNodes();

    for (Entry<String, List<TopologyNode>> entry : dashboardNodes.entrySet()) {
      for (TopologyNode node : entry.getValue()) {
        m_externalInfoBuilder.buildNodeZabbixInfo(node, model, payload);
      }
    }
    model.setReportStart(new Date(payload.getDate()));
    model.setReportEnd(new Date(payload.getDate() + TimeHelper.ONE_HOUR - 1));
    model.setDashboardGraph(dashboardGraph.toJson());
    model.setDashboardGraphData(dashboardGraph);
  }

  private void buildDependencyLineChart(Model model, Payload payload, Date reportTime) {
    DependencyReport dependencyReport = queryDependencyReport(payload);
    buildHourlyReport(dependencyReport, model, payload);
    buildHourlyLineGraph(dependencyReport, model);

    Segment segment = dependencyReport.findSegment(model.getMinute());
    Map<String, List<String>> dependency = parseDependencies(segment);

    model.setEvents(m_externalInfoBuilder.queryDependencyEvent(dependency, model.getDomain(), reportTime));
  }

  private void buildExceptionDashboard(Model model, Payload payload, long date) {
    model.setReportStart(new Date(payload.getDate()));
    model.setReportEnd(new Date(payload.getDate() + TimeHelper.ONE_HOUR - 1));
    m_externalInfoBuilder.buildTopErrorInfo(payload, model);
  }

  private void buildHourlyLineGraph(DependencyReport report, Model model) {
    LineGraphBuilder builder = new LineGraphBuilder();

    builder.visitDependencyReport(report);

    List<LineChart> index = builder.queryIndex();
    Map<String, List<LineChart>> dependencys = builder.queryDependencyGraph();

    model.setIndexGraph(buildLineChartGraph(index));
    model.setDependencyGraph(buildLineChartGraphs(dependencys));
  }

  private void buildHourlyReport(DependencyReport report, Model model, Payload payload) {
    Segment segment = report.findSegment(model.getMinute());

    model.setReport(report);
    model.setSegment(segment);

    if (payload.isAll()) {
      model.setSegment(buildAllSegmentsInfo(report));
    }
  }

  private List<String> buildLineChartGraph(List<LineChart> charts) {
    List<String> result = new ArrayList<String>();

    for (LineChart temp : charts) {
      result.add(temp.getJsonString());
    }
    return result;
  }

  private Map<String, List<String>> buildLineChartGraphs(Map<String, List<LineChart>> charts) {
    Map<String, List<String>> result = new HashMap<String, List<String>>();

    for (Entry<String, List<LineChart>> temp : charts.entrySet()) {
      result.put(temp.getKey(), buildLineChartGraph(temp.getValue()));
    }
    return result;
  }

  private void buildProjectTopology(Model model, Payload payload, Date reportTime) {
    TopologyGraph topologyGraph = m_graphManager.buildTopologyGraph(model.getDomain(), reportTime.getTime());
    Map<String, List<String>> graphDependency = parseDependencies(topologyGraph);
    Map<String, List<Event>> externalErrors = m_externalInfoBuilder.queryDependencyEvent(graphDependency,
          model.getDomain(), reportTime);

    DependencyReport report = queryDependencyReport(payload);
    buildHourlyReport(report, model, payload);
    model.setEvents(externalErrors);
    m_externalInfoBuilder.buildZabbixErrorOnGraph(topologyGraph,
          m_externalInfoBuilder.buildZabbixHeader(payload, model), externalErrors);
    m_externalInfoBuilder.buildExceptionInfoOnGraph(payload, model, topologyGraph);
    model.setReportStart(new Date(payload.getDate()));
    model.setReportEnd(new Date(payload.getDate() + TimeHelper.ONE_HOUR - 1));
    String build = new DefaultJsonBuilder().build(topologyGraph);

    model.setTopologyGraph(build);
  }

  @Override
  @PayloadMeta(Payload.class)
  @InboundActionMeta(name = DependencyAnalyzer.ID)
  public void handleInbound(Context ctx) throws ServletException, IOException {
  }

  @Override
  @OutboundActionMeta(name = DependencyAnalyzer.ID)
  public void handleOutbound(Context ctx) throws ServletException, IOException {
    Model model = new Model(ctx);
    Payload payload = ctx.getPayload();

    normalize(model, payload);

    Action action = payload.getAction();
    long date = payload.getDate();
    Date reportTime = new Date(date + TimeHelper.ONE_MINUTE * model.getMinute());

    switch (action) {
    case TOPOLOGY:
      buildProjectTopology(model, payload, reportTime);
      break;
    case LINE_CHART:
      buildDependencyLineChart(model, payload, reportTime);
      break;
    case DEPENDENCY_DASHBOARD:
      buildDependencyDashboard(model, payload, reportTime);
      break;
    case EXCEPTION_DASHBOARD:
      buildExceptionDashboard(model, payload, date);
     
      StateReport report = queryHourlyReport(payload);
      model.setMessage(buildCatInfoMessage(report));
      break;
    }
    m_jspViewer.view(ctx, model);
  }

  private void normalize(Model model, Payload payload) {
    model.setPage(ReportPage.DEPENDENCY);
    model.setAction(Action.LINE_CHART);

    m_normalizePayload.normalize(model, payload);

    Integer minute = parseQueryMinute(payload);
    int maxMinute = 60;
    List<Integer> minutes = new ArrayList<Integer>();

    if (payload.getPeriod().isCurrent()) {
      long current = System.currentTimeMillis() / 1000 / 60;
      maxMinute = (int) (current % (60));
    }
    for (int i = 0; i < 60; i++) {
      minutes.add(i);
    }
    model.setMinute(minute);
    model.setMaxMinute(maxMinute);
    model.setMinutes(minutes);
  }

  private Map<String, List<String>> parseDependencies(Segment segment) {
    Map<String, List<String>> results = new TreeMap<String, List<String>>();
    if (segment != null) {
      Map<String, Dependency> dependencies = segment.getDependencies();

      for (Dependency temp : dependencies.values()) {
        String type = temp.getType();
        String target = temp.getTarget();
        List<String> targets = results.get(type);

        if (targets == null) {
          targets = new ArrayList<String>();
          results.put(type, targets);
        }
        targets.add(target);
      }
    }
    return results;
  }

  private Map<String, List<String>> parseDependencies(TopologyGraph graph) {
    Map<String, List<String>> dependencies = new HashMap<String, List<String>>();
    Map<String, TopologyEdge> edges = graph.getEdges();

    for (TopologyEdge temp : edges.values()) {
      String type = temp.getType();
      String target = temp.getTarget();

      List<String> targets = dependencies.get(type);
      if (targets == null) {
        targets = new ArrayList<String>();
        dependencies.put(type, targets);
      }
      targets.add(target);
    }
    return dependencies;
  }

  private int parseQueryMinute(Payload payload) {
    int minute = 0;
    String min = payload.getMinute();

    if (StringUtil.isEmpty(min)) {
      long current = System.currentTimeMillis() / 1000 / 60;
      minute = (int) (current % (60));
    } else {
      minute = Integer.parseInt(min);
    }

    return minute;
  }

  private DependencyReport queryDependencyReport(Payload payload) {
    String domain = payload.getDomain();
    ModelRequest request = new ModelRequest(domain, payload.getDate());

    if (m_dependencyService.isEligable(request)) {
      ModelResponse<DependencyReport> response = m_dependencyService.invoke(request);
      DependencyReport report = response.getModel();

      if (report != null && report.getStartTime() == null) {
        report.setStartTime(new Date(payload.getDate()));
        report.setStartTime(new Date(payload.getDate() + TimeHelper.ONE_HOUR));
      }
      return report;
    } else {
      throw new RuntimeException("Internal error: no eligable dependency service registered for " + request + "!");
    }
  }

  private StateReport queryHourlyReport(Payload payload) {
    String domain = Constants.CAT;
    ModelRequest request = new ModelRequest(domain, payload.getDate()) //
          .setProperty("ip", payload.getIpAddress());

    if (m_stateService.isEligable(request)) {
      ModelResponse<StateReport> response = m_stateService.invoke(request);

      return response.getModel();
    } else {
      throw new RuntimeException("Internal error: no eligable sql service registered for " + request + "!");
    }
  }

}
TOP

Related Classes of com.dianping.cat.report.page.dependency.Handler

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.