]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-13398 Throw ES exception in case component is a portfolio, subview or app
authorJacek <jacek.poreda@sonarsource.com>
Fri, 19 Jun 2020 12:49:21 +0000 (14:49 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 26 Jun 2020 20:04:58 +0000 (20:04 +0000)
server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java
server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndexSyncProgressChecker.java
server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSyncProgressCheckerTest.java

index b55ce5a0b75d185f2ab682a308d1966653901fbc..0898737cec8bc55c60b7203097ceeaae035ded87 100644 (file)
@@ -160,7 +160,7 @@ public class BranchDao implements Dao {
     if (!components.isEmpty()) {
       List<Boolean> result = new LinkedList<>();
       return executeLargeInputs(components, input -> {
-        boolean groupNeedIssueSync = mapper(session).doAnyOfComponentsNeedIssueSync(components) > 0;
+        boolean groupNeedIssueSync = mapper(session).doAnyOfComponentsNeedIssueSync(input) > 0;
         result.add(groupNeedIssueSync);
         return result;
       }).stream()
index d95733ac75c4f3a2e8fc827ceb70d12d97c7b57c..e4426e519b748dd5d7836e2fbf992ded17d884d9 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -395,4 +396,16 @@ public class ComponentDao implements Dao {
     return Optional.ofNullable(mapper(dbSession).selectByAlmIdAndAlmRepositoryId(almId, almRepositoryId));
   }
 
+  public boolean existAnyOfComponentsWithQualifiers(DbSession session, Collection<String> componentKeys, Set<String> qualifiers) {
+    if (!componentKeys.isEmpty()) {
+      List<Boolean> result = new LinkedList<>();
+      return executeLargeInputs(componentKeys, input -> {
+        boolean groupNeedIssueSync = mapper(session).checkIfAnyOfComponentsWithQualifiers(input, qualifiers) > 0;
+        result.add(groupNeedIssueSync);
+        return result;
+      }).stream().anyMatch(b -> b);
+    }
+    return false;
+  }
+
 }
index 32f99628b4beb7bb8e9fcf8f3d1e8535210fb95d..3081461ed4c73ced8145b1afe5b56b9158682347 100644 (file)
@@ -157,4 +157,6 @@ public interface ComponentMapper {
   List<ProjectNclocDistributionDto> selectPrivateProjectsWithNcloc(@Param("organizationUuid") String organizationUuid);
 
   List<ComponentWithModuleUuidDto> selectEnabledComponentsWithModuleUuidFromProjectKey(String projectKey);
+
+  short checkIfAnyOfComponentsWithQualifiers(@Param("componentKeys") Collection<String> componentKeys, @Param("qualifiers") Set<String> qualifiers);
 }
index f6513e87ee6035359a718230b41383a22a75e6ad..0254590f60ab83997b2e6758f7d3f5820c73eae8 100644 (file)
     where
       m.name = 'ncloc'
       and b.key_type = 'BRANCH'
-      and b.branch_type = 'BRANCH'
-      and p.enabled = ${_true}
-      and p.private = ${_true}
-      and p.scope = 'PRJ'
-      and p.qualifier = 'TRK'
-      and p.copy_component_uuid is null
-      and p.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
+    and b.branch_type = 'BRANCH'
+    and p.enabled = ${_true}
+    and p.private = ${_true}
+    and p.scope = 'PRJ'
+    and p.qualifier = 'TRK'
+    and p.copy_component_uuid is null
+    and p.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
     group by p.kee, p.name
     order by ncloc desc
   </select>
+
+  <select id="checkIfAnyOfComponentsWithQualifiers" resultType="short">
+    select
+    case when exists
+    (
+    select c.uuid from components c
+    where c.kee in
+    <foreach collection="componentKeys" open="(" close=")" item="componentKey" separator=",">
+      #{componentKey,jdbcType=VARCHAR}
+    </foreach>
+    and c.scope = 'PRJ'
+    and c.qualifier in
+    <foreach collection="qualifiers" open="(" close=")" item="qualifier" separator=",">
+      #{qualifier,jdbcType=VARCHAR}
+    </foreach>
+    )
+    then 1
+    else 0
+    end
+  </select>
 </mapper>
index eb93250b8d0ab66d28332b7e1577141cfcfdf44b..a3d473b0c05401a8c475c500083fba853cf5517f 100644 (file)
@@ -56,6 +56,7 @@ import org.sonar.db.source.FileSourceDto;
 import static com.google.common.collect.ImmutableSet.of;
 import static com.google.common.collect.Sets.newHashSet;
 import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
 import static java.util.Collections.emptySet;
 import static java.util.Collections.singleton;
 import static java.util.Collections.singletonList;
@@ -67,9 +68,12 @@ import static org.assertj.core.api.Assertions.entry;
 import static org.assertj.core.api.Assertions.tuple;
 import static org.sonar.api.resources.Qualifiers.APP;
 import static org.sonar.api.resources.Qualifiers.PROJECT;
+import static org.sonar.api.resources.Qualifiers.SUBVIEW;
+import static org.sonar.api.resources.Qualifiers.VIEW;
 import static org.sonar.api.utils.DateUtils.parseDate;
 import static org.sonar.db.component.BranchType.BRANCH;
 import static org.sonar.db.component.BranchType.PULL_REQUEST;
+import static org.sonar.db.component.ComponentTesting.newApplication;
 import static org.sonar.db.component.ComponentTesting.newBranchDto;
 import static org.sonar.db.component.ComponentTesting.newDirectory;
 import static org.sonar.db.component.ComponentTesting.newFileDto;
@@ -1886,6 +1890,28 @@ public class ComponentDaoTest {
     assertThat(result).extracting(ProjectNclocDistributionDto::getNcloc).containsExactly(30L, 10L);
   }
 
+  @Test
+  public void existAnyOfComponentsWithQualifiers() {
+    ComponentDto projectDto = db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization()));
+
+    ComponentDto view = db.components().insertComponent(newView(db.getDefaultOrganization()));
+    ComponentDto subview = db.components().insertComponent(newSubView(view));
+
+    ComponentDto app = db.components().insertComponent(newApplication(db.getDefaultOrganization()));
+
+    assertThat(underTest.existAnyOfComponentsWithQualifiers(db.getSession(), emptyList(), newHashSet(APP, VIEW, SUBVIEW))).isFalse();
+    assertThat(underTest.existAnyOfComponentsWithQualifiers(db.getSession(), singletonList("not-existing-component"), newHashSet(APP, VIEW, SUBVIEW))).isFalse();
+    assertThat(underTest.existAnyOfComponentsWithQualifiers(db.getSession(), singletonList(projectDto.getKey()), newHashSet(APP, VIEW, SUBVIEW))).isFalse();
+
+    assertThat(underTest.existAnyOfComponentsWithQualifiers(db.getSession(), singletonList(projectDto.getKey()), newHashSet(PROJECT))).isTrue();
+
+    assertThat(underTest.existAnyOfComponentsWithQualifiers(db.getSession(), singletonList(view.getKey()), newHashSet(APP, VIEW, SUBVIEW))).isTrue();
+    assertThat(underTest.existAnyOfComponentsWithQualifiers(db.getSession(), singletonList(subview.getKey()), newHashSet(APP, VIEW, SUBVIEW))).isTrue();
+    assertThat(underTest.existAnyOfComponentsWithQualifiers(db.getSession(), singletonList(app.getKey()), newHashSet(APP, VIEW, SUBVIEW))).isTrue();
+
+    assertThat(underTest.existAnyOfComponentsWithQualifiers(db.getSession(), newHashSet(projectDto.getKey(), view.getKey()), newHashSet(APP, VIEW, SUBVIEW))).isTrue();
+  }
+
   private boolean privateFlagOfUuid(String uuid) {
     return underTest.selectByUuid(db.getSession(), uuid).get().isPrivate();
   }
