From 3e42999f5e483c6a93698c90b292277cc4347a80 Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Mon, 6 Mar 2017 10:39:07 +0100 Subject: [PATCH] SONAR-8838 Compute tag distribution for WS api/components/search_projects --- .../measure/index/ProjectMeasuresIndex.java | 20 ++++--- .../index/ProjectMeasuresIndexTest.java | 54 +++++++++++++++++++ 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java b/server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java index df6914a1bbc..f4ee4488274 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java @@ -85,7 +85,8 @@ public class ProjectMeasuresIndex extends BaseIndex { RELIABILITY_RATING_KEY, SECURITY_RATING_KEY, ALERT_STATUS_KEY, - FILTER_LANGUAGE); + FILTER_LANGUAGE, + FIELD_TAGS); private static final String FIELD_MEASURES_KEY = FIELD_MEASURES + "." + ProjectMeasuresIndexDefinition.FIELD_MEASURES_KEY; private static final String FIELD_MEASURES_VALUE = FIELD_MEASURES + "." + ProjectMeasuresIndexDefinition.FIELD_MEASURES_VALUE; @@ -102,6 +103,7 @@ public class ProjectMeasuresIndex extends BaseIndex { .put(SECURITY_RATING_KEY, (esSearch, filters) -> addRatingFacet(esSearch, SECURITY_RATING_KEY, filters)) .put(ALERT_STATUS_KEY, (esSearch, filters) -> esSearch.addAggregation(createStickyFacet(ALERT_STATUS_KEY, filters, createQualityGateFacet()))) .put(FILTER_LANGUAGE, (esSearch, filters) -> esSearch.addAggregation(createStickyFacet(FILTER_LANGUAGE, filters, createLanguagesFacet()))) + .put(FIELD_TAGS, (esSearch, filters) -> esSearch.addAggregation(createStickyFacet(FIELD_TAGS, filters, createTagsFacet()))) .build(); private final AuthorizationTypeSupport authorizationTypeSupport; @@ -123,7 +125,7 @@ public class ProjectMeasuresIndex extends BaseIndex { filters.values().forEach(esFilter::must); requestBuilder.setQuery(esFilter); - addFacets(requestBuilder, searchOptions, filters); + addFacets(query, requestBuilder, searchOptions, filters); addSort(query, requestBuilder); return new SearchIdResult<>(requestBuilder.get(), id -> id); } @@ -151,7 +153,7 @@ public class ProjectMeasuresIndex extends BaseIndex { .order(query.isAsc() ? ASC : DESC)); } - private static void addFacets(SearchRequestBuilder esSearch, SearchOptions options, Map filters) { + private static void addFacets(ProjectMeasuresQuery query, SearchRequestBuilder esSearch, SearchOptions options, Map filters) { options.getFacets().stream() .filter(FACET_FACTORIES::containsKey) .map(FACET_FACTORIES::get) @@ -166,12 +168,12 @@ public class ProjectMeasuresIndex extends BaseIndex { esSearch.addAggregation(createStickyFacet(metricKey, filters, createRatingFacet(metricKey))); } - private static AbstractAggregationBuilder createStickyFacet(String metricKey, Map filters, AbstractAggregationBuilder aggregationBuilder) { + private static AbstractAggregationBuilder createStickyFacet(String facetKey, Map filters, AbstractAggregationBuilder aggregationBuilder) { StickyFacetBuilder facetBuilder = new StickyFacetBuilder(matchAllQuery(), filters); - BoolQueryBuilder facetFilter = facetBuilder.getStickyFacetFilter(metricKey); + BoolQueryBuilder facetFilter = facetBuilder.getStickyFacetFilter(facetKey); return AggregationBuilders - .global(metricKey) - .subAggregation(AggregationBuilders.filter("facet_filter_" + metricKey) + .global(facetKey) + .subAggregation(AggregationBuilders.filter("facet_filter_" + facetKey) .filter(facetFilter) .subAggregation(aggregationBuilder)); } @@ -230,6 +232,10 @@ public class ProjectMeasuresIndex extends BaseIndex { .field(FIELD_LANGUAGES_VALUE))); } + private static AbstractAggregationBuilder createTagsFacet() { + return AggregationBuilders.terms(FIELD_TAGS).field(FIELD_TAGS); + } + private Map createFilters(ProjectMeasuresQuery query) { Map filters = new HashMap<>(); filters.put("__authorization", authorizationTypeSupport.createQueryFilter()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java index 9ab2994e931..bfbcbbfccb8 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java @@ -57,6 +57,7 @@ import static org.sonar.api.measures.Metric.Level.WARN; import static org.sonar.db.component.ComponentTesting.newProjectDto; import static org.sonar.db.user.GroupTesting.newGroupDto; import static org.sonar.db.user.UserTesting.newUserDto; +import static org.sonar.server.measure.index.ProjectMeasuresIndexDefinition.FIELD_TAGS; import static org.sonar.server.measure.index.ProjectMeasuresIndexDefinition.INDEX_TYPE_PROJECT_MEASURES; public class ProjectMeasuresIndexTest { @@ -1029,6 +1030,59 @@ public class ProjectMeasuresIndexTest { entry("xoo", 5L)); } + @Test + public void facet_tags() { + index( + newDoc().setTags(newArrayList("finance", "offshore", "java")), + newDoc().setTags(newArrayList("finance", "javascript")), + newDoc().setTags(newArrayList("marketing", "finance")), + newDoc().setTags(newArrayList("marketing", "offshore")), + newDoc().setTags(newArrayList("finance", "marketing")), + newDoc().setTags(newArrayList("finance"))); + + Map result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(FIELD_TAGS)).getFacets().get(FIELD_TAGS); + + assertThat(result).containsOnly( + entry("finance", 5L), + entry("marketing", 3L), + entry("offshore", 2L), + entry("java", 1L), + entry("javascript", 1L)); + } + + @Test + public void facet_tags_is_sticky() { + index( + newDoc().setTags(newArrayList("finance")).setQualityGateStatus(OK.name()), + newDoc().setTags(newArrayList("finance")).setQualityGateStatus(ERROR.name()), + newDoc().setTags(newArrayList("cpp")).setQualityGateStatus(WARN.name())); + + Facets facets = underTest.search( + new ProjectMeasuresQuery().setTags(newHashSet("cpp")), + new SearchOptions().addFacets(FIELD_TAGS).addFacets(ALERT_STATUS_KEY)) + .getFacets(); + + assertThat(facets.get(FIELD_TAGS)).containsOnly( + entry("finance", 2L), + entry("cpp", 1L)); + assertThat(facets.get(ALERT_STATUS_KEY)).containsOnly( + entry(OK.name(), 0L), + entry(ERROR.name(), 0L), + entry(WARN.name(), 1L)); + } + + @Test + public void facet_tags_size_limited_to_10() { + index( + newDoc().setTags(newArrayList("finance1", "finance2", "finance3", "finance4", "finance5", "finance6", "finance7", "finance8", "finance9", "finance10")), + newDoc().setTags(newArrayList("finance1", "finance2", "finance3", "finance4", "finance5", "finance6", "finance7", "finance8", "finance9", "finance10")), + newDoc().setTags(newArrayList("solo"))); + + Map result = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(FIELD_TAGS)).getFacets().get(FIELD_TAGS); + + assertThat(result).hasSize(10).containsOnlyKeys("finance1", "finance2", "finance3", "finance4", "finance5", "finance6", "finance7", "finance8", "finance9", "finance10"); + } + private void index(ProjectMeasuresDoc... docs) { es.putDocuments(INDEX_TYPE_PROJECT_MEASURES, docs); for (ProjectMeasuresDoc doc : docs) { -- 2.39.5