aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-webserver-es
diff options
context:
space:
mode:
authorJacek <jacek.poreda@sonarsource.com>2020-06-08 17:15:43 +0200
committersonartech <sonartech@sonarsource.com>2020-06-26 20:04:57 +0000
commit14d6de3529b12ec0af367e551cf66ac6daae1ca7 (patch)
tree7674e1e94f2991a2f5819eec401dadd4e0eac86e /server/sonar-webserver-es
parent52dea5983fffca49138dec3f8b58ed3160c8d37c (diff)
downloadsonarqube-14d6de3529b12ec0af367e551cf66ac6daae1ca7.tar.gz
sonarqube-14d6de3529b12ec0af367e551cf66ac6daae1ca7.zip
SONAR-13398 fail with 503 api/issues/search WS if needIssueSync is set to true
Diffstat (limited to 'server/sonar-webserver-es')
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/es/EsIndexSyncInProgressException.java9
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndexSyncProgressChecker.java30
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSyncProgressCheckerTest.java115
3 files changed, 132 insertions, 22 deletions
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/es/EsIndexSyncInProgressException.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/es/EsIndexSyncInProgressException.java
index bc75d400841..fe72723b7a7 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/es/EsIndexSyncInProgressException.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/es/EsIndexSyncInProgressException.java
@@ -20,13 +20,14 @@
package org.sonar.server.es;
import org.sonar.server.es.IndexType.IndexMainType;
+import org.sonar.server.exceptions.ServerException;
-public class EsIndexSyncInProgressException extends RuntimeException {
+public class EsIndexSyncInProgressException extends ServerException {
- private IndexMainType indexType;
+ private final IndexMainType indexType;
- public EsIndexSyncInProgressException(IndexMainType indexType) {
- super(String.format("Synchronization of %s index is in progress", indexType.toString()));
+ public EsIndexSyncInProgressException(IndexMainType indexType, String message) {
+ super(503, message);
this.indexType = indexType;
}
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndexSyncProgressChecker.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndexSyncProgressChecker.java
index 24e85e69222..6e9ea790226 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndexSyncProgressChecker.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndexSyncProgressChecker.java
@@ -22,6 +22,7 @@ package org.sonar.server.issue.index;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.List;
+import javax.annotation.Nullable;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.server.es.EsIndexSyncInProgressException;
@@ -39,31 +40,26 @@ public class IssueIndexSyncProgressChecker {
return new IssueSyncProgress(completed, total);
}
- /**
- * Checks if issue index sync is in progress, if it is, method throws exception org.sonar.server.es.EsIndexSyncInProgressException
- */
- public void checkIfIssueSyncInProgress(DbSession dbSession) throws EsIndexSyncInProgressException {
- if (isIssueSyncInProgress(dbSession)) {
- throw new EsIndexSyncInProgressException(IssueIndexDefinition.TYPE_ISSUE.getMainType());
+ public void checkIfAnyComponentsIssueSyncInProgress(DbSession dbSession, List<String> componentKeys, @Nullable String branch,
+ @Nullable String pullRequest) {
+ boolean needIssueSync = dbClient.branchDao().doAnyOfComponentsNeedIssueSync(dbSession, componentKeys, branch, pullRequest);
+ if (needIssueSync) {
+ throw new EsIndexSyncInProgressException(IssueIndexDefinition.TYPE_ISSUE.getMainType(),
+ "Results are temporarily unavailable. Indexing of issues is in progress.");
}
}
/**
- * Checks if project issue index sync is in progress, if it is, method throws exception org.sonar.server.es.EsIndexSyncInProgressException
+ * Checks if issue index sync is in progress, if it is, method throws exception org.sonar.server.es.EsIndexSyncInProgressException
*/
- public void checkIfProjectIssueSyncInProgress(DbSession dbSession, String projectUuid) throws EsIndexSyncInProgressException {
- if (doProjectNeedIssueSync(dbSession, projectUuid)) {
- throw new EsIndexSyncInProgressException(IssueIndexDefinition.TYPE_ISSUE.getMainType());
- }
- }
-
- public void checkIfAnyProjectIssueSyncInProgress(DbSession dbSession, Collection<String> projectUuids) throws EsIndexSyncInProgressException {
- if (!findProjectUuidsWithIssuesSyncNeed(dbSession, projectUuids).isEmpty()) {
- throw new EsIndexSyncInProgressException(IssueIndexDefinition.TYPE_ISSUE.getMainType());
+ public void checkIfIssueSyncInProgress(DbSession dbSession) {
+ if (isIssueSyncInProgress(dbSession)) {
+ throw new EsIndexSyncInProgressException(IssueIndexDefinition.TYPE_ISSUE.getMainType(),
+ "Results are temporarily unavailable. Indexing of issues is in progress.");
}
}
- public boolean isIssueSyncInProgress(DbSession dbSession) throws EsIndexSyncInProgressException {
+ public boolean isIssueSyncInProgress(DbSession dbSession) {
return dbClient.branchDao().hasAnyBranchWhereNeedIssueSync(dbSession, true);
}
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSyncProgressCheckerTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSyncProgressCheckerTest.java
index 3315c8cb37e..d036d47eea0 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSyncProgressCheckerTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSyncProgressCheckerTest.java
@@ -22,15 +22,23 @@ package org.sonar.server.issue.index;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.stream.IntStream;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.sonar.api.utils.System2;
+import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
+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;
@RunWith(DataProviderRunner.class)
public class IssueIndexSyncProgressCheckerTest {
@@ -107,10 +115,115 @@ public class IssueIndexSyncProgressCheckerTest {
assertThat(result.isCompleted()).isFalse();
}
- private void insertProjectWithBranches(boolean needIssueSync, int numberOfBranches) {
+ @Test
+ public void checkIfAnyComponentsIssueSyncInProgress_throws_exception_if_all_components_have_need_issue_sync_TRUE() {
+ ProjectDto projectDto1 = insertProjectWithBranches(true, 0);
+ ProjectDto projectDto2 = insertProjectWithBranches(true, 0);
+ DbSession session = db.getSession();
+ List<String> projectKeys = Arrays.asList(projectDto1.getKey(), projectDto2.getKey());
+ assertThatThrownBy(() -> underTest.checkIfAnyComponentsIssueSyncInProgress(session, projectKeys, null, null))
+ .isInstanceOf(EsIndexSyncInProgressException.class)
+ .hasFieldOrPropertyWithValue("httpCode", 503)
+ .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress.");
+ }
+
+ @Test
+ public void checkIfAnyComponentsIssueSyncInProgress_does_not_throw_exception_if_all_components_have_need_issue_sync_FALSE() {
+ underTest.checkIfAnyComponentsIssueSyncInProgress(db.getSession(), Collections.emptyList(), null, null);
+ ProjectDto projectDto1 = insertProjectWithBranches(false, 0);
+ ProjectDto projectDto2 = insertProjectWithBranches(false, 0);
+ underTest.checkIfAnyComponentsIssueSyncInProgress(db.getSession(), Arrays.asList(projectDto1.getKey(), projectDto2.getKey()), null, null);
+ }
+
+ @Test
+ public void checkIfAnyComponentsIssueSyncInProgress_throws_exception_if_at_least_one_component_has_need_issue_sync_TRUE() {
+ ProjectDto projectDto1 = insertProjectWithBranches(false, 0);
+ ProjectDto projectDto2 = insertProjectWithBranches(true, 0);
+
+ DbSession session = db.getSession();
+ List<String> projectKeys = Arrays.asList(projectDto1.getKey(), projectDto2.getKey());
+ assertThatThrownBy(() -> underTest.checkIfAnyComponentsIssueSyncInProgress(session, projectKeys, null, null))
+ .isInstanceOf(EsIndexSyncInProgressException.class)
+ .hasFieldOrPropertyWithValue("httpCode", 503)
+ .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress.");
+ }
+
+ @Test
+ public void checkIfAnyComponentsIssueSyncInProgress_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.checkIfAnyComponentsIssueSyncInProgress(session, projectKey1, null, null);
+
+ List<String> projectKey2 = singletonList(projectDto1.getKey());
+ // throws if flag set to TRUE
+ assertThatThrownBy(() -> underTest.checkIfAnyComponentsIssueSyncInProgress(session,
+ projectKey2, null, null))
+ .isInstanceOf(EsIndexSyncInProgressException.class)
+ .hasFieldOrPropertyWithValue("httpCode", 503)
+ .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress.");
+ }
+
+ @Test
+ public void checkIfAnyComponentsNeedIssueSync_single_view_subview_or_app() {
+ ProjectDto projectDto1 = insertProjectWithBranches(true, 0);
+
+ ComponentDto app = db.components().insertPublicApplication();
+ ComponentDto view = db.components().insertPrivatePortfolio();
+ ComponentDto subview = db.components().insertSubView(view);
+
+ DbSession session = db.getSession();
+ List<String> appViewOrSubviewKeys = Arrays.asList(projectDto1.getKey(), app.getDbKey(), view.getDbKey(), subview.getDbKey());
+
+ // throws if flag set to TRUE
+ assertThatThrownBy(() -> underTest.checkIfAnyComponentsIssueSyncInProgress(session,
+ appViewOrSubviewKeys, null, null))
+ .isInstanceOf(EsIndexSyncInProgressException.class)
+ .hasFieldOrPropertyWithValue("httpCode", 503)
+ .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress.");
+ }
+
+ @Test
+ public void checkIfIssueSyncInProgress_throws_exception_if_at_least_one_component_has_need_issue_sync_TRUE() {
+ insertProjectWithBranches(false, 0);
+ underTest.checkIfIssueSyncInProgress(db.getSession());
+ insertProjectWithBranches(true, 0);
+
+ DbSession session = db.getSession();
+ assertThatThrownBy(() -> underTest.checkIfIssueSyncInProgress(session))
+ .isInstanceOf(EsIndexSyncInProgressException.class)
+ .hasFieldOrPropertyWithValue("httpCode", 503)
+ .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress.");
+ }
+
+ @Test
+ public void doProjectNeedIssueSync() {
+ ProjectDto projectDto1 = insertProjectWithBranches(false, 0);
+ assertThat(underTest.doProjectNeedIssueSync(db.getSession(), projectDto1.getUuid())).isFalse();
+ ProjectDto projectDto2 = insertProjectWithBranches(true, 0);
+ assertThat(underTest.doProjectNeedIssueSync(db.getSession(), projectDto2.getUuid())).isTrue();
+ }
+
+ @Test
+ public void findProjectUuidsWithIssuesSyncNeed() {
+ ProjectDto projectDto1 = insertProjectWithBranches(false, 0);
+ ProjectDto projectDto2 = insertProjectWithBranches(false, 0);
+ ProjectDto projectDto3 = insertProjectWithBranches(true, 0);
+ ProjectDto projectDto4 = insertProjectWithBranches(true, 0);
+
+ assertThat(underTest.findProjectUuidsWithIssuesSyncNeed(db.getSession(),
+ Arrays.asList(projectDto1.getUuid(), projectDto2.getUuid(), projectDto3.getUuid(), projectDto4.getUuid())))
+ .containsOnly(projectDto3.getUuid(), projectDto4.getUuid());
+ }
+
+ private ProjectDto insertProjectWithBranches(boolean needIssueSync, int numberOfBranches) {
ProjectDto projectDto = db.components()
.insertPrivateProjectDto(db.getDefaultOrganization(), branchDto -> branchDto.setNeedIssueSync(needIssueSync));
IntStream.range(0, numberOfBranches).forEach(
i -> db.components().insertProjectBranch(projectDto, branchDto -> branchDto.setNeedIssueSync(needIssueSync)));
+ return projectDto;
}
}