index 04dddb7da78df2f2047154bf9576a456c5ff95e9..3f72e04166a64afd64446252bf2f060696443342 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.server.issue.index;
 
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import java.util.Collection;
 import java.util.Collections;
@@ -27,7 +28,12 @@ import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.server.es.EsIndexSyncInProgressException;
 
+import static org.sonar.api.resources.Qualifiers.APP;
+import static org.sonar.api.resources.Qualifiers.SUBVIEW;
+import static org.sonar.api.resources.Qualifiers.VIEW;
+
 public class IssueIndexSyncProgressChecker {
+  private static final ImmutableSet<String> APP_VIEW_OR_SUBVIEW = ImmutableSet.<String>builder().add(VIEW, SUBVIEW, APP).build();
   private final DbClient dbClient;
 
   public IssueIndexSyncProgressChecker(DbClient dbClient) {
@@ -43,7 +49,13 @@ public class IssueIndexSyncProgressChecker {
   }
 
   public void checkIfAnyComponentsNeedIssueSync(DbSession dbSession, List<String> componentKeys) {
-    boolean needIssueSync = dbClient.branchDao().doAnyOfComponentsNeedIssueSync(dbSession, componentKeys);
+    boolean isAppOrViewOrSubview = dbClient.componentDao().existAnyOfComponentsWithQualifiers(dbSession, componentKeys, APP_VIEW_OR_SUBVIEW);
+    boolean needIssueSync;
+    if (isAppOrViewOrSubview) {
+      needIssueSync = dbClient.branchDao().hasAnyBranchWhereNeedIssueSync(dbSession, true);
+    } else {
+      needIssueSync = dbClient.branchDao().doAnyOfComponentsNeedIssueSync(dbSession, componentKeys);
+    }
     if (needIssueSync) {
       throw new EsIndexSyncInProgressException(IssueIndexDefinition.TYPE_ISSUE.getMainType(),
           "Results are temporarily unavailable. Indexing of issues is in progress.");
index 254d2f58ba59b7715e21dd8dba43db717f33106c..06f073d3564290ea16045eeca08569e80f6de6f1 100644 (file)
@@ -40,7 +40,6 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.db.project.ProjectDto;
 import org.sonar.server.es.EsIndexSyncInProgressException;
 
-import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.sonar.db.ce.CeActivityDto.Status.FAILED;
@@ -205,7 +204,7 @@ public class IssueIndexSyncProgressCheckerTest {
   }
 
   @Test
-  public void checkIfAnyComponentsIssueSyncInProgress_throws_exception_if_all_components_have_need_issue_sync_TRUE() {
+  public void checkIfAnyComponentsNeedIssueSync_throws_exception_if_all_components_have_need_issue_sync_TRUE() {
     ProjectDto projectDto1 = insertProjectWithBranches(true, 0);
     ProjectDto projectDto2 = insertProjectWithBranches(true, 0);
     DbSession session = db.getSession();
@@ -217,7 +216,7 @@ public class IssueIndexSyncProgressCheckerTest {
   }
 
   @Test
-  public void checkIfAnyComponentsIssueSyncInProgress_does_not_throw_exception_if_all_components_have_need_issue_sync_FALSE() {
+  public void checkIfAnyComponentsNeedIssueSync_does_not_throw_exception_if_all_components_have_need_issue_sync_FALSE() {
     underTest.checkIfAnyComponentsNeedIssueSync(db.getSession(), Collections.emptyList());
     ProjectDto projectDto1 = insertProjectWithBranches(false, 0);
     ProjectDto projectDto2 = insertProjectWithBranches(false, 0);
@@ -225,7 +224,7 @@ public class IssueIndexSyncProgressCheckerTest {
   }
 
   @Test
-  public void checkIfAnyComponentsIssueSyncInProgress_throws_exception_if_at_least_one_component_has_need_issue_sync_TRUE() {
+  public void checkIfAnyComponentsNeedIssueSync_throws_exception_if_at_least_one_component_has_need_issue_sync_TRUE() {
     ProjectDto projectDto1 = insertProjectWithBranches(false, 0);
     ProjectDto projectDto2 = insertProjectWithBranches(true, 0);
 
@@ -238,19 +237,17 @@ public class IssueIndexSyncProgressCheckerTest {
   }
 
   @Test
-  public void checkIfAnyComponentsIssueSyncInProgress_single_component() {
+  public void checkIfComponentNeedIssueSync_single_component() {
     ProjectDto projectDto1 = insertProjectWithBranches(true, 0);
     ProjectDto projectDto2 = insertProjectWithBranches(false, 0);
 
     DbSession session = db.getSession();
-    List<String> projectKey1 = singletonList(projectDto2.getKey());
     // do nothing when need issue sync false
-    underTest.checkIfAnyComponentsNeedIssueSync(session, projectKey1);
+    underTest.checkIfComponentNeedIssueSync(session, projectDto2.getKey());
 
-    List<String> projectKey2 = singletonList(projectDto1.getKey());
     // throws if flag set to TRUE
-    assertThatThrownBy(() -> underTest.checkIfAnyComponentsNeedIssueSync(session,
-      projectKey2))
+    assertThatThrownBy(() -> underTest.checkIfComponentNeedIssueSync(session,
+      projectDto1.getKey()))
         .isInstanceOf(EsIndexSyncInProgressException.class)
         .hasFieldOrPropertyWithValue("httpCode", 503)
         .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress.");