package com.griddynamics.jagger.engine.e1.services; import com.griddynamics.jagger.coordinator.NodeContext; import com.griddynamics.jagger.dbapi.DatabaseService; import com.griddynamics.jagger.dbapi.dto.*; import com.griddynamics.jagger.dbapi.model.MetricNode; import com.griddynamics.jagger.dbapi.model.RootNode; import com.griddynamics.jagger.dbapi.model.TestDetailsNode; import com.griddynamics.jagger.dbapi.model.TestNode; import com.griddynamics.jagger.dbapi.util.SessionMatchingSetup; import com.griddynamics.jagger.engine.e1.services.data.service.*; import java.util.*; /** * Implementation of the @ref DataService * * @par Details: * @details Provides access to the tests results in the Jagger DB. You can get a full information about sessions, tests, metrics. @n * Where this service is available you can find in chapter: @ref section_listeners_services @n * @n * @ingroup Main_Services_group */ public class DefaultDataService implements DataService { private DatabaseService databaseService; // For all user operations - get all test results without matching private final SessionMatchingSetup SESSION_MATCHING_SETUP = new SessionMatchingSetup(false, Collections.<SessionMatchingSetup.MatchBy>emptySet()); public DefaultDataService(NodeContext context) { databaseService = context.getService(DatabaseService.class); } public DefaultDataService(DatabaseService databaseService) { this.databaseService = databaseService; } @Override public SessionEntity getSession(String sessionId) { Set<SessionEntity> sessions = getSessions(Arrays.asList(sessionId)); if (sessions.isEmpty()) { return null; } return sessions.iterator().next(); } @Override public DecisionPerSessionDto getSessionDecisions(String sessionId) { return databaseService.getDecisionPerSession(sessionId); } @Override public Set<SessionEntity> getSessions(Collection<String> sessionIds) { List<SessionDataDto> sessionDataDtoList = databaseService.getSessionInfoService().getBySessionIds(0, sessionIds.size(), new HashSet<String>(sessionIds)); if (sessionDataDtoList.isEmpty()) { return Collections.emptySet(); } Set<SessionEntity> entities = new TreeSet<>(new SessionEntity.IdComparator()); for (SessionDataDto sessionDataDto : sessionDataDtoList) { SessionEntity sessionEntity = new SessionEntity(); sessionEntity.setId(sessionDataDto.getSessionId()); sessionEntity.setStartDate(sessionDataDto.getStartDate()); sessionEntity.setEndDate(sessionDataDto.getEndDate()); sessionEntity.setKernels(sessionDataDto.getActiveKernelsCount()); sessionEntity.setComment(sessionDataDto.getComment()); entities.add(sessionEntity); } return entities; } @Override public Set<TestEntity> getTests(SessionEntity session) { return getTests(session.getId()); } @Override public Set<TestEntity> getTests(String sessionId) { Map<String, Set<TestEntity>> map = getTests(Arrays.asList(sessionId)); Set<TestEntity> result = map.get(sessionId); if (result != null) { return result; } return Collections.emptySet(); } @Override public Map<String, Set<TestEntity>> getTests(Collection<String> sessionIds) { return getTestsWithName(sessionIds, null, SESSION_MATCHING_SETUP); } @Override public TestEntity getTestByName(SessionEntity session, String testName) { return getTestByName(session.getId(), testName); } @Override public TestEntity getTestByName(String sessionId, String testName) { Map<String, TestEntity> map = getTestsByName(Collections.singletonList(sessionId), testName); TestEntity result = map.get(sessionId); if (result != null) { return result; } return null; } @Override public Map<String, TestEntity> getTestsByName(Collection<String> sessionIds, String testName) { Map<String, Set<TestEntity>> tests = getTestsWithName(sessionIds, testName, SESSION_MATCHING_SETUP); Map<String, TestEntity> result = new HashMap<String, TestEntity>(tests.size()); for (Map.Entry<String, Set<TestEntity>> entry : tests.entrySet()) { Set<TestEntity> testEntities = entry.getValue(); if (!testEntities.isEmpty()) { result.put(entry.getKey(), testEntities.iterator().next()); } } return result; } // if testName=null => no filtering for test name => all tests for session(s) will be returned // @return map <sessionId, set<test>> public Map<String, Set<TestEntity>> getTestsWithName(Collection<String> sessionIds, String testName, SessionMatchingSetup sessionMatchingSetup) { if (sessionIds.isEmpty()) { return Collections.emptyMap(); } // basic List<TaskDataDto> taskDataDtoList = databaseService.getTaskDataForSessions(new HashSet<String>(sessionIds), sessionMatchingSetup); // info Map<TaskDataDto, Map<String, TestInfoDto>> testInfoMap = databaseService.getTestInfoByTaskDataDto(taskDataDtoList); // decision Set<Long> ids = new HashSet<Long>(); for (TaskDataDto taskDataDto : taskDataDtoList) { ids.addAll(taskDataDto.getIds()); } Map<Long, TaskDecisionDto> idToDecisionPerTest = new HashMap<Long, TaskDecisionDto>(); for (TaskDecisionDto taskDecisionDto : databaseService.getDecisionsPerTask(ids)) { idToDecisionPerTest.put(taskDecisionDto.getId(), taskDecisionDto); } Map<String, Set<TestEntity>> result = new HashMap<String, Set<TestEntity>>(); for (TaskDataDto taskDataDto : taskDataDtoList) { for (Map.Entry<Long, String> entry : taskDataDto.getIdToSessionId().entrySet()) { if (((testName != null) && (testName.equals(taskDataDto.getTaskName()))) || (testName == null)) { Long testId = entry.getKey(); String sessionId = entry.getValue(); TestEntity testEntity = new TestEntity(); testEntity.setId(testId); testEntity.setDescription(taskDataDto.getDescription()); testEntity.setName(taskDataDto.getTaskName()); testEntity.setTaskDataDto(taskDataDto); if (testInfoMap.containsKey(taskDataDto)) { TestInfoDto testInfoDto = testInfoMap.get(taskDataDto).entrySet().iterator().next().getValue(); testEntity.setLoad(testInfoDto.getClock()); testEntity.setClockValue(testInfoDto.getClockValue()); testEntity.setTerminationStrategy(testInfoDto.getTermination()); testEntity.setStartDate(testInfoDto.getStartTime()); testEntity.setTestGroupIndex(testInfoDto.getNumber()); testEntity.setTestExecutionStatus(testInfoDto.getStatus()); } if (idToDecisionPerTest.containsKey(testId)) { testEntity.setDecision(idToDecisionPerTest.get(testId).getDecision()); } if (result.containsKey(sessionId)) { result.get(sessionId).add(testEntity); } else { Set<TestEntity> testEntitySet = new HashSet<TestEntity>(); testEntitySet.add(testEntity); result.put(sessionId, testEntitySet); } } } } // add empty results when not found for (String sessionId : sessionIds) { if (!result.containsKey(sessionId)) { result.put(sessionId, Collections.<TestEntity>emptySet()); } } return result; } @Override public Set<MetricEntity> getMetrics(Long testId) { Map<Long, Set<MetricEntity>> map = getMetricsByTestIds(Arrays.asList(testId)); Set<MetricEntity> result = map.get(testId); if (result != null) { return result; } return Collections.emptySet(); } @Override public Set<MetricEntity> getMetrics(TestEntity test) { Map<TestEntity, Set<MetricEntity>> map = getMetricsByTests(Arrays.asList(test)); Set<MetricEntity> result = map.get(test); if (result != null) { return result; } return Collections.emptySet(); } @Override public Map<TestEntity, Set<MetricEntity>> getMetricsByTests(Collection<TestEntity> tests) { Map<Long, TestEntity> map = new HashMap<Long, TestEntity>(tests.size()); Set<Long> ids = new HashSet<Long>(tests.size()); for (TestEntity test : tests) { map.put(test.getId(), test); ids.add(test.getId()); } Map<Long, Set<MetricEntity>> metrics = getMetricsByTestIds(ids); Map<TestEntity, Set<MetricEntity>> result = new HashMap<TestEntity, Set<MetricEntity>>(); for (Long key : map.keySet()) { result.put(map.get(key), metrics.get(key)); } return result; } @Override public Map<Long, Set<MetricEntity>> getMetricsByTestIds(Collection<Long> testIds) { if (testIds.isEmpty()) { return Collections.emptyMap(); } // Get List<String> sessionIds = databaseService.getSessionIdsByTaskIds(new HashSet<Long>(testIds)); // Get all test results without matching SessionMatchingSetup sessionMatchingSetup = new SessionMatchingSetup(false, Collections.<SessionMatchingSetup.MatchBy>emptySet()); RootNode rootNode = databaseService.getControlTreeForSessions(new HashSet<String>(sessionIds), sessionMatchingSetup); // Filter List<TestNode> summaryNodeTests = new ArrayList<TestNode>(); List<TestDetailsNode> detailsNodeTests = new ArrayList<TestDetailsNode>(); for (TestNode testNode : rootNode.getSummaryNode().getTests()) { Long testId = testNode.getTaskDataDto().getId(); if (testIds.contains(testId)) { summaryNodeTests.add(testNode); } } for (TestDetailsNode testDetailsNode : rootNode.getDetailsNode().getTests()) { Long testId = testDetailsNode.getTaskDataDto().getId(); if (testIds.contains(testId)) { detailsNodeTests.add(testDetailsNode); } } // Join Map<Long, Set<MetricNameDto>> metrics = new HashMap<Long, Set<MetricNameDto>>(); Set<String> metricsWithSummary = new HashSet<String>(); Set<String> metricsWithPlots = new HashSet<String>(); for (TestNode testNode : summaryNodeTests) { Long testId = testNode.getTaskDataDto().getId(); if (!metrics.containsKey(testId)) { metrics.put(testId, new HashSet<MetricNameDto>()); } for (MetricNode metricNode : testNode.getMetrics()) { for (MetricNameDto metricNameDto : metricNode.getMetricNameDtoList()) { metrics.get(testId).add(metricNameDto); metricsWithSummary.add(metricNameDto.getMetricName()); } } } for (TestDetailsNode testDetailsNode : detailsNodeTests) { Long testId = testDetailsNode.getTaskDataDto().getId(); if (!metrics.containsKey(testId)) { metrics.put(testId, new HashSet<MetricNameDto>()); } for (MetricNode metricNode : testDetailsNode.getMetrics()) { for (MetricNameDto metricNameDto : metricNode.getMetricNameDtoList()) { metrics.get(testId).add(metricNameDto); metricsWithPlots.add(metricNameDto.getMetricName()); } } } // Convert Map<Long, Set<MetricEntity>> result = new HashMap<Long, Set<MetricEntity>>(); for (Long key : metrics.keySet()) { result.put(key, new HashSet<MetricEntity>()); for (MetricNameDto metricNameDto : metrics.get(key)) { MetricEntity metricEntity = new MetricEntity(); metricEntity.setMetricNameDto(metricNameDto); if (metricsWithSummary.contains(metricNameDto.getMetricName())) { metricEntity.setSummaryAvailable(true); } if (metricsWithPlots.contains(metricNameDto.getMetricName())) { metricEntity.setPlotAvailable(true); } result.get(key).add(metricEntity); } } return result; } @Override public MetricSummaryValueEntity getMetricSummary(MetricEntity metric) { Map<MetricEntity, MetricSummaryValueEntity> map = getMetricSummary(Arrays.asList(metric)); return map.get(metric); } @Override public Map<MetricEntity, MetricSummaryValueEntity> getMetricSummary(Collection<MetricEntity> metrics) { Set<MetricNameDto> metricNameDtoSet = new HashSet<MetricNameDto>(); Map<MetricNameDto, MetricEntity> matchMap = new HashMap<MetricNameDto, MetricEntity>(); for (MetricEntity metric : metrics) { if (metric.isSummaryAvailable()) { metricNameDtoSet.add(metric.getMetricNameDto()); matchMap.put(metric.getMetricNameDto(), metric); } } Collection<SummarySingleDto> metricDtoList = databaseService.getSummaryByMetricNameDto(metricNameDtoSet, true).values(); Map<MetricEntity, MetricSummaryValueEntity> result = new HashMap<MetricEntity, MetricSummaryValueEntity>(); for (SummarySingleDto metricDto : metricDtoList) { MetricEntity metricEntity = matchMap.get(metricDto.getMetricName()); MetricSummaryValueEntity value = new MetricSummaryValueEntity(); value.setValue(Double.parseDouble(metricDto.getValues().iterator().next().getValue())); value.setDecision(metricDto.getValues().iterator().next().getDecision()); result.put(metricEntity, value); } return result; } @Override public List<MetricPlotPointEntity> getMetricPlotData(MetricEntity metric) { Map<MetricEntity, List<MetricPlotPointEntity>> map = getMetricPlotData(Collections.singletonList(metric)); return map.get(metric); } @Override public Map<MetricEntity, List<MetricPlotPointEntity>> getMetricPlotData(Collection<MetricEntity> metrics) { Set<MetricNameDto> metricNameDtoSet = new HashSet<MetricNameDto>(); Map<MetricNameDto, MetricEntity> matchMap = new HashMap<MetricNameDto, MetricEntity>(); for (MetricEntity metric : metrics) { if (metric.isPlotAvailable()) { metricNameDtoSet.add(metric.getMetricNameDto()); matchMap.put(metric.getMetricNameDto(), metric); } } Map<MetricNameDto, List<PlotSingleDto>> resultMap = databaseService.getPlotDataByMetricNameDto(metricNameDtoSet); Map<MetricEntity, List<MetricPlotPointEntity>> result = new HashMap<MetricEntity, List<MetricPlotPointEntity>>(); for (Map.Entry<MetricNameDto, List<PlotSingleDto>> entry : resultMap.entrySet()) { MetricEntity metricEntity = matchMap.get(entry.getKey()); List<MetricPlotPointEntity> values = new ArrayList<MetricPlotPointEntity>(); for (PointDto pointDto : entry.getValue().iterator().next().getPlotData()) { MetricPlotPointEntity metricPlotPointEntity = new MetricPlotPointEntity(); metricPlotPointEntity.setTime(pointDto.getX()); metricPlotPointEntity.setValue(pointDto.getY()); values.add(metricPlotPointEntity); } result.put(metricEntity, values); } return result; } public DatabaseService getDatabaseService() { return databaseService; } @Override public boolean isAvailable() { return true; } }