@@ -21,6 +21,7 @@ package org.sonar.server.issue.index; | |||
import com.google.common.collect.Sets; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import javax.annotation.Nullable; | |||
import org.sonar.db.DbClient; | |||
@@ -40,7 +41,7 @@ public class IssueIndexSyncProgressChecker { | |||
return new IssueSyncProgress(completed, total); | |||
} | |||
public void checkIfAnyComponentsIssueSyncInProgress(DbSession dbSession, List<String> componentKeys, @Nullable String branch, | |||
public void checkIfAnyComponentsNeedIssueSync(DbSession dbSession, List<String> componentKeys, @Nullable String branch, | |||
@Nullable String pullRequest) { | |||
boolean needIssueSync = dbClient.branchDao().doAnyOfComponentsNeedIssueSync(dbSession, componentKeys, branch, pullRequest); | |||
if (needIssueSync) { | |||
@@ -49,6 +50,10 @@ public class IssueIndexSyncProgressChecker { | |||
} | |||
} | |||
public void checkIfComponentNeedIssueSync(DbSession dbSession, String componentKey) { | |||
checkIfAnyComponentsNeedIssueSync(dbSession, Collections.singletonList(componentKey), null, null); | |||
} | |||
/** | |||
* Checks if issue index sync is in progress, if it is, method throws exception org.sonar.server.es.EsIndexSyncInProgressException | |||
*/ |
@@ -121,7 +121,7 @@ public class IssueIndexSyncProgressCheckerTest { | |||
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)) | |||
assertThatThrownBy(() -> underTest.checkIfAnyComponentsNeedIssueSync(session, projectKeys, null, null)) | |||
.isInstanceOf(EsIndexSyncInProgressException.class) | |||
.hasFieldOrPropertyWithValue("httpCode", 503) | |||
.hasMessage("Results are temporarily unavailable. Indexing of issues is in progress."); | |||
@@ -129,10 +129,10 @@ public class IssueIndexSyncProgressCheckerTest { | |||
@Test | |||
public void checkIfAnyComponentsIssueSyncInProgress_does_not_throw_exception_if_all_components_have_need_issue_sync_FALSE() { | |||
underTest.checkIfAnyComponentsIssueSyncInProgress(db.getSession(), Collections.emptyList(), null, null); | |||
underTest.checkIfAnyComponentsNeedIssueSync(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); | |||
underTest.checkIfAnyComponentsNeedIssueSync(db.getSession(), Arrays.asList(projectDto1.getKey(), projectDto2.getKey()), null, null); | |||
} | |||
@Test | |||
@@ -142,7 +142,7 @@ public class IssueIndexSyncProgressCheckerTest { | |||
DbSession session = db.getSession(); | |||
List<String> projectKeys = Arrays.asList(projectDto1.getKey(), projectDto2.getKey()); | |||
assertThatThrownBy(() -> underTest.checkIfAnyComponentsIssueSyncInProgress(session, projectKeys, null, null)) | |||
assertThatThrownBy(() -> underTest.checkIfAnyComponentsNeedIssueSync(session, projectKeys, null, null)) | |||
.isInstanceOf(EsIndexSyncInProgressException.class) | |||
.hasFieldOrPropertyWithValue("httpCode", 503) | |||
.hasMessage("Results are temporarily unavailable. Indexing of issues is in progress."); | |||
@@ -156,11 +156,11 @@ public class IssueIndexSyncProgressCheckerTest { | |||
DbSession session = db.getSession(); | |||
List<String> projectKey1 = singletonList(projectDto2.getKey()); | |||
// do nothing when need issue sync false | |||
underTest.checkIfAnyComponentsIssueSyncInProgress(session, projectKey1, null, null); | |||
underTest.checkIfAnyComponentsNeedIssueSync(session, projectKey1, null, null); | |||
List<String> projectKey2 = singletonList(projectDto1.getKey()); | |||
// throws if flag set to TRUE | |||
assertThatThrownBy(() -> underTest.checkIfAnyComponentsIssueSyncInProgress(session, | |||
assertThatThrownBy(() -> underTest.checkIfAnyComponentsNeedIssueSync(session, | |||
projectKey2, null, null)) | |||
.isInstanceOf(EsIndexSyncInProgressException.class) | |||
.hasFieldOrPropertyWithValue("httpCode", 503) |
@@ -186,7 +186,7 @@ public class SearchAction implements HotspotsWsAction { | |||
if (projectKey.isPresent()) { | |||
String branch = wsRequest.getBranch().orElse(null); | |||
String pullRequest = wsRequest.getPullRequest().orElse(null); | |||
issueIndexSyncProgressChecker.checkIfAnyComponentsIssueSyncInProgress(dbSession, singletonList(projectKey.get()), branch, pullRequest); | |||
issueIndexSyncProgressChecker.checkIfAnyComponentsNeedIssueSync(dbSession, singletonList(projectKey.get()), branch, pullRequest); | |||
} else { | |||
// component keys not provided - asking for global | |||
issueIndexSyncProgressChecker.checkIfIssueSyncInProgress(dbSession); |
@@ -546,7 +546,7 @@ public class SearchAction implements IssuesWsAction { | |||
if (components != null && !components.isEmpty()) { | |||
String branch = searchRequest.getBranch(); | |||
String pullRequest = searchRequest.getPullRequest(); | |||
issueIndexSyncProgressChecker.checkIfAnyComponentsIssueSyncInProgress(dbSession, components, branch, pullRequest); | |||
issueIndexSyncProgressChecker.checkIfAnyComponentsNeedIssueSync(dbSession, components, branch, pullRequest); | |||
} else { | |||
// component keys not provided - asking for global | |||
issueIndexSyncProgressChecker.checkIfIssueSyncInProgress(dbSession); |
@@ -37,6 +37,7 @@ import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.issue.index.IssueIndex; | |||
import org.sonar.server.issue.index.IssueIndexSyncProgressChecker; | |||
import org.sonar.server.issue.index.IssueQuery; | |||
import org.sonarqube.ws.Issues; | |||
@@ -58,11 +59,15 @@ public class TagsAction implements IssuesWsAction { | |||
private static final String PARAM_PROJECT = "project"; | |||
private final IssueIndex issueIndex; | |||
private final IssueIndexSyncProgressChecker issueIndexSyncProgressChecker; | |||
private final DbClient dbClient; | |||
private final ComponentFinder componentFinder; | |||
public TagsAction(IssueIndex issueIndex, DbClient dbClient, ComponentFinder componentFinder) { | |||
public TagsAction(IssueIndex issueIndex, | |||
IssueIndexSyncProgressChecker issueIndexSyncProgressChecker, DbClient dbClient, | |||
ComponentFinder componentFinder) { | |||
this.issueIndex = issueIndex; | |||
this.issueIndexSyncProgressChecker = issueIndexSyncProgressChecker; | |||
this.dbClient = dbClient; | |||
this.componentFinder = componentFinder; | |||
} | |||
@@ -93,8 +98,11 @@ public class TagsAction implements IssuesWsAction { | |||
@Override | |||
public void handle(Request request, Response response) throws Exception { | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
Optional<OrganizationDto> organization = getOrganization(dbSession, request.param(PARAM_ORGANIZATION)); | |||
Optional<ComponentDto> project = getProject(dbSession, organization, request.param(PARAM_PROJECT)); | |||
String projectKey = request.param(PARAM_PROJECT); | |||
String organizatioKey = request.param(PARAM_ORGANIZATION); | |||
checkIfAnyComponentsNeedIssueSync(dbSession, projectKey); | |||
Optional<OrganizationDto> organization = getOrganization(dbSession, organizatioKey); | |||
Optional<ComponentDto> project = getProject(dbSession, organization, projectKey); | |||
List<String> tags = searchTags(organization, project, request); | |||
Issues.TagsResponse.Builder tagsResponseBuilder = Issues.TagsResponse.newBuilder(); | |||
tags.forEach(tagsResponseBuilder::addTags); | |||
@@ -117,6 +125,14 @@ public class TagsAction implements IssuesWsAction { | |||
return Optional.of(project); | |||
} | |||
private void checkIfAnyComponentsNeedIssueSync(DbSession session, @Nullable String projectKey) { | |||
if (projectKey != null) { | |||
issueIndexSyncProgressChecker.checkIfComponentNeedIssueSync(session, projectKey); | |||
} else { | |||
issueIndexSyncProgressChecker.checkIfIssueSyncInProgress(session); | |||
} | |||
} | |||
private List<String> searchTags(Optional<OrganizationDto> organization, Optional<ComponentDto> project, Request request) { | |||
IssueQuery.Builder issueQueryBuilder = IssueQuery.builder() | |||
.types(ISSUE_TYPE_NAMES); |
@@ -671,9 +671,9 @@ public class SearchActionTest { | |||
.extracting(SearchWsResponse.Hotspot::getKey) | |||
.containsExactlyInAnyOrder(Arrays.stream(hotspotPR).map(IssueDto::getKey).toArray(String[]::new)); | |||
verify(issueIndexSyncProgressChecker).checkIfAnyComponentsIssueSyncInProgress(any(), argThat(arg -> arg.contains(project.getKey())), isNull(), isNull()); | |||
verify(issueIndexSyncProgressChecker).checkIfAnyComponentsIssueSyncInProgress(any(), argThat(arg -> arg.contains(project.getKey())), eq(branch.getBranch()), isNull()); | |||
verify(issueIndexSyncProgressChecker).checkIfAnyComponentsIssueSyncInProgress(any(), argThat(arg -> arg.contains(project.getKey())), isNull(), eq(branch.getPullRequest())); | |||
verify(issueIndexSyncProgressChecker).checkIfAnyComponentsNeedIssueSync(any(), argThat(arg -> arg.contains(project.getKey())), isNull(), isNull()); | |||
verify(issueIndexSyncProgressChecker).checkIfAnyComponentsNeedIssueSync(any(), argThat(arg -> arg.contains(project.getKey())), eq(branch.getBranch()), isNull()); | |||
verify(issueIndexSyncProgressChecker).checkIfAnyComponentsNeedIssueSync(any(), argThat(arg -> arg.contains(project.getKey())), isNull(), eq(branch.getPullRequest())); | |||
} | |||
@Test |
@@ -36,6 +36,7 @@ import org.sonar.db.rule.RuleDefinitionDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.es.EsTester; | |||
import org.sonar.server.issue.index.IssueIndex; | |||
import org.sonar.server.issue.index.IssueIndexSyncProgressChecker; | |||
import org.sonar.server.issue.index.IssueIndexer; | |||
import org.sonar.server.issue.index.IssueIteratorFactory; | |||
import org.sonar.server.permission.index.PermissionIndexerTester; | |||
@@ -52,6 +53,10 @@ import static java.util.Collections.emptySet; | |||
import static java.util.Collections.singletonList; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.assertj.core.api.Assertions.tuple; | |||
import static org.mockito.ArgumentMatchers.any; | |||
import static org.mockito.ArgumentMatchers.eq; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.sonar.api.resources.Qualifiers.PROJECT; | |||
import static org.sonar.db.component.ComponentTesting.newFileDto; | |||
import static org.sonar.db.component.ComponentTesting.newProjectCopy; | |||
@@ -69,12 +74,13 @@ public class TagsActionTest { | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private IssueIndex issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSession, new WebAuthorizationTypeSupport(userSession)); | |||
private IssueIndexSyncProgressChecker issueIndexSyncProgressChecker = mock(IssueIndexSyncProgressChecker.class); | |||
private IssueIndexer issueIndexer = new IssueIndexer(es.client(), db.getDbClient(), new IssueIteratorFactory(db.getDbClient()), null); | |||
private ViewIndexer viewIndexer = new ViewIndexer(db.getDbClient(), es.client()); | |||
private PermissionIndexerTester permissionIndexer = new PermissionIndexerTester(es, issueIndexer); | |||
private ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(PROJECT); | |||
private WsActionTester ws = new WsActionTester(new TagsAction(issueIndex, db.getDbClient(), new ComponentFinder(db.getDbClient(), resourceTypes))); | |||
private WsActionTester ws = new WsActionTester(new TagsAction(issueIndex, issueIndexSyncProgressChecker, db.getDbClient(), new ComponentFinder(db.getDbClient(), resourceTypes))); | |||
@Test | |||
public void search_tags() { | |||
@@ -88,6 +94,7 @@ public class TagsActionTest { | |||
TagsResponse result = ws.newRequest().executeProtobuf(TagsResponse.class); | |||
assertThat(result.getTagsList()).containsExactly("tag1", "tag2", "tag3", "tag4", "tag5"); | |||
verify(issueIndexSyncProgressChecker).checkIfIssueSyncInProgress(any()); | |||
} | |||
@Test | |||
@@ -187,6 +194,7 @@ public class TagsActionTest { | |||
assertThat(tagListOf(ws.newRequest() | |||
.setParam("organization", organization.getKey()) | |||
.setParam("project", project1.getKey()))).containsExactly("tag1"); | |||
verify(issueIndexSyncProgressChecker).checkIfComponentNeedIssueSync(any(), eq(project1.getKey())); | |||
} | |||
@Test |