From 641f4c3342821f14c3782cfb05dddd23dadfbdd4 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Mon, 6 Mar 2017 15:54:37 +0100 Subject: [PATCH] SONAR-8231 Return selected languages in languages facet --- .../sonar/server/es/StickyFacetBuilder.java | 25 +++++----- .../measure/index/ProjectMeasuresIndex.java | 49 ++++++++++--------- .../index/ProjectMeasuresIndexTest.java | 25 ++++++++++ 3 files changed, 64 insertions(+), 35 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/StickyFacetBuilder.java b/server/sonar-server/src/main/java/org/sonar/server/es/StickyFacetBuilder.java index e34ee1f98ba..d44850d4809 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/es/StickyFacetBuilder.java +++ b/server/sonar-server/src/main/java/org/sonar/server/es/StickyFacetBuilder.java @@ -101,20 +101,21 @@ public class StickyFacetBuilder { } public FilterAggregationBuilder addSelectedItemsToFacet(String fieldName, String facetName, FilterAggregationBuilder facetTopAggregation, Object... selected) { - if (selected.length > 0) { - String includes = Arrays.stream(selected) - .filter(Objects::nonNull) - .map(s -> EsUtils.escapeSpecialRegexChars(s.toString())) - .collect(PIPE_JOINER); + if (selected.length <= 0) { + return facetTopAggregation; + } + String includes = Arrays.stream(selected) + .filter(Objects::nonNull) + .map(s -> EsUtils.escapeSpecialRegexChars(s.toString())) + .collect(PIPE_JOINER); - TermsBuilder selectedTerms = AggregationBuilders.terms(facetName + "_selected") - .field(fieldName) - .include(includes); - if (subAggregation != null) { - selectedTerms = selectedTerms.subAggregation(subAggregation); - } - facetTopAggregation.subAggregation(selectedTerms); + TermsBuilder selectedTerms = AggregationBuilders.terms(facetName + "_selected") + .field(fieldName) + .include(includes); + if (subAggregation != null) { + selectedTerms = selectedTerms.subAggregation(subAggregation); } + facetTopAggregation.subAggregation(selectedTerms); return facetTopAggregation; } } 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 83453f26338..720bcabe602 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 @@ -27,6 +27,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.stream.IntStream; import javax.annotation.Nullable; import org.elasticsearch.action.search.SearchRequestBuilder; @@ -100,15 +101,16 @@ public class ProjectMeasuresIndex extends BaseIndex { private static final String FIELD_MEASURES_VALUE = FIELD_MEASURES + "." + ProjectMeasuresIndexDefinition.FIELD_MEASURES_VALUE; private static final Map FACET_FACTORIES = ImmutableMap.builder() - .put(NCLOC_KEY, (esSearch, filters) -> addRangeFacet(esSearch, NCLOC_KEY, ImmutableList.of(1_000d, 10_000d, 100_000d, 500_000d), filters)) - .put(DUPLICATED_LINES_DENSITY_KEY, (esSearch, filters) -> addRangeFacet(esSearch, DUPLICATED_LINES_DENSITY_KEY, ImmutableList.of(3d, 5d, 10d, 20d), filters)) - .put(COVERAGE_KEY, (esSearch, filters) -> addRangeFacet(esSearch, COVERAGE_KEY, ImmutableList.of(30d, 50d, 70d, 80d), filters)) - .put(SQALE_RATING_KEY, (esSearch, filters) -> addRatingFacet(esSearch, SQALE_RATING_KEY, filters)) - .put(RELIABILITY_RATING_KEY, (esSearch, filters) -> addRatingFacet(esSearch, RELIABILITY_RATING_KEY, filters)) - .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_LANGUAGES, (esSearch, filters) -> esSearch.addAggregation(createStickyFacet(FILTER_LANGUAGES, filters, createLanguagesFacet()))) - .put(FIELD_TAGS, (esSearch, filters) -> esSearch.addAggregation(createStickyFacet(FIELD_TAGS, filters, createTagsFacet()))) + .put(NCLOC_KEY, (esSearch, query, facetBuilder) -> addRangeFacet(esSearch, NCLOC_KEY, ImmutableList.of(1_000d, 10_000d, 100_000d, 500_000d), facetBuilder)) + .put(DUPLICATED_LINES_DENSITY_KEY, + (esSearch, query, facetBuilder) -> addRangeFacet(esSearch, DUPLICATED_LINES_DENSITY_KEY, ImmutableList.of(3d, 5d, 10d, 20d), facetBuilder)) + .put(COVERAGE_KEY, (esSearch, query, facetBuilder) -> addRangeFacet(esSearch, COVERAGE_KEY, ImmutableList.of(30d, 50d, 70d, 80d), facetBuilder)) + .put(SQALE_RATING_KEY, (esSearch, query, facetBuilder) -> addRatingFacet(esSearch, SQALE_RATING_KEY, facetBuilder)) + .put(RELIABILITY_RATING_KEY, (esSearch, query, facetBuilder) -> addRatingFacet(esSearch, RELIABILITY_RATING_KEY, facetBuilder)) + .put(SECURITY_RATING_KEY, (esSearch, query, facetBuilder) -> addRatingFacet(esSearch, SECURITY_RATING_KEY, facetBuilder)) + .put(ALERT_STATUS_KEY, (esSearch, query, facetBuilder) -> esSearch.addAggregation(createStickyFacet(ALERT_STATUS_KEY, facetBuilder, createQualityGateFacet()))) + .put(FILTER_LANGUAGES, ProjectMeasuresIndex::addLanguagesFacet) + .put(FIELD_TAGS, (esSearch, query, facetBuilder) -> esSearch.addAggregation(createStickyFacet(FIELD_TAGS, facetBuilder, createTagsFacet()))) .build(); private final AuthorizationTypeSupport authorizationTypeSupport; @@ -130,7 +132,7 @@ public class ProjectMeasuresIndex extends BaseIndex { filters.values().forEach(esFilter::must); requestBuilder.setQuery(esFilter); - addFacets(query, requestBuilder, searchOptions, filters); + addFacets(requestBuilder, searchOptions, filters, query); addSort(query, requestBuilder); return new SearchIdResult<>(requestBuilder.get(), id -> id); } @@ -158,23 +160,28 @@ public class ProjectMeasuresIndex extends BaseIndex { .order(query.isAsc() ? ASC : DESC)); } - private static void addFacets(ProjectMeasuresQuery query, SearchRequestBuilder esSearch, SearchOptions options, Map filters) { + private static void addFacets(SearchRequestBuilder esSearch, SearchOptions options, Map filters, ProjectMeasuresQuery query) { + StickyFacetBuilder facetBuilder = new StickyFacetBuilder(matchAllQuery(), filters); options.getFacets().stream() .filter(FACET_FACTORIES::containsKey) .map(FACET_FACTORIES::get) - .forEach(factory -> factory.addFacet(esSearch, filters)); + .forEach(factory -> factory.addFacet(esSearch, query, facetBuilder)); } - private static void addRangeFacet(SearchRequestBuilder esSearch, String metricKey, List thresholds, Map filters) { - esSearch.addAggregation(createStickyFacet(metricKey, filters, createRangeFacet(metricKey, thresholds))); + private static void addRangeFacet(SearchRequestBuilder esSearch, String metricKey, List thresholds, StickyFacetBuilder facetBuilder) { + esSearch.addAggregation(createStickyFacet(metricKey, facetBuilder, createRangeFacet(metricKey, thresholds))); } - private static void addRatingFacet(SearchRequestBuilder esSearch, String metricKey, Map filters) { - esSearch.addAggregation(createStickyFacet(metricKey, filters, createRatingFacet(metricKey))); + private static void addRatingFacet(SearchRequestBuilder esSearch, String metricKey, StickyFacetBuilder facetBuilder) { + esSearch.addAggregation(createStickyFacet(metricKey, facetBuilder, createRatingFacet(metricKey))); } - private static AbstractAggregationBuilder createStickyFacet(String facetKey, Map filters, AbstractAggregationBuilder aggregationBuilder) { - StickyFacetBuilder facetBuilder = new StickyFacetBuilder(matchAllQuery(), filters); + private static void addLanguagesFacet(SearchRequestBuilder esSearch, ProjectMeasuresQuery query, StickyFacetBuilder facetBuilder) { + Optional> languages = query.getLanguages(); + esSearch.addAggregation(facetBuilder.buildStickyFacet(FIELD_LANGUAGES, FILTER_LANGUAGES, languages.isPresent() ? languages.get().toArray() : new Object[] {})); + } + + private static AbstractAggregationBuilder createStickyFacet(String facetKey, StickyFacetBuilder facetBuilder, AbstractAggregationBuilder aggregationBuilder) { BoolQueryBuilder facetFilter = facetBuilder.getStickyFacetFilter(facetKey); return AggregationBuilders .global(facetKey) @@ -227,10 +234,6 @@ public class ProjectMeasuresIndex extends BaseIndex { return qualityGateStatusFilter; } - private static AbstractAggregationBuilder createLanguagesFacet() { - return AggregationBuilders.terms(FILTER_LANGUAGES).field(FIELD_LANGUAGES); - } - private static AbstractAggregationBuilder createTagsFacet() { return AggregationBuilders.terms(FIELD_TAGS).field(FIELD_TAGS); } @@ -332,7 +335,7 @@ public class ProjectMeasuresIndex extends BaseIndex { @FunctionalInterface private interface FacetSetter { - void addFacet(SearchRequestBuilder esSearch, Map filters); + void addFacet(SearchRequestBuilder esSearch, ProjectMeasuresQuery query, StickyFacetBuilder facetBuilder); } } 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 df5e1fd36c5..d734e26ef2b 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 @@ -1052,6 +1052,31 @@ public class ProjectMeasuresIndexTest { entry("500000.0-*", 0L)); } + @Test + public void facet_languages_returns_more_than_10_languages_when_languages_filter_contains_value_not_in_top_10() { + index( + newDoc().setLanguages(asList("", "java", "xoo", "css", "cpp")), + newDoc().setLanguages(asList("xml", "php", "python", "perl", "ruby")), + newDoc().setLanguages(asList("js", "scala"))); + + Facets facets = underTest.search(new ProjectMeasuresQuery().setLanguages(ImmutableSet.of("xoo", "xml")), new SearchOptions().addFacets(LANGUAGES)).getFacets(); + + assertThat(facets.get(LANGUAGES)).containsOnly( + entry("", 1L), + entry("cpp", 1L), + entry("css", 1L), + entry("java", 1L), + entry("js", 1L), + entry("perl", 1L), + entry("php", 1L), + entry("python", 1L), + entry("ruby", 1L), + entry("scala", 1L), + entry("xoo", 1L), + entry("xml", 1L) + ); + } + @Test public void facet_languages_contains_only_projects_authorized_for_user() throws Exception { // User can see these projects -- 2.39.5