package com.griddynamics.jagger.dbapi.fetcher; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import com.griddynamics.jagger.dbapi.dto.MetricNameDto; import com.griddynamics.jagger.dbapi.dto.PlotSingleDto; import com.griddynamics.jagger.dbapi.dto.TestInfoDto; import com.griddynamics.jagger.dbapi.util.FetchUtil; import com.griddynamics.jagger.util.Pair; import org.springframework.beans.factory.annotation.Autowired; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import static com.google.common.collect.TreeMultimap.create; /** * User: mnovozhilov * Date: 6/10/14 * Time: 4:07 PM * * This is class is needed because session scope processing of data for test group metrics is equal * processing monitoring parameters. We use delegates of required classes. */ public class AbstractSessionScopeFetcher<F extends AbstractMetricPlotFetcher> extends PlotsDbMetricDataFetcher { private F abstractMetricPlotFetcher; private FetchUtil fetchUtil; @Autowired public void setAbstractMetricPlotFetcher(F abstractMetricPlotFetcher) { this.abstractMetricPlotFetcher = abstractMetricPlotFetcher; } @Autowired public void setFetchUtil(FetchUtil fetchUtil) { this.fetchUtil = fetchUtil; } @Override protected Set<Pair<MetricNameDto, List<PlotSingleDto>>> fetchData(List<MetricNameDto> metricNames) { if (metricNames.isEmpty()) { return Collections.emptySet(); } Collection<AbstractMetricPlotFetcher.MetricRawData> allRawData = abstractMetricPlotFetcher.getAllRawData(metricNames); if (allRawData.isEmpty()) { log.warn("No plot data found for metrics : {}", metricNames); return Collections.emptySet(); } return getResult(allRawData, metricNames); } protected Set<Pair<MetricNameDto, List<PlotSingleDto>>> getResult(Collection<AbstractMetricPlotFetcher.MetricRawData> allRawData, List<MetricNameDto> metricNames) { Set<Long> taskIds = new HashSet<>(); for (MetricNameDto metricName : metricNames) { taskIds.addAll(metricName.getTaskIds()); } Multimap<String, AbstractMetricPlotFetcher.MetricRawData> metricIdRawMap = getMetricIdRawMap(allRawData, taskIds); Multimap<MetricNameDto, PlotSingleDto> metricNamePlotMap = ArrayListMultimap.create(); for (MetricNameDto metricName : metricNames) { Collection<AbstractMetricPlotFetcher.MetricRawData> rawDatas; if (metricIdRawMap.isEmpty()) continue; rawDatas = metricIdRawMap.get(metricName.getMetricName()); if (rawDatas == null || rawDatas.isEmpty()) { continue; } metricNamePlotMap.put(metricName, abstractMetricPlotFetcher.assemble(metricName, rawDatas)); } Set<Pair<MetricNameDto, List<PlotSingleDto>>> resultSet = new HashSet<>(metricNames.size()); for (MetricNameDto metricName : metricNamePlotMap.keySet()) { List<PlotSingleDto> plotDatasetDtoList = new ArrayList<>(metricNamePlotMap.get(metricName)); resultSet.add(Pair.of(metricName, plotDatasetDtoList)); } return resultSet; } private Multimap<String, AbstractMetricPlotFetcher.MetricRawData> getMetricIdRawMap( Collection<AbstractMetricPlotFetcher.MetricRawData> allRawDataForProcessing, Set<Long> taskIds) { Collection<AbstractMetricPlotFetcher.MetricRawData> allRawData = dataProcess(allRawDataForProcessing, taskIds); Multimap<String, AbstractMetricPlotFetcher.MetricRawData> metricIdRawMap = ArrayListMultimap.create(); for (AbstractMetricPlotFetcher.MetricRawData rawData : allRawData) { metricIdRawMap.put(rawData.getMetricId(), rawData); } return metricIdRawMap; } private Collection<AbstractMetricPlotFetcher.MetricRawData> dataProcess(Collection<AbstractMetricPlotFetcher.MetricRawData> forProcess, Set<Long> taskIds) { List<AbstractMetricPlotFetcher.MetricRawData> result = Lists.newArrayList(); Map<Long, Map<String, TestInfoDto>> testStartEndMap = fetchUtil.getTestInfoByTaskIds(taskIds); Map<String, Multimap<Number, AbstractMetricPlotFetcher.MetricRawData>> lines = getLineForSessionScope(forProcess); for (String metricId : lines.keySet()) { Long lastTimeOfPreviousTask = 0L; Long timeShift = 0L; Long finishTimeFirstTask = 0L; Long startTimeSecondTask = null; Long startTimePre = null; for (Long taskId : testStartEndMap.keySet()) { Long testStartTime = testStartEndMap.get(taskId).values().iterator().next().getStartTime().getTime(); Long testEndTime = testStartEndMap.get(taskId).values().iterator().next().getEndTime().getTime(); if (lines.get(metricId).containsKey(taskId) && !testStartTime.equals(startTimePre)) { for (AbstractMetricPlotFetcher.MetricRawData metricRawData : lines.get(metricId).get(taskId)) { if (startTimeSecondTask == null) startTimeSecondTask = testStartTime; if (!startTimeSecondTask.equals(testStartTime)) { startTimeSecondTask = testStartTime; timeShift = startTimeSecondTask - finishTimeFirstTask + lastTimeOfPreviousTask; } metricRawData.setTime(metricRawData.getTime() + timeShift); result.add(metricRawData); lastTimeOfPreviousTask = metricRawData.getTime(); finishTimeFirstTask = testEndTime; } } startTimePre = testStartTime; } } return result; } private Map<String, Multimap<Number, AbstractMetricPlotFetcher.MetricRawData>> getLineForSessionScope( Collection<AbstractMetricPlotFetcher.MetricRawData> forProcess) { Map<String, Multimap<Number, AbstractMetricPlotFetcher.MetricRawData>> lines = new HashMap<>(); for (AbstractMetricPlotFetcher.MetricRawData metricRawData : forProcess) { String metricId = metricRawData.getMetricId(); if (lines.get(metricId) == null) { Multimap<Number, AbstractMetricPlotFetcher.MetricRawData> multimap = create(numberComparator, metricRawDataComparator); lines.put(metricId, multimap); } lines.get(metricId).put(metricRawData.getWorkloadTaskDataId(), metricRawData); } return lines; } private static Comparator<AbstractMetricPlotFetcher.MetricRawData> metricRawDataComparator = (s1, s2) -> { Long s1Long = s1.getTime(); return s1Long.compareTo(s2.getTime()); }; private static Comparator<Number> numberComparator = (s1, s2) -> { Long s1Long = s1.longValue(); return s1Long.compareTo(s2.longValue()); }; }