]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-13444 order projects by last analysis date
authorPierre <pierre.guillot@sonarsource.com>
Wed, 10 Jun 2020 08:10:47 +0000 (10:10 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 26 Jun 2020 20:04:57 +0000 (20:04 +0000)
server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml
server/sonar-webserver-core/src/main/java/org/sonar/server/issue/index/AsyncIssueIndexingImpl.java
server/sonar-webserver-core/src/test/java/org/sonar/server/issue/index/AsyncIssueIndexingImplTest.java

index b4be8752d57717f0991ee0fbea7d6894d335b760..836a428a9fa6e5b33f1f86ebb5015a69e24eeb7d 100644 (file)
     <include refid="columns"/>
     from project_branches pb
     where need_issue_sync = ${_true}
-    order by pb.updated_at, uuid
+    order by pb.updated_at desc, uuid
   </select>
 
   <update id="updateAllNeedIssueSync">
index 7dc3d84359e9f34ce0de8e0e209bc91ea3875f5e..ce9b250075b0d482bece541f6ec125d3cf42f479 100644 (file)
  */
 package org.sonar.server.issue.index;
 
+import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 import org.sonar.api.server.ServerSide;
 import org.sonar.api.utils.log.Logger;
@@ -32,6 +36,7 @@ import org.sonar.db.DbSession;
 import org.sonar.db.ce.CeActivityDto;
 import org.sonar.db.ce.CeQueueDto;
 import org.sonar.db.component.BranchDto;
+import org.sonar.db.component.SnapshotDto;
 
 import static java.util.Collections.emptyMap;
 import static org.sonar.db.ce.CeTaskTypes.BRANCH_ISSUE_SYNC;
@@ -68,16 +73,49 @@ public class AsyncIssueIndexingImpl implements AsyncIssueIndexing {
       String branchListForDisplay = branchInNeedOfIssueSync.stream().map(BranchDto::toString).collect(Collectors.joining(", "));
       LOG.info("{} branch found in need of issue sync : {}", branchInNeedOfIssueSync.size(), branchListForDisplay);
 
-      List<CeTaskSubmit> tasks = branchInNeedOfIssueSync.stream()
-        .map(this::buildTaskSubmit)
-        .collect(Collectors.toList());
-      ceQueue.massSubmit(tasks);
+      List<String> projectUuids = new ArrayList<>(branchInNeedOfIssueSync.stream().map(BranchDto::getProjectUuid).collect(Collectors.toSet()));
+      LOG.info("{} projects found in need of issue sync.", projectUuids.size());
 
-      dbSession.commit();
+      sortProjectUuids(dbSession, projectUuids);
 
+      Map<String, List<BranchDto>> branchesByProject = branchInNeedOfIssueSync.stream()
+        .collect(Collectors.groupingBy(BranchDto::getProjectUuid));
+
+      List<CeTaskSubmit> tasks = new ArrayList<>();
+      for (String projectUuid : projectUuids) {
+        List<BranchDto> branches = branchesByProject.get(projectUuid);
+        for (BranchDto branch : branches) {
+          tasks.add(buildTaskSubmit(branch));
+        }
+      }
+
+      ceQueue.massSubmit(tasks);
+      dbSession.commit();
     }
   }
 
