Handler.java 9.3 KB
Newer Older
1 2 3
package com.dianping.cat.report.page.storage;

import java.io.IOException;
4
import java.util.ArrayList;
J
jialinsun 已提交
5
import java.util.Date;
6
import java.util.HashSet;
J
jialinsun 已提交
7
import java.util.LinkedHashMap;
8
import java.util.List;
9
import java.util.Map;
J
jialinsun 已提交
10
import java.util.Map.Entry;
11 12 13 14 15 16
import java.util.Set;

import javax.servlet.ServletException;

import org.unidal.lookup.annotation.Inject;
import org.unidal.lookup.util.StringUtils;
J
jialinsun 已提交
17
import org.unidal.tuple.Pair;
18 19 20 21 22 23 24 25 26
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.consumer.storage.StorageAnalyzer;
import com.dianping.cat.consumer.storage.model.entity.StorageReport;
import com.dianping.cat.helper.JsonBuilder;
J
jialinsun 已提交
27
import com.dianping.cat.helper.SortHelper;
28
import com.dianping.cat.helper.TimeHelper;
J
jialinsun 已提交
29
import com.dianping.cat.home.storage.alert.entity.Storage;
30
import com.dianping.cat.home.storage.alert.entity.StorageAlertInfo;
31 32 33
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.graph.LineChart;
import com.dianping.cat.report.page.PayloadNormalizer;
Y
youyong205 已提交
34
import com.dianping.cat.report.page.storage.task.StorageReportService;
J
jialinsun 已提交
35
import com.dianping.cat.report.page.storage.topology.StorageAlertInfoManager;
Y
youyong205 已提交
36 37 38
import com.dianping.cat.report.page.storage.transform.HourlyLineChartVisitor;
import com.dianping.cat.report.page.storage.transform.StorageMergeHelper;
import com.dianping.cat.report.page.storage.transform.StorageOperationFilter;
Y
youyong205 已提交
39
import com.dianping.cat.report.service.ModelService;
40 41
import com.dianping.cat.service.ModelRequest;
import com.dianping.cat.service.ModelResponse;
42
import com.dianping.cat.system.config.StorageGroupConfigManager;
J
jialinsun 已提交
43
import com.dianping.cat.system.config.StorageGroupConfigManager.Department;
44 45 46 47 48

public class Handler implements PageHandler<Context> {
	@Inject
	private JspViewer m_jspViewer;

J
jialinsun 已提交
49
	@Inject
Y
youyong205 已提交
50
	private StorageReportService m_reportService;
J
jialinsun 已提交
51

52 53 54 55 56 57 58
	@Inject
	private PayloadNormalizer m_normalizePayload;

	@Inject(type = ModelService.class, value = StorageAnalyzer.ID)
	private ModelService<StorageReport> m_service;

	@Inject
J
jialinsun 已提交
59
	private StorageMergeHelper m_mergeHelper;
60

61
	@Inject
J
jialinsun 已提交
62
	private StorageAlertInfoManager m_alertInfoManager;
63 64 65 66

