return mapper(dbSession).updateNeedIssueSync(branchUuid, needIssueSync, now); | return mapper(dbSession).updateNeedIssueSync(branchUuid, needIssueSync, now); | ||||
} | } | ||||
public boolean doAnyOfComponentsNeedIssueSync(DbSession session, List<String> components, @Nullable String branch, | |||||
@Nullable String pullRequest) { | |||||
public boolean doAnyOfComponentsNeedIssueSync(DbSession session, List<String> components) { | |||||
if (!components.isEmpty()) { | if (!components.isEmpty()) { | ||||
List<Boolean> result = new LinkedList<>(); | List<Boolean> result = new LinkedList<>(); | ||||
return executeLargeInputs(components, input -> { | return executeLargeInputs(components, input -> { | ||||
boolean groupNeedIssueSync = mapper(session).doAnyOfComponentsNeedIssueSync(components, branch, pullRequest) > 0; | |||||
boolean groupNeedIssueSync = mapper(session).doAnyOfComponentsNeedIssueSync(components) > 0; | |||||
result.add(groupNeedIssueSync); | result.add(groupNeedIssueSync); | ||||
return result; | return result; | ||||
}).stream() | }).stream() |
long updateNeedIssueSync(@Param("uuid") String uuid, @Param("needIssueSync")boolean needIssueSync,@Param("now") long now); | long updateNeedIssueSync(@Param("uuid") String uuid, @Param("needIssueSync")boolean needIssueSync,@Param("now") long now); | ||||
short doAnyOfComponentsNeedIssueSync(@Param("componentKeys") List<String> components, @Nullable @Param("branch") String branch, | |||||
@Nullable @Param("pullRequest") String pullRequest); | |||||
short doAnyOfComponentsNeedIssueSync(@Param("componentKeys") List<String> components); | |||||
} | } |
#{componentKey,jdbcType=VARCHAR} | #{componentKey,jdbcType=VARCHAR} | ||||
</foreach> | </foreach> | ||||
and pb.need_issue_sync = ${_true} | and pb.need_issue_sync = ${_true} | ||||
<if test="branch != null"> | |||||
and pb.kee = #{branch,jdbcType=VARCHAR} | |||||
</if> | |||||
<if test="pullRequest != null"> | |||||
and pb.kee = #{pullRequest,jdbcType=VARCHAR} | |||||
</if> | |||||
) | ) | ||||
then 1 | then 1 | ||||
else 0 | else 0 |
@Test | @Test | ||||
public void doAnyOfComponentsNeedIssueSync() { | public void doAnyOfComponentsNeedIssueSync() { | ||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, emptyList(), null, null)).isFalse(); | |||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, emptyList())).isFalse(); | |||||
ComponentDto project = db.components().insertPrivateProject(); | |||||
ProjectDto projectDto = db.components().getProjectDto(project); | |||||
ComponentDto project1 = db.components().insertPrivateProject(); | |||||
ComponentDto project2 = db.components().insertPrivateProject(); | |||||
ProjectDto projectDto = db.components().getProjectDto(project1); | |||||
db.components().insertProjectBranch(projectDto, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)); | db.components().insertProjectBranch(projectDto, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)); | ||||
BranchDto projectBranch1 = db.components().insertProjectBranch(projectDto, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)); | BranchDto projectBranch1 = db.components().insertProjectBranch(projectDto, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(true)); | ||||
BranchDto projectBranch2 = db.components().insertProjectBranch(projectDto, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)); | BranchDto projectBranch2 = db.components().insertProjectBranch(projectDto, b -> b.setBranchType(BranchType.BRANCH).setNeedIssueSync(false)); | ||||
BranchDto pullRequest2 = db.components().insertProjectBranch(projectDto, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(false)); | BranchDto pullRequest2 = db.components().insertProjectBranch(projectDto, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(false)); | ||||
db.components().insertProjectBranch(projectDto, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true)); | db.components().insertProjectBranch(projectDto, b -> b.setBranchType(BranchType.PULL_REQUEST).setNeedIssueSync(true)); | ||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, singletonList(project.getKey()), null, null)).isTrue(); | |||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, singletonList(project.getKey()), projectBranch1.getKey(), null)).isTrue(); | |||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, singletonList(project.getKey()), projectBranch2.getKey(), null)).isFalse(); | |||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, singletonList(project.getKey()), null, pullRequest1.getKey())).isTrue(); | |||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, singletonList(project.getKey()), null, pullRequest2.getKey())).isFalse(); | |||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, singletonList(project1.getKey()))).isTrue(); | |||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, singletonList(project2.getKey()))).isFalse(); | |||||
} | } | ||||
@Test | @Test | ||||
.map(ComponentDto::getDbKey) | .map(ComponentDto::getDbKey) | ||||
.collect(Collectors.toList()); | .collect(Collectors.toList()); | ||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, componentKeys, null, null)).isFalse(); | |||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, componentKeys)).isFalse(); | |||||
ComponentDto project = db.components().insertPrivateProject(); | ComponentDto project = db.components().insertPrivateProject(); | ||||
ProjectDto projectDto = db.components().getProjectDto(project); | ProjectDto projectDto = db.components().getProjectDto(project); | ||||
componentKeys.add(project.getDbKey()); | componentKeys.add(project.getDbKey()); | ||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, componentKeys, null, null)).isTrue(); | |||||
assertThat(underTest.doAnyOfComponentsNeedIssueSync(dbSession, componentKeys)).isTrue(); | |||||
} | } | ||||
} | } |
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.List; | import java.util.List; | ||||
import javax.annotation.Nullable; | |||||
import org.sonar.db.DbClient; | import org.sonar.db.DbClient; | ||||
import org.sonar.db.DbSession; | import org.sonar.db.DbSession; | ||||
import org.sonar.server.es.EsIndexSyncInProgressException; | import org.sonar.server.es.EsIndexSyncInProgressException; | ||||
return new IssueSyncProgress(completed, total); | return new IssueSyncProgress(completed, total); | ||||
} | } | ||||
public void checkIfAnyComponentsNeedIssueSync(DbSession dbSession, List<String> componentKeys, @Nullable String branch, | |||||
@Nullable String pullRequest) { | |||||
boolean needIssueSync = dbClient.branchDao().doAnyOfComponentsNeedIssueSync(dbSession, componentKeys, branch, pullRequest); | |||||
public void checkIfAnyComponentsNeedIssueSync(DbSession dbSession, List<String> componentKeys) { | |||||
boolean needIssueSync = dbClient.branchDao().doAnyOfComponentsNeedIssueSync(dbSession, componentKeys); | |||||
if (needIssueSync) { | if (needIssueSync) { | ||||
throw new EsIndexSyncInProgressException(IssueIndexDefinition.TYPE_ISSUE.getMainType(), | throw new EsIndexSyncInProgressException(IssueIndexDefinition.TYPE_ISSUE.getMainType(), | ||||
"Results are temporarily unavailable. Indexing of issues is in progress."); | "Results are temporarily unavailable. Indexing of issues is in progress."); | ||||
} | } | ||||
} | } | ||||
public void checkIfAnyComponentsNeedIssueSync(DbSession dbSession, List<String> componentKeys) { | |||||
checkIfAnyComponentsNeedIssueSync(dbSession, componentKeys, null, null); | |||||
} | |||||
public void checkIfComponentNeedIssueSync(DbSession dbSession, String componentKey) { | public void checkIfComponentNeedIssueSync(DbSession dbSession, String componentKey) { | ||||
checkIfComponentNeedIssueSync(dbSession, componentKey, null); | |||||
} | |||||
public void checkIfComponentNeedIssueSync(DbSession dbSession, String componentKey, @Nullable String branchKey) { | |||||
checkIfAnyComponentsNeedIssueSync(dbSession, Collections.singletonList(componentKey), branchKey, null); | |||||
checkIfAnyComponentsNeedIssueSync(dbSession, Collections.singletonList(componentKey)); | |||||
} | } | ||||
/** | /** |
ProjectDto projectDto2 = insertProjectWithBranches(true, 0); | ProjectDto projectDto2 = insertProjectWithBranches(true, 0); | ||||
DbSession session = db.getSession(); | DbSession session = db.getSession(); | ||||
List<String> projectKeys = Arrays.asList(projectDto1.getKey(), projectDto2.getKey()); | List<String> projectKeys = Arrays.asList(projectDto1.getKey(), projectDto2.getKey()); | ||||
assertThatThrownBy(() -> underTest.checkIfAnyComponentsNeedIssueSync(session, projectKeys, null, null)) | |||||
assertThatThrownBy(() -> underTest.checkIfAnyComponentsNeedIssueSync(session, projectKeys)) | |||||
.isInstanceOf(EsIndexSyncInProgressException.class) | .isInstanceOf(EsIndexSyncInProgressException.class) | ||||
.hasFieldOrPropertyWithValue("httpCode", 503) | .hasFieldOrPropertyWithValue("httpCode", 503) | ||||
.hasMessage("Results are temporarily unavailable. Indexing of issues is in progress."); | .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress."); | ||||
@Test | @Test | ||||
public void checkIfAnyComponentsIssueSyncInProgress_does_not_throw_exception_if_all_components_have_need_issue_sync_FALSE() { | public void checkIfAnyComponentsIssueSyncInProgress_does_not_throw_exception_if_all_components_have_need_issue_sync_FALSE() { | ||||
underTest.checkIfAnyComponentsNeedIssueSync(db.getSession(), Collections.emptyList(), null, null); | |||||
underTest.checkIfAnyComponentsNeedIssueSync(db.getSession(), Collections.emptyList()); | |||||
ProjectDto projectDto1 = insertProjectWithBranches(false, 0); | ProjectDto projectDto1 = insertProjectWithBranches(false, 0); | ||||
ProjectDto projectDto2 = insertProjectWithBranches(false, 0); | ProjectDto projectDto2 = insertProjectWithBranches(false, 0); | ||||
underTest.checkIfAnyComponentsNeedIssueSync(db.getSession(), Arrays.asList(projectDto1.getKey(), projectDto2.getKey()), null, null); | |||||
underTest.checkIfAnyComponentsNeedIssueSync(db.getSession(), Arrays.asList(projectDto1.getKey(), projectDto2.getKey())); | |||||
} | } | ||||
@Test | @Test | ||||
DbSession session = db.getSession(); | DbSession session = db.getSession(); | ||||
List<String> projectKeys = Arrays.asList(projectDto1.getKey(), projectDto2.getKey()); | List<String> projectKeys = Arrays.asList(projectDto1.getKey(), projectDto2.getKey()); | ||||
assertThatThrownBy(() -> underTest.checkIfAnyComponentsNeedIssueSync(session, projectKeys, null, null)) | |||||
assertThatThrownBy(() -> underTest.checkIfAnyComponentsNeedIssueSync(session, projectKeys)) | |||||
.isInstanceOf(EsIndexSyncInProgressException.class) | .isInstanceOf(EsIndexSyncInProgressException.class) | ||||
.hasFieldOrPropertyWithValue("httpCode", 503) | .hasFieldOrPropertyWithValue("httpCode", 503) | ||||
.hasMessage("Results are temporarily unavailable. Indexing of issues is in progress."); | .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress."); | ||||
DbSession session = db.getSession(); | DbSession session = db.getSession(); | ||||
List<String> projectKey1 = singletonList(projectDto2.getKey()); | List<String> projectKey1 = singletonList(projectDto2.getKey()); | ||||
// do nothing when need issue sync false | // do nothing when need issue sync false | ||||
underTest.checkIfAnyComponentsNeedIssueSync(session, projectKey1, null, null); | |||||
underTest.checkIfAnyComponentsNeedIssueSync(session, projectKey1); | |||||
List<String> projectKey2 = singletonList(projectDto1.getKey()); | List<String> projectKey2 = singletonList(projectDto1.getKey()); | ||||
// throws if flag set to TRUE | // throws if flag set to TRUE | ||||
assertThatThrownBy(() -> underTest.checkIfAnyComponentsNeedIssueSync(session, | assertThatThrownBy(() -> underTest.checkIfAnyComponentsNeedIssueSync(session, | ||||
projectKey2, null, null)) | |||||
projectKey2)) | |||||
.isInstanceOf(EsIndexSyncInProgressException.class) | .isInstanceOf(EsIndexSyncInProgressException.class) | ||||
.hasFieldOrPropertyWithValue("httpCode", 503) | .hasFieldOrPropertyWithValue("httpCode", 503) | ||||
.hasMessage("Results are temporarily unavailable. Indexing of issues is in progress."); | .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress."); | ||||
List<String> appViewOrSubviewKeys = Arrays.asList(projectDto1.getKey(), app.getDbKey(), view.getDbKey(), subview.getDbKey()); | List<String> appViewOrSubviewKeys = Arrays.asList(projectDto1.getKey(), app.getDbKey(), view.getDbKey(), subview.getDbKey()); | ||||
// throws if flag set to TRUE | // throws if flag set to TRUE | ||||
assertThatThrownBy(() -> underTest.checkIfAnyComponentsIssueSyncInProgress(session, | |||||
appViewOrSubviewKeys, null, null)) | |||||
assertThatThrownBy(() -> underTest.checkIfAnyComponentsNeedIssueSync(session, | |||||
appViewOrSubviewKeys)) | |||||
.isInstanceOf(EsIndexSyncInProgressException.class) | .isInstanceOf(EsIndexSyncInProgressException.class) | ||||
.hasFieldOrPropertyWithValue("httpCode", 503) | .hasFieldOrPropertyWithValue("httpCode", 503) | ||||
.hasMessage("Results are temporarily unavailable. Indexing of issues is in progress."); | .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress."); |
private void checkIfNeedIssueSync(DbSession dbSession, WsRequest wsRequest) { | private void checkIfNeedIssueSync(DbSession dbSession, WsRequest wsRequest) { | ||||
Optional<String> projectKey = wsRequest.getProjectKey(); | Optional<String> projectKey = wsRequest.getProjectKey(); | ||||
if (projectKey.isPresent()) { | if (projectKey.isPresent()) { | ||||
String branch = wsRequest.getBranch().orElse(null); | |||||
String pullRequest = wsRequest.getPullRequest().orElse(null); | |||||
issueIndexSyncProgressChecker.checkIfAnyComponentsNeedIssueSync(dbSession, singletonList(projectKey.get()), branch, pullRequest); | |||||
issueIndexSyncProgressChecker.checkIfComponentNeedIssueSync(dbSession, projectKey.get()); | |||||
} else { | } else { | ||||
// component keys not provided - asking for global | // component keys not provided - asking for global | ||||
issueIndexSyncProgressChecker.checkIfIssueSyncInProgress(dbSession); | issueIndexSyncProgressChecker.checkIfIssueSyncInProgress(dbSession); |
private void checkIfNeedIssueSync(DbSession dbSession, SearchRequest searchRequest) { | private void checkIfNeedIssueSync(DbSession dbSession, SearchRequest searchRequest) { | ||||
List<String> components = searchRequest.getComponents(); | List<String> components = searchRequest.getComponents(); | ||||
if (components != null && !components.isEmpty()) { | if (components != null && !components.isEmpty()) { | ||||
String branch = searchRequest.getBranch(); | |||||
String pullRequest = searchRequest.getPullRequest(); | |||||
issueIndexSyncProgressChecker.checkIfAnyComponentsNeedIssueSync(dbSession, components, branch, pullRequest); | |||||
issueIndexSyncProgressChecker.checkIfAnyComponentsNeedIssueSync(dbSession, components); | |||||
} else { | } else { | ||||
// component keys not provided - asking for global | // component keys not provided - asking for global | ||||
issueIndexSyncProgressChecker.checkIfIssueSyncInProgress(dbSession); | issueIndexSyncProgressChecker.checkIfIssueSyncInProgress(dbSession); |
import static org.mockito.ArgumentMatchers.eq; | import static org.mockito.ArgumentMatchers.eq; | ||||
import static org.mockito.ArgumentMatchers.isNull; | import static org.mockito.ArgumentMatchers.isNull; | ||||
import static org.mockito.Mockito.mock; | import static org.mockito.Mockito.mock; | ||||
import static org.mockito.Mockito.times; | |||||
import static org.mockito.Mockito.verify; | import static org.mockito.Mockito.verify; | ||||
import static org.sonar.api.issue.Issue.RESOLUTION_FIXED; | import static org.sonar.api.issue.Issue.RESOLUTION_FIXED; | ||||
import static org.sonar.api.issue.Issue.RESOLUTION_SAFE; | import static org.sonar.api.issue.Issue.RESOLUTION_SAFE; | ||||
.extracting(SearchWsResponse.Hotspot::getKey) | .extracting(SearchWsResponse.Hotspot::getKey) | ||||
.containsExactlyInAnyOrder(Arrays.stream(hotspotPR).map(IssueDto::getKey).toArray(String[]::new)); | .containsExactlyInAnyOrder(Arrays.stream(hotspotPR).map(IssueDto::getKey).toArray(String[]::new)); | ||||
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())); | |||||
verify(issueIndexSyncProgressChecker, times(3)).checkIfComponentNeedIssueSync(any(), eq(project.getDbKey())); | |||||
} | } | ||||
@Test | @Test |