+  private void sortProjectUuids(DbSession dbSession, List<String> projectUuids) {
+    Map<String, SnapshotDto> snapshotByProjectUuid = dbClient.snapshotDao()
+      .selectLastAnalysesByRootComponentUuids(dbSession, projectUuids).stream()
+      .collect(Collectors.toMap(SnapshotDto::getComponentUuid, Function.identity()));
+
+    projectUuids.sort(compareBySnapshot(snapshotByProjectUuid));
+  }
+
+  private static Comparator<String> compareBySnapshot(Map<String, SnapshotDto> snapshotByProjectUuid) {
+    return (uuid1, uuid2) -> {
+      SnapshotDto snapshot1 = snapshotByProjectUuid.get(uuid1);
+      SnapshotDto snapshot2 = snapshotByProjectUuid.get(uuid2);
+      if (snapshot1 == null) {
+        return 1;
+      }
+      if (snapshot2 == null) {
+        return -1;
+      }
+      return snapshot2.getCreatedAt().compareTo(snapshot1.getCreatedAt());
+    };
+  }
+
   private void removeExistingIndexationTasks(DbSession dbSession) {
     List<String> uuids = dbClient.ceQueueDao().selectAllInAscOrder(dbSession).stream()
       .filter(p -> p.getTaskType().equals(BRANCH_ISSUE_SYNC))
index 852e62e36949aacaca2c4effe56b71c84fb5a54c..f8c4ddb158c15daf2b14042b1bef36416d2d2129 100644 (file)
  */
 package org.sonar.server.issue.index;
 
+import java.util.Collection;
+import java.util.List;
 import java.util.Optional;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.api.utils.log.LoggerLevel;
@@ -36,6 +39,7 @@ import org.sonar.db.ce.CeActivityDto;
 import org.sonar.db.ce.CeActivityDto.Status;
 import org.sonar.db.ce.CeQueueDto;
 import org.sonar.db.component.BranchDto;
+import org.sonar.db.component.SnapshotDto;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.anyCollection;
@@ -46,6 +50,7 @@ import static org.mockito.Mockito.when;
 import static org.sonar.db.ce.CeTaskTypes.BRANCH_ISSUE_SYNC;
 import static org.sonar.db.ce.CeTaskTypes.REPORT;
 import static org.sonar.db.component.BranchType.BRANCH;
+import static org.sonar.db.component.SnapshotDto.STATUS_PROCESSED;
 
 public class AsyncIssueIndexingImplTest {
 
@@ -130,4 +135,55 @@ public class AsyncIssueIndexingImplTest {
         "Indexation task deletion complete.");
   }
 
+  @Test
+  public void order_by_last_analysis_date() {
+    BranchDto dto = new BranchDto()
+      .setBranchType(BRANCH)
+      .setKey("branch_1")
+      .setUuid("branch_uuid1")
+      .setProjectUuid("project_uuid1");
+    dbClient.branchDao().insert(dbTester.getSession(), dto);
+    dbTester.commit();
+    insertSnapshot("analysis_1", "project_uuid1", 1);
+
+    BranchDto dto2 = new BranchDto()
+      .setBranchType(BRANCH)
+      .setKey("branch_2")
+      .setUuid("branch_uuid2")
+      .setProjectUuid("project_uuid2");
+    dbClient.branchDao().insert(dbTester.getSession(), dto2);
+    dbTester.commit();
+    insertSnapshot("analysis_2", "project_uuid2", 2);
+
+    underTest.triggerOnIndexCreation();
+
+    verify(ceQueue, times(2)).prepareSubmit();
+
+    ArgumentCaptor<Collection<CeTaskSubmit>> captor = ArgumentCaptor.forClass(Collection.class);
+
+    verify(ceQueue, times(1)).massSubmit(captor.capture());
+    List<Collection<CeTaskSubmit>> captures = captor.getAllValues();
+    assertThat(captures).hasSize(1);
+    Collection<CeTaskSubmit> tasks = captures.get(0);
+    assertThat(tasks).hasSize(2);
+    assertThat(tasks)
+      .extracting(p -> p.getComponent().get().getUuid())
+      .containsExactly("branch_uuid2", "branch_uuid1");
+
+    assertThat(logTester.logs(LoggerLevel.INFO))
+      .contains("2 projects found in need of issue sync.");
+  }
+
+  private SnapshotDto insertSnapshot(String analysisUuid, String projectUuid, long createdAt) {
+    SnapshotDto snapshot = new SnapshotDto()
+      .setUuid(analysisUuid)
+      .setComponentUuid(projectUuid)
+      .setStatus(STATUS_PROCESSED)
+      .setCreatedAt(createdAt)
+      .setLast(true);
+    dbTester.getDbClient().snapshotDao().insert(dbTester.getSession(), snapshot);
+    dbTester.commit();
+    return snapshot;
+  }
+
 }