View Javadoc

1   package org.whatsitcalled.webflange.service;
2   
3   import java.awt.Color;
4   import java.awt.image.BufferedImage;
5   import java.text.SimpleDateFormat;
6   import java.util.Calendar;
7   import java.util.Date;
8   import java.util.List;
9   
10  import org.apache.log4j.Logger;
11  import org.jfree.chart.ChartFactory;
12  import org.jfree.chart.JFreeChart;
13  import org.jfree.chart.axis.DateAxis;
14  import org.jfree.chart.axis.NumberAxis;
15  import org.jfree.chart.plot.PlotOrientation;
16  import org.jfree.chart.plot.XYPlot;
17  import org.jfree.chart.renderer.xy.XYItemRenderer;
18  import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
19  import org.jfree.data.time.FixedMillisecond;
20  import org.jfree.data.time.TimeSeries;
21  import org.jfree.data.time.TimeSeriesCollection;
22  import org.jfree.data.xy.XYSeries;
23  import org.jfree.data.xy.XYSeriesCollection;
24  import org.jfree.ui.RectangleInsets;
25  import org.whatsitcalled.webflange.file.FileManager;
26  import org.whatsitcalled.webflange.file.FileManagerException;
27  import org.whatsitcalled.webflange.model.Chart;
28  import org.whatsitcalled.webflange.model.ChartDAO;
29  import org.whatsitcalled.webflange.model.LoadTest;
30  import org.whatsitcalled.webflange.model.LoadTestDAO;
31  import org.whatsitcalled.webflange.model.LoadTestRun;
32  import org.whatsitcalled.webflange.model.LoadTestRunDAO;
33  import org.whatsitcalled.webflange.model.LoadTestSummary;
34  import org.whatsitcalled.webflange.model.LoadTestSummaryDAO;
35  
36  //TODO provide a way to configure width, height and y axis label
37  public class ChartServiceImpl implements ChartService {
38  	ChartDAO chartDAO;
39  
40  	LoadTestDAO loadTestDAO;
41  
42  	LoadTestRunDAO runDAO;
43  
44  	FileManager fileManager;
45  
46  	LoadTestSummaryDAO summaryDAO;
47  
48  	private static Logger LOGGER = Logger.getLogger(ChartServiceImpl.class);
49  
50  	public void generateDefaultChart(Chart chart, Long loadTestId) {
51  		LoadTest test = loadTestDAO.getLoadTest(loadTestId);
52  		reGenerateDefaultChart(chart, test);
53  		test.getCharts().add(chart);
54  
55  		loadTestDAO.saveLoadTest(test);
56  
57  	}
58  
59  	public void reGenerateDefaultChart(Chart chart, LoadTest test) {
60  		chart.setTime(Calendar.getInstance().getTimeInMillis());
61  		List summaries = summaryDAO.getLoadTestRunTotals(test);
62  
63  		// Create a series for each stat
64  		// TODO we need a way to configure the y axis
65  		// label
66  		TimeSeries testsSeries = new TimeSeries("Tests", FixedMillisecond.class);
67  		TimeSeries errorsSeries = new TimeSeries("Errors",
68  				FixedMillisecond.class);
69  		TimeSeries meanTestTimeSeries = new TimeSeries("Avg. Response Time",
70  				FixedMillisecond.class);
71  		TimeSeries testTimeStandardDeviationSeries = new TimeSeries(
72  				"Resp. Time Standard Deviation", FixedMillisecond.class);
73  		TimeSeries meanResponseLengthSeries = new TimeSeries(
74  				"Mean Response Length", FixedMillisecond.class);
75  		TimeSeries responseBytesPerSecondSeries = new TimeSeries(
76  				"Response Bytes Per Second", FixedMillisecond.class);
77  		TimeSeries responseErrorsSeries = new TimeSeries("Response Errors",
78  				FixedMillisecond.class);
79  		TimeSeries meanTimeToResolveHostSeries = new TimeSeries(
80  				"Mean Time To Resolve Host", FixedMillisecond.class);
81  		TimeSeries meanTimeToEstablishConnectionSeries = new TimeSeries(
82  				"Mean Time To Establish Connection", FixedMillisecond.class);
83  		TimeSeries meanTimeToFirstByteSeries = new TimeSeries(
84  				"Mean Time To First Byte", FixedMillisecond.class);
85  
86  		for (Object o : summaries) {
87  			LoadTestSummary s = (LoadTestSummary) o;
88  			FixedMillisecond m = new FixedMillisecond(new Date(s.getRun()
89  					.getTime()));
90  			// add to each series
91  			testsSeries.add(m, s.getTests());
92  			errorsSeries.add(m, s.getErrors());
93  			meanTestTimeSeries.add(m, s.getMeanTestTime());
94  			testTimeStandardDeviationSeries.add(m, s
95  					.getTestTimeStandardDeviation());
96  			meanResponseLengthSeries.add(m, s.getMeanResponseLength());
97  			responseBytesPerSecondSeries.add(m, s.getResponseBytesPerSecond());
98  			responseErrorsSeries.add(m, s.getResponseErrors());
99  			meanTimeToResolveHostSeries.add(m, s.getMeanTimeToResolveHost());
100 			meanTimeToEstablishConnectionSeries.add(m, s
101 					.getMeanTimeToEstablishConnection());
102 			meanTimeToFirstByteSeries.add(m, s.getMeanTimeToFirstByte());
103 		}
104 
105 		TimeSeriesCollection dataset = new TimeSeriesCollection();
106 		// add all selected series to the dataset
107 		if (chart.isShowTests())
108 			dataset.addSeries(testsSeries);
109 		if (chart.isShowErrors())
110 			dataset.addSeries(errorsSeries);
111 		if (chart.isShowMeanTestTime())
112 			dataset.addSeries(meanTestTimeSeries);
113 		if (chart.isShowTestTimeStandardDeviation())
114 			dataset.addSeries(testTimeStandardDeviationSeries);
115 		if (chart.isShowMeanResponseLength())
116 			dataset.addSeries(meanResponseLengthSeries);
117 		if (chart.isShowResponseBytesPerSecond())
118 			dataset.addSeries(responseBytesPerSecondSeries);
119 		if (chart.isShowResponseErrors())
120 			dataset.addSeries(responseErrorsSeries);
121 		if (chart.isShowMeanTimeToResolveHost())
122 			dataset.addSeries(meanTimeToResolveHostSeries);
123 		if (chart.isShowMeanTimeToEstablishConnection())
124 			dataset.addSeries(meanTimeToEstablishConnectionSeries);
125 		if (chart.isShowMeanTimeToFirstByte())
126 			dataset.addSeries(meanTimeToFirstByteSeries);
127 
128 		JFreeChart chart1 = ChartFactory.createTimeSeriesChart(chart.getName(), // title
129 				"Run Time", // x-axis label
130 				"Units", // y-axis label
131 				dataset, // data
132 				true, // create legend?
133 				true, // generate tooltips?
134 				false // generate URLs?
135 				);
136 
137 		chart1.setBackgroundPaint(Color.white);
138 
139 		XYPlot plot = (XYPlot) chart1.getPlot();
140 		plot.setBackgroundPaint(Color.white);
141 		plot.setDomainGridlinePaint(Color.white);
142 		plot.setRangeGridlinePaint(Color.white);
143 		plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
144 		plot.setDomainCrosshairVisible(true);
145 		plot.setRangeCrosshairVisible(true);
146 
147 		XYItemRenderer r = plot.getRenderer();
148 		if (r instanceof XYLineAndShapeRenderer) {
149 			XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
150 			renderer.setBaseShapesVisible(true);
151 			renderer.setBaseShapesFilled(true);
152 		}
153 
154 		DateAxis axis = (DateAxis) plot.getDomainAxis();
155 		axis.setDateFormatOverride(new SimpleDateFormat("MM-dd-yyyy HH:mm:ss"));
156 
157 		BufferedImage bi = chart1.createBufferedImage(800, 600);
158 		chart.setChartImage(bi);
159 
160 		chartDAO.saveChart(chart);
161 	}
162 
163 	public void generateDefaultChart(Chart chart, LoadTestRun run) {
164 
165 		reGenerateDefaultChart(chart, run);
166 		run.getCharts().add(chart);
167 
168 		runDAO.saveLoadTestRun(run);
169 	}
170 
171 	public void reGenerateDefaultChart(Chart chart, LoadTestRun run) {
172 		chart.setTime(Calendar.getInstance().getTimeInMillis());
173 		List summaries = summaryDAO.getLoadTestSummaries(run);
174 
175 		// Create a series for each stat
176 		// TODO we need a way to configure the y axis label
177 		XYSeries testsSeries = new XYSeries("Tests");
178 		XYSeries errorsSeries = new XYSeries("Errors");
179 		XYSeries meanTestTimeSeries = new XYSeries("Avg. Response Time");
180 		XYSeries testTimeStandardDeviationSeries = new XYSeries(
181 				"Resp. Time Standard Deviation");
182 		XYSeries meanResponseLengthSeries = new XYSeries("Mean Response Length");
183 		XYSeries responseBytesPerSecondSeries = new XYSeries(
184 				"Response Bytes Per Second");
185 		XYSeries responseErrorsSeries = new XYSeries("Response Errors");
186 		XYSeries meanTimeToResolveHostSeries = new XYSeries(
187 				"Mean Time To Resolve Host");
188 		XYSeries meanTimeToEstablishConnectionSeries = new XYSeries(
189 				"Mean Time To Establish Connection");
190 		XYSeries meanTimeToFirstByteSeries = new XYSeries(
191 				"Mean Time To First Byte");
192 
193 		int n = 0;
194 		for (Object o : summaries) {
195 			LoadTestSummary s = (LoadTestSummary) o;
196 			// add to each series
197 			testsSeries.add(n, s.getTests());
198 			errorsSeries.add(n, s.getErrors());
199 			meanTestTimeSeries.add(n, s.getMeanTestTime());
200 			testTimeStandardDeviationSeries.add(n, s
201 					.getTestTimeStandardDeviation());
202 			meanResponseLengthSeries.add(n, s.getMeanResponseLength());
203 			responseBytesPerSecondSeries.add(n, s.getResponseBytesPerSecond());
204 			responseErrorsSeries.add(n, s.getResponseErrors());
205 			meanTimeToResolveHostSeries.add(n, s.getMeanTimeToResolveHost());
206 			meanTimeToEstablishConnectionSeries.add(n, s
207 					.getMeanTimeToEstablishConnection());
208 			meanTimeToFirstByteSeries.add(n, s.getMeanTimeToFirstByte());
209 			n++;
210 		}
211 
212 		XYSeriesCollection dataset = new XYSeriesCollection();
213 		// add all selected series to the dataset
214 		if (chart.isShowTests())
215 			dataset.addSeries(testsSeries);
216 		if (chart.isShowErrors())
217 			dataset.addSeries(errorsSeries);
218 		if (chart.isShowMeanTestTime())
219 			dataset.addSeries(meanTestTimeSeries);
220 		if (chart.isShowTestTimeStandardDeviation())
221 			dataset.addSeries(testTimeStandardDeviationSeries);
222 		if (chart.isShowMeanResponseLength())
223 			dataset.addSeries(meanResponseLengthSeries);
224 		if (chart.isShowResponseBytesPerSecond())
225 			dataset.addSeries(responseBytesPerSecondSeries);
226 		if (chart.isShowResponseErrors())
227 			dataset.addSeries(responseErrorsSeries);
228 		if (chart.isShowMeanTimeToResolveHost())
229 			dataset.addSeries(meanTimeToResolveHostSeries);
230 		if (chart.isShowMeanTimeToEstablishConnection())
231 			dataset.addSeries(meanTimeToEstablishConnectionSeries);
232 		if (chart.isShowMeanTimeToFirstByte())
233 			dataset.addSeries(meanTimeToFirstByteSeries);
234 
235 		JFreeChart chart1 = ChartFactory.createScatterPlot(chart.getName(), // title
236 				"Test", // x-axis label
237 				"Units", // y-axis label
238 				dataset, // data
239 				PlotOrientation.VERTICAL, // plot orientation
240 				true, // create legend?
241 				true, // generate tooltips?
242 				false // generate URLs?
243 				);
244 
245 		chart1.setBackgroundPaint(Color.white);
246 
247 		XYPlot plot = (XYPlot) chart1.getPlot();
248 		// change the auto tick unit selection to integer units only...
249 		plot.getDomainAxis().setStandardTickUnits(
250 				NumberAxis.createIntegerTickUnits());
251 		plot.setBackgroundPaint(Color.white);
252 		plot.setDomainGridlinePaint(Color.white);
253 		plot.setRangeGridlinePaint(Color.white);
254 		plot.setAxisOffset(new RectangleInsets(10.0, 10.0, 10.0, 10.0));
255 		plot.setDomainCrosshairVisible(true);
256 		plot.setRangeCrosshairVisible(true);
257 
258 		XYItemRenderer r = plot.getRenderer();
259 		if (r instanceof XYLineAndShapeRenderer) {
260 			XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
261 			renderer.setBaseShapesVisible(false);
262 			renderer.setBaseItemLabelsVisible(false);
263 			renderer.setBaseShapesFilled(true);
264 
265 			int sn = 0;
266 			if (chart.isShowTests()) {
267 				renderer.setSeriesPaint(sn, Color.red);
268 				renderer.setSeriesShapesVisible(sn, true);
269 				renderer.setSeriesItemLabelsVisible(sn, true);
270 				sn++;
271 			}
272 			if (chart.isShowErrors()) {
273 				renderer.setSeriesPaint(sn, Color.black);
274 				renderer.setSeriesShapesVisible(sn, true);
275 				renderer.setSeriesItemLabelsVisible(sn, true);
276 				sn++;
277 			}
278 			if (chart.isShowMeanTestTime()) {
279 				renderer.setSeriesPaint(sn, Color.blue);
280 				renderer.setSeriesShapesVisible(sn, true);
281 				renderer.setSeriesItemLabelsVisible(sn, true);
282 				sn++;
283 			}
284 			if (chart.isShowTestTimeStandardDeviation()) {
285 				renderer.setSeriesPaint(sn, Color.cyan);
286 				renderer.setSeriesShapesVisible(sn, true);
287 				renderer.setSeriesItemLabelsVisible(sn, true);
288 				sn++;
289 			}
290 			if (chart.isShowMeanResponseLength()) {
291 				renderer.setSeriesPaint(sn, Color.darkGray);
292 				renderer.setSeriesShapesVisible(sn, true);
293 				renderer.setSeriesItemLabelsVisible(sn, true);
294 				sn++;
295 			}
296 			if (chart.isShowResponseBytesPerSecond()) {
297 				renderer.setSeriesPaint(sn, Color.green);
298 				renderer.setSeriesShapesVisible(sn, true);
299 				renderer.setSeriesItemLabelsVisible(sn, true);
300 				sn++;
301 			}
302 			if (chart.isShowResponseErrors()) {
303 				renderer.setSeriesPaint(sn, Color.magenta);
304 				renderer.setSeriesShapesVisible(sn, true);
305 				renderer.setSeriesItemLabelsVisible(sn, true);
306 				sn++;
307 			}
308 			if (chart.isShowMeanTimeToResolveHost()) {
309 				renderer.setSeriesPaint(sn, Color.orange);
310 				renderer.setSeriesShapesVisible(sn, true);
311 				renderer.setSeriesItemLabelsVisible(sn, true);
312 				sn++;
313 			}
314 			if (chart.isShowMeanTimeToEstablishConnection()) {
315 				renderer.setSeriesPaint(sn, Color.pink);
316 				renderer.setSeriesShapesVisible(sn, true);
317 				renderer.setSeriesItemLabelsVisible(sn, true);
318 				sn++;
319 			}
320 			if (chart.isShowMeanTimeToFirstByte()) {
321 				renderer.setSeriesPaint(sn, Color.yellow);
322 				renderer.setSeriesShapesVisible(sn, true);
323 				renderer.setSeriesItemLabelsVisible(sn, true);
324 			}
325 		}
326 		
327 		n = 0;
328 /*		for (Object o : summaries) {
329 			LoadTestSummary s = (LoadTestSummary) o;
330 			plot.getDomainAxis().setLabel(s.getTestUri());
331 			plot.getDomainAxis(n).setLabelAngle(90);
332 			n++;
333 		}
334 */
335 		// TODO overide the axis with the test names
336 		// DateAxis axis = (DateAxis) plot.getDomainAxis();
337 		// axis.setDateFormatOverride(new SimpleDateFormat("MM-dd-yyyy
338 		// HH:mm:ss"));
339 
340 		BufferedImage bi = chart1.createBufferedImage(800, 600);
341 		chart.setChartImage(bi);
342 
343 		chartDAO.saveChart(chart);
344 
345 	}
346 
347 	public void prepareChart(Chart chart, Long loadTestId) {
348 		LoadTest test = loadTestDAO.getLoadTest(loadTestId);
349 		long chartTime = chart.getTime();
350 		long runTime = test.getLastRun().getTime();
351 		// TODO first check if the chart needs to be regenerated
352 		LOGGER.debug("Checking if chart should be regenerated.  chartTime: "
353 				+ chartTime + " runTime: " + runTime);
354 		if (chartTime < runTime) {
355 			LOGGER.debug("Regenerating chart: " + chart.getId());
356 			reGenerateDefaultChart(chart, test);
357 		}
358 		// Load the image
359 		try {
360 			fileManager.loadChartFile(chart);
361 		} catch (FileManagerException e) {
362 			// TODO Auto-generated catch block
363 			e.printStackTrace();
364 		}
365 
366 	}
367 
368 	public void prepareChart(Chart chart, LoadTestRun run) {
369 		//first check if the chart needs to be regenerated
370 		if (chart.getTime() < run.getTime()) {
371 			reGenerateDefaultChart(chart, run);
372 		}
373 		// Load the image
374 		try {
375 			fileManager.loadChartFile(chart);
376 		} catch (FileManagerException e) {
377 			// TODO Auto-generated catch block
378 			e.printStackTrace();
379 		}
380 
381 	}
382 
383 	public void removeChart(Chart chart, LoadTest test) {
384 		try {
385 			fileManager.deleteChartFile(chart);
386 		} catch (FileManagerException e) {
387 			LOGGER.error("Unable to delete chart file.",e);
388 		}
389 		test.getCharts().remove(chart);
390 		loadTestDAO.saveLoadTest(test);
391 	}
392 
393 	public void removeChart(Chart chart, LoadTestRun run) {
394 		try {
395 			fileManager.deleteChartFile(chart);
396 		} catch (FileManagerException e) {
397 			// TODO Auto-generated catch block
398 			e.printStackTrace();
399 		}
400 		run.getCharts().remove(chart);
401 		runDAO.saveLoadTestRun(run);
402 	}
403 
404 	public void saveChart(Chart chart) {
405 		chartDAO.saveChart(chart);
406 	}
407 
408 	public ChartDAO getChartDAO() {
409 		return chartDAO;
410 	}
411 
412 	public void setChartDAO(ChartDAO chartDAO) {
413 		this.chartDAO = chartDAO;
414 	}
415 
416 	public FileManager getFileManager() {
417 		return fileManager;
418 	}
419 
420 	public void setFileManager(FileManager fileManager) {
421 		this.fileManager = fileManager;
422 	}
423 
424 	public LoadTestDAO getLoadTestDAO() {
425 		return loadTestDAO;
426 	}
427 
428 	public void setLoadTestDAO(LoadTestDAO loadTestDAO) {
429 		this.loadTestDAO = loadTestDAO;
430 	}
431 
432 	public LoadTestSummaryDAO getSummaryDAO() {
433 		return summaryDAO;
434 	}
435 
436 	public void setSummaryDAO(LoadTestSummaryDAO summaryDAO) {
437 		this.summaryDAO = summaryDAO;
438 	}
439 
440 	public LoadTestRunDAO getRunDAO() {
441 		return runDAO;
442 	}
443 
444 	public void setRunDAO(LoadTestRunDAO runDAO) {
445 		this.runDAO = runDAO;
446 	}
447 
448 }