public static final String FACET_TAGS = "tags";
public static final String FACET_REPOSITORIES = "repositories";
public static final String FACET_SEVERITIES = "severities";
+ public static final String FACET_ACTIVE_SEVERITIES = "active_severities";
public static final String FACET_STATUSES = "statuses";
public static final String FACET_DEBT_CHARACTERISTICS = "debt_characteristics";
public static final String FACET_OLD_DEFAULT = "true";
stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.SEVERITY.field(), FACET_SEVERITIES, Severity.ALL.toArray()));
}
+ addActiveSeverityFacetIfNeeded(query, options, aggregations, stickyFacetBuilder);
+
addCharacteristicsFacetIfNeeded(query, options, aggregations, stickyFacetBuilder);
return aggregations;
}
}
+ private void addActiveSeverityFacetIfNeeded(RuleQuery query, QueryContext options, Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {
+ if (options.facets().contains(FACET_ACTIVE_SEVERITIES)) {
+ // We are building a children aggregation on active rules
+ // so the rule filter has to be used as parent filter for active rules
+ // from which we remove filters that concern active rules ("activation")
+ HasParentFilterBuilder ruleFilter = FilterBuilders.hasParentFilter(
+ IndexDefinition.RULE.getIndexType(),
+ stickyFacetBuilder.getStickyFacetFilter("activation"));
+
+ // Rebuilding the active rule filter without severities
+ BoolFilterBuilder childrenFilter = FilterBuilders.boolFilter();
+ this.addTermFilter(childrenFilter, ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field(), query.getQProfileKey());
+ this.addTermFilter(childrenFilter, ActiveRuleNormalizer.ActiveRuleField.INHERITANCE.field(), query.getInheritance());
+ FilterBuilder activeRuleFilter;
+ if (childrenFilter.hasClauses()) {
+ activeRuleFilter = childrenFilter.must(ruleFilter);
+ } else {
+ activeRuleFilter = ruleFilter;
+ }
+
+ AggregationBuilder activeSeverities = AggregationBuilders.children(FACET_ACTIVE_SEVERITIES + "_children")
+ .childType(IndexDefinition.ACTIVE_RULE.getIndexType())
+ .subAggregation(AggregationBuilders.filter(FACET_ACTIVE_SEVERITIES + "_filter")
+ .filter(activeRuleFilter)
+ .subAggregation(
+ AggregationBuilders
+ .terms(FACET_ACTIVE_SEVERITIES)
+ .field(ActiveRuleNormalizer.ActiveRuleField.SEVERITY.field())
+ .include(Joiner.on('|').join(Severity.ALL))
+ .size(Severity.ALL.size())));
+
+ aggregations.put(FACET_ACTIVE_SEVERITIES, AggregationBuilders.global(FACET_ACTIVE_SEVERITIES).subAggregation(activeSeverities));
+ }
+ }
+
private void addCharacteristicsFacetIfNeeded(RuleQuery query, QueryContext options, Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {
if (options.facets().contains(FACET_DEBT_CHARACTERISTICS)) {
RuleIndex.FACET_TAGS,
RuleIndex.FACET_DEBT_CHARACTERISTICS,
RuleIndex.FACET_SEVERITIES,
+ RuleIndex.FACET_ACTIVE_SEVERITIES,
RuleIndex.FACET_STATUSES,
RuleIndex.FACET_OLD_DEFAULT
});
@Override
protected void writeFacets(Request request, QueryContext context, Result<?> results, JsonWriter json) {
- addMandatoryFacetValues(results, RuleIndex.FACET_DEBT_CHARACTERISTICS, request.paramAsStrings(PARAM_SEVERITIES));
+ addMandatoryFacetValues(results, RuleIndex.FACET_DEBT_CHARACTERISTICS, request.paramAsStrings(PARAM_DEBT_CHARACTERISTICS));
addMandatoryFacetValues(results, RuleIndex.FACET_LANGUAGES, request.paramAsStrings(PARAM_LANGUAGES));
addMandatoryFacetValues(results, RuleIndex.FACET_REPOSITORIES, request.paramAsStrings(PARAM_REPOSITORIES));
addMandatoryFacetValues(results, RuleIndex.FACET_STATUSES, RuleIndex.ALL_STATUSES_EXCEPT_REMOVED);
addMandatoryFacetValues(results, RuleIndex.FACET_SEVERITIES, Severity.ALL);
+ addMandatoryFacetValues(results, RuleIndex.FACET_ACTIVE_SEVERITIES, Severity.ALL);
addMandatoryFacetValues(results, RuleIndex.FACET_TAGS, request.paramAsStrings(PARAM_TAGS));
mergeNoneAndEmptyBucketOnCharacteristics(results);
import javax.annotation.Nullable;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import static com.google.common.collect.Lists.newArrayList;
import static org.assertj.core.api.Assertions.assertThat;
assertThat(result.getHits()).hasSize(3);
}
+ @Test
+ public void search_by_profile_and_active_severity() throws InterruptedException {
+ QualityProfileDto qualityProfileDto1 = QProfileTesting.newXooP1();
+ QualityProfileDto qualityProfileDto2 = QProfileTesting.newXooP2();
+ db.qualityProfileDao().insert(dbSession, qualityProfileDto1, qualityProfileDto2);
+
+ RuleDto rule1 = RuleTesting.newXooX1().setSeverity("MAJOR");
+ RuleDto rule2 = RuleTesting.newXooX2().setSeverity("MINOR");
+ RuleDto rule3 = RuleTesting.newXooX3().setSeverity("INFO");
+ dao.insert(dbSession, rule1, rule2, rule3);
+
+ db.activeRuleDao().insert(
+ dbSession,
+ ActiveRuleDto.createFor(qualityProfileDto1, rule1).setSeverity("BLOCKER"),
+ ActiveRuleDto.createFor(qualityProfileDto2, rule1).setSeverity("BLOCKER"),
+ ActiveRuleDto.createFor(qualityProfileDto1, rule2).setSeverity("CRITICAL"));
+ dbSession.commit();
+ dbSession.clearCache();
+
+ // 1. get all active rules.
+ Result<Rule> result = index.search(new RuleQuery().setActivation(true).setQProfileKey(qualityProfileDto1.getKey()),
+ new QueryContext());
+ assertThat(result.getHits()).hasSize(2);
+
+ // 2. get rules with active severity critical.
+ result = index.search(new RuleQuery().setActivation(true).setQProfileKey(qualityProfileDto1.getKey()).setActiveSeverities(Arrays.asList("CRITICAL")),
+ new QueryContext().addFacets(Arrays.asList(RuleIndex.FACET_ACTIVE_SEVERITIES)));
+ assertThat(result.getHits()).hasSize(1);
+ assertThat(result.getHits().get(0).name()).isEqualTo(rule2.getName());
+ // check stickyness of active severity facet
+ assertThat(result.getFacetValues(RuleIndex.FACET_ACTIVE_SEVERITIES)).containsOnly(new FacetValue("BLOCKER", 1), new FacetValue("CRITICAL", 1));
+
+ // 3. count activation severities of all active rules
+ result = index.search(new RuleQuery(),
+ new QueryContext().addFacets(Arrays.asList(RuleIndex.FACET_ACTIVE_SEVERITIES)));
+ assertThat(result.getHits()).hasSize(3);
+ assertThat(result.getFacetValues(RuleIndex.FACET_ACTIVE_SEVERITIES)).containsOnly(new FacetValue("BLOCKER", 2), new FacetValue("CRITICAL", 1));
+ }
+
@Test
public void complex_param_value() throws InterruptedException {
String value = "//expression[primary/qualifiedIdentifier[count(IDENTIFIER) = 2]/IDENTIFIER[2]/@tokenValue = 'firstOf' and primary/identifierSuffix/arguments/expression[not(primary) or primary[not(qualifiedIdentifier) or identifierSuffix]]]";
@Test
public void sticky_facets() {
- Integer numberOfSystemTags = 2;
dao.insert(dbSession,
RuleTesting.newDto(RuleKey.of("xoo", "S001")).setLanguage("java").setTags(ImmutableSet.<String>of()),
RuleTesting.newDto(RuleKey.of("xoo", "S002")).setLanguage("java").setTags(ImmutableSet.<String>of()),