	@Inject
	private StorageGroupConfigManager m_storageGroupConfigManager;

67 68 69
	@Inject
	private JsonBuilder m_jsonBuilder;

J
jialinsun 已提交
70 71
	private Map<String, Map<String, List<String>>> buildAlertLinks(Map<String, StorageAlertInfo> alertInfos, String type) {
		Map<String, Map<String, List<String>>> links = new LinkedHashMap<String, Map<String, List<String>>>();
J
jialinsun 已提交
72 73 74 75 76 77 78 79 80 81
		String format = m_storageGroupConfigManager.getSqlLinkFormat();
		
		if (format != null) {
			for (Entry<String, StorageAlertInfo> alertInfo : alertInfos.entrySet()) {
				String key = alertInfo.getKey();
				Map<String, List<String>> linkMap = links.get(key);

				if (linkMap == null) {
					linkMap = new LinkedHashMap<String, List<String>>();
					links.put(key, linkMap);
J
jialinsun 已提交
82
				}
J
jialinsun 已提交
83 84 85 86 87 88 89 90 91 92 93
				for (Entry<String, Storage> entry : alertInfo.getValue().getStorages().entrySet()) {
					String id = entry.getKey();
					Storage storage = entry.getValue();
					List<String> ls = linkMap.get(id);

					if (ls == null) {
						ls = new ArrayList<String>();
						linkMap.put(id, ls);
					}
					for (String ip : storage.getMachines().keySet()) {
						String url = m_storageGroupConfigManager.buildUrl(format, id, ip);
J
jialinsun 已提交
94

J
jialinsun 已提交
95 96 97
						if (url != null) {
							ls.add(url);
						}
J
jialinsun 已提交
98 99 100 101 102 103 104
					}
				}
			}
		}
		return links;
	}

J
jialinsun 已提交
105 106
	private void buildLineCharts(Model model, Payload payload, String ipAddress, StorageReport storageReport) {
		HourlyLineChartVisitor visitor = new HourlyLineChartVisitor(ipAddress, payload.getProject(),
J
jialinsun 已提交
107
		      storageReport.getOps(), storageReport.getStartTime());
J
jialinsun 已提交
108

J
jialinsun 已提交
109 110 111 112 113 114 115 116 117
		visitor.visitStorageReport(storageReport);
		Map<String, LineChart> lineCharts = visitor.getLineChart();

		model.setCountTrend(m_jsonBuilder.toJson(lineCharts.get(StorageConstants.COUNT)));
		model.setAvgTrend(m_jsonBuilder.toJson(lineCharts.get(StorageConstants.AVG)));
		model.setErrorTrend(m_jsonBuilder.toJson(lineCharts.get(StorageConstants.ERROR)));
		model.setLongTrend(m_jsonBuilder.toJson(lineCharts.get(StorageConstants.LONG)));
	}

J
jialinsun 已提交
118
	private Pair<Boolean, Set<String>> buildOperations(Payload payload, Model model, Set<String> defaultValue) {
J
jialinsun 已提交
119
		String operations = payload.getOperations();
J
jialinsun 已提交
120
		Set<String> ops = new HashSet<String>();
J
jialinsun 已提交
121
		boolean filter = false;
J
jialinsun 已提交
122

J
jialinsun 已提交
123 124 125
		if (operations.length() > 0) {
			filter = true;
			String[] op = operations.split(";");
J
jialinsun 已提交
126

J
jialinsun 已提交
127 128
			for (int i = 0; i < op.length; i++) {
				ops.add(op[i]);
J
jialinsun 已提交
129 130
			}
		} else {
J
jialinsun 已提交
131
			ops.addAll(defaultValue);
J
jialinsun 已提交
132
		}
J
jialinsun 已提交
133
		return new Pair<Boolean, Set<String>>(filter, ops);
J
jialinsun 已提交
134 135
	}

J
jialinsun 已提交
136 137 138 139
	private String buildOperationStr(List<String> ops) {
		return StringUtils.join(ops, ";");
	}

J
jialinsun 已提交
140
	private StorageReport buildReport(Payload payload, Model model, StorageReport storageReport) {
J
jialinsun 已提交
141
		if (storageReport != null) {
J
jialinsun 已提交
142 143 144 145
			Set<String> allOps = storageReport.getOps();
			model.setOperations(allOps);

			Pair<Boolean, Set<String>> pair = buildOperations(payload, model, allOps);
J
jialinsun 已提交
146
			storageReport = m_mergeHelper.mergeReport(storageReport, payload.getIpAddress(), Constants.ALL);
J
jialinsun 已提交
147

J
jialinsun 已提交
148
			if (pair.getKey()) {
J
jialinsun 已提交
149
				StorageOperationFilter filter = new StorageOperationFilter(pair.getValue());
J
jialinsun 已提交
150 151 152 153
				filter.visitStorageReport(storageReport);

				storageReport = filter.getStorageReport();
			}
J
jialinsun 已提交
154 155 156 157
			StorageSorter sorter = new StorageSorter(storageReport, payload.getSort());
			storageReport = sorter.getSortedReport();

			model.setReport(storageReport);
J
jialinsun 已提交
158

J
jialinsun 已提交
159 160 161
			Map<String, Department> departments = m_storageGroupConfigManager.queryStorageDepartments(
			      SortHelper.sortDomain(storageReport.getIds()), payload.getType());
			model.setDepartments(departments);
J
jialinsun 已提交
162

J
jialinsun 已提交
163
		}
J
jialinsun 已提交
164
		return storageReport;
J
jialinsun 已提交
165
	}
J
jialinsun 已提交
166

J
jialinsun 已提交
167 168 169 170
	private String buildReportId(Payload payload) {
		return payload.getId() + "-" + payload.getType();
	}

171 172 173 174 175 176 177 178 179 180 181 182 183
	@Override
	@PayloadMeta(Payload.class)
	@InboundActionMeta(name = "storage")
	public void handleInbound(Context ctx) throws ServletException, IOException {
	}

