aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2016-10-24 16:21:30 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2016-10-24 16:21:30 +0200
commit2415c0342d0d36fd070332256c6a752d4556e6d9 (patch)
tree322378084b085a034750bce754cf53df0f46e8e9
parent7fbdae0b91dd971fe4f5f5991987369319faf3de (diff)
downloadsonarqube-2415c0342d0d36fd070332256c6a752d4556e6d9.tar.gz
sonarqube-2415c0342d0d36fd070332256c6a752d4556e6d9.zip
SONAR-8315 Make facets optional in WS api/components/search_projects
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/es/ProjectMeasuresIndex.java43
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java11
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/es/ProjectMeasuresIndexTest.java48
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java6
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java1
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchProjectsRequest.java15
-rw-r--r--sonar-ws/src/test/java/org/sonarqube/ws/client/component/ComponentsServiceTest.java3
-rw-r--r--sonar-ws/src/test/java/org/sonarqube/ws/client/component/SearchProjectsRequestTest.java24
8 files changed, 121 insertions, 30 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/es/ProjectMeasuresIndex.java b/server/sonar-server/src/main/java/org/sonar/server/component/es/ProjectMeasuresIndex.java
index 00368bc78a1..86b4385f93b 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/es/ProjectMeasuresIndex.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/es/ProjectMeasuresIndex.java
@@ -71,6 +71,15 @@ import static org.sonar.server.component.es.ProjectMeasuresIndexDefinition.TYPE_
public class ProjectMeasuresIndex extends BaseIndex {
+ public static final List<String> SUPPORTED_FACETS = ImmutableList.of(
+ NCLOC_KEY,
+ DUPLICATED_LINES_DENSITY_KEY,
+ COVERAGE_KEY,
+ SQALE_RATING_KEY,
+ RELIABILITY_RATING_KEY,
+ SECURITY_RATING_KEY,
+ ALERT_STATUS_KEY);
+
private static final String FIELD_KEY = FIELD_MEASURES + "." + FIELD_MEASURES_KEY;
private static final String FIELD_VALUE = FIELD_MEASURES + "." + FIELD_MEASURES_VALUE;
@@ -95,18 +104,34 @@ public class ProjectMeasuresIndex extends BaseIndex {
filters.values().forEach(esFilter::must);
requestBuilder.setQuery(esFilter);
- addFacets(requestBuilder, filters);
+ addFacets(requestBuilder, searchOptions, filters);
return new SearchIdResult<>(requestBuilder.get(), id -> id);
}
- private static void addFacets(SearchRequestBuilder esSearch, Map<String, QueryBuilder> filters) {
- addRangeFacet(esSearch, NCLOC_KEY, ImmutableList.of(1_000d, 10_000d, 100_000d, 500_000d), filters);
- addRangeFacet(esSearch, DUPLICATED_LINES_DENSITY_KEY, ImmutableList.of(3d, 5d, 10d, 20d), filters);
- addRangeFacet(esSearch, COVERAGE_KEY, ImmutableList.of(30d, 50d, 70d, 80d), filters);
- addRatingFacet(esSearch, SQALE_RATING_KEY, filters);
- addRatingFacet(esSearch, RELIABILITY_RATING_KEY, filters);
- addRatingFacet(esSearch, SECURITY_RATING_KEY, filters);
- esSearch.addAggregation(createStickyFacet(ALERT_STATUS_KEY, filters, createQualityGateFacet()));
+ private static void addFacets(SearchRequestBuilder esSearch, SearchOptions options, Map<String, QueryBuilder> filters) {
+ if (!options.getFacets().isEmpty()) {
+ if (options.getFacets().contains(NCLOC_KEY)) {
+ addRangeFacet(esSearch, NCLOC_KEY, ImmutableList.of(1_000d, 10_000d, 100_000d, 500_000d), filters);
+ }
+ if (options.getFacets().contains(DUPLICATED_LINES_DENSITY_KEY)) {
+ addRangeFacet(esSearch, DUPLICATED_LINES_DENSITY_KEY, ImmutableList.of(3d, 5d, 10d, 20d), filters);
+ }
+ if (options.getFacets().contains(COVERAGE_KEY)) {
+ addRangeFacet(esSearch, COVERAGE_KEY, ImmutableList.of(30d, 50d, 70d, 80d), filters);
+ }
+ if (options.getFacets().contains(SQALE_RATING_KEY)) {
+ addRatingFacet(esSearch, SQALE_RATING_KEY, filters);
+ }
+ if (options.getFacets().contains(RELIABILITY_RATING_KEY)) {
+ addRatingFacet(esSearch, RELIABILITY_RATING_KEY, filters);
+ }
+ if (options.getFacets().contains(SECURITY_RATING_KEY)) {
+ addRatingFacet(esSearch, SECURITY_RATING_KEY, filters);
+ }
+ if (options.getFacets().contains(ALERT_STATUS_KEY)) {
+ esSearch.addAggregation(createStickyFacet(ALERT_STATUS_KEY, filters, createQualityGateFacet()));
+ }
+ }
}
private static void addRangeFacet(SearchRequestBuilder esSearch, String metricKey, List<Double> thresholds, Map<String, QueryBuilder> filters) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java
index a8df99d9422..d8cbb5332d6 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java
@@ -46,6 +46,7 @@ import org.sonarqube.ws.WsComponents.SearchProjectsWsResponse;
import org.sonarqube.ws.client.component.SearchProjectsRequest;
import static com.google.common.base.MoreObjects.firstNonNull;
+import static org.sonar.server.component.es.ProjectMeasuresIndex.SUPPORTED_FACETS;
import static org.sonar.server.component.ws.ProjectMeasuresQueryFactory.newProjectMeasuresQuery;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
@@ -73,6 +74,9 @@ public class SearchProjectsAction implements ComponentsWsAction {
.setResponseExample(getClass().getResource("search_projects-example.json"))
.setHandler(this);
+ action.createParam(Param.FACETS)
+ .setDescription("Comma-separated list of the facets to be computed. No facet is computed by default.")
+ .setPossibleValues(SUPPORTED_FACETS);
action
.createParam(PARAM_FILTER)
.setDescription("TODO");
@@ -98,7 +102,9 @@ public class SearchProjectsAction implements ComponentsWsAction {
ProjectMeasuresQuery query = newProjectMeasuresQuery(filter);
projectMeasuresQueryValidator.validate(dbSession, query);
- SearchIdResult<String> searchResults = index.search(query, new SearchOptions().setPage(request.getPage(), request.getPageSize()));
+ SearchIdResult<String> searchResults = index.search(query, new SearchOptions()
+ .addFacets(request.getFacets())
+ .setPage(request.getPage(), request.getPageSize()));
Ordering<ComponentDto> ordering = Ordering.explicit(searchResults.getIds()).onResultOf(ComponentDto::uuid);
List<ComponentDto> projects = ordering.immutableSortedCopy(dbClient.componentDao().selectByUuids(dbSession, searchResults.getIds()));
@@ -111,6 +117,9 @@ public class SearchProjectsAction implements ComponentsWsAction {
.setFilter(httpRequest.param(PARAM_FILTER))
.setPage(httpRequest.mandatoryParamAsInt(Param.PAGE))
.setPageSize(httpRequest.mandatoryParamAsInt(Param.PAGE_SIZE));
+ if (httpRequest.hasParam(Param.FACETS)) {
+ request.setFacets(httpRequest.paramAsStrings(Param.FACETS));
+ }
return request.build();
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/es/ProjectMeasuresIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/es/ProjectMeasuresIndexTest.java
index 2ea96edc3cd..ecfc28f97a0 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/es/ProjectMeasuresIndexTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/es/ProjectMeasuresIndexTest.java
@@ -44,6 +44,7 @@ import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
+import static org.sonar.api.measures.CoreMetrics.COVERAGE_KEY;
import static org.sonar.api.measures.Metric.Level.ERROR;
import static org.sonar.api.measures.Metric.Level.OK;
import static org.sonar.api.measures.Metric.Level.WARN;
@@ -249,10 +250,21 @@ public class ProjectMeasuresIndexTest {
}
@Test
+ public void does_not_return_facet_when_no_facets_in_options() throws Exception {
+ addDocs(
+ newDoc("P11", "K1", "N1").setMeasures(newArrayList(newMeasure(NCLOC, 10d), newMeasure(COVERAGE_KEY, 30d), newMeasure(MAINTAINABILITY_RATING, 3d)))
+ .setQualityGate(OK.name()));
+
+ Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets();
+
+ assertThat(facets.getAll()).isEmpty();
+ }
+
+ @Test
public void facet_ncloc() {
addDocs(
// 3 docs with ncloc<1K
- newDoc("P11", "K1", "N1").setMeasures(newArrayList(newMeasure(NCLOC, 0d), newMeasure(COVERAGE, 0d))),
+ newDoc("P11", "K1", "N1").setMeasures(newArrayList(newMeasure(NCLOC, 0d))),
newDoc("P12", "K1", "N1").setMeasures(newArrayList(newMeasure(NCLOC, 0d))),
newDoc("P13", "K1", "N1").setMeasures(newArrayList(newMeasure(NCLOC, 999d))),
// 2 docs with ncloc>=1K and ncloc<10K
@@ -273,7 +285,7 @@ public class ProjectMeasuresIndexTest {
newDoc("P54", "K3", "N3").setMeasures(newArrayList(newMeasure(NCLOC, 1_000_000d))),
newDoc("P55", "K3", "N3").setMeasures(newArrayList(newMeasure(NCLOC, 100_000_000_000d))));
- Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets();
+ Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(NCLOC)).getFacets();
assertThat(facets.get(NCLOC)).containsExactly(
entry("*-1000.0", 3L),
@@ -304,7 +316,7 @@ public class ProjectMeasuresIndexTest {
Facets facets = underTest.search(new ProjectMeasuresQuery()
.addMetricCriterion(new MetricCriterion(NCLOC, Operator.LT, 10_000d))
.addMetricCriterion(new MetricCriterion(DUPLICATION, Operator.LT, 10d)),
- new SearchOptions()).getFacets();
+ new SearchOptions().addFacets(NCLOC, COVERAGE)).getFacets();
// Sticky facet on ncloc does not take into account ncloc filter
assertThat(facets.get(NCLOC)).containsExactly(
@@ -345,7 +357,7 @@ public class ProjectMeasuresIndexTest {
// doc with ncloc>= 500K
newDoc("P53", "K3", "N3").setMeasures(newArrayList(newMeasure(NCLOC, 501_000d))));
- Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets();
+ Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(NCLOC)).getFacets();
assertThat(facets.get(NCLOC)).containsExactly(
entry("*-1000.0", 3L),
@@ -380,7 +392,7 @@ public class ProjectMeasuresIndexTest {
newDoc("P54", "K3", "N3").setMeasures(newArrayList(newMeasure(COVERAGE, 90.5d))),
newDoc("P55", "K3", "N3").setMeasures(newArrayList(newMeasure(COVERAGE, 100d))));
- Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets();
+ Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(COVERAGE)).getFacets();
assertThat(facets.get(COVERAGE)).containsExactly(
entry("*-30.0", 3L),
@@ -411,7 +423,7 @@ public class ProjectMeasuresIndexTest {
Facets facets = underTest.search(new ProjectMeasuresQuery()
.addMetricCriterion(new MetricCriterion(COVERAGE, Operator.LT, 30d))
.addMetricCriterion(new MetricCriterion(DUPLICATION, Operator.LT, 10d)),
- new SearchOptions()).getFacets();
+ new SearchOptions().addFacets(COVERAGE, NCLOC)).getFacets();
// Sticky facet on coverage does not take into account coverage filter
assertThat(facets.get(COVERAGE)).containsExactly(
@@ -452,7 +464,7 @@ public class ProjectMeasuresIndexTest {
// docs with coverage>= 80%
newDoc("P51", "K3", "N3").setMeasures(newArrayList(newMeasure(COVERAGE, 80d))));
- Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets();
+ Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(COVERAGE)).getFacets();
assertThat(facets.get(COVERAGE)).containsExactly(
entry("*-30.0", 3L),
@@ -487,7 +499,7 @@ public class ProjectMeasuresIndexTest {
newDoc("P54", "K3", "N3").setMeasures(newArrayList(newMeasure(DUPLICATION, 80d))),
newDoc("P55", "K3", "N3").setMeasures(newArrayList(newMeasure(DUPLICATION, 100d))));
- Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets();
+ Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(DUPLICATION)).getFacets();
assertThat(facets.get(DUPLICATION)).containsExactly(
entry("*-3.0", 3L),
@@ -516,7 +528,7 @@ public class ProjectMeasuresIndexTest {
Facets facets = underTest.search(new ProjectMeasuresQuery()
.addMetricCriterion(new MetricCriterion(DUPLICATION, Operator.LT, 10d))
.addMetricCriterion(new MetricCriterion(COVERAGE, Operator.LT, 30d)),
- new SearchOptions()).getFacets();
+ new SearchOptions().addFacets(DUPLICATION, NCLOC)).getFacets();
// Sticky facet on duplication does not take into account duplication filter
assertThat(facets.get(DUPLICATION)).containsExactly(
@@ -557,7 +569,7 @@ public class ProjectMeasuresIndexTest {
// docs with duplication>= 20%
newDoc("P51", "K3", "N3").setMeasures(newArrayList(newMeasure(DUPLICATION, 20d))));
- Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets();
+ Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(DUPLICATION)).getFacets();
assertThat(facets.get(DUPLICATION)).containsExactly(
entry("*-3.0", 3L),
@@ -592,7 +604,7 @@ public class ProjectMeasuresIndexTest {
newDoc("P54", "K3", "N3").setMeasures(newArrayList(newMeasure(MAINTAINABILITY_RATING, 5d))),
newDoc("P55", "K3", "N3").setMeasures(newArrayList(newMeasure(MAINTAINABILITY_RATING, 5d))));
- Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets();
+ Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(MAINTAINABILITY_RATING)).getFacets();
assertThat(facets.get(MAINTAINABILITY_RATING)).containsExactly(
entry("1", 3L),
@@ -627,7 +639,7 @@ public class ProjectMeasuresIndexTest {
Facets facets = underTest.search(new ProjectMeasuresQuery()
.addMetricCriterion(new MetricCriterion(MAINTAINABILITY_RATING, Operator.LT, 3d))
.addMetricCriterion(new MetricCriterion(COVERAGE, Operator.LT, 30d)),
- new SearchOptions()).getFacets();
+ new SearchOptions().addFacets(MAINTAINABILITY_RATING, NCLOC)).getFacets();
// Sticky facet on maintainability rating does not take into account maintainability rating filter
assertThat(facets.get(MAINTAINABILITY_RATING)).containsExactly(
@@ -668,7 +680,7 @@ public class ProjectMeasuresIndexTest {
// docs with rating E
newDoc("P51", "K3", "N3").setMeasures(newArrayList(newMeasure(MAINTAINABILITY_RATING, 5d))));
- Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets();
+ Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(MAINTAINABILITY_RATING)).getFacets();
assertThat(facets.get(MAINTAINABILITY_RATING)).containsExactly(
entry("1", 3L),
@@ -703,7 +715,7 @@ public class ProjectMeasuresIndexTest {
newDoc("P54", "K3", "N3").setMeasures(newArrayList(newMeasure(RELIABILITY_RATING, 5d))),
newDoc("P55", "K3", "N3").setMeasures(newArrayList(newMeasure(RELIABILITY_RATING, 5d))));
- Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets();
+ Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(RELIABILITY_RATING)).getFacets();
assertThat(facets.get(RELIABILITY_RATING)).containsExactly(
entry("1", 3L),
@@ -738,7 +750,7 @@ public class ProjectMeasuresIndexTest {
newDoc("P54", "K3", "N3").setMeasures(newArrayList(newMeasure(SECURITY_RATING, 5.0d))),
newDoc("P55", "K3", "N3").setMeasures(newArrayList(newMeasure(SECURITY_RATING, 5.0d))));
- Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets();
+ Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(SECURITY_RATING)).getFacets();
assertThat(facets.get(SECURITY_RATING)).containsExactly(
entry("1", 3L),
@@ -764,7 +776,7 @@ public class ProjectMeasuresIndexTest {
newDoc("P33", "K1", "N1").setQualityGate(ERROR.name()),
newDoc("P34", "K1", "N1").setQualityGate(ERROR.name()));
- LinkedHashMap<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets().get(ALERT_STATUS_KEY);
+ LinkedHashMap<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(ALERT_STATUS_KEY)).getFacets().get(ALERT_STATUS_KEY);
assertThat(result).containsExactly(
entry(ERROR.name(), 4L),
@@ -791,7 +803,7 @@ public class ProjectMeasuresIndexTest {
Facets facets = underTest.search(new ProjectMeasuresQuery()
.setQualityGateStatus(ERROR)
.addMetricCriterion(new MetricCriterion(COVERAGE, Operator.LT, 55d)),
- new SearchOptions()).getFacets();
+ new SearchOptions().addFacets(ALERT_STATUS_KEY, NCLOC)).getFacets();
// Sticky facet on quality gate does not take into account quality gate filter
assertThat(facets.get(ALERT_STATUS_KEY)).containsOnly(
@@ -829,7 +841,7 @@ public class ProjectMeasuresIndexTest {
newDoc("P33", "K1", "N1").setQualityGate(ERROR.name()),
newDoc("P34", "K1", "N1").setQualityGate(ERROR.name()));
- LinkedHashMap<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions()).getFacets().get(ALERT_STATUS_KEY);
+ LinkedHashMap<String, Long> result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(ALERT_STATUS_KEY)).getFacets().get(ALERT_STATUS_KEY);
assertThat(result).containsExactly(
entry(ERROR.name(), 0L),
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java
index 27ad3e17081..d1576249ee9 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java
@@ -20,6 +20,7 @@
package org.sonar.server.component.ws;
+import com.google.common.base.Joiner;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
@@ -186,13 +187,13 @@ public class SearchProjectsActionTest {
}
@Test
- public void return_loc_facet() {
+ public void return_nloc_facet() {
insertProjectInDbAndEs(newProjectDto().setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d)));
insertProjectInDbAndEs(newProjectDto().setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d)));
insertProjectInDbAndEs(newProjectDto().setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d)));
insertProjectInDbAndEs(newProjectDto().setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 500_001d)));
insertMetrics(COVERAGE, NCLOC);
- SearchProjectsWsResponse result = call(request);
+ SearchProjectsWsResponse result = call(request.setFacets(singletonList(NCLOC)));
Common.Facet facet = result.getFacets().getFacetsList().stream()
.filter(oneFacet -> NCLOC.equals(oneFacet.getProperty()))
@@ -237,6 +238,7 @@ public class SearchProjectsActionTest {
if (filter != null) {
httpRequest.setParam(PARAM_FILTER, filter);
}
+ httpRequest.setParam(Param.FACETS, Joiner.on(",").join(wsRequest.getFacets()));
try {
return SearchProjectsWsResponse.parseFrom(httpRequest.execute().getInputStream());
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java
index 2deb2884b23..eb648f24109 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java
@@ -106,6 +106,7 @@ public class ComponentsService extends BaseService {
public SearchProjectsWsResponse searchProjects(SearchProjectsRequest request) {
GetRequest get = new GetRequest(path(ACTION_SEARCH_PROJECTS))
.setParam(PARAM_FILTER, request.getFilter())
+ .setParam(Param.FACETS, request.getFacets())
.setParam(Param.PAGE, request.getPage())
.setParam(Param.PAGE_SIZE, request.getPageSize());
return call(get, SearchProjectsWsResponse.parser());
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchProjectsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchProjectsRequest.java
index 8ae6cb22d8e..3b6ebceeceb 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchProjectsRequest.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchProjectsRequest.java
@@ -20,9 +20,12 @@
package org.sonarqube.ws.client.component;
+import java.util.ArrayList;
+import java.util.List;
import javax.annotation.CheckForNull;
import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
public class SearchProjectsRequest {
public static final int MAX_PAGE_SIZE = 500;
@@ -31,11 +34,13 @@ public class SearchProjectsRequest {
private final int page;
private final int pageSize;
private final String filter;
+ private final List<String> facets;
private SearchProjectsRequest(Builder builder) {
this.page = builder.page;
this.pageSize = builder.pageSize;
this.filter = builder.filter;
+ this.facets = builder.facets;
}
@CheckForNull
@@ -43,6 +48,10 @@ public class SearchProjectsRequest {
return filter;
}
+ public List<String> getFacets() {
+ return facets;
+ }
+
public int getPageSize() {
return pageSize;
}
@@ -59,6 +68,7 @@ public class SearchProjectsRequest {
private Integer page;
private Integer pageSize;
private String filter;
+ private List<String> facets = new ArrayList<>();
private Builder() {
// enforce static factory method
@@ -69,6 +79,11 @@ public class SearchProjectsRequest {
return this;
}
+ public Builder setFacets(List<String> facets) {
+ this.facets = requireNonNull(facets);
+ return this;
+ }
+
public Builder setPage(int page) {
this.page = page;
return this;
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/component/ComponentsServiceTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/component/ComponentsServiceTest.java
index 5627eaf8beb..b79214d3983 100644
--- a/sonar-ws/src/test/java/org/sonarqube/ws/client/component/ComponentsServiceTest.java
+++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/component/ComponentsServiceTest.java
@@ -26,6 +26,7 @@ import org.sonar.api.server.ws.WebService.Param;
import org.sonarqube.ws.client.ServiceTester;
import org.sonarqube.ws.client.WsConnector;
+import static java.util.Collections.singletonList;
import static org.mockito.Mockito.mock;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
@@ -40,6 +41,7 @@ public class ComponentsServiceTest {
public void search_projects() {
underTest.searchProjects(SearchProjectsRequest.builder()
.setFilter("ncloc > 10")
+ .setFacets(singletonList("ncloc"))
.setPage(3)
.setPageSize(10)
.build());
@@ -47,6 +49,7 @@ public class ComponentsServiceTest {
serviceTester.assertThat(serviceTester.getGetRequest())
.hasPath("search_projects")
.hasParam(PARAM_FILTER, "ncloc > 10")
+ .hasParam(Param.FACETS, singletonList("ncloc"))
.hasParam(Param.PAGE, 3)
.hasParam(Param.PAGE_SIZE, 10)
.andNoOtherParam();
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/component/SearchProjectsRequestTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/component/SearchProjectsRequestTest.java
index 49aaafa722f..023d89a8600 100644
--- a/sonar-ws/src/test/java/org/sonarqube/ws/client/component/SearchProjectsRequestTest.java
+++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/component/SearchProjectsRequestTest.java
@@ -24,6 +24,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
public class SearchProjectsRequestTest {
@@ -43,6 +44,29 @@ public class SearchProjectsRequestTest {
}
@Test
+ public void set_facets() throws Exception {
+ SearchProjectsRequest result = underTest
+ .setFacets(singletonList("ncloc"))
+ .build();
+
+ assertThat(result.getFacets()).containsOnly("ncloc");
+ }
+
+ @Test
+ public void facets_are_empty_by_default() throws Exception {
+ SearchProjectsRequest result = underTest.build();
+
+ assertThat(result.getFacets()).isEmpty();
+ }
+
+ @Test
+ public void fail_if_facets_is_null() {
+ expectedException.expect(NullPointerException.class);
+
+ underTest.setFacets(null);
+ }
+
+ @Test
public void default_page_values() {
SearchProjectsRequest result = underTest.build();