diff options
author | Teryk Bellahsene <teryk.bellahsene@sonarsource.com> | 2017-07-14 17:12:23 +0200 |
---|---|---|
committer | Teryk Bellahsene <teryk@users.noreply.github.com> | 2017-07-24 10:19:35 +0200 |
commit | 65fc8f900285d67c59f2c94dfc8428949874b39e (patch) | |
tree | 29023f98205994ee7228110c40bb24635be1ff5f /server | |
parent | aab783fde3f151d600b204767888198711faa108 (diff) | |
download | sonarqube-65fc8f900285d67c59f2c94dfc8428949874b39e.tar.gz sonarqube-65fc8f900285d67c59f2c94dfc8428949874b39e.zip |
Select finished analyses in DB by component uuids and from dates
Diffstat (limited to 'server')
6 files changed, 141 insertions, 6 deletions
diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/queue/InternalCeQueueImpl.java b/server/sonar-ce/src/main/java/org/sonar/ce/queue/InternalCeQueueImpl.java index 72c98073dce..ee30acd613a 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/queue/InternalCeQueueImpl.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/queue/InternalCeQueueImpl.java @@ -43,7 +43,6 @@ import org.sonar.db.ce.CeQueueDto; import org.sonar.server.organization.DefaultOrganizationProvider; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; import static java.util.Objects.requireNonNull; @ComputeEngineSide @@ -99,14 +98,14 @@ public class InternalCeQueueImpl extends CeQueueImpl implements InternalCeQueue public void remove(CeTask task, CeActivityDto.Status status, @Nullable CeTaskResult taskResult, @Nullable Throwable error) { checkArgument(error == null || status == CeActivityDto.Status.FAILED, "Error can be provided only when status is FAILED"); try (DbSession dbSession = dbClient.openSession(false)) { - Optional<CeQueueDto> queueDto = dbClient.ceQueueDao().selectByUuid(dbSession, task.getUuid()); - checkState(queueDto.isPresent(), "Task does not exist anymore: %s", task); - CeActivityDto activityDto = new CeActivityDto(queueDto.get()); + CeQueueDto queueDto = dbClient.ceQueueDao().selectByUuid(dbSession, task.getUuid()) + .orElseThrow(() -> new IllegalStateException("Task does not exist anymore: " + task)); + CeActivityDto activityDto = new CeActivityDto(queueDto); activityDto.setStatus(status); updateQueueStatus(status, activityDto); updateTaskResult(activityDto, taskResult); updateError(activityDto, error); - remove(dbSession, queueDto.get(), activityDto); + remove(dbSession, queueDto, activityDto); } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDao.java index 15409db9997..2c759cafb42 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDao.java @@ -23,15 +23,21 @@ import com.google.common.collect.Lists; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Optional; +import java.util.stream.IntStream; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.apache.ibatis.session.RowBounds; +import org.sonar.core.util.stream.MoreCollectors; import org.sonar.db.Dao; import org.sonar.db.DbSession; +import org.sonar.db.ce.CeActivityDto.Status; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.FluentIterable.from; +import static java.util.Objects.requireNonNull; import static org.sonar.db.DatabaseUtils.executeLargeInputs; public class SnapshotDao implements Dao { @@ -91,6 +97,20 @@ public class SnapshotDao implements Dao { return snapshotDtos.isEmpty() ? null : snapshotDtos.get(0); } + /** + * + */ + public List<SnapshotDto> selectFinishedByComponentUuidsAndFromDates(DbSession dbSession, List<String> componentUuids, List<Long> fromDates) { + checkArgument(componentUuids.size() == fromDates.size(), "The number of components (%s) and from dates (%s) must be the same.", + String.valueOf(componentUuids.size()), + String.valueOf(fromDates.size())); + List<ComponentUuidFromDatePair> componentUuidFromDatePairs = IntStream.range(0, componentUuids.size()) + .mapToObj(i -> new ComponentUuidFromDatePair(componentUuids.get(i), fromDates.get(i))) + .collect(MoreCollectors.toList(componentUuids.size())); + + return executeLargeInputs(componentUuidFromDatePairs, partition -> mapper(dbSession).selectFinishedByComponentUuidsAndFromDates(partition, Status.SUCCESS), i -> i / 2); + } + public void switchIsLastFlagAndSetProcessedStatus(DbSession dbSession, String componentUuid, String analysisUuid) { SnapshotMapper mapper = mapper(dbSession); mapper.unsetIsLastFlagForComponentUuid(componentUuid); @@ -129,4 +149,47 @@ public class SnapshotDao implements Dao { private static SnapshotMapper mapper(DbSession session) { return session.getMapper(SnapshotMapper.class); } + + static class ComponentUuidFromDatePair implements Comparable<ComponentUuidFromDatePair> { + private final String componentUuid; + private final long from; + + ComponentUuidFromDatePair(String componentUuid, long from) { + this.componentUuid = requireNonNull(componentUuid); + this.from = from; + } + + @Override + public int compareTo(ComponentUuidFromDatePair other) { + if (this == other) { + return 0; + } + + int c = componentUuid.compareTo(other.componentUuid); + if (c == 0) { + c = Long.compare(from, other.from); + } + + return c; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ComponentUuidFromDatePair other = (ComponentUuidFromDatePair) o; + return componentUuid.equals(other.componentUuid) + && from == other.from; + } + + @Override + public int hashCode() { + return Objects.hash(componentUuid, from); + } + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotMapper.java index 60f979748d5..b8a6226d44f 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotMapper.java @@ -24,6 +24,8 @@ import java.util.List; import javax.annotation.CheckForNull; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.session.RowBounds; +import org.sonar.db.ce.CeActivityDto; +import org.sonar.db.component.SnapshotDao.ComponentUuidFromDatePair; public interface SnapshotMapper { @@ -52,4 +54,7 @@ public interface SnapshotMapper { void setIsLastFlagForAnalysisUuid(@Param("analysisUuid") String analysisUuid); void update(SnapshotDto analysis); + + List<SnapshotDto> selectFinishedByComponentUuidsAndFromDates(@Param("componentUuidFromDatePairs") List<ComponentUuidFromDatePair> pairs, + @Param("ceStatus") CeActivityDto.Status ceStatus); } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/SnapshotMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/SnapshotMapper.xml index 5d2a0a478d6..3ba07ab067c 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/SnapshotMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/SnapshotMapper.xml @@ -98,6 +98,22 @@ </if> </select> + <select id="selectFinishedByComponentUuidsAndFromDates" parameterType="map" resultType="Snapshot"> + select + <include refid="snapshotColumns" /> + from snapshots s + inner join projects p on p.uuid=s.component_uuid and p.enabled=${_true} + inner join ce_activity ca on s.uuid = ca.analysis_uuid and s.component_uuid = ca.component_uuid + where + <foreach collection="componentUuidFromDatePairs" open="(" close=")" item="componentUuidFromDatePair" separator=" or "> + (s.component_uuid=#{componentUuidFromDatePair.componentUuid, jdbcType=VARCHAR} and s.created_at >= #{componentUuidFromDatePair.from, jdbcType=BIGINT}) + </foreach> + and s.status = 'P' + and ca.status=#{ceStatus, jdbcType=VARCHAR} + order by + s.created_at + </select> + <select id="selectPreviousVersionSnapshots" parameterType="map" resultType="Snapshot"> SELECT <include refid="snapshotColumns" /> diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/SnapshotDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/SnapshotDaoTest.java index f026bbbf4e9..d8c38d9a25b 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/SnapshotDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/SnapshotDaoTest.java @@ -19,6 +19,7 @@ */ package org.sonar.db.component; +import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Optional; @@ -30,10 +31,15 @@ import org.sonar.api.utils.System2; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; +import org.sonar.db.ce.CeActivityDto; +import org.sonar.db.ce.CeQueueDto; +import org.sonar.db.ce.CeTaskTypes; import org.sonar.db.organization.OrganizationTesting; import static com.google.common.collect.Lists.newArrayList; import static java.util.Collections.emptyList; +import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; +import static org.apache.commons.lang.math.RandomUtils.nextLong; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; import static org.sonar.db.component.SnapshotDto.STATUS_PROCESSED; @@ -199,6 +205,36 @@ public class SnapshotDaoTest { } @Test + public void selectFinishedByComponentUuidsAndFromDates() { + long from = 1_500_000_000_000L; + long otherFrom = 1_200_000_000_000L; + ComponentDto firstProject = db.components().insertPrivateProject(); + ComponentDto secondProject = db.components().insertPrivateProject(); + ComponentDto thirdProject = db.components().insertPrivateProject(); + SnapshotDto unprocessedAnalysis = db.components().insertSnapshot(newAnalysis(firstProject).setStatus(STATUS_UNPROCESSED).setCreatedAt(from + 1_000_000L)); + insertActivity(unprocessedAnalysis, CeActivityDto.Status.CANCELED); + SnapshotDto finishedAnalysis = db.components().insertSnapshot(newAnalysis(firstProject).setStatus(STATUS_PROCESSED).setCreatedAt(from)); + insertActivity(finishedAnalysis, CeActivityDto.Status.SUCCESS); + SnapshotDto otherFinishedAnalysis = db.components().insertSnapshot(newAnalysis(firstProject).setStatus(STATUS_PROCESSED).setCreatedAt(from + 1_000_000L)); + insertActivity(otherFinishedAnalysis, CeActivityDto.Status.SUCCESS); + SnapshotDto canceledAnalysis = db.components().insertSnapshot(newAnalysis(firstProject).setStatus(STATUS_PROCESSED).setCreatedAt(from)); + insertActivity(canceledAnalysis, CeActivityDto.Status.CANCELED); + SnapshotDto oldAnalysis = db.components().insertSnapshot(newAnalysis(firstProject).setStatus(STATUS_PROCESSED).setCreatedAt(from - 1L)); + insertActivity(oldAnalysis, CeActivityDto.Status.SUCCESS); + SnapshotDto analysisOnSecondProject = db.components().insertSnapshot(newAnalysis(secondProject).setStatus(STATUS_PROCESSED).setCreatedAt(otherFrom)); + insertActivity(analysisOnSecondProject, CeActivityDto.Status.SUCCESS); + SnapshotDto oldAnalysisOnThirdProject = db.components().insertSnapshot(newAnalysis(thirdProject).setStatus(STATUS_PROCESSED).setCreatedAt(otherFrom - 1L)); + insertActivity(oldAnalysisOnThirdProject, CeActivityDto.Status.SUCCESS); + + List<SnapshotDto> result = underTest.selectFinishedByComponentUuidsAndFromDates(dbSession, + Arrays.asList(firstProject.uuid(), secondProject.uuid(), thirdProject.uuid()), + Arrays.asList(from, otherFrom, otherFrom)); + + assertThat(result).extracting(SnapshotDto::getUuid) + .containsExactlyInAnyOrder(finishedAnalysis.getUuid(), otherFinishedAnalysis.getUuid(), analysisOnSecondProject.getUuid()); + } + + @Test public void insert() { ComponentDto project = db.components().insertPrivateProject(); @@ -334,4 +370,20 @@ public class SnapshotDaoTest { .setPeriodDate(1_500_000_000_001L) .setBuildDate(1_500_000_000_006L); } + + private CeActivityDto insertActivity(SnapshotDto analysis, CeActivityDto.Status status) { + CeQueueDto queueDto = new CeQueueDto(); + queueDto.setTaskType(CeTaskTypes.REPORT); + queueDto.setComponentUuid(analysis.getComponentUuid()); + queueDto.setUuid(randomAlphanumeric(40)); + queueDto.setCreatedAt(nextLong()); + CeActivityDto activityDto = new CeActivityDto(queueDto); + activityDto.setStatus(status); + activityDto.setExecutionTimeMs(nextLong()); + activityDto.setExecutedAt(nextLong()); + activityDto.setAnalysisUuid(analysis.getUuid()); + db.getDbClient().ceActivityDao().insert(db.getSession(), activityDto); + db.commit(); + return activityDto; + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java index dc171f42bbf..07aa4ea77a5 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java @@ -394,7 +394,7 @@ public class ActivityActionTest { activityDto.setExecutionTimeMs(500L); activityDto.setExecutedAt(EXECUTED_AT); activityDto.setAnalysisUuid("U1"); - dbTester.getDbClient().ceActivityDao().insert(dbTester.getSession(), activityDto); + dbTester.getDbClient().ceActivityDao(). insert(dbTester.getSession(), activityDto); dbTester.commit(); return activityDto; } |