/*
* Copyright (c) 2010-2012 Grid Dynamics Consulting Services, Inc, All Rights Reserved
* http://www.griddynamics.com
*
* This library is free software; you can redistribute it and/or modify it under the terms of
* the Apache License; either
* version 2.0 of the License, or any later version.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.griddynamics.jagger.engine.e1.reporting;
import com.google.common.collect.Lists;
import com.griddynamics.jagger.engine.e1.services.data.service.TestEntity;
import com.griddynamics.jagger.reporting.AbstractReportProvider;
import com.griddynamics.jagger.reporting.chart.ChartHelper;
import com.griddynamics.jagger.util.StandardMetricsNamesUtil;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.renderers.JCommonDrawableRenderer;
import org.jfree.chart.JFreeChart;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WorkloadScalabilityPlotsReporter extends AbstractReportProvider {
public static final Comparator<ScenarioPlotDTO> BY_NAME = Comparator.comparing(ScenarioPlotDTO::getScenarioName);
private HashMap<String, String> clockDictionary;
public HashMap<String, String> getClockDictionary() {
return clockDictionary;
}
public void setClockDictionary(HashMap<String, String> clockDictionary) {
this.clockDictionary = clockDictionary;
}
@Override
public JRDataSource getDataSource(String sessionId) {
List<ScenarioPlotDTO> plots = Lists.newArrayList();
Map<TestEntity, Map<String, Double>> dataForScalabilityPlots =
getContext().getSummaryReporter().getDataForScalabilityPlots(sessionId);
plots.addAll(getScenarioPlots(dataForScalabilityPlots));
plots.sort(BY_NAME);
return new JRBeanCollectionDataSource(plots);
}
private Collection<ScenarioPlotDTO> getScenarioPlots(Map<TestEntity,Map<String,Double>> dataForScalabilityPlots) {
HashMap<String, ScenarioPlotDTO> throughputPlots = new HashMap<String, ScenarioPlotDTO>();
for (TestEntity testEntity : dataForScalabilityPlots.keySet()) {
String scenarioName = testEntity.getName();
if (!throughputPlots.containsKey(scenarioName)) {
// Back compatibility: collect all tests with equal name
Map<TestEntity,Map<String,Double>> resultData = new HashMap<TestEntity, Map<String, Double>>();
for (Map.Entry<TestEntity,Map<String,Double>> mapEntry : dataForScalabilityPlots.entrySet()) {
if (mapEntry.getKey().getName().equals(scenarioName)) {
resultData.put(testEntity, mapEntry.getValue());
}
}
XYDataset latencyData = getLatencyData(resultData);
XYDataset throughputData = getThroughputData(resultData);
String clockForPlot = getClockForPlot(resultData);
JFreeChart chartThroughput = ChartHelper.createXYChart(null, throughputData, clockForPlot,
"Throughput (TPS)", 6, 3, ChartHelper.ColorTheme.LIGHT);
JFreeChart chartLatency = ChartHelper.createXYChart(null, latencyData, clockForPlot,
"Latency (sec)", 6, 3, ChartHelper.ColorTheme.LIGHT);
ScenarioPlotDTO plotDTO = new ScenarioPlotDTO();
plotDTO.setScenarioName(scenarioName);
plotDTO.setThroughputPlot(new JCommonDrawableRenderer(chartThroughput));
plotDTO.setLatencyPlot(new JCommonDrawableRenderer(chartLatency));
throughputPlots.put(scenarioName, plotDTO);
}
}
return throughputPlots.values();
}
private String getClockForPlot(Map<TestEntity,Map<String,Double>> resultData) {
String clock = "-";
if (!resultData.isEmpty()) {
clock = resultData.entrySet().iterator().next().getKey().getLoad();
if (clockDictionary != null) {
for (String key : clockDictionary.keySet()) {
if (clock.contains(key)) {
return clockDictionary.get(key);
}
}
}
}
return clock;
}
private XYDataset getThroughputData(Map<TestEntity,Map<String,Double>> resultData) {
XYSeries throughput = new XYSeries("Throughput");
throughput.add(0, 0);
for (Map.Entry<TestEntity,Map<String,Double>> mapEntry : resultData.entrySet()) {
throughput.add(mapEntry.getKey().getClockValue().doubleValue(), mapEntry.getValue().get(StandardMetricsNamesUtil.THROUGHPUT_ID).doubleValue());
}
return new XYSeriesCollection(throughput);
}
private XYDataset getLatencyData(Map<TestEntity,Map<String,Double>> resultData) {
XYSeries meanLatency = new XYSeries("Mean");
XYSeries stdDevLatency = new XYSeries("StdDev");
meanLatency.add(0, 0);
stdDevLatency.add(0, 0);
for (Map.Entry<TestEntity,Map<String,Double>> mapEntry : resultData.entrySet()) {
meanLatency.add(mapEntry.getKey().getClockValue().doubleValue(), mapEntry.getValue().get(StandardMetricsNamesUtil.LATENCY_ID).doubleValue());
stdDevLatency.add(mapEntry.getKey().getClockValue().doubleValue(), mapEntry.getValue().get(StandardMetricsNamesUtil.LATENCY_STD_DEV_AGG_ID).doubleValue());
}
XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(meanLatency);
dataset.addSeries(stdDevLatency);
return dataset;
}
public static class ScenarioPlotDTO {
private String scenarioName;
private JCommonDrawableRenderer throughputPlot;
private JCommonDrawableRenderer latencyPlot;
public String getScenarioName() {
return scenarioName;
}
public void setScenarioName(String scenarioName) {
this.scenarioName = scenarioName;
}
public JCommonDrawableRenderer getThroughputPlot() {
return throughputPlot;
}
public void setThroughputPlot(JCommonDrawableRenderer throughputPlot) {
this.throughputPlot = throughputPlot;
}
public JCommonDrawableRenderer getLatencyPlot() {
return latencyPlot;
}
public void setLatencyPlot(JCommonDrawableRenderer latencyPlot) {
this.latencyPlot = latencyPlot;
}
}
}