	@Override
	@OutboundActionMeta(name = "storage")
	public void handleOutbound(Context ctx) throws ServletException, IOException {
		Model model = new Model(ctx);
		Payload payload = ctx.getPayload();
		normalize(model, payload);
		String ipAddress = payload.getIpAddress();
J
jialinsun 已提交
184
		StorageReport storageReport = null;
185 186

		switch (payload.getAction()) {
J
jialinsun 已提交
187 188
		case HOURLY_STORAGE:
			storageReport = queryHourlyReport(payload);
J
jialinsun 已提交
189 190

			buildReport(payload, model, storageReport);
191
			break;
J
jialinsun 已提交
192 193
		case HOURLY_STORAGE_GRAPH:
			storageReport = queryHourlyReport(payload);
J
jialinsun 已提交
194
			storageReport = buildReport(payload, model, storageReport);
J
jialinsun 已提交
195

196 197
			buildLineCharts(model, payload, ipAddress, storageReport);
			break;
J
jialinsun 已提交
198 199
		case HISTORY_STORAGE:
			storageReport = queryHistoryReport(payload);
J
jialinsun 已提交
200 201

			buildReport(payload, model, storageReport);
J
jialinsun 已提交
202
			break;
203
		case DASHBOARD:
J
jialinsun 已提交
204
			Map<String, StorageAlertInfo> alertInfos = m_alertInfoManager.queryAlertInfos(payload, model);
205

J
jialinsun 已提交
206 207
			model.setLinks(buildAlertLinks(alertInfos, payload.getType()));
			model.setAlertInfos(alertInfos);
208 209 210
			model.setReportStart(new Date(payload.getDate()));
			model.setReportEnd(new Date(payload.getDate() + TimeHelper.ONE_HOUR - 1));
			break;
211
		}
J
jialinsun 已提交
212

213 214 215 216 217 218 219
		model.setPage(ReportPage.STORAGE);

		if (!ctx.isProcessStopped()) {
			m_jspViewer.view(ctx, model);
		}
	}

J
jialinsun 已提交
220 221 222
	private void normalize(Model model, Payload payload) {
		model.setPage(ReportPage.STORAGE);
		m_normalizePayload.normalize(model, payload);
223

J
jialinsun 已提交
224 225 226 227
		if (payload.getAction() == Action.DASHBOARD) {
			Integer minute = parseQueryMinute(payload);
			int maxMinute = 60;
			List<Integer> minutes = new ArrayList<Integer>();
228

J
jialinsun 已提交
229 230 231
			if (payload.getPeriod().isCurrent()) {
				long current = payload.getCurrentTimeMillis() / 1000 / 60;
				maxMinute = (int) (current % (60));
232
			}
J
jialinsun 已提交
233 234 235 236 237 238
			for (int i = 0; i < 60; i++) {
				minutes.add(i);
			}
			model.setMinute(minute);
			model.setMaxMinute(maxMinute);
			model.setMinutes(minutes);
J
jialinsun 已提交
239 240 241 242 243 244 245 246 247 248 249 250 251
		} else {
			if (payload.getOperations() == null) {
				String type = payload.getType();
				List<String> defaultMethods = new ArrayList<String>();

				if (StorageConstants.CACHE_TYPE.equals(type)) {
					defaultMethods = StorageConstants.CACHE_METHODS;
				} else if (StorageConstants.SQL_TYPE.equals(type)) {
					defaultMethods = StorageConstants.SQL_METHODS;
				}

				payload.setOperations(buildOperationStr(defaultMethods));
			}
252 253 254
		}
	}

255 256 257 258 259 260 261 262 263 264 265 266 267 268
	private int parseQueryMinute(Payload payload) {
		int minute = 0;
		String min = payload.getMinute();

		if (StringUtils.isEmpty(min)) {
			long current = payload.getCurrentTimeMillis() / 1000 / 60;
			minute = (int) (current % (60));
		} else {
			minute = Integer.parseInt(min);
		}

		return minute;
	}

J
jialinsun 已提交
269
	public StorageReport queryHistoryReport(Payload payload) {
J
jialinsun 已提交
270 271
		Date start = payload.getHistoryStartDate();
		Date end = payload.getHistoryEndDate();
272

Y
youyong205 已提交
273
		return m_reportService.queryReport(buildReportId(payload), start, end);
J
jialinsun 已提交
274
	}
J
jialinsun 已提交
275

J
jialinsun 已提交
276 277
	private StorageReport queryHourlyReport(Payload payload) {
		ModelRequest request = new ModelRequest(buildReportId(payload), payload.getDate()).setProperty("ip",
J
jialinsun 已提交
278
		      payload.getIpAddress());
J
jialinsun 已提交
279

J
jialinsun 已提交
280 281 282
		if (m_service.isEligable(request)) {
			ModelResponse<StorageReport> response = m_service.invoke(request);
			StorageReport report = response.getModel();
283

J
jialinsun 已提交
284 285 286
			return report;
		} else {
			throw new RuntimeException("Internal error: no eligable transaction service registered for " + request + "!");
287
		}
288 289
	}
}