aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-webserver-es
diff options
context:
space:
mode:
authorBenjamin Campomenosi <109955405+benjamin-campomenosi-sonarsource@users.noreply.github.com>2023-11-02 14:52:28 +0100
committersonartech <sonartech@sonarsource.com>2023-11-08 20:02:52 +0000
commit0bc3c36c61a82eb18a66e2433164d06d548d127a (patch)
tree30efe10e56cf79ffbf8e56f6672ebe4669ab3ad4 /server/sonar-webserver-es
parenta1be2cd1286ff3a24fc27d9c9a387069f5eafb91 (diff)
downloadsonarqube-0bc3c36c61a82eb18a66e2433164d06d548d127a.tar.gz
sonarqube-0bc3c36c61a82eb18a66e2433164d06d548d127a.zip
SONAR-20871 Add simple status to the issue index
Diffstat (limited to 'server/sonar-webserver-es')
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java11
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java13
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java1
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java30
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java33
5 files changed, 80 insertions, 8 deletions
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
index 08cf93e12a4..e9da3ec2e45 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
@@ -77,6 +77,7 @@ import org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version;
import org.sonar.api.server.rule.RulesDefinition.PciDssVersion;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
+import org.sonar.core.issue.status.SimpleStatus;
import org.sonar.server.es.EsClient;
import org.sonar.server.es.EsUtils;
import org.sonar.server.es.SearchOptions;
@@ -144,6 +145,7 @@ import static org.sonar.server.issue.index.IssueIndex.Facet.RULES;
import static org.sonar.server.issue.index.IssueIndex.Facet.SANS_TOP_25;
import static org.sonar.server.issue.index.IssueIndex.Facet.SCOPES;
import static org.sonar.server.issue.index.IssueIndex.Facet.SEVERITIES;
+import static org.sonar.server.issue.index.IssueIndex.Facet.SIMPLE_STATUSES;
import static org.sonar.server.issue.index.IssueIndex.Facet.SONARSOURCE_SECURITY;
import static org.sonar.server.issue.index.IssueIndex.Facet.STATUSES;
import static org.sonar.server.issue.index.IssueIndex.Facet.TAGS;
@@ -181,6 +183,7 @@ import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_SANS
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_SCOPE;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_SEVERITY;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_SEVERITY_VALUE;
+import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_SIMPLE_STATUS;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_SQ_SECURITY_CATEGORY;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_STATUS;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_TAGS;
@@ -214,6 +217,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_RULES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SANS_TOP_25;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SCOPES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SEVERITIES;
+import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SIMPLE_STATUSES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SONARSOURCE_SECURITY;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STATUSES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TAGS;
@@ -263,6 +267,7 @@ public class IssueIndex {
STATUSES(PARAM_STATUSES, FIELD_ISSUE_STATUS, STICKY, Issue.STATUSES.size()),
// Resolutions facet returns one more element than the number of resolutions to take into account unresolved issues
RESOLUTIONS(PARAM_RESOLUTIONS, FIELD_ISSUE_RESOLUTION, STICKY, Issue.RESOLUTIONS.size() + 1),
+ SIMPLE_STATUSES(PARAM_SIMPLE_STATUSES, FIELD_ISSUE_SIMPLE_STATUS, STICKY, SimpleStatus.values().length),
TYPES(PARAM_TYPES, FIELD_ISSUE_TYPE, STICKY, RuleType.values().length),
SCOPES(PARAM_SCOPES, FIELD_ISSUE_SCOPE, STICKY, MAX_FACET_SIZE),
LANGUAGES(PARAM_LANGUAGES, FIELD_ISSUE_LANGUAGE, STICKY, MAX_FACET_SIZE),
@@ -481,6 +486,7 @@ public class IssueIndex {
FIELD_ISSUE_RULE_UUID,
query.ruleUuids()));
filters.addFilter(FIELD_ISSUE_STATUS, STATUSES.getFilterScope(), createTermsFilter(FIELD_ISSUE_STATUS, query.statuses()));
+ filters.addFilter(FIELD_ISSUE_SIMPLE_STATUS, SIMPLE_STATUSES.getFilterScope(), createTermsFilter(FIELD_ISSUE_SIMPLE_STATUS, query.simpleStatuses()));
filters.addFilter(FIELD_ISSUE_CODE_VARIANTS, CODE_VARIANTS.getFilterScope(), createTermsFilter(FIELD_ISSUE_CODE_VARIANTS, query.codeVariants()));
// security category
@@ -839,6 +845,7 @@ public class IssueIndex {
private void configureTopAggregations(TopAggregationHelper aggregationHelper, IssueQuery query, SearchOptions options,
AllFilters queryFilters, SearchSourceBuilder esRequest) {
addFacetIfNeeded(options, aggregationHelper, esRequest, STATUSES, NO_SELECTED_VALUES);
+ addFacetIfNeeded(options, aggregationHelper, esRequest, SIMPLE_STATUSES, query.simpleStatuses().toArray());
addFacetIfNeeded(options, aggregationHelper, esRequest, PROJECT_UUIDS, query.projectUuids().toArray());
addFacetIfNeeded(options, aggregationHelper, esRequest, DIRECTORIES, query.directories().toArray());
addFacetIfNeeded(options, aggregationHelper, esRequest, FILES, query.files().toArray());
@@ -924,7 +931,7 @@ public class IssueIndex {
.map(softwareQuality -> new FiltersAggregator.KeyedFilter(softwareQuality.name(),
query.impactSeverities().isEmpty() ? mainQuery.apply(softwareQuality)
: mainQuery.apply(softwareQuality)
- .filter(termsQuery(FIELD_ISSUE_IMPACT_SEVERITY, query.impactSeverities()))))
+ .filter(termsQuery(FIELD_ISSUE_IMPACT_SEVERITY, query.impactSeverities()))))
.toArray(FiltersAggregator.KeyedFilter[]::new);
AggregationBuilder aggregation = aggregationHelper.buildTopAggregation(
@@ -948,7 +955,7 @@ public class IssueIndex {
.map(severity -> new FiltersAggregator.KeyedFilter(severity.name(),
query.impactSoftwareQualities().isEmpty() ? mainQuery.apply(severity)
: mainQuery.apply(severity)
- .filter(termsQuery(FIELD_ISSUE_IMPACT_SOFTWARE_QUALITY, query.impactSoftwareQualities()))))
+ .filter(termsQuery(FIELD_ISSUE_IMPACT_SOFTWARE_QUALITY, query.impactSoftwareQualities()))))
.toArray(FiltersAggregator.KeyedFilter[]::new);
AggregationBuilder aggregation = aggregationHelper.buildTopAggregation(
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java
index 33eefc1e188..291ba957330 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java
@@ -62,6 +62,7 @@ public class IssueQuery {
private final Collection<String> impactSeverities;
private final Collection<String> impactSoftwareQualities;
private final Collection<String> statuses;
+ private final Collection<String> simpleStatuses;
private final Collection<String> resolutions;
private final Collection<String> components;
private final Collection<String> projects;
@@ -110,6 +111,7 @@ public class IssueQuery {
this.impactSoftwareQualities = defaultCollection(builder.impactSoftwareQualities);
this.statuses = defaultCollection(builder.statuses);
this.resolutions = defaultCollection(builder.resolutions);
+ this.simpleStatuses = defaultCollection(builder.simpleStatuses);
this.components = defaultCollection(builder.components);
this.projects = defaultCollection(builder.projects);
this.directories = defaultCollection(builder.directories);
@@ -171,6 +173,10 @@ public class IssueQuery {
return statuses;
}
+ public Collection<String> simpleStatuses() {
+ return simpleStatuses;
+ }
+
public Collection<String> resolutions() {
return resolutions;
}
@@ -179,7 +185,6 @@ public class IssueQuery {
return components;
}
-
public Collection<String> projectUuids() {
return projects;
}
@@ -363,6 +368,7 @@ public class IssueQuery {
private Collection<String> impactSoftwareQualities;
private Collection<String> statuses;
private Collection<String> resolutions;
+ private Collection<String> simpleStatuses;
private Collection<String> components;
private Collection<String> projects;
private Collection<String> directories;
@@ -427,6 +433,11 @@ public class IssueQuery {
return this;
}
+ public Builder simpleStatuses(@Nullable Collection<String> l) {
+ this.simpleStatuses = l;
+ return this;
+ }
+
public Builder componentUuids(@Nullable Collection<String> l) {
this.components = l;
return this;
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
index 27562572a1a..6412996c006 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
@@ -129,6 +129,7 @@ public class IssueQueryFactory {
.impactSeverities(request.getImpactSeverities())
.statuses(request.getStatuses())
.resolutions(request.getResolutions())
+ .simpleStatuses(request.getSimpleStatuses())
.resolved(request.getResolved())
.rules(ruleDtos)
.ruleUuids(ruleUuids)
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java
index 2f15ebbde63..a2bd2f309ca 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java
@@ -29,6 +29,7 @@ import org.junit.Test;
import org.sonar.api.issue.impact.Severity;
import org.sonar.api.rules.RuleType;
import org.sonar.api.server.rule.RulesDefinition.OwaspAsvsVersion;
+import org.sonar.core.issue.status.SimpleStatus;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.server.es.Facets;
@@ -371,6 +372,31 @@ public class IssueIndexFacetsTest extends IssueIndexTestCommon {
}
@Test
+ public void search_shouldReturnSimpleStatusesFacet() {
+ ComponentDto mainBranch = newPrivateProjectDto();
+ ComponentDto file = newFileDto(mainBranch);
+
+ indexIssues(
+ newDoc("I1", mainBranch.uuid(), file).setSimpleStatus(SimpleStatus.CONFIRMED.name()),
+ newDoc("I2", mainBranch.uuid(), file).setSimpleStatus(SimpleStatus.FIXED.name()),
+ newDoc("I3", mainBranch.uuid(), file).setSimpleStatus(SimpleStatus.OPEN.name()),
+ newDoc("I4", mainBranch.uuid(), file).setSimpleStatus(SimpleStatus.OPEN.name()),
+ newDoc("I5", mainBranch.uuid(), file).setSimpleStatus(SimpleStatus.ACCEPTED.name()),
+ newDoc("I6", mainBranch.uuid(), file).setSimpleStatus(SimpleStatus.ACCEPTED.name()),
+ newDoc("I7", mainBranch.uuid(), file).setSimpleStatus(SimpleStatus.ACCEPTED.name()),
+ newDoc("I8", mainBranch.uuid(), file).setSimpleStatus(SimpleStatus.FALSE_POSITIVE.name()),
+ newDoc("I9", mainBranch.uuid(), file).setSimpleStatus(SimpleStatus.FALSE_POSITIVE.name()));
+
+ assertThatFacetHasSize(IssueQuery.builder().build(), "simpleStatuses", 5);
+ assertThatFacetHasOnly(IssueQuery.builder(), "simpleStatuses",
+ entry("OPEN", 2L),
+ entry("CONFIRMED", 1L),
+ entry("FALSE_POSITIVE", 2L),
+ entry("ACCEPTED", 3L),
+ entry("FIXED", 1L));
+ }
+
+ @Test
public void facets_on_resolutions_return_5_entries_max() {
ComponentDto project = newPrivateProjectDto();
ComponentDto file = newFileDto(project);
@@ -869,7 +895,7 @@ public class IssueIndexFacetsTest extends IssueIndexTestCommon {
}
@SafeVarargs
- private final void assertThatFacetHasExactly(IssueQuery.Builder query, String facet, Map.Entry<String, Long>... expectedEntries) {
+ private void assertThatFacetHasExactly(IssueQuery.Builder query, String facet, Map.Entry<String, Long>... expectedEntries) {
SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(singletonList(facet)));
Facets facets = new Facets(result, system2.getDefaultTimeZone().toZoneId());
assertThat(facets.getNames()).containsOnly(facet, "effort");
@@ -877,7 +903,7 @@ public class IssueIndexFacetsTest extends IssueIndexTestCommon {
}
@SafeVarargs
- private final void assertThatFacetHasOnly(IssueQuery.Builder query, String facet, Map.Entry<String, Long>... expectedEntries) {
+ private void assertThatFacetHasOnly(IssueQuery.Builder query, String facet, Map.Entry<String, Long>... expectedEntries) {
SearchResponse result = underTest.search(query.build(), new SearchOptions().addFacets(singletonList(facet)));
Facets facets = new Facets(result, system2.getDefaultTimeZone().toZoneId());
assertThat(facets.getNames()).containsOnly(facet, "effort");
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java
index d6f0c5a7519..8292c9caac8 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java
@@ -28,6 +28,7 @@ import org.junit.Test;
import org.sonar.api.issue.Issue;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
+import org.sonar.core.issue.status.SimpleStatus;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.server.es.SearchOptions;
@@ -672,7 +673,7 @@ public class IssueIndexFiltersTest extends IssueIndexTestCommon {
assertThatThrownBy(() -> underTest.search(IssueQuery.builder()
.createdAfter(parseDate("2014-09-20")).createdBefore(parseDate("2014-09-20"))
.build(), new SearchOptions()))
- .isInstanceOf(IllegalArgumentException.class);
+ .isInstanceOf(IllegalArgumentException.class);
}
@Test
@@ -705,8 +706,8 @@ public class IssueIndexFiltersTest extends IssueIndexTestCommon {
public void fail_if_created_before_equals_created_after() {
assertThatThrownBy(() -> underTest.search(IssueQuery.builder().createdAfter(parseDate("2014-09-20"))
.createdBefore(parseDate("2014-09-20")).build(), new SearchOptions()))
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessageContaining("Start bound cannot be larger or equal to end bound");
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Start bound cannot be larger or equal to end bound");
}
@Test
@@ -923,6 +924,32 @@ public class IssueIndexFiltersTest extends IssueIndexTestCommon {
"I1", "I2", "I3", "I4", "I5", "I6", "I7", "I8");
}
+ @Test
+ public void search_whenFilteringBySimpleStatus_shouldReturnRelevantIssues() {
+ ComponentDto project = newPrivateProjectDto();
+ ComponentDto file = newFileDto(project);
+
+ indexIssues(
+ newDoc("I1", project.uuid(), file).setSimpleStatus(SimpleStatus.CONFIRMED.name()),
+ newDoc("I2", project.uuid(), file).setSimpleStatus(SimpleStatus.FIXED.name()),
+ newDoc("I3", project.uuid(), file).setSimpleStatus(SimpleStatus.OPEN.name()),
+ newDoc("I4", project.uuid(), file).setSimpleStatus(SimpleStatus.OPEN.name()),
+ newDoc("I5", project.uuid(), file).setSimpleStatus(SimpleStatus.ACCEPTED.name()),
+ newDoc("I6", project.uuid(), file).setSimpleStatus(SimpleStatus.ACCEPTED.name()),
+ newDoc("I7", project.uuid(), file).setSimpleStatus(SimpleStatus.ACCEPTED.name()),
+ newDoc("I8", project.uuid(), file).setSimpleStatus(SimpleStatus.FALSE_POSITIVE.name()),
+ newDoc("I9", project.uuid(), file).setSimpleStatus(SimpleStatus.FALSE_POSITIVE.name()));
+
+ assertThatSearchReturnsOnly(IssueQuery.builder().simpleStatuses(Set.of(SimpleStatus.CONFIRMED.name(), SimpleStatus.OPEN.name())),
+ "I1", "I3", "I4");
+
+ assertThatSearchReturnsOnly(IssueQuery.builder().simpleStatuses(Set.of(SimpleStatus.FALSE_POSITIVE.name(), SimpleStatus.ACCEPTED.name())),
+ "I5", "I6", "I7", "I8", "I9");
+
+ assertThatSearchReturnsOnly(IssueQuery.builder().simpleStatuses(Set.of(SimpleStatus.FIXED.name())),
+ "I2");
+ }
+
private void indexView(String viewUuid, List<String> projectBranchUuids) {
viewIndexer.index(new ViewDoc().setUuid(viewUuid).setProjectBranchUuids(projectBranchUuids));
}