1 package org.whatsitcalled.webflange.webapp;
2
3 import java.awt.Color;
4 import java.awt.Graphics2D;
5 import java.io.File;
6 import java.text.Format;
7 import java.text.SimpleDateFormat;
8 import java.util.ArrayList;
9 import java.util.Date;
10 import java.util.List;
11
12 import org.apache.log4j.Logger;
13 import org.apache.wicket.AttributeModifier;
14 import org.apache.wicket.PageParameters;
15 import org.apache.wicket.behavior.HeaderContributor;
16 import org.apache.wicket.behavior.SimpleAttributeModifier;
17 import org.apache.wicket.markup.html.IHeaderContributor;
18 import org.apache.wicket.markup.html.IHeaderResponse;
19 import org.apache.wicket.markup.html.basic.Label;
20 import org.apache.wicket.markup.html.form.Button;
21 import org.apache.wicket.markup.html.form.CheckBox;
22 import org.apache.wicket.markup.html.form.Form;
23 import org.apache.wicket.markup.html.form.RequiredTextField;
24 import org.apache.wicket.markup.html.form.TextField;
25 import org.apache.wicket.markup.html.image.Image;
26 import org.apache.wicket.markup.html.image.resource.RenderedDynamicImageResource;
27 import org.apache.wicket.markup.html.link.BookmarkablePageLink;
28 import org.apache.wicket.markup.html.link.DownloadLink;
29 import org.apache.wicket.markup.html.link.Link;
30 import org.apache.wicket.markup.html.list.ListItem;
31 import org.apache.wicket.markup.html.list.ListView;
32 import org.apache.wicket.markup.html.panel.Panel;
33 import org.apache.wicket.markup.repeater.Item;
34 import org.apache.wicket.markup.repeater.data.DataView;
35 import org.apache.wicket.markup.repeater.data.IDataProvider;
36 import org.apache.wicket.model.AbstractReadOnlyModel;
37 import org.apache.wicket.model.CompoundPropertyModel;
38 import org.apache.wicket.model.IModel;
39 import org.apache.wicket.model.Model;
40 import org.apache.wicket.model.PropertyModel;
41 import org.whatsitcalled.webflange.ResourceFactory;
42 import org.whatsitcalled.webflange.model.Chart;
43 import org.whatsitcalled.webflange.model.LoadTest;
44 import org.whatsitcalled.webflange.model.LoadTestRun;
45 import org.whatsitcalled.webflange.model.LoadTestSummary;
46 import org.whatsitcalled.webflange.service.LoadTestRunningException;
47 import org.whatsitcalled.webflange.webapp.model.LoadTestSummaryDataProvider;
48
49 public class ReportsPanel extends Panel {
50
51 private static final Logger LOGGER = Logger.getLogger(ReportsPanel.class);
52
53 private LoadTestReportPanel loadTestReportPanel;
54
55 private LoadTestRunReportPanel loadTestRunReportPanel;
56
57 public ReportsPanel(String arg0, PageParameters parameters) {
58 super(arg0);
59 loadTestReportPanel = new LoadTestReportPanel("loadTestReportPanel");
60 loadTestReportPanel.setVisible(false);
61 loadTestRunReportPanel = new LoadTestRunReportPanel(
62 "loadTestRunReportPanel");
63 loadTestRunReportPanel.setVisible(false);
64 add(loadTestReportPanel);
65 add(loadTestRunReportPanel);
66
67 if (parameters.containsKey("testId")) {
68 Long id = parameters.getLong("testId");
69 LoadTest test = ResourceFactory.getLoadTestDAO().getLoadTest(id);
70 loadTestReportPanel.setModel(new CompoundPropertyModel(test));
71 loadTestReportPanel.setVisible(true);
72 loadTestRunReportPanel.setVisible(false);
73 } else if (parameters.containsKey("runId")) {
74 Long id = parameters.getLong("runId");
75 LoadTestRun run = ResourceFactory.getLoadTestRunDAO()
76 .getLoadTestRun(id);
77 loadTestRunReportPanel.setModel(new CompoundPropertyModel(run));
78 loadTestRunReportPanel.setVisible(true);
79 loadTestReportPanel.setVisible(false);
80 }
81 }
82
83 public class ChartNavPanel extends Panel {
84 private LoadTest test;
85 private LoadTestRun run;
86 private List<Chart> charts;
87 public ChartNavPanel(String id, LoadTest test) {
88 super(id);
89 this.test = test;
90 this.run = null;
91 if (test.getRuns().size() < 1) {
92 this.charts = new ArrayList<Chart>();
93 this.setVisible(false);
94 } else {
95 this.charts = test.getCharts();
96 this.setVisible(true);
97 }
98 setModel(new CompoundPropertyModel(this.charts));
99 }
100
101 public ChartNavPanel(String id, LoadTestRun run) {
102 super(id);
103 this.test = null;
104 this.run = run;
105 this.charts = run.getCharts();
106 setModel(new CompoundPropertyModel(this.charts));
107 }
108
109 @Override
110 protected void onModelChanged() {
111 super.onModelChanged();
112 removeAll();
113 addOrReplace(new ListView("chartList", this.charts) {
114 public void populateItem(final ListItem item) {
115
116 final Chart chart = (Chart) item.getModelObject();
117
118
119 item.add(new Label("chartName", chart.getName() + " "));
120
121
122 Link chartLink = new Link("chartLink") {
123 public void onClick() {
124 Chart chart = (Chart) getParent().getModelObject();
125 if (chart.isVisible()) {
126 LOGGER
127 .debug("Hiding chart: "
128 + chart.getName());
129 chart.setVisible(false);
130 } else {
131 LOGGER.debug("Showing chart: "
132 + chart.getName());
133 chart.setVisible(true);
134 }
135 ResourceFactory.getChartService().saveChart(chart);
136 }
137 };
138 chartLink.add(new Label("chartVisible", new Model() {
139 public Object getObject() {
140 return chart.isVisible() ? "hide" : "show";
141 }
142 }));
143 item.add(chartLink);
144 item.add(new Link("deleteChart") {
145 public void onClick() {
146 Chart chart = (Chart) getParent().getModelObject();
147 if (run == null) {
148 ResourceFactory.getChartService().removeChart(chart, test);
149 loadTestReportPanel.removeAll();
150 loadTestReportPanel.setModelObject(test);
151 loadTestReportPanel.modelChanged();
152 } else {
153 ResourceFactory.getChartService().removeChart(chart, run);
154 loadTestRunReportPanel.removeAll();
155 loadTestRunReportPanel.setModelObject(run);
156 loadTestRunReportPanel.modelChanged();
157 }
158 }
159 });
160 }
161 });
162
163 addOrReplace(new ListView("charts", this.charts) {
164 public void populateItem(final ListItem item) {
165 final Chart chart = (Chart) item.getModelObject();
166
167
168 if (run == null ) {
169 ResourceFactory.getChartService().prepareChart(chart, test.getId());
170 }
171 else ResourceFactory.getChartService().prepareChart(chart, run);
172
173 ChartDynamicImageResource resource = new ChartDynamicImageResource(chart);
174
175
176 Image chartImage = new Image("chartImage", resource);
177 item.add(chartImage);
178 item.setVisible(chart.isVisible());
179 }
180 });
181 }
182 }
183
184 public class LoadTestReportPanel extends Panel {
185
186 private String name = "";
187
188 public LoadTestReportPanel(String arg0) {
189 super(arg0);
190 }
191
192 @Override
193 protected void onModelChanged() {
194 super.onModelChanged();
195 removeAll();
196 final LoadTest test = (LoadTest) getModelObject();
197
198 if (test.getEnabled()) {
199
200 HeaderContributor contributor = new HeaderContributor(
201 new IHeaderContributor() {
202 public void renderHead(IHeaderResponse response) {
203 response
204 .renderString("<meta http-equiv=\"refresh\" content=\"60\" >\n");
205 }
206 });
207 add(contributor);
208 }
209
210 addOrReplace(new Label("testName", test.getName()));
211
212
213 ChartNavPanel chartNavPanel = new ChartNavPanel("chartNav", test);
214 chartNavPanel.setVisible(test.getCharts().size() > 0);
215 addOrReplace(chartNavPanel);
216
217
218 LoadTestChartForm chartForm = new LoadTestChartForm("chartForm",
219 new CompoundPropertyModel(new Chart()),test);
220 addOrReplace(chartForm);
221 }
222 public void setLoadTest(final Long id) {
223 LoadTest newLoadTest = ResourceFactory
224 .getLoadTestService().getLoadTest(id);
225 ResourceFactory
226 .getLoadTestService().saveLoadTest(newLoadTest);
227 setModel(new CompoundPropertyModel(newLoadTest));
228 }
229
230 }
231
232 public class LoadTestChartForm extends Form {
233
234 private LoadTest loadTest;
235 private LoadTestSummaryDataView view;
236
237 public LoadTestChartForm(String arg0, IModel arg1, LoadTest test) {
238 super(arg0, arg1);
239 setLoadTest(test);
240 this.view = new LoadTestSummaryDataView("summaries",
241 new LoadTestSummaryDataProvider(test), test);
242 addOrReplace(view);
243 final Button delete = new Button("deleteButton") {
244 public void onSubmit() {
245 List<LoadTestRun> runs = view.getRuns();
246 try {
247 ResourceFactory.getLoadTestService()
248 .removeSelectedRuns(loadTest.getId(), runs);
249 loadTestReportPanel.setLoadTest(loadTest.getId());
250 } catch (LoadTestRunningException e) {
251 LOGGER.error("Unable to delete runs...");
252 }
253 }
254 };
255 delete.add(new SimpleAttributeModifier("onclick",
256 "return confirm('Delete selected runs?');"));
257 delete.add(new TestNotEnabledValidator(test.getId(), test.getName() + " must not be enabled or running to delete run data!"));
258 add(delete);
259
260 final Button chart = new Button("chartButton") {
261 public void onSubmit() {
262 Chart chart = getChart();
263 ResourceFactory.getChartService().generateDefaultChart(
264 chart, loadTest.getId());
265
266 List<LoadTestRun> runs = view.getRuns();
267 for (LoadTestRun run : runs) {
268 if (run.getSelected()) {
269 LOGGER.debug("Run is selected: " + run.getTime());
270 }
271 }
272 loadTestReportPanel.setLoadTest(loadTest.getId());
273 }
274
275 };
276 add(chart);
277
278 TextField name = new TextField("name") {
279 public boolean isRequired() {
280 Form form = (Form) findParent(Form.class);
281 return form.getRootForm().findSubmittingButton() == chart;
282 }
283
284 };
285
286 add(name);
287 add(new CheckBox("showTests"));
288 add(new CheckBox("showErrors"));
289 add(new CheckBox("showMeanTestTime"));
290 add(new CheckBox("showTestTimeStandardDeviation"));
291 add(new CheckBox("showMeanResponseLength"));
292 add(new CheckBox("showResponseBytesPerSecond"));
293 add(new CheckBox("showResponseErrors"));
294 add(new CheckBox("showMeanTimeToResolveHost"));
295 add(new CheckBox("showMeanTimeToEstablishConnection"));
296 add(new CheckBox("showMeanTimeToFirstByte"));
297
298 }
299
300 private Chart getChart() {
301 return (Chart) this.getModelObject();
302 }
303
304 public LoadTest getLoadTest() {
305 return loadTest;
306 }
307
308 public void setLoadTest(final LoadTest loadTest) {
309 this.loadTest = loadTest;
310 }
311
312 }
313
314 public class LoadTestRunReportPanel extends Panel {
315
316 private String name = "";
317
318 public LoadTestRunReportPanel(String arg0) {
319 super(arg0);
320 }
321
322 @Override
323 protected void onModelChanged() {
324 super.onModelChanged();
325 final LoadTestRun run = (LoadTestRun) getModelObject();
326
327
328 File dataFile = ResourceFactory.getLoadTestService().getDataFile(
329 run);
330 DownloadLink dfLink = new DownloadLink("dataFileLink", dataFile);
331 dfLink.setVisible(dataFile.exists());
332 addOrReplace(dfLink);
333
334 File summaryFile = ResourceFactory.getLoadTestService()
335 .getSummaryFile(run);
336 DownloadLink sfLink = new DownloadLink("summaryFileLink",
337 summaryFile);
338 sfLink.setVisible(summaryFile.exists());
339 addOrReplace(sfLink);
340
341 File errorFile = ResourceFactory.getLoadTestService()
342 .getErrorFile(run);
343 DownloadLink efLink = new DownloadLink("errorFileLink", errorFile);
344 efLink.setVisible(errorFile.exists());
345 addOrReplace(efLink);
346
347
348 Label testNameLabel = new Label("testName", run.getLoadTest()
349 .getName());
350 Link testLink = new BookmarkablePageLink("testLink",
351 HomePage.class, new PageParameters("testId="
352 + run.getLoadTest().getId()));
353 testLink.add(testNameLabel);
354 addOrReplace(testLink);
355 addOrReplace(new Label("runName", getFormattedDate(run.getTime())));
356
357
358 ChartNavPanel chartNavPanel = new ChartNavPanel("chartNav", run);
359 chartNavPanel.setVisible(run.getCharts().size() > 0);
360 addOrReplace(chartNavPanel);
361
362 LoadTestRunChartForm chartForm = new LoadTestRunChartForm(
363 "chartForm", new CompoundPropertyModel(new Chart()));
364 addOrReplace(chartForm);
365 chartForm.setRun(run);
366 }
367 public void setRun(final Long id) {
368 LoadTestRun newLoadTestRun = ResourceFactory
369 .getLoadTestRunDAO().getLoadTestRun(id);
370 ResourceFactory.getLoadTestRunDAO().saveLoadTestRun(newLoadTestRun);
371 setModel(new CompoundPropertyModel(newLoadTestRun));
372 }
373 }
374
375 public class LoadTestRunChartForm extends Form {
376
377 private LoadTestRun run;
378
379 public LoadTestRunChartForm(String arg0, IModel arg1) {
380 super(arg0, arg1);
381 add(new RequiredTextField("name"));
382 add(new CheckBox("showTests"));
383 add(new CheckBox("showErrors"));
384 add(new CheckBox("showMeanTestTime"));
385 add(new CheckBox("showTestTimeStandardDeviation"));
386 add(new CheckBox("showMeanResponseLength"));
387 add(new CheckBox("showResponseBytesPerSecond"));
388 add(new CheckBox("showResponseErrors"));
389 add(new CheckBox("showMeanTimeToResolveHost"));
390 add(new CheckBox("showMeanTimeToEstablishConnection"));
391 add(new CheckBox("showMeanTimeToFirstByte"));
392
393 }
394
395 @Override
396 protected void onSubmit() {
397 Chart chart = getChart();
398 ResourceFactory.getChartService().generateDefaultChart(chart, run);
399 loadTestRunReportPanel.setRun(run.getId());
400 }
401
402 private Chart getChart() {
403 return (Chart) this.getModelObject();
404 }
405
406 public LoadTestRun getRun() {
407 return run;
408 }
409
410 public void setRun(final LoadTestRun run) {
411 this.run = run;
412 add(new LoadTestRunSummaryDataView("summaries",
413 new LoadTestSummaryDataProvider(run), run));
414 }
415
416 }
417
418 public String getFormattedDate(long ldate) {
419 Format formatter = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
420 Date date = new Date(ldate);
421 return formatter.format(date);
422 }
423
424 protected final class LoadTestSummaryDataView extends DataView {
425 private LoadTest test = null;
426 private List<LoadTestRun> runs = new ArrayList<LoadTestRun>();
427
428 protected LoadTestSummaryDataView(String arg0, IDataProvider arg1,
429 LoadTest test) {
430 super(arg0, arg1);
431 this.test = test;
432 }
433
434 protected void populateItem(final Item item) {
435 final LoadTestSummary summary = (LoadTestSummary) item
436 .getModelObject();
437
438 LoadTestRun curRun = summary.getRun();
439 runs.add(curRun);
440 CheckBox runCheckBox = new CheckBox("selected", new PropertyModel(
441 curRun, "selected"));
442 item.add(runCheckBox);
443
444
445 String name = null;
446 BookmarkablePageLink link = null;
447 String dateString = getFormattedDate(summary.getRun().getTime());
448 name = dateString;
449 link = new BookmarkablePageLink("link", HomePage.class,
450 new PageParameters("runId=" + summary.getRun().getId()));
451 link.add(new Label("test", name));
452 item.add(link);
453 item.add(new Label("errors", Long.toString(summary.getErrors())));
454 item.add(new Label("meanResponseLength", Long.toString(summary
455 .getMeanResponseLength())));
456 item.add(new Label("meanTestTime", Long.toString(summary
457 .getMeanTestTime())));
458 item.add(new Label("meanTimeToEstablishConnection", Long
459 .toString(summary.getMeanTimeToEstablishConnection())));
460 item.add(new Label("meanTimeToFirstByte", Long.toString(summary
461 .getMeanTimeToFirstByte())));
462 item.add(new Label("meanTimeToResolveHost", Long.toString(summary
463 .getMeanTimeToResolveHost())));
464 item.add(new Label("responseBytesPerSecond", Long.toString(summary
465 .getResponseBytesPerSecond())));
466 item.add(new Label("responseErrors", Long.toString(summary
467 .getResponseErrors())));
468 item.add(new Label("tests", Long.toString(summary.getTests())));
469 item.add(new Label("testTimeStandardDeviation", Float
470 .toString(summary.getTestTimeStandardDeviation())));
471
472 item.add(new AttributeModifier("class", true,
473 new AbstractReadOnlyModel() {
474 public Object getObject() {
475 return (item.getIndex() % 2 == 1) ? "even" : "odd";
476 }
477 }));
478
479 }
480
481 public List<LoadTestRun> getRuns() {
482 return runs;
483 }
484
485 public void setRuns(List<LoadTestRun> runs) {
486 this.runs = runs;
487 }
488
489 }
490
491 public class ChartDynamicImageResource extends RenderedDynamicImageResource {
492
493 private Chart chart;
494
495 public ChartDynamicImageResource(Chart c) {
496 super(c.getChartImage().getWidth(), c.getChartImage().getHeight());
497 this.chart = c;
498 }
499
500 @Override
501 protected boolean render(Graphics2D g) {
502 g.drawImage(chart.getChartImage(), 0, 0, Color.WHITE, null);
503 return true;
504 }
505
506 }
507
508 protected final class LoadTestRunSummaryDataView extends DataView {
509 private LoadTestRun run = null;
510
511 private List<LoadTestRun> runs = new ArrayList<LoadTestRun>();
512
513 protected LoadTestRunSummaryDataView(String arg0, IDataProvider arg1,
514 LoadTestRun run) {
515 super(arg0, arg1);
516 this.run = run;
517 }
518
519 protected void populateItem(final Item item) {
520 final LoadTestSummary summary = (LoadTestSummary) item
521 .getModelObject();
522
523
524 String name = null;
525 BookmarkablePageLink link = null;
526 name = summary.getTestName();
527 link = new BookmarkablePageLink("link", HomePage.class,
528 new PageParameters("testId=" + run.getLoadTest().getId()));
529 link.add(new Label("test", name));
530 item.add(link);
531 item.add(new Label("errors", Long.toString(summary.getErrors())));
532 item.add(new Label("meanResponseLength", Long.toString(summary
533 .getMeanResponseLength())));
534 item.add(new Label("meanTestTime", Long.toString(summary
535 .getMeanTestTime())));
536 item.add(new Label("meanTimeToEstablishConnection", Long
537 .toString(summary.getMeanTimeToEstablishConnection())));
538 item.add(new Label("meanTimeToFirstByte", Long.toString(summary
539 .getMeanTimeToFirstByte())));
540 item.add(new Label("meanTimeToResolveHost", Long.toString(summary
541 .getMeanTimeToResolveHost())));
542 item.add(new Label("responseBytesPerSecond", Long.toString(summary
543 .getResponseBytesPerSecond())));
544 item.add(new Label("responseErrors", Long.toString(summary
545 .getResponseErrors())));
546 item.add(new Label("tests", Long.toString(summary.getTests())));
547 item.add(new Label("testTimeStandardDeviation", Float
548 .toString(summary.getTestTimeStandardDeviation())));
549
550 item.add(new Label("uri", summary.getTestUri()));
551 item.add(new AttributeModifier("class", true,
552 new AbstractReadOnlyModel() {
553 public Object getObject() {
554 return (item.getIndex() % 2 == 1) ? "even" : "odd";
555 }
556 }));
557
558 }
559
560 }
561
562
563 }