import org.sonar.server.platform.ServerImpl;
import org.sonar.server.platform.ServerSettings;
import org.sonar.server.platform.TempFolderProvider;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex2;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
import org.sonar.server.ruby.PlatformRackBridge;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleNormalizer;
import org.sonar.server.search.EsSearchModule;
import org.sonar.server.search.IndexQueue;
EsSearchModule.class,
// rules/qprofiles
- RuleIndex2.class,
- ActiveRuleIndex2.class,
+ RuleIndex.class,
+ ActiveRuleIndex.class,
RuleNormalizer.class,
ActiveRuleNormalizer.class,
import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.qualityprofile.index.ActiveRuleDoc;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex2;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.search.FacetValue;
public class QProfileLoader {
private final DbClient dbClient;
- private final ActiveRuleIndex2 activeRuleIndex;
- private final RuleIndex2 ruleIndex;
+ private final ActiveRuleIndex activeRuleIndex;
+ private final RuleIndex ruleIndex;
- public QProfileLoader(DbClient dbClient, ActiveRuleIndex2 activeRuleIndex, RuleIndex2 ruleIndex) {
+ public QProfileLoader(DbClient dbClient, ActiveRuleIndex activeRuleIndex, RuleIndex ruleIndex) {
this.dbClient = dbClient;
this.activeRuleIndex = activeRuleIndex;
this.ruleIndex = ruleIndex;
import org.sonar.server.activity.ActivityService;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.util.TypeValidations;
private final DbClient db;
private final TypeValidations typeValidations;
private final RuleActivatorContextFactory contextFactory;
- private final RuleIndex2 ruleIndex;
+ private final RuleIndex ruleIndex;
private final ActiveRuleIndexer activeRuleIndexer;
private final ActivityService activityService;
- public RuleActivator(System2 system2, DbClient db, RuleIndex2 ruleIndex,
+ public RuleActivator(System2 system2, DbClient db, RuleIndex ruleIndex,
RuleActivatorContextFactory contextFactory, TypeValidations typeValidations,
ActiveRuleIndexer activeRuleIndexer, ActivityService activityService) {
this.system2 = system2;
*/
package org.sonar.server.qualityprofile.index;
+import com.google.common.base.Function;
+import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import org.elasticsearch.action.get.GetRequestBuilder;
+import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.index.query.FilterBuilder;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
+import org.elasticsearch.search.aggregations.Aggregations;
+import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
+import org.elasticsearch.search.aggregations.metrics.valuecount.InternalValueCount;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
-import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.ActiveRuleKey;
+import org.sonar.server.es.BaseIndex;
+import org.sonar.server.es.EsClient;
import org.sonar.server.qualityprofile.ActiveRule;
import org.sonar.server.rule.index.RuleIndexDefinition;
-import org.sonar.server.search.BaseIndex;
import org.sonar.server.search.FacetValue;
-import org.sonar.server.search.IndexDefinition;
-import org.sonar.server.search.IndexField;
-import org.sonar.server.search.SearchClient;
-@Deprecated
-public class ActiveRuleIndex extends BaseIndex<ActiveRule, ActiveRuleDto, ActiveRuleKey> {
+import static org.sonar.server.es.EsUtils.SCROLL_TIME_IN_MINUTES;
+import static org.sonar.server.es.EsUtils.scroll;
+import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE;
+import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_KEY;
+import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY;
+import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_STATUS;
+import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX;
+import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE;
+import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE;
+
+/**
+ * The unique entry-point to interact with Elasticsearch index "active rules".
+ * All the requests are listed here.
+ */
+public class ActiveRuleIndex extends BaseIndex {
public static final String COUNT_ACTIVE_RULES = "countActiveRules";
- public ActiveRuleIndex(ActiveRuleNormalizer normalizer, SearchClient node) {
- super(IndexDefinition.ACTIVE_RULE, normalizer, node);
- }
-
- @Override
- protected String getKeyValue(ActiveRuleKey key) {
- return key.toString();
- }
-
- @Override
- protected Map mapKey() {
- Map<String, Object> mapping = new HashMap<>();
- mapping.put("path", ActiveRuleNormalizer.ActiveRuleField.KEY.field());
- return mapping;
+ public ActiveRuleIndex(EsClient client) {
+ super(client);
}
- @Override
- protected Map mapProperties() {
- Map<String, Object> mapping = new HashMap<>();
- for (IndexField field : ActiveRuleNormalizer.ActiveRuleField.ALL_FIELDS) {
- mapping.put(field.field(), mapField(field));
+ /**
+ * @deprecated since 5.5, use {@link org.sonar.db.qualityprofile.ActiveRuleDao instead}
+ */
+ @Deprecated
+ @CheckForNull
+ public ActiveRule getNullableByKey(ActiveRuleKey key) {
+ GetRequestBuilder request = getClient().prepareGet()
+ .setIndex(RuleIndexDefinition.INDEX)
+ .setType(RuleIndexDefinition.TYPE_ACTIVE_RULE)
+ .setId(key.toString())
+ .setFetchSource(true)
+ .setRouting(key.ruleKey().repository());
+
+ GetResponse response = request.get();
+ if (response.isExists()) {
+ return new ActiveRuleDoc(response.getSource());
}
- return mapping;
- }
-
- @Override
- protected Map mapDomain() {
- Map<String, Object> mapping = new HashMap<>();
- mapping.put("dynamic", false);
- mapping.put("_id", mapKey());
- mapping.put("_parent", mapParent());
- mapping.put("_routing", mapRouting());
- mapping.put("properties", mapProperties());
- return mapping;
- }
-
- private Map mapRouting() {
- Map<String, Object> mapping = new HashMap<>();
- mapping.put("required", true);
- mapping.put("path", ActiveRuleNormalizer.ActiveRuleField.RULE_KEY.field());
- return mapping;
- }
-
- private Object mapParent() {
- Map<String, Object> mapping = new HashMap<>();
- mapping.put("type", this.getParentType());
- return mapping;
- }
-
- @Override
- public ActiveRule toDoc(Map<String, Object> fields) {
- return new ActiveRuleDoc(fields);
+ return null;
}
/**
- * finder methods
+ * @deprecated since 5.5, use {@link org.sonar.db.qualityprofile.ActiveRuleDao instead}
*/
+ @Deprecated
public List<ActiveRule> findByRule(RuleKey key) {
- SearchRequestBuilder request = getClient().prepareSearch(this.getIndexName())
+ SearchRequestBuilder request = getClient().prepareSearch(RuleIndexDefinition.INDEX)
.setQuery(QueryBuilders
- .hasParentQuery(this.getParentType(),
- QueryBuilders.idsQuery(this.getParentType())
+ .hasParentQuery(RuleIndexDefinition.TYPE_RULE,
+ QueryBuilders.idsQuery(RuleIndexDefinition.TYPE_RULE)
.addIds(key.toString())
))
- .setRouting(key.toString())
- // TODO replace by scrolling
+ .setRouting(key.repository())
.setSize(Integer.MAX_VALUE);
SearchResponse response = request.get();
List<ActiveRule> activeRules = new ArrayList<>();
for (SearchHit hit : response.getHits()) {
- activeRules.add(toDoc(hit.getSource()));
+ activeRules.add(new ActiveRuleDoc(hit.getSource()));
}
return activeRules;
}
- public Iterator<ActiveRule> findByProfile(String key) {
- SearchRequestBuilder request = getClient().prepareSearch(getIndexName())
- .setTypes(IndexDefinition.ACTIVE_RULE.getIndexType())
+ /**
+ * @deprecated since 5.5, use {@link org.sonar.db.qualityprofile.ActiveRuleDao instead}
+ */
+ @Deprecated
+ public Iterator<ActiveRuleDoc> findByProfile(String key) {
+ SearchRequestBuilder request = getClient().prepareSearch(RuleIndexDefinition.INDEX)
+ .setTypes(RuleIndexDefinition.TYPE_ACTIVE_RULE)
.setSearchType(SearchType.SCAN)
.setScroll(TimeValue.timeValueMinutes(SCROLL_TIME_IN_MINUTES))
.setSize(100)
.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), FilterBuilders.boolFilter()
- .must(FilterBuilders.termFilter(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field(), key))
- .mustNot(FilterBuilders.hasParentFilter(this.getParentType(),
- FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_STATUS, RuleStatus.REMOVED.name())))))
- .setRouting(key);
+ .must(FilterBuilders.termFilter(RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_KEY, key))
+ .mustNot(FilterBuilders.hasParentFilter(RuleIndexDefinition.TYPE_RULE,
+ FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_STATUS, RuleStatus.REMOVED.name())))));
SearchResponse response = request.get();
- return scroll(response.getScrollId());
+ return scroll(getClient(), response.getScrollId(), ToDoc.INSTANCE);
}
- private String getParentType() {
- return IndexDefinition.RULE.getIndexType();
- }
-
- public Long countByQualityProfileKey(String key) {
- return countByField(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY,
- FilterBuilders.hasParentFilter(IndexDefinition.RULE.getIndexType(),
+ public Map<String, Long> countAllByQualityProfileKey() {
+ return countByField(FIELD_ACTIVE_RULE_PROFILE_KEY,
+ FilterBuilders.hasParentFilter(TYPE_RULE,
FilterBuilders.notFilter(
- FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_STATUS, "REMOVED")))).get(key);
+ FilterBuilders.termFilter(FIELD_RULE_STATUS, "REMOVED"))));
}
- public Map<String, Long> countAllByQualityProfileKey() {
- return countByField(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY,
- FilterBuilders.hasParentFilter(IndexDefinition.RULE.getIndexType(),
- FilterBuilders.notFilter(
- FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_STATUS, "REMOVED"))));
+ private Map<String, Long> countByField(String indexField, FilterBuilder filter) {
+ Map<String, Long> counts = new HashMap<>();
+
+ SearchRequestBuilder request = getClient().prepareSearch(INDEX)
+ .setTypes(TYPE_ACTIVE_RULE)
+ .setQuery(QueryBuilders.filteredQuery(
+ QueryBuilders.matchAllQuery(),
+ filter))
+ .setSize(0)
+ .addAggregation(AggregationBuilders
+ .terms(indexField)
+ .field(indexField)
+ .order(Terms.Order.count(false))
+ .size(Integer.MAX_VALUE)
+ .minDocCount(0));
+
+ SearchResponse response = request.get();
+
+ Terms values =
+ response.getAggregations().get(indexField);
+
+ for (Terms.Bucket value : values.getBuckets()) {
+ counts.put(value.getKey(), value.getDocCount());
+ }
+ return counts;
}
public Map<String, Multimap<String, FacetValue>> getStatsByProfileKeys(List<String> keys) {
- SearchRequestBuilder request = getClient().prepareSearch(this.getIndexName())
+ SearchRequestBuilder request = getClient().prepareSearch(INDEX)
.setQuery(QueryBuilders.filteredQuery(
- QueryBuilders.termsQuery(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field(), keys),
+ QueryBuilders.termsQuery(FIELD_ACTIVE_RULE_PROFILE_KEY, keys),
FilterBuilders.boolFilter()
- .mustNot(FilterBuilders.hasParentFilter(this.getParentType(),
- FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_STATUS, RuleStatus.REMOVED.name())))))
- .addAggregation(AggregationBuilders.terms(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field())
- .field(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field()).size(0)
- .subAggregation(AggregationBuilders.terms(ActiveRuleNormalizer.ActiveRuleField.INHERITANCE.field())
- .field(ActiveRuleNormalizer.ActiveRuleField.INHERITANCE.field()))
- .subAggregation(AggregationBuilders.terms(ActiveRuleNormalizer.ActiveRuleField.SEVERITY.field())
- .field(ActiveRuleNormalizer.ActiveRuleField.SEVERITY.field()))
+ .mustNot(FilterBuilders.hasParentFilter(TYPE_RULE,
+ FilterBuilders.termFilter(FIELD_RULE_STATUS, RuleStatus.REMOVED.name())))))
+ .addAggregation(AggregationBuilders.terms(FIELD_ACTIVE_RULE_PROFILE_KEY)
+ .field(RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_KEY).size(0)
+ .subAggregation(AggregationBuilders.terms(FIELD_ACTIVE_RULE_INHERITANCE)
+ .field(RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE))
+ .subAggregation(AggregationBuilders.terms(FIELD_ACTIVE_RULE_SEVERITY)
+ .field(RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY))
.subAggregation(AggregationBuilders.count(COUNT_ACTIVE_RULES)))
.setSize(0)
- .setTypes(this.getIndexType());
+ .setTypes(TYPE_ACTIVE_RULE);
SearchResponse response = request.get();
Map<String, Multimap<String, FacetValue>> stats = new HashMap<>();
- Aggregation aggregation = response.getAggregations().get(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field());
+ Aggregation aggregation = response.getAggregations().get(FIELD_ACTIVE_RULE_PROFILE_KEY);
for (Terms.Bucket value : ((Terms) aggregation).getBuckets()) {
- stats.put(value.getKey()
- , this.processAggregations(value.getAggregations()));
+ stats.put(value.getKey(), processAggregations(value.getAggregations()));
}
return stats;
}
+
+ private Multimap<String, FacetValue> processAggregations(Aggregations aggregations) {
+ Multimap<String, FacetValue> stats = ArrayListMultimap.create();
+ if (aggregations != null) {
+ for (Aggregation aggregation : aggregations.asList()) {
+ if (aggregation instanceof StringTerms) {
+ for (Terms.Bucket value : ((Terms) aggregation).getBuckets()) {
+ FacetValue facetValue = new FacetValue(value.getKey(), value.getDocCount());
+ stats.put(aggregation.getName(), facetValue);
+ }
+ } else if (aggregation instanceof InternalValueCount) {
+ InternalValueCount count = (InternalValueCount) aggregation;
+ FacetValue facetValue = new FacetValue(count.getName(), count.getValue());
+ stats.put(count.getName(), facetValue);
+ }
+ }
+ }
+ return stats;
+ }
+
+ private enum ToDoc implements Function<Map<String, Object>, ActiveRuleDoc> {
+ INSTANCE;
+
+ @Override
+ public ActiveRuleDoc apply(@Nonnull Map<String, Object> input) {
+ return new ActiveRuleDoc(input);
+ }
+ }
+
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.qualityprofile.index;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-import org.elasticsearch.action.get.GetRequestBuilder;
-import org.elasticsearch.action.get.GetResponse;
-import org.elasticsearch.action.search.SearchRequestBuilder;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.action.search.SearchType;
-import org.elasticsearch.common.unit.TimeValue;
-import org.elasticsearch.index.query.FilterBuilder;
-import org.elasticsearch.index.query.FilterBuilders;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.search.SearchHit;
-import org.elasticsearch.search.aggregations.Aggregation;
-import org.elasticsearch.search.aggregations.AggregationBuilders;
-import org.elasticsearch.search.aggregations.Aggregations;
-import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
-import org.elasticsearch.search.aggregations.bucket.terms.Terms;
-import org.elasticsearch.search.aggregations.metrics.valuecount.InternalValueCount;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
-import org.sonar.db.qualityprofile.ActiveRuleKey;
-import org.sonar.server.es.BaseIndex;
-import org.sonar.server.es.EsClient;
-import org.sonar.server.qualityprofile.ActiveRule;
-import org.sonar.server.rule.index.RuleIndexDefinition;
-import org.sonar.server.search.FacetValue;
-
-import static org.sonar.server.es.EsUtils.SCROLL_TIME_IN_MINUTES;
-import static org.sonar.server.es.EsUtils.scroll;
-import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE;
-import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_KEY;
-import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY;
-import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_STATUS;
-import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX;
-import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE;
-import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE;
-
-/**
- * The unique entry-point to interact with Elasticsearch index "active rules".
- * All the requests are listed here.
- */
-public class ActiveRuleIndex2 extends BaseIndex {
-
- public static final String COUNT_ACTIVE_RULES = "countActiveRules";
-
- public ActiveRuleIndex2(EsClient client) {
- super(client);
- }
-
- /**
- * @deprecated since 5.5, use {@link org.sonar.db.qualityprofile.ActiveRuleDao instead}
- */
- @Deprecated
- @CheckForNull
- public ActiveRule getNullableByKey(ActiveRuleKey key) {
- GetRequestBuilder request = getClient().prepareGet()
- .setIndex(RuleIndexDefinition.INDEX)
- .setType(RuleIndexDefinition.TYPE_ACTIVE_RULE)
- .setId(key.toString())
- .setFetchSource(true)
- .setRouting(key.ruleKey().repository());
-
- GetResponse response = request.get();
- if (response.isExists()) {
- return new ActiveRuleDoc(response.getSource());
- }
- return null;
- }
-
- /**
- * @deprecated since 5.5, use {@link org.sonar.db.qualityprofile.ActiveRuleDao instead}
- */
- @Deprecated
- public List<ActiveRule> findByRule(RuleKey key) {
- SearchRequestBuilder request = getClient().prepareSearch(RuleIndexDefinition.INDEX)
- .setQuery(QueryBuilders
- .hasParentQuery(RuleIndexDefinition.TYPE_RULE,
- QueryBuilders.idsQuery(RuleIndexDefinition.TYPE_RULE)
- .addIds(key.toString())
- ))
- .setRouting(key.repository())
- .setSize(Integer.MAX_VALUE);
-
- SearchResponse response = request.get();
-
- List<ActiveRule> activeRules = new ArrayList<>();
- for (SearchHit hit : response.getHits()) {
- activeRules.add(new ActiveRuleDoc(hit.getSource()));
- }
- return activeRules;
- }
-
- /**
- * @deprecated since 5.5, use {@link org.sonar.db.qualityprofile.ActiveRuleDao instead}
- */
- @Deprecated
- public Iterator<ActiveRuleDoc> findByProfile(String key) {
- SearchRequestBuilder request = getClient().prepareSearch(RuleIndexDefinition.INDEX)
- .setTypes(RuleIndexDefinition.TYPE_ACTIVE_RULE)
- .setSearchType(SearchType.SCAN)
- .setScroll(TimeValue.timeValueMinutes(SCROLL_TIME_IN_MINUTES))
- .setSize(100)
- .setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), FilterBuilders.boolFilter()
- .must(FilterBuilders.termFilter(RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_KEY, key))
- .mustNot(FilterBuilders.hasParentFilter(RuleIndexDefinition.TYPE_RULE,
- FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_STATUS, RuleStatus.REMOVED.name())))));
-
- SearchResponse response = request.get();
- return scroll(getClient(), response.getScrollId(), ToDoc.INSTANCE);
- }
-
- public Map<String, Long> countAllByQualityProfileKey() {
- return countByField(FIELD_ACTIVE_RULE_PROFILE_KEY,
- FilterBuilders.hasParentFilter(TYPE_RULE,
- FilterBuilders.notFilter(
- FilterBuilders.termFilter(FIELD_RULE_STATUS, "REMOVED"))));
- }
-
- private Map<String, Long> countByField(String indexField, FilterBuilder filter) {
- Map<String, Long> counts = new HashMap<>();
-
- SearchRequestBuilder request = getClient().prepareSearch(INDEX)
- .setTypes(TYPE_ACTIVE_RULE)
- .setQuery(QueryBuilders.filteredQuery(
- QueryBuilders.matchAllQuery(),
- filter))
- .setSize(0)
- .addAggregation(AggregationBuilders
- .terms(indexField)
- .field(indexField)
- .order(Terms.Order.count(false))
- .size(Integer.MAX_VALUE)
- .minDocCount(0));
-
- SearchResponse response = request.get();
-
- Terms values =
- response.getAggregations().get(indexField);
-
- for (Terms.Bucket value : values.getBuckets()) {
- counts.put(value.getKey(), value.getDocCount());
- }
- return counts;
- }
-
- public Map<String, Multimap<String, FacetValue>> getStatsByProfileKeys(List<String> keys) {
- SearchRequestBuilder request = getClient().prepareSearch(INDEX)
- .setQuery(QueryBuilders.filteredQuery(
- QueryBuilders.termsQuery(FIELD_ACTIVE_RULE_PROFILE_KEY, keys),
- FilterBuilders.boolFilter()
- .mustNot(FilterBuilders.hasParentFilter(TYPE_RULE,
- FilterBuilders.termFilter(FIELD_RULE_STATUS, RuleStatus.REMOVED.name())))))
- .addAggregation(AggregationBuilders.terms(FIELD_ACTIVE_RULE_PROFILE_KEY)
- .field(RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_KEY).size(0)
- .subAggregation(AggregationBuilders.terms(FIELD_ACTIVE_RULE_INHERITANCE)
- .field(RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE))
- .subAggregation(AggregationBuilders.terms(FIELD_ACTIVE_RULE_SEVERITY)
- .field(RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY))
- .subAggregation(AggregationBuilders.count(COUNT_ACTIVE_RULES)))
- .setSize(0)
- .setTypes(TYPE_ACTIVE_RULE);
- SearchResponse response = request.get();
- Map<String, Multimap<String, FacetValue>> stats = new HashMap<>();
- Aggregation aggregation = response.getAggregations().get(FIELD_ACTIVE_RULE_PROFILE_KEY);
- for (Terms.Bucket value : ((Terms) aggregation).getBuckets()) {
- stats.put(value.getKey(), processAggregations(value.getAggregations()));
- }
-
- return stats;
- }
-
- private Multimap<String, FacetValue> processAggregations(Aggregations aggregations) {
- Multimap<String, FacetValue> stats = ArrayListMultimap.create();
- if (aggregations != null) {
- for (Aggregation aggregation : aggregations.asList()) {
- if (aggregation instanceof StringTerms) {
- for (Terms.Bucket value : ((Terms) aggregation).getBuckets()) {
- FacetValue facetValue = new FacetValue(value.getKey(), value.getDocCount());
- stats.put(aggregation.getName(), facetValue);
- }
- } else if (aggregation instanceof InternalValueCount) {
- InternalValueCount count = (InternalValueCount) aggregation;
- FacetValue facetValue = new FacetValue(count.getName(), count.getValue());
- stats.put(count.getName(), facetValue);
- }
- }
- }
- return stats;
- }
-
- private enum ToDoc implements Function<Map<String, Object>, ActiveRuleDoc> {
- INSTANCE;
-
- @Override
- public ActiveRuleDoc apply(@Nonnull Map<String, Object> input) {
- return new ActiveRuleDoc(input);
- }
- }
-
-}
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.search.FacetValue;
-import static org.sonar.server.qualityprofile.index.ActiveRuleIndex2.COUNT_ACTIVE_RULES;
+import static org.sonar.server.qualityprofile.index.ActiveRuleIndex.COUNT_ACTIVE_RULES;
public class InheritanceAction implements QProfileWsAction {
import org.sonar.api.rule.RuleKey;
import org.sonar.api.server.ServerSide;
import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.search.QueryContext;
@ServerSide
public class RuleService {
- private final RuleIndex2 index;
+ private final RuleIndex index;
private final RuleUpdater ruleUpdater;
private final RuleCreator ruleCreator;
private final RuleDeleter ruleDeleter;
private final UserSession userSession;
- public RuleService(RuleIndex2 index, RuleUpdater ruleUpdater, RuleCreator ruleCreator, RuleDeleter ruleDeleter, UserSession userSession) {
+ public RuleService(RuleIndex index, RuleUpdater ruleUpdater, RuleCreator ruleCreator, RuleDeleter ruleDeleter, UserSession userSession) {
this.index = index;
this.ruleUpdater = ruleUpdater;
this.ruleCreator = ruleCreator;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.action.search.SearchScrollRequestBuilder;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolFilterBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.SimpleQueryStringBuilder;
-import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
-import org.sonar.db.rule.RuleDto;
-import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
-import org.sonar.server.rule.Rule;
-import org.sonar.server.search.BaseIndex;
-import org.sonar.server.search.IndexDefinition;
+import org.sonar.server.es.BaseIndex;
+import org.sonar.server.es.EsClient;
+import org.sonar.server.es.SearchIdResult;
+import org.sonar.server.es.SearchOptions;
import org.sonar.server.search.IndexField;
-import org.sonar.server.search.QueryContext;
-import org.sonar.server.search.Result;
-import org.sonar.server.search.SearchClient;
import org.sonar.server.search.StickyFacetBuilder;
-import static com.google.common.collect.Lists.newArrayList;
+import static org.sonar.server.es.EsUtils.SCROLL_TIME_IN_MINUTES;
+import static org.sonar.server.es.EsUtils.scrollIds;
-@Deprecated
-public class RuleIndex extends BaseIndex<Rule, RuleDto, RuleKey> {
+/**
+ * The unique entry-point to interact with Elasticsearch index "rules".
+ * All the requests are listed here.
+ */
+public class RuleIndex extends BaseIndex {
public static final String FACET_LANGUAGES = "languages";
public static final String FACET_TAGS = "tags";
Arrays.asList(RuleStatus.values()),
new Function<RuleStatus, String>() {
@Override
- public String apply(RuleStatus input) {
+ public String apply(@Nonnull RuleStatus input) {
return input.toString();
}
}),
new Predicate<String>() {
@Override
- public boolean apply(String input) {
+ public boolean apply(@Nonnull String input) {
return !RuleStatus.REMOVED.toString().equals(input);
}
}));
- public RuleIndex(RuleNormalizer normalizer, SearchClient client) {
- super(IndexDefinition.RULE, normalizer, client);
+ public RuleIndex(EsClient client) {
+ super(client);
}
- @Override
- protected String getKeyValue(RuleKey key) {
- return key.toString();
- }
+ public SearchIdResult<RuleKey> search(RuleQuery query, SearchOptions options) {
+ SearchRequestBuilder esSearch = getClient()
+ .prepareSearch(RuleIndexDefinition.INDEX)
+ .setTypes(RuleIndexDefinition.TYPE_RULE);
- @Override
- protected Map mapKey() {
- Map<String, Object> mapping = new HashMap<>();
- mapping.put("path", RuleNormalizer.RuleField.KEY.field());
- return mapping;
- }
+ QueryBuilder qb = buildQuery(query);
+ Map<String, FilterBuilder> filters = buildFilters(query);
- @Override
- protected Map mapProperties() {
- Map<String, Object> mapping = new HashMap<>();
- for (IndexField field : RuleNormalizer.RuleField.ALL_FIELDS) {
- mapping.put(field.field(), mapField(field));
- }
- return mapping;
- }
-
- private void setFields(QueryContext options, SearchRequestBuilder esSearch) {
- /* integrate Option's Fields */
- Set<String> fields = new HashSet<>();
- if (!options.getFieldsToReturn().isEmpty()) {
- for (String fieldToReturn : options.getFieldsToReturn()) {
- if (!fieldToReturn.isEmpty()) {
- fields.add(fieldToReturn);
- }
- }
- // required field
- fields.add(RuleNormalizer.RuleField.KEY.field());
- } else {
- for (IndexField indexField : RuleNormalizer.RuleField.ALL_FIELDS) {
- fields.add(indexField.field());
+ if (!options.getFacets().isEmpty()) {
+ for (AggregationBuilder aggregation : getFacets(query, options, qb, filters).values()) {
+ esSearch.addAggregation(aggregation);
}
}
- esSearch.setFetchSource(fields.toArray(new String[fields.size()]), null);
- }
+ setSorting(query, esSearch);
+ setPagination(options, esSearch);
- private void setSorting(RuleQuery query, SearchRequestBuilder esSearch) {
- /* integrate Query Sort */
- String queryText = query.getQueryText();
- if (query.getSortField() != null) {
- FieldSortBuilder sort = SortBuilders.fieldSort(query.getSortField());
- if (query.isAscendingSort()) {
- sort.order(SortOrder.ASC);
- } else {
- sort.order(SortOrder.DESC);
- }
- esSearch.addSort(sort);
- } else if (queryText != null && !queryText.isEmpty()) {
- esSearch.addSort(SortBuilders.scoreSort());
- } else {
- esSearch.addSort(RuleNormalizer.RuleField.UPDATED_AT.sortField(), SortOrder.DESC);
- // deterministic sort when exactly the same updated_at (same millisecond)
- esSearch.addSort(RuleNormalizer.RuleField.KEY.sortField()
- , SortOrder.ASC);
+ BoolFilterBuilder fb = FilterBuilders.boolFilter();
+ for (FilterBuilder filterBuilder : filters.values()) {
+ fb.must(filterBuilder);
}
- }
- protected void setPagination(QueryContext options, SearchRequestBuilder esSearch) {
- esSearch.setFrom(options.getOffset());
- esSearch.setSize(options.getLimit());
+ esSearch.setQuery(QueryBuilders.filteredQuery(qb, fb));
+ return new SearchIdResult<>(esSearch.get(), ToRuleKey.INSTANCE);
}
- private QueryBuilder termQuery(IndexField field, String query, float boost) {
- return QueryBuilders.multiMatchQuery(query,
- field.field(), field.field() + "." + IndexField.SEARCH_PARTIAL_SUFFIX)
- .operator(MatchQueryBuilder.Operator.AND)
- .boost(boost);
- }
+ /**
+ * Return all keys matching the search query, without pagination nor facets
+ */
+ public Iterator<RuleKey> searchAll(RuleQuery query) {
+ SearchRequestBuilder esSearch = getClient()
+ .prepareSearch(RuleIndexDefinition.INDEX)
+ .setTypes(RuleIndexDefinition.TYPE_RULE)
+ .setSearchType(SearchType.SCAN)
+ .setScroll(TimeValue.timeValueMinutes(SCROLL_TIME_IN_MINUTES));
- private QueryBuilder termAnyQuery(IndexField field, String query, float boost) {
- return QueryBuilders.multiMatchQuery(query,
- field.field(), field.field() + "." + IndexField.SEARCH_PARTIAL_SUFFIX)
- .operator(MatchQueryBuilder.Operator.OR)
- .boost(boost);
+ QueryBuilder qb = buildQuery(query);
+ Map<String, FilterBuilder> filters = buildFilters(query);
+ setSorting(query, esSearch);
+
+ BoolFilterBuilder fb = FilterBuilders.boolFilter();
+ for (FilterBuilder filterBuilder : filters.values()) {
+ fb.must(filterBuilder);
+ }
+
+ esSearch.setQuery(QueryBuilders.filteredQuery(qb, fb));
+ SearchResponse response = esSearch.get();
+ return scrollIds(getClient(), response.getScrollId(), ToRuleKey.INSTANCE);
}
/* Build main query (search based) */
- protected QueryBuilder getQuery(RuleQuery query) {
+ private QueryBuilder buildQuery(RuleQuery query) {
// No contextual query case
String queryText = query.getQueryText();
// Human readable type of querying
qb.should(QueryBuilders.simpleQueryStringQuery(query.getQueryText())
- .field(RuleNormalizer.RuleField.NAME.field() + "." + IndexField.SEARCH_WORDS_SUFFIX, 20f)
- .field(RuleNormalizer.RuleField.HTML_DESCRIPTION.field() + "." + IndexField.SEARCH_WORDS_SUFFIX, 3f)
+ .field(RuleIndexDefinition.FIELD_RULE_NAME + "." + BaseIndex.SEARCH_WORDS_SUFFIX, 20f)
+ .field(RuleIndexDefinition.FIELD_RULE_HTML_DESCRIPTION + "." + BaseIndex.SEARCH_WORDS_SUFFIX, 3f)
.defaultOperator(SimpleQueryStringBuilder.Operator.AND)
).boost(20f);
// Match and partial Match queries
- qb.should(this.termQuery(RuleNormalizer.RuleField.KEY, queryString, 15f));
- qb.should(this.termQuery(RuleNormalizer.RuleField._KEY, queryString, 35f));
- qb.should(this.termQuery(RuleNormalizer.RuleField.LANGUAGE, queryString, 3f));
- qb.should(this.termQuery(RuleNormalizer.RuleField.ALL_TAGS, queryString, 10f));
- qb.should(this.termAnyQuery(RuleNormalizer.RuleField.ALL_TAGS, queryString, 1f));
+ qb.should(this.termQuery(RuleIndexDefinition.FIELD_RULE_KEY, queryString, 15f));
+ qb.should(this.termQuery(RuleIndexDefinition.FIELD_RULE_KEY_AS_LIST, queryString, 35f));
+ qb.should(this.termQuery(RuleIndexDefinition.FIELD_RULE_LANGUAGE, queryString, 3f));
+ qb.should(this.termQuery(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, queryString, 10f));
+ qb.should(this.termAnyQuery(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, queryString, 1f));
return qb;
}
+ private QueryBuilder termQuery(String field, String query, float boost) {
+ return QueryBuilders.multiMatchQuery(query,
+ field, field + "." + IndexField.SEARCH_PARTIAL_SUFFIX)
+ .operator(MatchQueryBuilder.Operator.AND)
+ .boost(boost);
+ }
+
+ private QueryBuilder termAnyQuery(String field, String query, float boost) {
+ return QueryBuilders.multiMatchQuery(query,
+ field, field + "." + IndexField.SEARCH_PARTIAL_SUFFIX)
+ .operator(MatchQueryBuilder.Operator.OR)
+ .boost(boost);
+ }
+
/* Build main filter (match based) */
- protected Map<String, FilterBuilder> getFilters(RuleQuery query, QueryContext options) {
+ private Map<String, FilterBuilder> buildFilters(RuleQuery query) {
Map<String, FilterBuilder> filters = new HashMap<>();
/* Add enforced filter on rules that are REMOVED */
- filters.put(RuleNormalizer.RuleField.STATUS.field(),
+ filters.put(RuleIndexDefinition.FIELD_RULE_STATUS,
FilterBuilders.boolFilter().mustNot(
- FilterBuilders.termFilter(RuleNormalizer.RuleField.STATUS.field(),
+ FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_STATUS,
RuleStatus.REMOVED.toString())));
if (!StringUtils.isEmpty(query.getInternalKey())) {
- filters.put(RuleNormalizer.RuleField.INTERNAL_KEY.field(),
- FilterBuilders.termFilter(RuleNormalizer.RuleField.INTERNAL_KEY.field(), query.getInternalKey()));
+ filters.put(RuleIndexDefinition.FIELD_RULE_INTERNAL_KEY,
+ FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_INTERNAL_KEY, query.getInternalKey()));
}
if (!StringUtils.isEmpty(query.getRuleKey())) {
- filters.put(RuleNormalizer.RuleField.RULE_KEY.field(),
- FilterBuilders.termFilter(RuleNormalizer.RuleField.RULE_KEY.field(), query.getRuleKey()));
+ filters.put(RuleIndexDefinition.FIELD_RULE_RULE_KEY,
+ FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_RULE_KEY, query.getRuleKey()));
}
if (!CollectionUtils.isEmpty(query.getLanguages())) {
- filters.put(RuleNormalizer.RuleField.LANGUAGE.field(),
- FilterBuilders.termsFilter(RuleNormalizer.RuleField.LANGUAGE.field(), query.getLanguages()));
+ filters.put(RuleIndexDefinition.FIELD_RULE_LANGUAGE,
+ FilterBuilders.termsFilter(RuleIndexDefinition.FIELD_RULE_LANGUAGE, query.getLanguages()));
}
if (!CollectionUtils.isEmpty(query.getRepositories())) {
- filters.put(RuleNormalizer.RuleField.REPOSITORY.field(),
- FilterBuilders.termsFilter(RuleNormalizer.RuleField.REPOSITORY.field(), query.getRepositories()));
+ filters.put(RuleIndexDefinition.FIELD_RULE_REPOSITORY,
+ FilterBuilders.termsFilter(RuleIndexDefinition.FIELD_RULE_REPOSITORY, query.getRepositories()));
}
if (!CollectionUtils.isEmpty(query.getSeverities())) {
- filters.put(RuleNormalizer.RuleField.SEVERITY.field(),
- FilterBuilders.termsFilter(RuleNormalizer.RuleField.SEVERITY.field(), query.getSeverities()));
+ filters.put(RuleIndexDefinition.FIELD_RULE_SEVERITY,
+ FilterBuilders.termsFilter(RuleIndexDefinition.FIELD_RULE_SEVERITY, query.getSeverities()));
}
if (!StringUtils.isEmpty(query.getKey())) {
- filters.put(RuleNormalizer.RuleField.KEY.field(),
- FilterBuilders.termFilter(RuleNormalizer.RuleField.KEY.field(), query.getKey()));
+ filters.put(RuleIndexDefinition.FIELD_RULE_KEY,
+ FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_KEY, query.getKey()));
}
if (!CollectionUtils.isEmpty(query.getTags())) {
- filters.put(RuleNormalizer.RuleField.ALL_TAGS.field(),
- FilterBuilders.termsFilter(RuleNormalizer.RuleField.ALL_TAGS.field(), query.getTags()));
+ filters.put(RuleIndexDefinition.FIELD_RULE_ALL_TAGS,
+ FilterBuilders.termsFilter(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, query.getTags()));
}
- if (query.getAvailableSince() != null) {
- filters.put("availableSince", FilterBuilders.rangeFilter(RuleNormalizer.RuleField.CREATED_AT.field())
- .gte(query.getAvailableSince()));
+ if (query.getAvailableSinceLong() != null) {
+ filters.put("availableSince", FilterBuilders.rangeFilter(RuleIndexDefinition.FIELD_RULE_CREATED_AT)
+ .gte(query.getAvailableSinceLong()));
}
Collection<RuleStatus> statusValues = query.getStatuses();
for (RuleStatus status : statusValues) {
stringStatus.add(status.name());
}
- filters.put(RuleNormalizer.RuleField.STATUS.field(),
- FilterBuilders.termsFilter(RuleNormalizer.RuleField.STATUS.field(), stringStatus));
+ filters.put(RuleIndexDefinition.FIELD_RULE_STATUS,
+ FilterBuilders.termsFilter(RuleIndexDefinition.FIELD_RULE_STATUS, stringStatus));
}
Boolean isTemplate = query.isTemplate();
if (isTemplate != null) {
- filters.put(RuleNormalizer.RuleField.IS_TEMPLATE.field(),
- FilterBuilders.termFilter(RuleNormalizer.RuleField.IS_TEMPLATE.field(), Boolean.toString(isTemplate)));
+ filters.put(RuleIndexDefinition.FIELD_RULE_IS_TEMPLATE,
+ FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_IS_TEMPLATE, Boolean.toString(isTemplate)));
}
String template = query.templateKey();
if (template != null) {
- filters.put(RuleNormalizer.RuleField.TEMPLATE_KEY.field(),
- FilterBuilders.termFilter(RuleNormalizer.RuleField.TEMPLATE_KEY.field(), template));
+ filters.put(RuleIndexDefinition.FIELD_RULE_TEMPLATE_KEY,
+ FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_TEMPLATE_KEY, template));
}
// ActiveRule Filter (profile and inheritance)
BoolFilterBuilder childrenFilter = FilterBuilders.boolFilter();
- this.addTermFilter(childrenFilter, ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field(), query.getQProfileKey());
- this.addTermFilter(childrenFilter, ActiveRuleNormalizer.ActiveRuleField.INHERITANCE.field(), query.getInheritance());
- this.addTermFilter(childrenFilter, ActiveRuleNormalizer.ActiveRuleField.SEVERITY.field(), query.getActiveSeverities());
+ addTermFilter(childrenFilter, RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_KEY, query.getQProfileKey());
+ addTermFilter(childrenFilter, RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE, query.getInheritance());
+ addTermFilter(childrenFilter, RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY, query.getActiveSeverities());
// ChildQuery
FilterBuilder childQuery;
/** Implementation of activation query */
if (Boolean.TRUE.equals(query.getActivation())) {
filters.put("activation",
- FilterBuilders.hasChildFilter(IndexDefinition.ACTIVE_RULE.getIndexType(),
+ FilterBuilders.hasChildFilter(RuleIndexDefinition.TYPE_ACTIVE_RULE,
childQuery));
} else if (Boolean.FALSE.equals(query.getActivation())) {
filters.put("activation",
FilterBuilders.boolFilter().mustNot(
- FilterBuilders.hasChildFilter(IndexDefinition.ACTIVE_RULE.getIndexType(),
+ FilterBuilders.hasChildFilter(RuleIndexDefinition.TYPE_ACTIVE_RULE,
childQuery)));
}
return filters;
}
- protected Map<String, AggregationBuilder> getFacets(RuleQuery query, QueryContext options, QueryBuilder queryBuilder, Map<String, FilterBuilder> filters) {
+ private BoolFilterBuilder addTermFilter(BoolFilterBuilder filter, String field, @Nullable Collection<String> values) {
+ if (values != null && !values.isEmpty()) {
+ BoolFilterBuilder valuesFilter = FilterBuilders.boolFilter();
+ for (String value : values) {
+ FilterBuilder valueFilter = FilterBuilders.termFilter(field, value);
+ valuesFilter.should(valueFilter);
+ }
+ filter.must(valuesFilter);
+ }
+ return filter;
+ }
+
+ private BoolFilterBuilder addTermFilter(BoolFilterBuilder filter, String field, @Nullable String value) {
+ if (value != null && !value.isEmpty()) {
+ filter.must(FilterBuilders.termFilter(field, value));
+ }
+ return filter;
+ }
+
+ private Map<String, AggregationBuilder> getFacets(RuleQuery query, SearchOptions options, QueryBuilder queryBuilder, Map<String, FilterBuilder> filters) {
Map<String, AggregationBuilder> aggregations = new HashMap<>();
StickyFacetBuilder stickyFacetBuilder = stickyFacetBuilder(queryBuilder, filters);
- addDefaultFacets(query, options, queryBuilder, filters, aggregations, stickyFacetBuilder);
+ addDefaultFacets(query, options, aggregations, stickyFacetBuilder);
addStatusFacetIfNeeded(options, aggregations, stickyFacetBuilder);
- if (options.facets().contains(FACET_SEVERITIES)) {
+ if (options.getFacets().contains(FACET_SEVERITIES)) {
aggregations.put(FACET_SEVERITIES,
- stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.SEVERITY.field(), FACET_SEVERITIES, Severity.ALL.toArray()));
+ stickyFacetBuilder.buildStickyFacet(RuleIndexDefinition.FIELD_RULE_SEVERITY, FACET_SEVERITIES, Severity.ALL.toArray()));
}
addActiveSeverityFacetIfNeeded(query, options, aggregations, stickyFacetBuilder);
return aggregations;
+ }
+ private void addDefaultFacets(RuleQuery query, SearchOptions options, Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {
+ if (options.getFacets().contains(FACET_LANGUAGES) || options.getFacets().contains(FACET_OLD_DEFAULT)) {
+ Collection<String> languages = query.getLanguages();
+ aggregations.put(FACET_LANGUAGES,
+ stickyFacetBuilder.buildStickyFacet(RuleIndexDefinition.FIELD_RULE_LANGUAGE, FACET_LANGUAGES,
+ languages == null ? new String[0] : languages.toArray()));
+ }
+ if (options.getFacets().contains(FACET_TAGS) || options.getFacets().contains(FACET_OLD_DEFAULT)) {
+ Collection<String> tags = query.getTags();
+ aggregations.put(FACET_TAGS,
+ stickyFacetBuilder.buildStickyFacet(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, FACET_TAGS,
+ tags == null ? new String[0] : tags.toArray()));
+ }
+ if (options.getFacets().contains("repositories") || options.getFacets().contains(FACET_OLD_DEFAULT)) {
+ Collection<String> repositories = query.getRepositories();
+ aggregations.put(FACET_REPOSITORIES,
+ stickyFacetBuilder.buildStickyFacet(RuleIndexDefinition.FIELD_RULE_REPOSITORY, FACET_REPOSITORIES,
+ repositories == null ? new String[0] : repositories.toArray()));
+ }
}
- private void addStatusFacetIfNeeded(QueryContext options, Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {
- if (options.facets().contains(FACET_STATUSES)) {
- BoolFilterBuilder facetFilter = stickyFacetBuilder.getStickyFacetFilter(RuleNormalizer.RuleField.STATUS.field());
+ private void addStatusFacetIfNeeded(SearchOptions options, Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {
+ if (options.getFacets().contains(FACET_STATUSES)) {
+ BoolFilterBuilder facetFilter = stickyFacetBuilder.getStickyFacetFilter(RuleIndexDefinition.FIELD_RULE_STATUS);
AggregationBuilder statuses = AggregationBuilders.filter(FACET_STATUSES + "_filter")
.filter(facetFilter)
.subAggregation(
AggregationBuilders
.terms(FACET_STATUSES)
- .field(RuleNormalizer.RuleField.STATUS.field())
+ .field(RuleIndexDefinition.FIELD_RULE_STATUS)
.include(Joiner.on('|').join(ALL_STATUSES_EXCEPT_REMOVED))
.exclude(RuleStatus.REMOVED.toString())
.size(ALL_STATUSES_EXCEPT_REMOVED.size()));
}
}
- private void addActiveSeverityFacetIfNeeded(RuleQuery query, QueryContext options, Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {
- if (options.facets().contains(FACET_ACTIVE_SEVERITIES)) {
+ private void addActiveSeverityFacetIfNeeded(RuleQuery query, SearchOptions options, Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {
+ if (options.getFacets().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(),
+ RuleIndexDefinition.TYPE_RULE,
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());
+ this.addTermFilter(childrenFilter, RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_KEY, query.getQProfileKey());
+ this.addTermFilter(childrenFilter, RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE, query.getInheritance());
FilterBuilder activeRuleFilter;
if (childrenFilter.hasClauses()) {
activeRuleFilter = childrenFilter.must(ruleFilter);
}
AggregationBuilder activeSeverities = AggregationBuilders.children(FACET_ACTIVE_SEVERITIES + "_children")
- .childType(IndexDefinition.ACTIVE_RULE.getIndexType())
+ .childType(RuleIndexDefinition.TYPE_ACTIVE_RULE)
.subAggregation(AggregationBuilders.filter(FACET_ACTIVE_SEVERITIES + "_filter")
.filter(activeRuleFilter)
.subAggregation(
AggregationBuilders
.terms(FACET_ACTIVE_SEVERITIES)
- .field(ActiveRuleNormalizer.ActiveRuleField.SEVERITY.field())
+ .field(RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY)
.include(Joiner.on('|').join(Severity.ALL))
.size(Severity.ALL.size())));
}
}
- protected void addDefaultFacets(RuleQuery query, QueryContext options, QueryBuilder queryBuilder, Map<String, FilterBuilder> filters,
- Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {
- if (options.facets().contains(FACET_LANGUAGES) || options.facets().contains(FACET_OLD_DEFAULT)) {
- Collection<String> languages = query.getLanguages();
- aggregations.put(FACET_LANGUAGES,
- stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.LANGUAGE.field(), FACET_LANGUAGES,
- languages == null ? new String[0] : languages.toArray()));
- }
- if (options.facets().contains(FACET_TAGS) || options.facets().contains(FACET_OLD_DEFAULT)) {
- Collection<String> tags = query.getTags();
- aggregations.put(FACET_TAGS,
- stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.ALL_TAGS.field(), FACET_TAGS,
- tags == null ? new String[0] : tags.toArray()));
- }
- if (options.facets().contains("repositories") || options.facets().contains(FACET_OLD_DEFAULT)) {
- Collection<String> repositories = query.getRepositories();
- aggregations.put(FACET_REPOSITORIES,
- stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.REPOSITORY.field(), FACET_REPOSITORIES,
- repositories == null ? new String[0] : repositories.toArray()));
- }
+ private StickyFacetBuilder stickyFacetBuilder(QueryBuilder query, Map<String, FilterBuilder> filters) {
+ return new StickyFacetBuilder(query, filters);
}
- public Result<Rule> search(RuleQuery query, QueryContext options) {
- SearchRequestBuilder esSearch = getClient()
- .prepareSearch(this.getIndexName())
- .setTypes(this.getIndexType())
- .setIndices(this.getIndexName());
-
- if (options.isScroll()) {
- esSearch.setSearchType(SearchType.SCAN);
- esSearch.setScroll(TimeValue.timeValueMinutes(3));
- }
-
- QueryBuilder qb = this.getQuery(query);
- Map<String, FilterBuilder> filters = this.getFilters(query, options);
-
- if (options.isFacet()) {
- for (AggregationBuilder aggregation : getFacets(query, options, qb, filters).values()) {
- esSearch.addAggregation(aggregation);
+ private void setSorting(RuleQuery query, SearchRequestBuilder esSearch) {
+ /* integrate Query Sort */
+ String queryText = query.getQueryText();
+ if (query.getSortField() != null) {
+ FieldSortBuilder sort = SortBuilders.fieldSort(appendSortSuffixIfNeeded(query.getSortField()));
+ if (query.isAscendingSort()) {
+ sort.order(SortOrder.ASC);
+ } else {
+ sort.order(SortOrder.DESC);
}
+ esSearch.addSort(sort);
+ } else if (queryText != null && !queryText.isEmpty()) {
+ esSearch.addSort(SortBuilders.scoreSort());
+ } else {
+ esSearch.addSort(appendSortSuffixIfNeeded(RuleIndexDefinition.FIELD_RULE_UPDATED_AT), SortOrder.DESC);
+ // deterministic sort when exactly the same updated_at (same millisecond)
+ esSearch.addSort(appendSortSuffixIfNeeded(RuleIndexDefinition.FIELD_RULE_KEY), SortOrder.ASC);
}
+ }
- setSorting(query, esSearch);
- setPagination(options, esSearch);
- setFields(options, esSearch);
-
- BoolFilterBuilder fb = FilterBuilders.boolFilter();
- for (FilterBuilder ffb : filters.values()) {
- fb.must(ffb);
- }
-
- esSearch.setQuery(QueryBuilders.filteredQuery(qb, fb));
- SearchResponse esResult = esSearch.get();
- return new Result<>(this, esResult);
+ public static String appendSortSuffixIfNeeded(String field) {
+ return field +
+ ((field.equals(RuleIndexDefinition.FIELD_RULE_NAME)
+ || field.equals(RuleIndexDefinition.FIELD_RULE_KEY))
+ ? "." + BaseIndex.SORT_SUFFIX
+ : "");
}
- @Override
- protected Rule toDoc(Map<String, Object> fields) {
- Preconditions.checkNotNull(fields, "Cannot construct Rule with null response");
- return new RuleDoc(fields);
+ private void setPagination(SearchOptions options, SearchRequestBuilder esSearch) {
+ esSearch.setFrom(options.getOffset());
+ esSearch.setSize(options.getLimit());
}
public Set<String> terms(String fields) {
terms.include(".*" + query + ".*");
}
SearchRequestBuilder request = this.getClient()
- .prepareSearch(this.getIndexName())
+ .prepareSearch(RuleIndexDefinition.INDEX)
.setQuery(QueryBuilders.matchAllQuery())
.addAggregation(terms);
return tags;
}
- /**
- * @deprecated please use getByKey(RuleKey key)
- */
- @Deprecated
- @CheckForNull
- public Rule getById(int id) {
- SearchRequestBuilder request = getClient().prepareSearch(this.getIndexName())
- .setTypes(this.getIndexType())
- .setQuery(QueryBuilders.termQuery(RuleNormalizer.RuleField.ID.field(), id))
- .setSize(1);
- SearchResponse response = request.get();
-
- SearchHit hit = response.getHits().getAt(0);
- if (hit == null) {
- return null;
- } else {
- return toDoc(hit.getSource());
- }
- }
+ private enum ToRuleKey implements Function<String, RuleKey> {
+ INSTANCE;
- /**
- * @deprecated please use getByKey(RuleKey key)
- */
- @Deprecated
- public List<Rule> getByIds(Collection<Integer> ids) {
- SearchRequestBuilder request = getClient().prepareSearch(this.getIndexName())
- .setTypes(this.getIndexType())
- .setSearchType(SearchType.SCAN)
- .setScroll(TimeValue.timeValueSeconds(3L))
- .setSize(100)
- .setQuery(QueryBuilders.termsQuery(RuleNormalizer.RuleField.ID.field(), ids));
- SearchResponse scrollResp = request.get();
-
- List<Rule> rules = newArrayList();
- while (true) {
- SearchScrollRequestBuilder scrollRequest = getClient()
- .prepareSearchScroll(scrollResp.getScrollId())
- .setScroll(TimeValue.timeValueSeconds(3L));
-
- scrollResp = scrollRequest.get();
-
- for (SearchHit hit : scrollResp.getHits()) {
- rules.add(toDoc(hit.getSource()));
- }
- // Break condition: No hits are returned
- if (scrollResp.getHits().getHits().length == 0) {
- break;
- }
+ @Override
+ public RuleKey apply(@Nonnull String input) {
+ return RuleKey.parse(input);
}
- return rules;
}
+
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.rule.index;
-
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.StringUtils;
-import org.elasticsearch.action.search.SearchRequestBuilder;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.action.search.SearchType;
-import org.elasticsearch.common.unit.TimeValue;
-import org.elasticsearch.index.query.BoolFilterBuilder;
-import org.elasticsearch.index.query.BoolQueryBuilder;
-import org.elasticsearch.index.query.FilterBuilder;
-import org.elasticsearch.index.query.FilterBuilders;
-import org.elasticsearch.index.query.HasParentFilterBuilder;
-import org.elasticsearch.index.query.MatchQueryBuilder;
-import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.index.query.SimpleQueryStringBuilder;
-import org.elasticsearch.search.aggregations.AggregationBuilder;
-import org.elasticsearch.search.aggregations.AggregationBuilders;
-import org.elasticsearch.search.aggregations.bucket.terms.Terms;
-import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
-import org.elasticsearch.search.sort.FieldSortBuilder;
-import org.elasticsearch.search.sort.SortBuilders;
-import org.elasticsearch.search.sort.SortOrder;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
-import org.sonar.api.rule.Severity;
-import org.sonar.server.es.BaseIndex;
-import org.sonar.server.es.EsClient;
-import org.sonar.server.es.SearchIdResult;
-import org.sonar.server.es.SearchOptions;
-import org.sonar.server.search.IndexField;
-import org.sonar.server.search.StickyFacetBuilder;
-
-import static org.sonar.server.es.EsUtils.SCROLL_TIME_IN_MINUTES;
-import static org.sonar.server.es.EsUtils.scrollIds;
-
-/**
- * The unique entry-point to interact with Elasticsearch index "rules".
- * All the requests are listed here.
- */
-public class RuleIndex2 extends BaseIndex {
-
- public static final String FACET_LANGUAGES = "languages";
- 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_OLD_DEFAULT = "true";
-
- public static final List<String> ALL_STATUSES_EXCEPT_REMOVED = ImmutableList.copyOf(
- Collections2.filter(
- Collections2.transform(
- Arrays.asList(RuleStatus.values()),
- new Function<RuleStatus, String>() {
- @Override
- public String apply(@Nonnull RuleStatus input) {
- return input.toString();
- }
- }),
- new Predicate<String>() {
- @Override
- public boolean apply(@Nonnull String input) {
- return !RuleStatus.REMOVED.toString().equals(input);
- }
- }));
-
- public RuleIndex2(EsClient client) {
- super(client);
- }
-
- public SearchIdResult<RuleKey> search(RuleQuery query, SearchOptions options) {
- SearchRequestBuilder esSearch = getClient()
- .prepareSearch(RuleIndexDefinition.INDEX)
- .setTypes(RuleIndexDefinition.TYPE_RULE);
-
- QueryBuilder qb = buildQuery(query);
- Map<String, FilterBuilder> filters = buildFilters(query);
-
- if (!options.getFacets().isEmpty()) {
- for (AggregationBuilder aggregation : getFacets(query, options, qb, filters).values()) {
- esSearch.addAggregation(aggregation);
- }
- }
-
- setSorting(query, esSearch);
- setPagination(options, esSearch);
-
- BoolFilterBuilder fb = FilterBuilders.boolFilter();
- for (FilterBuilder filterBuilder : filters.values()) {
- fb.must(filterBuilder);
- }
-
- esSearch.setQuery(QueryBuilders.filteredQuery(qb, fb));
- return new SearchIdResult<>(esSearch.get(), ToRuleKey.INSTANCE);
- }
-
- /**
- * Return all keys matching the search query, without pagination nor facets
- */
- public Iterator<RuleKey> searchAll(RuleQuery query) {
- SearchRequestBuilder esSearch = getClient()
- .prepareSearch(RuleIndexDefinition.INDEX)
- .setTypes(RuleIndexDefinition.TYPE_RULE)
- .setSearchType(SearchType.SCAN)
- .setScroll(TimeValue.timeValueMinutes(SCROLL_TIME_IN_MINUTES));
-
- QueryBuilder qb = buildQuery(query);
- Map<String, FilterBuilder> filters = buildFilters(query);
- setSorting(query, esSearch);
-
- BoolFilterBuilder fb = FilterBuilders.boolFilter();
- for (FilterBuilder filterBuilder : filters.values()) {
- fb.must(filterBuilder);
- }
-
- esSearch.setQuery(QueryBuilders.filteredQuery(qb, fb));
- SearchResponse response = esSearch.get();
- return scrollIds(getClient(), response.getScrollId(), ToRuleKey.INSTANCE);
- }
-
- /* Build main query (search based) */
- private QueryBuilder buildQuery(RuleQuery query) {
-
- // No contextual query case
- String queryText = query.getQueryText();
- if (queryText == null || queryText.isEmpty()) {
- return QueryBuilders.matchAllQuery();
- }
-
- // Build RuleBased contextual query
- BoolQueryBuilder qb = QueryBuilders.boolQuery();
- String queryString = query.getQueryText();
-
- // Human readable type of querying
- qb.should(QueryBuilders.simpleQueryStringQuery(query.getQueryText())
- .field(RuleIndexDefinition.FIELD_RULE_NAME + "." + BaseIndex.SEARCH_WORDS_SUFFIX, 20f)
- .field(RuleIndexDefinition.FIELD_RULE_HTML_DESCRIPTION + "." + BaseIndex.SEARCH_WORDS_SUFFIX, 3f)
- .defaultOperator(SimpleQueryStringBuilder.Operator.AND)
- ).boost(20f);
-
- // Match and partial Match queries
- qb.should(this.termQuery(RuleIndexDefinition.FIELD_RULE_KEY, queryString, 15f));
- qb.should(this.termQuery(RuleIndexDefinition.FIELD_RULE_KEY_AS_LIST, queryString, 35f));
- qb.should(this.termQuery(RuleIndexDefinition.FIELD_RULE_LANGUAGE, queryString, 3f));
- qb.should(this.termQuery(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, queryString, 10f));
- qb.should(this.termAnyQuery(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, queryString, 1f));
-
- return qb;
- }
-
- private QueryBuilder termQuery(String field, String query, float boost) {
- return QueryBuilders.multiMatchQuery(query,
- field, field + "." + IndexField.SEARCH_PARTIAL_SUFFIX)
- .operator(MatchQueryBuilder.Operator.AND)
- .boost(boost);
- }
-
- private QueryBuilder termAnyQuery(String field, String query, float boost) {
- return QueryBuilders.multiMatchQuery(query,
- field, field + "." + IndexField.SEARCH_PARTIAL_SUFFIX)
- .operator(MatchQueryBuilder.Operator.OR)
- .boost(boost);
- }
-
- /* Build main filter (match based) */
- private Map<String, FilterBuilder> buildFilters(RuleQuery query) {
-
- Map<String, FilterBuilder> filters = new HashMap<>();
-
- /* Add enforced filter on rules that are REMOVED */
- filters.put(RuleIndexDefinition.FIELD_RULE_STATUS,
- FilterBuilders.boolFilter().mustNot(
- FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_STATUS,
- RuleStatus.REMOVED.toString())));
-
- if (!StringUtils.isEmpty(query.getInternalKey())) {
- filters.put(RuleIndexDefinition.FIELD_RULE_INTERNAL_KEY,
- FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_INTERNAL_KEY, query.getInternalKey()));
- }
-
- if (!StringUtils.isEmpty(query.getRuleKey())) {
- filters.put(RuleIndexDefinition.FIELD_RULE_RULE_KEY,
- FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_RULE_KEY, query.getRuleKey()));
- }
-
- if (!CollectionUtils.isEmpty(query.getLanguages())) {
- filters.put(RuleIndexDefinition.FIELD_RULE_LANGUAGE,
- FilterBuilders.termsFilter(RuleIndexDefinition.FIELD_RULE_LANGUAGE, query.getLanguages()));
- }
-
- if (!CollectionUtils.isEmpty(query.getRepositories())) {
- filters.put(RuleIndexDefinition.FIELD_RULE_REPOSITORY,
- FilterBuilders.termsFilter(RuleIndexDefinition.FIELD_RULE_REPOSITORY, query.getRepositories()));
- }
-
- if (!CollectionUtils.isEmpty(query.getSeverities())) {
- filters.put(RuleIndexDefinition.FIELD_RULE_SEVERITY,
- FilterBuilders.termsFilter(RuleIndexDefinition.FIELD_RULE_SEVERITY, query.getSeverities()));
- }
-
- if (!StringUtils.isEmpty(query.getKey())) {
- filters.put(RuleIndexDefinition.FIELD_RULE_KEY,
- FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_KEY, query.getKey()));
- }
-
- if (!CollectionUtils.isEmpty(query.getTags())) {
- filters.put(RuleIndexDefinition.FIELD_RULE_ALL_TAGS,
- FilterBuilders.termsFilter(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, query.getTags()));
- }
-
- if (query.getAvailableSinceLong() != null) {
- filters.put("availableSince", FilterBuilders.rangeFilter(RuleIndexDefinition.FIELD_RULE_CREATED_AT)
- .gte(query.getAvailableSinceLong()));
- }
-
- Collection<RuleStatus> statusValues = query.getStatuses();
- if (statusValues != null && !statusValues.isEmpty()) {
- Collection<String> stringStatus = new ArrayList<>();
- for (RuleStatus status : statusValues) {
- stringStatus.add(status.name());
- }
- filters.put(RuleIndexDefinition.FIELD_RULE_STATUS,
- FilterBuilders.termsFilter(RuleIndexDefinition.FIELD_RULE_STATUS, stringStatus));
- }
-
- Boolean isTemplate = query.isTemplate();
- if (isTemplate != null) {
- filters.put(RuleIndexDefinition.FIELD_RULE_IS_TEMPLATE,
- FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_IS_TEMPLATE, Boolean.toString(isTemplate)));
- }
-
- String template = query.templateKey();
- if (template != null) {
- filters.put(RuleIndexDefinition.FIELD_RULE_TEMPLATE_KEY,
- FilterBuilders.termFilter(RuleIndexDefinition.FIELD_RULE_TEMPLATE_KEY, template));
- }
-
- // ActiveRule Filter (profile and inheritance)
- BoolFilterBuilder childrenFilter = FilterBuilders.boolFilter();
- addTermFilter(childrenFilter, RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_KEY, query.getQProfileKey());
- addTermFilter(childrenFilter, RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE, query.getInheritance());
- addTermFilter(childrenFilter, RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY, query.getActiveSeverities());
-
- // ChildQuery
- FilterBuilder childQuery;
- if (childrenFilter.hasClauses()) {
- childQuery = childrenFilter;
- } else {
- childQuery = FilterBuilders.matchAllFilter();
- }
-
- /** Implementation of activation query */
- if (Boolean.TRUE.equals(query.getActivation())) {
- filters.put("activation",
- FilterBuilders.hasChildFilter(RuleIndexDefinition.TYPE_ACTIVE_RULE,
- childQuery));
- } else if (Boolean.FALSE.equals(query.getActivation())) {
- filters.put("activation",
- FilterBuilders.boolFilter().mustNot(
- FilterBuilders.hasChildFilter(RuleIndexDefinition.TYPE_ACTIVE_RULE,
- childQuery)));
- }
-
- return filters;
- }
-
- private BoolFilterBuilder addTermFilter(BoolFilterBuilder filter, String field, @Nullable Collection<String> values) {
- if (values != null && !values.isEmpty()) {
- BoolFilterBuilder valuesFilter = FilterBuilders.boolFilter();
- for (String value : values) {
- FilterBuilder valueFilter = FilterBuilders.termFilter(field, value);
- valuesFilter.should(valueFilter);
- }
- filter.must(valuesFilter);
- }
- return filter;
- }
-
- private BoolFilterBuilder addTermFilter(BoolFilterBuilder filter, String field, @Nullable String value) {
- if (value != null && !value.isEmpty()) {
- filter.must(FilterBuilders.termFilter(field, value));
- }
- return filter;
- }
-
- private Map<String, AggregationBuilder> getFacets(RuleQuery query, SearchOptions options, QueryBuilder queryBuilder, Map<String, FilterBuilder> filters) {
- Map<String, AggregationBuilder> aggregations = new HashMap<>();
- StickyFacetBuilder stickyFacetBuilder = stickyFacetBuilder(queryBuilder, filters);
-
- addDefaultFacets(query, options, aggregations, stickyFacetBuilder);
-
- addStatusFacetIfNeeded(options, aggregations, stickyFacetBuilder);
-
- if (options.getFacets().contains(FACET_SEVERITIES)) {
- aggregations.put(FACET_SEVERITIES,
- stickyFacetBuilder.buildStickyFacet(RuleIndexDefinition.FIELD_RULE_SEVERITY, FACET_SEVERITIES, Severity.ALL.toArray()));
- }
-
- addActiveSeverityFacetIfNeeded(query, options, aggregations, stickyFacetBuilder);
- return aggregations;
- }
-
- private void addDefaultFacets(RuleQuery query, SearchOptions options, Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {
- if (options.getFacets().contains(FACET_LANGUAGES) || options.getFacets().contains(FACET_OLD_DEFAULT)) {
- Collection<String> languages = query.getLanguages();
- aggregations.put(FACET_LANGUAGES,
- stickyFacetBuilder.buildStickyFacet(RuleIndexDefinition.FIELD_RULE_LANGUAGE, FACET_LANGUAGES,
- languages == null ? new String[0] : languages.toArray()));
- }
- if (options.getFacets().contains(FACET_TAGS) || options.getFacets().contains(FACET_OLD_DEFAULT)) {
- Collection<String> tags = query.getTags();
- aggregations.put(FACET_TAGS,
- stickyFacetBuilder.buildStickyFacet(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, FACET_TAGS,
- tags == null ? new String[0] : tags.toArray()));
- }
- if (options.getFacets().contains("repositories") || options.getFacets().contains(FACET_OLD_DEFAULT)) {
- Collection<String> repositories = query.getRepositories();
- aggregations.put(FACET_REPOSITORIES,
- stickyFacetBuilder.buildStickyFacet(RuleIndexDefinition.FIELD_RULE_REPOSITORY, FACET_REPOSITORIES,
- repositories == null ? new String[0] : repositories.toArray()));
- }
- }
-
- private void addStatusFacetIfNeeded(SearchOptions options, Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {
- if (options.getFacets().contains(FACET_STATUSES)) {
- BoolFilterBuilder facetFilter = stickyFacetBuilder.getStickyFacetFilter(RuleIndexDefinition.FIELD_RULE_STATUS);
- AggregationBuilder statuses = AggregationBuilders.filter(FACET_STATUSES + "_filter")
- .filter(facetFilter)
- .subAggregation(
- AggregationBuilders
- .terms(FACET_STATUSES)
- .field(RuleIndexDefinition.FIELD_RULE_STATUS)
- .include(Joiner.on('|').join(ALL_STATUSES_EXCEPT_REMOVED))
- .exclude(RuleStatus.REMOVED.toString())
- .size(ALL_STATUSES_EXCEPT_REMOVED.size()));
-
- aggregations.put(FACET_STATUSES, AggregationBuilders.global(FACET_STATUSES).subAggregation(statuses));
- }
- }
-
- private void addActiveSeverityFacetIfNeeded(RuleQuery query, SearchOptions options, Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {
- if (options.getFacets().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(
- RuleIndexDefinition.TYPE_RULE,
- stickyFacetBuilder.getStickyFacetFilter("activation"));
-
- // Rebuilding the active rule filter without severities
- BoolFilterBuilder childrenFilter = FilterBuilders.boolFilter();
- this.addTermFilter(childrenFilter, RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_KEY, query.getQProfileKey());
- this.addTermFilter(childrenFilter, RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE, query.getInheritance());
- FilterBuilder activeRuleFilter;
- if (childrenFilter.hasClauses()) {
- activeRuleFilter = childrenFilter.must(ruleFilter);
- } else {
- activeRuleFilter = ruleFilter;
- }
-
- AggregationBuilder activeSeverities = AggregationBuilders.children(FACET_ACTIVE_SEVERITIES + "_children")
- .childType(RuleIndexDefinition.TYPE_ACTIVE_RULE)
- .subAggregation(AggregationBuilders.filter(FACET_ACTIVE_SEVERITIES + "_filter")
- .filter(activeRuleFilter)
- .subAggregation(
- AggregationBuilders
- .terms(FACET_ACTIVE_SEVERITIES)
- .field(RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY)
- .include(Joiner.on('|').join(Severity.ALL))
- .size(Severity.ALL.size())));
-
- aggregations.put(FACET_ACTIVE_SEVERITIES, AggregationBuilders.global(FACET_ACTIVE_SEVERITIES).subAggregation(activeSeverities));
- }
- }
-
- private StickyFacetBuilder stickyFacetBuilder(QueryBuilder query, Map<String, FilterBuilder> filters) {
- return new StickyFacetBuilder(query, filters);
- }
-
- private void setSorting(RuleQuery query, SearchRequestBuilder esSearch) {
- /* integrate Query Sort */
- String queryText = query.getQueryText();
- if (query.getSortField() != null) {
- FieldSortBuilder sort = SortBuilders.fieldSort(appendSortSuffixIfNeeded(query.getSortField()));
- if (query.isAscendingSort()) {
- sort.order(SortOrder.ASC);
- } else {
- sort.order(SortOrder.DESC);
- }
- esSearch.addSort(sort);
- } else if (queryText != null && !queryText.isEmpty()) {
- esSearch.addSort(SortBuilders.scoreSort());
- } else {
- esSearch.addSort(appendSortSuffixIfNeeded(RuleIndexDefinition.FIELD_RULE_UPDATED_AT), SortOrder.DESC);
- // deterministic sort when exactly the same updated_at (same millisecond)
- esSearch.addSort(appendSortSuffixIfNeeded(RuleIndexDefinition.FIELD_RULE_KEY), SortOrder.ASC);
- }
- }
-
- public static String appendSortSuffixIfNeeded(String field) {
- return field +
- ((field.equals(RuleIndexDefinition.FIELD_RULE_NAME)
- || field.equals(RuleIndexDefinition.FIELD_RULE_KEY))
- ? "." + BaseIndex.SORT_SUFFIX
- : "");
- }
-
- private void setPagination(SearchOptions options, SearchRequestBuilder esSearch) {
- esSearch.setFrom(options.getOffset());
- esSearch.setSize(options.getLimit());
- }
-
- public Set<String> terms(String fields) {
- return terms(fields, null, Integer.MAX_VALUE);
- }
-
- public Set<String> terms(String fields, @Nullable String query, int size) {
- Set<String> tags = new HashSet<>();
- String key = "_ref";
-
- TermsBuilder terms = AggregationBuilders.terms(key)
- .field(fields)
- .size(size)
- .minDocCount(1);
- if (query != null) {
- terms.include(".*" + query + ".*");
- }
- SearchRequestBuilder request = this.getClient()
- .prepareSearch(RuleIndexDefinition.INDEX)
- .setQuery(QueryBuilders.matchAllQuery())
- .addAggregation(terms);
-
- SearchResponse esResponse = request.get();
-
- Terms aggregation = esResponse.getAggregations().get(key);
-
- if (aggregation != null) {
- for (Terms.Bucket value : aggregation.getBuckets()) {
- tags.add(value.getKey());
- }
- }
- return tags;
- }
-
- private enum ToRuleKey implements Function<String, RuleKey> {
- INSTANCE;
-
- @Override
- public RuleKey apply(@Nonnull String input) {
- return RuleKey.parse(input);
- }
- }
-
-}
import org.sonar.server.es.SearchIdResult;
import org.sonar.server.qualityprofile.ActiveRule;
import org.sonar.server.rule.Rule;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.search.ws.SearchOptions;
import org.sonarqube.ws.Rules.SearchResponse;
import static com.google.common.collect.FluentIterable.from;
-import static org.sonar.server.rule.index.RuleIndex2.ALL_STATUSES_EXCEPT_REMOVED;
-import static org.sonar.server.rule.index.RuleIndex2.FACET_ACTIVE_SEVERITIES;
-import static org.sonar.server.rule.index.RuleIndex2.FACET_LANGUAGES;
-import static org.sonar.server.rule.index.RuleIndex2.FACET_OLD_DEFAULT;
-import static org.sonar.server.rule.index.RuleIndex2.FACET_REPOSITORIES;
-import static org.sonar.server.rule.index.RuleIndex2.FACET_SEVERITIES;
-import static org.sonar.server.rule.index.RuleIndex2.FACET_STATUSES;
-import static org.sonar.server.rule.index.RuleIndex2.FACET_TAGS;
+import static org.sonar.server.rule.index.RuleIndex.ALL_STATUSES_EXCEPT_REMOVED;
+import static org.sonar.server.rule.index.RuleIndex.FACET_ACTIVE_SEVERITIES;
+import static org.sonar.server.rule.index.RuleIndex.FACET_LANGUAGES;
+import static org.sonar.server.rule.index.RuleIndex.FACET_OLD_DEFAULT;
+import static org.sonar.server.rule.index.RuleIndex.FACET_REPOSITORIES;
+import static org.sonar.server.rule.index.RuleIndex.FACET_SEVERITIES;
+import static org.sonar.server.rule.index.RuleIndex.FACET_STATUSES;
+import static org.sonar.server.rule.index.RuleIndex.FACET_TAGS;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
/**
private static final Collection<String> DEFAULT_FACETS = ImmutableSet.of(PARAM_LANGUAGES, PARAM_REPOSITORIES, "tags");
private final DbClient dbClient;
- private final RuleIndex2 ruleIndex;
+ private final RuleIndex ruleIndex;
private final ActiveRuleCompleter activeRuleCompleter;
private final RuleMapping mapping;
private final RuleMapper mapper;
- public SearchAction(RuleIndex2 ruleIndex, ActiveRuleCompleter activeRuleCompleter, RuleMapping mapping, DbClient dbClient, RuleMapper mapper) {
+ public SearchAction(RuleIndex ruleIndex, ActiveRuleCompleter activeRuleCompleter, RuleMapping mapping, DbClient dbClient, RuleMapper mapper) {
this.ruleIndex = ruleIndex;
this.activeRuleCompleter = activeRuleCompleter;
this.mapping = mapping;
org.sonar.server.es.SearchOptions searchQueryContext = mapping.newQueryOptions(SearchOptions.create(request))
.setLimit(context.getLimit())
.setOffset(context.getOffset());
- if (context.getFacets().contains(RuleIndex2.FACET_OLD_DEFAULT)) {
+ if (context.getFacets().contains(RuleIndex.FACET_OLD_DEFAULT)) {
searchQueryContext.addFacets(DEFAULT_FACETS);
} else {
searchQueryContext.addFacets(context.getFacets());
import org.sonar.db.rule.RuleParamDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.qualityprofile.index.ActiveRuleDoc;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex2;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.tester.ServerTester;
DbClient db;
DbSession dbSession;
- ActiveRuleIndex2 index;
+ ActiveRuleIndex index;
RuleActivator ruleActivator;
QProfileCopier copier;
RuleIndexer ruleIndexer;
db = tester.get(DbClient.class);
dbSession = db.openSession(false);
ruleActivator = tester.get(RuleActivator.class);
- index = tester.get(ActiveRuleIndex2.class);
+ index = tester.get(ActiveRuleIndex.class);
copier = tester.get(QProfileCopier.class);
ruleIndexer = tester.get(RuleIndexer.class);
ruleIndexer.setEnabled(true);
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex2;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.tester.MockUserSession;
DbClient db;
DbSession dbSession;
- ActiveRuleIndex2 activeRuleIndex;
+ ActiveRuleIndex activeRuleIndex;
ActiveRuleIndexer activeRuleIndexer;
RuleIndexer ruleIndexer;
QProfileFactory factory;
db = tester.get(DbClient.class);
dbSession = db.openSession(false);
factory = tester.get(QProfileFactory.class);
- activeRuleIndex = tester.get(ActiveRuleIndex2.class);
+ activeRuleIndex = tester.get(ActiveRuleIndex.class);
activeRuleIndexer = tester.get(ActiveRuleIndexer.class);
activeRuleIndexer.setEnabled(true);
ruleIndexer = tester.get(RuleIndexer.class);
import org.sonar.db.qualityprofile.QualityProfileDao;
import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.server.platform.Platform;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex2;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.tester.UserSessionRule;
// Severity and parameter value come back to origin after reset
activeRuleDto = tester.get(ActiveRuleDao.class).selectOrFailByKey(dbSession, activeRuleKey);
assertThat(activeRuleDto.getSeverityString()).isEqualTo(CRITICAL);
- ActiveRule activeRule = tester.get(ActiveRuleIndex2.class).getNullableByKey(activeRuleKey);
+ ActiveRule activeRule = tester.get(ActiveRuleIndex.class).getNullableByKey(activeRuleKey);
assertThat(activeRule.severity()).isEqualTo(CRITICAL);
activeRuleParamDtos = tester.get(ActiveRuleDao.class).selectParamsByActiveRuleKey(dbSession, activeRuleKey);
import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.platform.Platform;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.tester.ServerTester;
assertThat(activeRuleDao.selectByKey(dbSession, activeRuleKey)).isPresent();
// Check in ES
- assertThat(tester.get(RuleIndex2.class).search(new RuleQuery().setActivation(true), new SearchOptions()).getIds()).containsOnly(ruleKey, RuleKey.of("xoo", "x2"));
+ assertThat(tester.get(RuleIndex.class).search(new RuleQuery().setActivation(true), new SearchOptions()).getIds()).containsOnly(ruleKey, RuleKey.of("xoo", "x2"));
tester.get(Platform.class).restart();
assertThat(activeRule.getSeverityString()).isEqualTo(Severity.CRITICAL);
// Check in ES
- assertThat(tester.get(RuleIndex2.class).search(new RuleQuery().setActivation(true), new SearchOptions()).getIds()).containsOnly(ruleKey, RuleKey.of("xoo", "x2"));
+ assertThat(tester.get(RuleIndex.class).search(new RuleQuery().setActivation(true), new SearchOptions()).getIds()).containsOnly(ruleKey, RuleKey.of("xoo", "x2"));
// TODO
// Check ActiveRuleParameters in DB
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.Message;
import org.sonar.server.qualityprofile.index.ActiveRuleDoc;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex2;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.search.QueryContext;
RuleIndexer ruleIndexer;
- ActiveRuleIndex2 activeRuleIndex;
+ ActiveRuleIndex activeRuleIndex;
ActiveRuleIndexer activeRuleIndexer;
QualityProfileDto profileDto;
db = tester.get(DbClient.class);
dbSession = db.openSession(false);
ruleActivator = tester.get(RuleActivator.class);
- activeRuleIndex = tester.get(ActiveRuleIndex2.class);
+ activeRuleIndex = tester.get(ActiveRuleIndex.class);
activeRuleIndexer = tester.get(ActiveRuleIndexer.class);
activeRuleIndexer.setEnabled(true);
ruleIndexer = tester.get(RuleIndexer.class);
// 0. No active rules so far (base case) and plenty rules available
verifyZeroActiveRules(XOO_P1_KEY);
- assertThat(tester.get(RuleIndex2.class)
+ assertThat(tester.get(RuleIndex.class)
.search(new RuleQuery().setRepositories(Arrays.asList("bulk")), new SearchOptions()).getTotal())
.isEqualTo(bulkSize);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.qualityprofile.index;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.api.config.Settings;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
-import org.sonar.db.qualityprofile.ActiveRuleKey;
-import org.sonar.db.rule.RuleTesting;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.qualityprofile.ActiveRule;
-import org.sonar.server.rule.index.RuleDoc;
-import org.sonar.server.rule.index.RuleDocTesting;
-import org.sonar.server.rule.index.RuleIndexDefinition;
-import org.sonar.server.rule.index.RuleIndexer;
-import org.sonar.server.search.FacetValue;
-
-import static java.util.Arrays.asList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.entry;
-import static org.sonar.api.rule.Severity.BLOCKER;
-import static org.sonar.api.rule.Severity.MAJOR;
-import static org.sonar.api.rule.Severity.MINOR;
-import static org.sonar.server.qualityprofile.ActiveRule.Inheritance.INHERITED;
-import static org.sonar.server.qualityprofile.ActiveRule.Inheritance.OVERRIDES;
-import static org.sonar.server.rule.index.RuleDocTesting.newDoc;
-import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX;
-import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE;
-
-public class ActiveRuleIndex2Test {
-
- static final RuleKey RULE_KEY_1 = RuleTesting.XOO_X1;
- static final RuleKey RULE_KEY_2 = RuleTesting.XOO_X2;
-
- static final String QUALITY_PROFILE_KEY1 = "qp1";
- static final String QUALITY_PROFILE_KEY2 = "qp2";
-
- @ClassRule
- public static EsTester tester = new EsTester().addDefinitions(new RuleIndexDefinition(new Settings()));
-
- ActiveRuleIndex2 index;
-
- ActiveRuleIndexer activeRuleIndexer;
- RuleIndexer ruleIndexer;
-
- @Before
- public void setUp() {
- tester.truncateIndices();
- activeRuleIndexer = new ActiveRuleIndexer(null, tester.client());
- ruleIndexer = new RuleIndexer(null, tester.client());
- index = new ActiveRuleIndex2(tester.client());
- }
-
- @Test
- public void count_all_by_quality_profile_key() {
- indexRules(RuleDocTesting.newDoc(RULE_KEY_1));
-
- indexActiveRules(
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)));
-
- // 0. Test base case
- assertThat(tester.countDocuments(INDEX, TYPE_ACTIVE_RULE)).isEqualTo(2);
-
- // 1. Assert by term aggregation;
- assertThat(index.countAllByQualityProfileKey()).containsOnly(entry(QUALITY_PROFILE_KEY1, 1L), entry(QUALITY_PROFILE_KEY2, 1L));
- }
-
- @Test
- public void stats_for_all() {
- indexRules(
- newDoc(RULE_KEY_1),
- newDoc(RULE_KEY_2));
-
- ActiveRuleKey activeRuleKey1 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1);
- ActiveRuleKey activeRuleKey2 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2);
-
- indexActiveRules(
- ActiveRuleDocTesting.newDoc(activeRuleKey1).setSeverity(BLOCKER),
- ActiveRuleDocTesting.newDoc(activeRuleKey2).setSeverity(MINOR),
- // Profile 2 is a child a profile 1
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)).setSeverity(MAJOR)
- .setParentKey(activeRuleKey1.toString()).setInheritance(INHERITED.name()),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_2)).setSeverity(BLOCKER)
- .setParentKey(activeRuleKey2.toString()).setInheritance(OVERRIDES.name()));
-
- // 0. Test base case
- assertThat(tester.countDocuments(INDEX, TYPE_ACTIVE_RULE)).isEqualTo(4);
-
- // 1. Assert by term aggregation;
- Map<String, Multimap<String, FacetValue>> stats = index.getStatsByProfileKeys(ImmutableList.of(QUALITY_PROFILE_KEY1, QUALITY_PROFILE_KEY2));
- assertThat(stats).hasSize(2);
- }
-
- /**
- * SONAR-5844
- */
- @Test
- public void stats_for_all_with_lof_of_profiles() {
- indexRules(RuleDocTesting.newDoc(RULE_KEY_1), RuleDocTesting.newDoc(RULE_KEY_2));
-
- indexActiveRules(
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)));
-
- List<String> profileKeys = new ArrayList<>();
- List<ActiveRuleDoc> docs = new ArrayList<>();
- for (int i = 0; i < 30; i++) {
- String profileKey = "profile-" + i;
- profileKeys.add(profileKey);
- docs.add(ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(profileKey, RULE_KEY_1)).setSeverity(BLOCKER));
- docs.add(ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(profileKey, RULE_KEY_2)).setSeverity(MAJOR));
- }
- indexActiveRules(docs.toArray(new ActiveRuleDoc[]{}));
-
- Map<String, Multimap<String, FacetValue>> stats = index.getStatsByProfileKeys(profileKeys);
- assertThat(stats).hasSize(30);
- }
-
- @Test
- public void get_by_key() {
- indexRules(RuleDocTesting.newDoc(RULE_KEY_1));
- ActiveRuleKey key = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1);
- indexActiveRules(ActiveRuleDocTesting.newDoc(key));
-
- assertThat(index.getNullableByKey(key)).isNotNull();
- assertThat(index.getNullableByKey(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2))).isNull();
- }
-
- @Test
- public void find_active_rules() {
- indexRules(
- RuleDocTesting.newDoc(RULE_KEY_1),
- RuleDocTesting.newDoc(RULE_KEY_2),
- RuleDocTesting.newDoc(RuleKey.of("xoo", "removed")).setStatus(RuleStatus.REMOVED.name())
- );
-
- indexActiveRules(
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2)),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_2)),
- // Removed rule can still be activated for instance when removing the checkstyle plugin, active rules related on checkstyle are not
- // removed
- // because if the plugin is re-install, quality profiles using these rule are not changed.
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RuleKey.of("xoo", "removed")))
- );
-
- // 1. find by rule key
-
- // in es
- List<ActiveRule> activeRules = index.findByRule(RULE_KEY_1);
- assertThat(activeRules).hasSize(1);
- assertThat(activeRules.get(0).key().ruleKey()).isEqualTo(RULE_KEY_1);
-
- activeRules = index.findByRule(RULE_KEY_2);
- assertThat(activeRules).hasSize(2);
- assertThat(activeRules.get(0).key().ruleKey()).isEqualTo(RULE_KEY_2);
-
- activeRules = index.findByRule(RuleKey.of("unknown", "unknown"));
- assertThat(activeRules).isEmpty();
-
- // 2. find by profile
- List<ActiveRuleDoc> activeRuleDocs = Lists.newArrayList(index.findByProfile(QUALITY_PROFILE_KEY1));
- assertThat(activeRuleDocs).hasSize(2);
- assertThat(activeRuleDocs.get(0).key().qProfile()).isEqualTo(QUALITY_PROFILE_KEY1);
- assertThat(activeRuleDocs.get(1).key().qProfile()).isEqualTo(QUALITY_PROFILE_KEY1);
-
- activeRuleDocs = Lists.newArrayList(index.findByProfile(QUALITY_PROFILE_KEY2));
- assertThat(activeRuleDocs).hasSize(1);
- assertThat(activeRuleDocs.get(0).key().qProfile()).isEqualTo(QUALITY_PROFILE_KEY2);
-
- activeRuleDocs = Lists.newArrayList(index.findByProfile("unknown"));
- assertThat(activeRuleDocs).isEmpty();
- }
-
- @Test
- public void find_many_active_rules_by_profile() {
- int nb = 150;
- RuleDoc[] ruleDocs = new RuleDoc[nb];
- ActiveRuleDoc[] activeRuleDocs = new ActiveRuleDoc[nb];
- for (int i = 0; i < nb; i++) {
- RuleKey ruleKey = RuleKey.of("xoo", "S00" + i);
- ruleDocs[i] = RuleDocTesting.newDoc(ruleKey);
- activeRuleDocs[i] = ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, ruleKey));
- }
- indexRules(ruleDocs);
- indexActiveRules(activeRuleDocs);
-
- // verify index
- assertThat(index.findByProfile(QUALITY_PROFILE_KEY1)).hasSize(nb);
- }
-
- @Test
- public void find_many_active_rules_by_rule() {
- indexRules(RuleDocTesting.newDoc(RULE_KEY_1));
-
- int nb = 150;
- ActiveRuleDoc[] activeRuleDocs = new ActiveRuleDoc[nb];
- for (int i = 0; i < nb; i++) {
- activeRuleDocs[i] = ActiveRuleDocTesting.newDoc(ActiveRuleKey.of("qp" + i, RULE_KEY_1));
- }
- indexActiveRules(activeRuleDocs);
-
- // verify index
- assertThat(index.findByRule(RULE_KEY_1)).hasSize(nb);
- }
-
- private void indexActiveRules(ActiveRuleDoc... docs) {
- activeRuleIndexer.index(asList(docs).iterator());
- }
-
- private void indexRules(RuleDoc... rules) {
- ruleIndexer.index(asList(rules).iterator());
- }
-
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.qualityprofile.index;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.db.qualityprofile.ActiveRuleKey;
+import org.sonar.db.rule.RuleTesting;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.qualityprofile.ActiveRule;
+import org.sonar.server.rule.index.RuleDoc;
+import org.sonar.server.rule.index.RuleDocTesting;
+import org.sonar.server.rule.index.RuleIndexDefinition;
+import org.sonar.server.rule.index.RuleIndexer;
+import org.sonar.server.search.FacetValue;
+
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.entry;
+import static org.sonar.api.rule.Severity.BLOCKER;
+import static org.sonar.api.rule.Severity.MAJOR;
+import static org.sonar.api.rule.Severity.MINOR;
+import static org.sonar.server.qualityprofile.ActiveRule.Inheritance.INHERITED;
+import static org.sonar.server.qualityprofile.ActiveRule.Inheritance.OVERRIDES;
+import static org.sonar.server.rule.index.RuleDocTesting.newDoc;
+import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX;
+import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE;
+
+public class ActiveRuleIndexTest {
+
+ static final RuleKey RULE_KEY_1 = RuleTesting.XOO_X1;
+ static final RuleKey RULE_KEY_2 = RuleTesting.XOO_X2;
+
+ static final String QUALITY_PROFILE_KEY1 = "qp1";
+ static final String QUALITY_PROFILE_KEY2 = "qp2";
+
+ @ClassRule
+ public static EsTester tester = new EsTester().addDefinitions(new RuleIndexDefinition(new Settings()));
+
+ ActiveRuleIndex index;
+
+ ActiveRuleIndexer activeRuleIndexer;
+ RuleIndexer ruleIndexer;
+
+ @Before
+ public void setUp() {
+ tester.truncateIndices();
+ activeRuleIndexer = new ActiveRuleIndexer(null, tester.client());
+ ruleIndexer = new RuleIndexer(null, tester.client());
+ index = new ActiveRuleIndex(tester.client());
+ }
+
+ @Test
+ public void count_all_by_quality_profile_key() {
+ indexRules(RuleDocTesting.newDoc(RULE_KEY_1));
+
+ indexActiveRules(
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)));
+
+ // 0. Test base case
+ assertThat(tester.countDocuments(INDEX, TYPE_ACTIVE_RULE)).isEqualTo(2);
+
+ // 1. Assert by term aggregation;
+ assertThat(index.countAllByQualityProfileKey()).containsOnly(entry(QUALITY_PROFILE_KEY1, 1L), entry(QUALITY_PROFILE_KEY2, 1L));
+ }
+
+ @Test
+ public void stats_for_all() {
+ indexRules(
+ newDoc(RULE_KEY_1),
+ newDoc(RULE_KEY_2));
+
+ ActiveRuleKey activeRuleKey1 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1);
+ ActiveRuleKey activeRuleKey2 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2);
+
+ indexActiveRules(
+ ActiveRuleDocTesting.newDoc(activeRuleKey1).setSeverity(BLOCKER),
+ ActiveRuleDocTesting.newDoc(activeRuleKey2).setSeverity(MINOR),
+ // Profile 2 is a child a profile 1
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)).setSeverity(MAJOR)
+ .setParentKey(activeRuleKey1.toString()).setInheritance(INHERITED.name()),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_2)).setSeverity(BLOCKER)
+ .setParentKey(activeRuleKey2.toString()).setInheritance(OVERRIDES.name()));
+
+ // 0. Test base case
+ assertThat(tester.countDocuments(INDEX, TYPE_ACTIVE_RULE)).isEqualTo(4);
+
+ // 1. Assert by term aggregation;
+ Map<String, Multimap<String, FacetValue>> stats = index.getStatsByProfileKeys(ImmutableList.of(QUALITY_PROFILE_KEY1, QUALITY_PROFILE_KEY2));
+ assertThat(stats).hasSize(2);
+ }
+
+ /**
+ * SONAR-5844
+ */
+ @Test
+ public void stats_for_all_with_lof_of_profiles() {
+ indexRules(RuleDocTesting.newDoc(RULE_KEY_1), RuleDocTesting.newDoc(RULE_KEY_2));
+
+ indexActiveRules(
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)));
+
+ List<String> profileKeys = new ArrayList<>();
+ List<ActiveRuleDoc> docs = new ArrayList<>();
+ for (int i = 0; i < 30; i++) {
+ String profileKey = "profile-" + i;
+ profileKeys.add(profileKey);
+ docs.add(ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(profileKey, RULE_KEY_1)).setSeverity(BLOCKER));
+ docs.add(ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(profileKey, RULE_KEY_2)).setSeverity(MAJOR));
+ }
+ indexActiveRules(docs.toArray(new ActiveRuleDoc[]{}));
+
+ Map<String, Multimap<String, FacetValue>> stats = index.getStatsByProfileKeys(profileKeys);
+ assertThat(stats).hasSize(30);
+ }
+
+ @Test
+ public void get_by_key() {
+ indexRules(RuleDocTesting.newDoc(RULE_KEY_1));
+ ActiveRuleKey key = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1);
+ indexActiveRules(ActiveRuleDocTesting.newDoc(key));
+
+ assertThat(index.getNullableByKey(key)).isNotNull();
+ assertThat(index.getNullableByKey(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2))).isNull();
+ }
+
+ @Test
+ public void find_active_rules() {
+ indexRules(
+ RuleDocTesting.newDoc(RULE_KEY_1),
+ RuleDocTesting.newDoc(RULE_KEY_2),
+ RuleDocTesting.newDoc(RuleKey.of("xoo", "removed")).setStatus(RuleStatus.REMOVED.name())
+ );
+
+ indexActiveRules(
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2)),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_2)),
+ // Removed rule can still be activated for instance when removing the checkstyle plugin, active rules related on checkstyle are not
+ // removed
+ // because if the plugin is re-install, quality profiles using these rule are not changed.
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RuleKey.of("xoo", "removed")))
+ );
+
+ // 1. find by rule key
+
+ // in es
+ List<ActiveRule> activeRules = index.findByRule(RULE_KEY_1);
+ assertThat(activeRules).hasSize(1);
+ assertThat(activeRules.get(0).key().ruleKey()).isEqualTo(RULE_KEY_1);
+
+ activeRules = index.findByRule(RULE_KEY_2);
+ assertThat(activeRules).hasSize(2);
+ assertThat(activeRules.get(0).key().ruleKey()).isEqualTo(RULE_KEY_2);
+
+ activeRules = index.findByRule(RuleKey.of("unknown", "unknown"));
+ assertThat(activeRules).isEmpty();
+
+ // 2. find by profile
+ List<ActiveRuleDoc> activeRuleDocs = Lists.newArrayList(index.findByProfile(QUALITY_PROFILE_KEY1));
+ assertThat(activeRuleDocs).hasSize(2);
+ assertThat(activeRuleDocs.get(0).key().qProfile()).isEqualTo(QUALITY_PROFILE_KEY1);
+ assertThat(activeRuleDocs.get(1).key().qProfile()).isEqualTo(QUALITY_PROFILE_KEY1);
+
+ activeRuleDocs = Lists.newArrayList(index.findByProfile(QUALITY_PROFILE_KEY2));
+ assertThat(activeRuleDocs).hasSize(1);
+ assertThat(activeRuleDocs.get(0).key().qProfile()).isEqualTo(QUALITY_PROFILE_KEY2);
+
+ activeRuleDocs = Lists.newArrayList(index.findByProfile("unknown"));
+ assertThat(activeRuleDocs).isEmpty();
+ }
+
+ @Test
+ public void find_many_active_rules_by_profile() {
+ int nb = 150;
+ RuleDoc[] ruleDocs = new RuleDoc[nb];
+ ActiveRuleDoc[] activeRuleDocs = new ActiveRuleDoc[nb];
+ for (int i = 0; i < nb; i++) {
+ RuleKey ruleKey = RuleKey.of("xoo", "S00" + i);
+ ruleDocs[i] = RuleDocTesting.newDoc(ruleKey);
+ activeRuleDocs[i] = ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, ruleKey));
+ }
+ indexRules(ruleDocs);
+ indexActiveRules(activeRuleDocs);
+
+ // verify index
+ assertThat(index.findByProfile(QUALITY_PROFILE_KEY1)).hasSize(nb);
+ }
+
+ @Test
+ public void find_many_active_rules_by_rule() {
+ indexRules(RuleDocTesting.newDoc(RULE_KEY_1));
+
+ int nb = 150;
+ ActiveRuleDoc[] activeRuleDocs = new ActiveRuleDoc[nb];
+ for (int i = 0; i < nb; i++) {
+ activeRuleDocs[i] = ActiveRuleDocTesting.newDoc(ActiveRuleKey.of("qp" + i, RULE_KEY_1));
+ }
+ indexActiveRules(activeRuleDocs);
+
+ // verify index
+ assertThat(index.findByRule(RULE_KEY_1)).hasSize(nb);
+ }
+
+ private void indexActiveRules(ActiveRuleDoc... docs) {
+ activeRuleIndexer.index(asList(docs).iterator());
+ }
+
+ private void indexRules(RuleDoc... rules) {
+ ruleIndexer.index(asList(rules).iterator());
+ }
+
+}
import org.sonar.server.qualityprofile.QProfileTesting;
import org.sonar.server.qualityprofile.RuleActivator;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.tester.ServerTester;
WsTester wsTester;
RuleIndexer ruleIndexer;
ActiveRuleIndexer activeRuleIndexer;
- RuleIndex2 ruleIndex;
+ RuleIndex ruleIndex;
@Before
public void setUp() {
ruleIndexer.setEnabled(true);
activeRuleIndexer = tester.get(ActiveRuleIndexer.class);
activeRuleIndexer.setEnabled(true);
- ruleIndex = tester.get(RuleIndex2.class);
+ ruleIndex = tester.get(RuleIndex.class);
userSessionRule.login("gandalf").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
}
import org.sonar.server.qualityprofile.QProfileLoader;
import org.sonar.server.qualityprofile.QProfileTesting;
import org.sonar.server.qualityprofile.index.ActiveRuleDoc;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex2;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.ws.WsTester;
import org.sonar.server.ws.WsTester.Result;
ProfileExporter exporter1 = newExporter("polop");
ProfileExporter exporter2 = newExporter("palap");
- ActiveRuleIndex2 activeRuleIndex = mock(ActiveRuleIndex2.class);
+ ActiveRuleIndex activeRuleIndex = mock(ActiveRuleIndex.class);
when(activeRuleIndex.findByProfile(Matchers.anyString())).thenReturn(Sets.<ActiveRuleDoc>newHashSet().iterator());
- exporters = new QProfileExporters(new QProfileLoader(dbClient, activeRuleIndex, mock(RuleIndex2.class)), null, null, new ProfileExporter[] {exporter1, exporter2}, null);
+ exporters = new QProfileExporters(new QProfileLoader(dbClient, activeRuleIndex, mock(RuleIndex.class)), null, null, new ProfileExporter[] {exporter1, exporter2}, null);
wsTester = new WsTester(new QProfilesWs(mock(RuleActivationActions.class),
mock(BulkRuleActivationActions.class),
mock(ProjectAssociationActions.class),
import org.sonar.server.qualityprofile.QProfileFactory;
import org.sonar.server.qualityprofile.QProfileName;
import org.sonar.server.qualityprofile.QProfileTesting;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex2;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.rule.ws.SearchAction;
assertThat(db.activeRuleDao().selectByProfileKey(session, profile.getKey())).hasSize(0);
// 2. Assert ActiveRule with BLOCKER severity
- assertThat(tester.get(RuleIndex2.class).search(
+ assertThat(tester.get(RuleIndex.class).search(
new RuleQuery().setSeverities(ImmutableSet.of("BLOCKER")),
new SearchOptions()).getIds()).hasSize(2);
session.commit();
// 2. Assert ActiveRule with MINOR severity
- assertThat(tester.get(ActiveRuleIndex2.class).findByRule(rule0.getKey()).get(0).severity()).isEqualTo("MINOR");
+ assertThat(tester.get(ActiveRuleIndex.class).findByRule(rule0.getKey()).get(0).severity()).isEqualTo("MINOR");
}
import org.sonar.server.qualityprofile.QProfileService;
import org.sonar.server.qualityprofile.QProfileTesting;
import org.sonar.server.qualityprofile.RuleActivation;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.tester.UserSessionRule;
DbClient db = TESTER.get(DbClient.class);
DbSession dbSession = TESTER.get(DbClient.class).openSession(false);
- RuleIndex2 ruleIndex = TESTER.get(RuleIndex2.class);
+ RuleIndex ruleIndex = TESTER.get(RuleIndex.class);
RuleDao ruleDao = db.ruleDao();
@Before
db = TESTER.get(DbClient.class);
dbSession = TESTER.get(DbClient.class).openSession(false);
dbSession.clearCache();
- ruleIndex = TESTER.get(RuleIndex2.class);
+ ruleIndex = TESTER.get(RuleIndex.class);
}
@Test
import org.sonar.server.es.EsTester;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.qualityprofile.RuleActivator;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.rule.index.RuleQuery;
RuleIndexer ruleIndexer;
- RuleIndex2 ruleIndex;
+ RuleIndex ruleIndex;
@Before
public void before() {
when(system.now()).thenReturn(DATE1.getTime());
ruleIndexer = new RuleIndexer(dbClient, esTester.client());
ruleIndexer.setEnabled(true);
- ruleIndex = new RuleIndex2(esTester.client());
+ ruleIndex = new RuleIndex(esTester.client());
}
@Test
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.exceptions.BadRequestException;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.tester.ServerTester;
DbClient db = tester.get(DbClient.class);
RuleDao dao = tester.get(RuleDao.class);
RuleCreator creator = tester.get(RuleCreator.class);
- RuleIndex2 ruleIndex = tester.get(RuleIndex2.class);
+ RuleIndex ruleIndex = tester.get(RuleIndex.class);
RuleIndexer ruleIndexer;
@Before
import org.sonar.server.qualityprofile.RuleActivation;
import org.sonar.server.qualityprofile.RuleActivator;
import org.sonar.server.qualityprofile.index.ActiveRuleDoc;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex2;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.tester.UserSessionRule;
DbClient db = tester.get(DbClient.class);
RuleDao dao = tester.get(RuleDao.class);
- RuleIndex2 index = tester.get(RuleIndex2.class);
+ RuleIndex index = tester.get(RuleIndex.class);
RuleDeleter deleter = tester.get(RuleDeleter.class);
DbSession dbSession = tester.get(DbClient.class).openSession(false);
assertThat(customRuleReloaded.getStatus()).isEqualTo(RuleStatus.REMOVED);
// Verify there's no more active rule from custom rule
- List<ActiveRuleDoc> activeRules = Lists.newArrayList(tester.get(ActiveRuleIndex2.class).findByProfile(profileDto.getKey()));
+ List<ActiveRuleDoc> activeRules = Lists.newArrayList(tester.get(ActiveRuleIndex.class).findByProfile(profileDto.getKey()));
assertThat(activeRules).isEmpty();
// Verify in index
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.exceptions.UnauthorizedException;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.tester.ServerTester;
public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
RuleDao dao = tester.get(RuleDao.class);
- RuleIndex2 index = tester.get(RuleIndex2.class);
+ RuleIndex index = tester.get(RuleIndex.class);
RuleService service = tester.get(RuleService.class);
DbSession dbSession;
RuleIndexer ruleIndexer;
import org.sonar.server.qualityprofile.QProfileTesting;
import org.sonar.server.qualityprofile.RuleActivation;
import org.sonar.server.qualityprofile.RuleActivator;
-import org.sonar.server.rule.index.RuleIndex2;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.tester.UserSessionRule;
DbClient db = tester.get(DbClient.class);
RuleDao ruleDao = tester.get(RuleDao.class);
DbSession dbSession = db.openSession(false);
- RuleIndex2 ruleIndex = tester.get(RuleIndex2.class);
+ RuleIndex ruleIndex = tester.get(RuleIndex.class);
RuleUpdater underTest = tester.get(RuleUpdater.class);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.rule.index;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.api.config.Settings;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
-import org.sonar.db.qualityprofile.ActiveRuleKey;
-import org.sonar.db.rule.RuleTesting;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.es.SearchIdResult;
-import org.sonar.server.es.SearchOptions;
-import org.sonar.server.qualityprofile.index.ActiveRuleDoc;
-import org.sonar.server.qualityprofile.index.ActiveRuleDocTesting;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
-
-import static java.util.Arrays.asList;
-import static java.util.Collections.singleton;
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.data.MapEntry.entry;
-import static org.junit.Assert.fail;
-import static org.sonar.api.rule.Severity.BLOCKER;
-import static org.sonar.api.rule.Severity.CRITICAL;
-import static org.sonar.api.rule.Severity.INFO;
-import static org.sonar.api.rule.Severity.MAJOR;
-import static org.sonar.api.rule.Severity.MINOR;
-import static org.sonar.server.qualityprofile.ActiveRule.Inheritance.INHERITED;
-import static org.sonar.server.qualityprofile.ActiveRule.Inheritance.OVERRIDES;
-import static org.sonar.server.rule.index.RuleDocTesting.newDoc;
-import static org.sonar.server.rule.index.RuleIndex2.FACET_LANGUAGES;
-import static org.sonar.server.rule.index.RuleIndex2.FACET_REPOSITORIES;
-import static org.sonar.server.rule.index.RuleIndex2.FACET_TAGS;
-import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX;
-import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE;
-
-public class RuleIndex2Test {
-
- static final RuleKey RULE_KEY_1 = RuleTesting.XOO_X1;
- static final RuleKey RULE_KEY_2 = RuleTesting.XOO_X2;
- static final RuleKey RULE_KEY_3 = RuleTesting.XOO_X3;
- static final RuleKey RULE_KEY_4 = RuleKey.of("xoo", "x4");
-
- static final String QUALITY_PROFILE_KEY1 = "qp1";
- static final String QUALITY_PROFILE_KEY2 = "qp2";
-
- @ClassRule
- public static EsTester tester = new EsTester().addDefinitions(new RuleIndexDefinition(new Settings()));
-
- RuleIndex2 index;
-
- RuleIndexer ruleIndexer;
- ActiveRuleIndexer activeRuleIndexer;
-
- @Before
- public void setUp() {
- tester.truncateIndices();
- ruleIndexer = new RuleIndexer(null, tester.client());
- activeRuleIndexer = new ActiveRuleIndexer(null, tester.client());
- index = new RuleIndex2(tester.client());
- }
-
- @Test
- public void search_all_rules() {
- indexRules(
- newDoc(RuleKey.of("javascript", "S001")),
- newDoc(RuleKey.of("java", "S002")));
-
- SearchIdResult results = index.search(new RuleQuery(), new SearchOptions());
-
- assertThat(results.getTotal()).isEqualTo(2);
- assertThat(results.getIds()).hasSize(2);
- }
-
- @Test
- public void search_key_by_query() {
- indexRules(
- newDoc(RuleKey.of("javascript", "X001")),
- newDoc(RuleKey.of("cobol", "X001")),
- newDoc(RuleKey.of("php", "S002")));
-
- // key
- RuleQuery query = new RuleQuery().setQueryText("X001");
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
-
- // partial key does not match
- query = new RuleQuery().setQueryText("X00");
- assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
-
- // repo:key -> nice-to-have !
- query = new RuleQuery().setQueryText("javascript:X001");
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(1);
- }
-
- @Test
- public void filter_by_key() {
- indexRules(
- newDoc(RuleKey.of("javascript", "X001")),
- newDoc(RuleKey.of("cobol", "X001")),
- newDoc(RuleKey.of("php", "S002")));
-
- // key
- RuleQuery query = new RuleQuery().setKey(RuleKey.of("javascript", "X001").toString());
-
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(1);
-
- // partial key does not match
- query = new RuleQuery().setKey("X001");
- assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
- }
-
- @Test
- public void search_name_by_query() {
- indexRules(newDoc(RuleKey.of("javascript", "S001"))
- .setName("testing the partial match and matching of rule"));
-
- // substring
- RuleQuery query = new RuleQuery().setQueryText("test");
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(1);
-
- // substring
- query = new RuleQuery().setQueryText("partial match");
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(1);
-
- // case-insensitive
- query = new RuleQuery().setQueryText("TESTING");
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(1);
-
- // not found
- query = new RuleQuery().setQueryText("not present");
- assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
- }
-
- @Test
- public void search_name_with_protected_chars() {
- String nameWithProtectedChars = "ja#va&sc\"r:ipt";
-
- indexRules(newDoc(RuleKey.of("javascript", "S001"))
- .setName(nameWithProtectedChars));
-
- RuleQuery protectedCharsQuery = new RuleQuery().setQueryText(nameWithProtectedChars);
- List<RuleKey> results = index.search(protectedCharsQuery, new SearchOptions()).getIds();
- assertThat(results).containsOnly(RuleKey.of("javascript", "S001"));
- }
-
- @Test
- public void search_by_any_of_repositories() {
- indexRules(
- newDoc(RuleKey.of("findbugs", "S001")),
- newDoc(RuleKey.of("pmd", "S002")));
-
- RuleQuery query = new RuleQuery().setRepositories(asList("checkstyle", "pmd"));
- SearchIdResult results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("pmd", "S002"));
-
- // no results
- query = new RuleQuery().setRepositories(singletonList("checkstyle"));
- assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
-
- // empty list => no filter
- query = new RuleQuery().setRepositories(Collections.<String>emptyList());
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
- }
-
- @Test
- public void search_by_tag() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setAllTags(singleton("tag1")),
- newDoc(RuleKey.of("java", "S002")).setAllTags(singleton("tag2")));
-
- // find all
- RuleQuery query = new RuleQuery();
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
-
- // tag1 in query
- query = new RuleQuery().setQueryText("tag1");
- assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RuleKey.of("java", "S001"));
-
- // tag1 and tag2 in query
- query = new RuleQuery().setQueryText("tag1 tag2");
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
-
- // tag2 in filter
- query = new RuleQuery().setTags(ImmutableSet.of("tag2"));
- assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RuleKey.of("java", "S002"));
-
- // tag2 in filter and tag1 tag2 in query
- query = new RuleQuery().setTags(ImmutableSet.of("tag2")).setQueryText("tag1");
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(0);
-
- // tag2 in filter and tag1 in query
- query = new RuleQuery().setTags(ImmutableSet.of("tag2")).setQueryText("tag1 tag2");
- assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RuleKey.of("java", "S002"));
-
- // null list => no filter
- query = new RuleQuery().setTags(Collections.<String>emptySet());
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
-
- // null list => no filter
- query = new RuleQuery().setTags(null);
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
- }
-
- @Test
- public void search_by_is_template() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setIsTemplate(false),
- newDoc(RuleKey.of("java", "S002")).setIsTemplate(true));
-
- // find all
- RuleQuery query = new RuleQuery();
- SearchIdResult results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).hasSize(2);
-
- // Only template
- query = new RuleQuery().setIsTemplate(true);
- results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S002"));
-
- // Only not template
- query = new RuleQuery().setIsTemplate(false);
- results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S001"));
-
- // null => no filter
- query = new RuleQuery().setIsTemplate(null);
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
- }
-
- @Test
- public void search_by_template_key() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setIsTemplate(true),
- newDoc(RuleKey.of("java", "S001_MY_CUSTOM")).setTemplateKey("java:S001"));
-
- // find all
- RuleQuery query = new RuleQuery();
- SearchIdResult results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).hasSize(2);
-
- // Only custom rule
- query = new RuleQuery().setTemplateKey("java:S001");
- results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S001_MY_CUSTOM"));
-
- // null => no filter
- query = new RuleQuery().setTemplateKey(null);
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
- }
-
- @Test
- public void search_by_any_of_languages() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setLanguage("java"),
- newDoc(RuleKey.of("javascript", "S002")).setLanguage("js"));
-
- RuleQuery query = new RuleQuery().setLanguages(asList("cobol", "js"));
- SearchIdResult results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("javascript", "S002"));
-
- // no results
- query = new RuleQuery().setLanguages(singletonList("cpp"));
- assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
-
- // empty list => no filter
- query = new RuleQuery().setLanguages(Collections.<String>emptyList());
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
-
- // null list => no filter
- query = new RuleQuery().setLanguages(null);
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
- }
-
- @Test
- public void search_by_any_of_severities() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setSeverity(BLOCKER),
- newDoc(RuleKey.of("java", "S002")).setSeverity(INFO));
-
- RuleQuery query = new RuleQuery().setSeverities(asList(INFO, MINOR));
- SearchIdResult results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S002"));
-
- // no results
- query = new RuleQuery().setSeverities(singletonList(MINOR));
- assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
-
- // empty list => no filter
- query = new RuleQuery().setSeverities(Collections.<String>emptyList());
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
-
- // null list => no filter
- query = new RuleQuery().setSeverities();
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
- }
-
- @Test
- public void search_by_any_of_statuses() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setStatus(RuleStatus.BETA.name()),
- newDoc(RuleKey.of("java", "S002")).setStatus(RuleStatus.READY.name()));
-
- RuleQuery query = new RuleQuery().setStatuses(asList(RuleStatus.DEPRECATED, RuleStatus.READY));
- SearchIdResult<RuleKey> results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S002"));
-
- // no results
- query = new RuleQuery().setStatuses(singletonList(RuleStatus.DEPRECATED));
- assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
-
- // empty list => no filter
- query = new RuleQuery().setStatuses(Collections.<RuleStatus>emptyList());
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
-
- // null list => no filter
- query = new RuleQuery().setStatuses(null);
- assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
- }
-
- @Test
- public void search_by_profile() throws InterruptedException {
- indexRules(
- newDoc(RULE_KEY_1),
- newDoc(RULE_KEY_2),
- newDoc(RULE_KEY_3));
-
- indexActiveRules(
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2)));
-
- assertThat(tester.countDocuments(INDEX, TYPE_ACTIVE_RULE)).isEqualTo(3);
-
- // 1. get all active rules.
- assertThat(index.search(new RuleQuery().setActivation(true), new SearchOptions()).getIds())
- .containsOnly(RULE_KEY_1, RULE_KEY_2);
-
- // 2. get all inactive rules.
- assertThat(index.search(new RuleQuery().setActivation(false), new SearchOptions()).getIds())
- .containsOnly(RULE_KEY_3);
-
- // 3. get all rules not active on profile
- assertThat(index.search(new RuleQuery().setActivation(false).setQProfileKey(QUALITY_PROFILE_KEY2), new SearchOptions()).getIds())
- .containsOnly(RULE_KEY_2, RULE_KEY_3);
-
- // 4. get all active rules on profile
- assertThat(index.search(new RuleQuery().setActivation(true).setQProfileKey(QUALITY_PROFILE_KEY2), new SearchOptions()).getIds())
- .containsOnly(RULE_KEY_1);
- }
-
- @Test
- public void search_by_profile_and_inheritance() {
- indexRules(
- newDoc(RULE_KEY_1),
- newDoc(RULE_KEY_2),
- newDoc(RULE_KEY_3),
- newDoc(RULE_KEY_4));
-
- ActiveRuleKey activeRuleKey1 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1);
- ActiveRuleKey activeRuleKey2 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2);
- ActiveRuleKey activeRuleKey3 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_3);
-
- indexActiveRules(
- ActiveRuleDocTesting.newDoc(activeRuleKey1),
- ActiveRuleDocTesting.newDoc(activeRuleKey2),
- ActiveRuleDocTesting.newDoc(activeRuleKey3),
- // Profile 2 is a child a profile 1
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1))
- .setParentKey(activeRuleKey1.toString()).setInheritance(INHERITED.name()),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_2))
- .setParentKey(activeRuleKey2.toString()).setInheritance(OVERRIDES.name()),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_3))
- .setParentKey(activeRuleKey3.toString()).setInheritance(INHERITED.name()));
-
- // 0. get all rules
- assertThat(index.search(new RuleQuery(), new SearchOptions()).getIds())
- .hasSize(4);
-
- // 1. get all active rules
- assertThat(index.search(new RuleQuery()
- .setActivation(true), new SearchOptions()).getIds())
- .hasSize(3);
-
- // 2. get all inactive rules.
- assertThat(index.search(new RuleQuery()
- .setActivation(false), new SearchOptions()).getIds())
- .containsOnly(RULE_KEY_4);
-
- // 3. get Inherited Rules on profile1
- assertThat(index.search(new RuleQuery().setActivation(true)
- .setQProfileKey(QUALITY_PROFILE_KEY1)
- .setInheritance(ImmutableSet.of(INHERITED.name())),
- new SearchOptions()).getIds())
- .isEmpty();
-
- // 4. get Inherited Rules on profile2
- assertThat(index.search(new RuleQuery().setActivation(true)
- .setQProfileKey(QUALITY_PROFILE_KEY2)
- .setInheritance(ImmutableSet.of(INHERITED.name())),
- new SearchOptions()).getIds())
- .hasSize(2);
-
- // 5. get Overridden Rules on profile1
- assertThat(index.search(new RuleQuery().setActivation(true)
- .setQProfileKey(QUALITY_PROFILE_KEY1)
- .setInheritance(ImmutableSet.of(OVERRIDES.name())),
- new SearchOptions()).getIds())
- .isEmpty();
-
- // 6. get Overridden Rules on profile2
- assertThat(index.search(new RuleQuery().setActivation(true)
- .setQProfileKey(QUALITY_PROFILE_KEY2)
- .setInheritance(ImmutableSet.of(OVERRIDES.name())),
- new SearchOptions()).getIds())
- .hasSize(1);
-
- // 7. get Inherited AND Overridden Rules on profile1
- assertThat(index.search(new RuleQuery().setActivation(true)
- .setQProfileKey(QUALITY_PROFILE_KEY1)
- .setInheritance(ImmutableSet.of(INHERITED.name(), OVERRIDES.name())),
- new SearchOptions()).getIds())
- .isEmpty();
-
- // 8. get Inherited AND Overridden Rules on profile2
- assertThat(index.search(new RuleQuery().setActivation(true)
- .setQProfileKey(QUALITY_PROFILE_KEY2)
- .setInheritance(ImmutableSet.of(INHERITED.name(), OVERRIDES.name())),
- new SearchOptions()).getIds())
- .hasSize(3);
- }
-
- @Test
- public void search_by_profile_and_active_severity() {
- indexRules(
- newDoc(RULE_KEY_1).setSeverity(MAJOR),
- newDoc(RULE_KEY_2).setSeverity(MINOR),
- newDoc(RULE_KEY_3).setSeverity(INFO));
-
- indexActiveRules(
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)).setSeverity(BLOCKER),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)).setSeverity(BLOCKER),
- ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2)).setSeverity(CRITICAL));
-
- // 1. get all active rules.
- assertThat(index.search(new RuleQuery().setActivation(true).setQProfileKey(QUALITY_PROFILE_KEY1), new SearchOptions()).getIds())
- .hasSize(2);
-
- // 2. get rules with active severity critical.
- SearchIdResult<RuleKey> result = index.search(new RuleQuery().setActivation(true)
- .setQProfileKey(QUALITY_PROFILE_KEY1).setActiveSeverities(singletonList(CRITICAL)),
- new SearchOptions().addFacets(singletonList(RuleIndex2.FACET_ACTIVE_SEVERITIES)));
- assertThat(result.getIds()).containsOnly(RULE_KEY_2);
-
- // check stickyness of active severity facet
- assertThat(result.getFacets().get(RuleIndex2.FACET_ACTIVE_SEVERITIES)).containsOnly(entry(BLOCKER, 1L), entry(CRITICAL, 1L));
-
- // 3. count activation severities of all active rules
- result = index.search(new RuleQuery(), new SearchOptions().addFacets(singletonList(RuleIndex2.FACET_ACTIVE_SEVERITIES)));
- assertThat(result.getIds()).hasSize(3);
- assertThat(result.getFacets().get(RuleIndex2.FACET_ACTIVE_SEVERITIES)).containsOnly(entry(BLOCKER, 2L), entry(CRITICAL, 1L));
- }
-
- @Test
- public void all_tags() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setAllTags(asList("tag1", "sys1", "sys2")),
- newDoc(RuleKey.of("java", "S002")).setAllTags(asList("tag2")));
-
- assertThat(index.terms(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, null, 10)).containsOnly("tag1", "tag2", "sys1", "sys2");
- }
-
- @Test
- public void available_since() throws InterruptedException {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setCreatedAt(1000L),
- newDoc(RuleKey.of("java", "S002")).setCreatedAt(2000L));
-
- // 0. find all rules;
- assertThat(index.search(new RuleQuery(), new SearchOptions()).getIds()).hasSize(2);
-
- // 1. find all rules available since a date;
- RuleQuery availableSinceQuery = new RuleQuery().setAvailableSince(2000L);
- assertThat(index.search(availableSinceQuery, new SearchOptions()).getIds()).containsOnly(RuleKey.of("java", "S002"));
-
- // 2. find no new rules since tomorrow.
- RuleQuery availableSinceNowQuery = new RuleQuery().setAvailableSince(3000L);
- assertThat(index.search(availableSinceNowQuery, new SearchOptions()).getIds()).hasSize(0);
- }
-
- @Test
- public void global_facet_on_repositories_and_tags() {
- indexRules(
- newDoc(RuleKey.of("php", "S001")).setAllTags(singletonList("sysTag")),
- newDoc(RuleKey.of("php", "S002")).setAllTags(singletonList("tag1")),
- newDoc(RuleKey.of("javascript", "S002")).setAllTags(asList("tag1", "tag2")));
-
- // should not have any facet!
- RuleQuery query = new RuleQuery();
- SearchIdResult result = index.search(query, new SearchOptions());
- assertThat(result.getFacets().getAll()).isEmpty();
-
- // should not have any facet on non matching query!
- result = index.search(new RuleQuery().setQueryText("aeiou"), new SearchOptions().addFacets(singletonList("repositories")));
- assertThat(result.getFacets().getAll()).hasSize(1);
- assertThat(result.getFacets().getAll().get("repositories")).isEmpty();
-
- // Repositories Facet is preset
- result = index.search(query, new SearchOptions().addFacets(asList("repositories", "tags")));
- assertThat(result.getFacets()).isNotNull();
- assertThat(result.getFacets().getAll()).hasSize(2);
-
- // Verify the value of a given facet
- Map<String, Long> repoFacets = result.getFacets().get("repositories");
- assertThat(repoFacets).containsOnly(entry("php", 2L), entry("javascript", 1L));
-
- // Check that tag facet has both Tags and SystemTags values
- Map<String, Long> tagFacets = result.getFacets().get("tags");
- assertThat(tagFacets).containsOnly(entry("tag1", 2L), entry("sysTag", 1L), entry("tag2", 1L));
- }
-
- @Test
- public void sticky_facets() {
- indexRules(
- newDoc(RuleKey.of("xoo", "S001")).setLanguage("java").setAllTags(Collections.<String>emptyList()),
- newDoc(RuleKey.of("xoo", "S002")).setLanguage("java").setAllTags(Collections.<String>emptyList()),
- newDoc(RuleKey.of("xoo", "S003")).setLanguage("java").setAllTags(asList("T1", "T2")),
- newDoc(RuleKey.of("xoo", "S011")).setLanguage("cobol").setAllTags(Collections.<String>emptyList()),
- newDoc(RuleKey.of("xoo", "S012")).setLanguage("cobol").setAllTags(Collections.<String>emptyList()),
- newDoc(RuleKey.of("foo", "S013")).setLanguage("cobol").setAllTags(asList("T3", "T4")),
- newDoc(RuleKey.of("foo", "S111")).setLanguage("cpp").setAllTags(Collections.<String>emptyList()),
- newDoc(RuleKey.of("foo", "S112")).setLanguage("cpp").setAllTags(Collections.<String>emptyList()),
- newDoc(RuleKey.of("foo", "S113")).setLanguage("cpp").setAllTags(asList("T2", "T3")));
-
- // 0 assert Base
- assertThat(index.search(new RuleQuery(), new SearchOptions()).getIds()).hasSize(9);
-
- // 1 Facet with no filters at all
- SearchIdResult result = index.search(new RuleQuery(), new SearchOptions().addFacets(asList("languages", "repositories", "tags")));
- assertThat(result.getFacets().getAll()).hasSize(3);
- assertThat(result.getFacets().getAll().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java", "cobol");
- assertThat(result.getFacets().getAll().get(FACET_REPOSITORIES).keySet()).containsOnly("xoo", "foo");
- assertThat(result.getFacets().getAll().get(FACET_TAGS).keySet()).containsOnly("T1", "T2", "T3", "T4");
-
- // 2 Facet with a language filter
- // -- lang facet should still have all language
- result = index.search(new RuleQuery().setLanguages(ImmutableList.of("cpp"))
- , new SearchOptions().addFacets(asList("languages", "repositories", "tags")));
- assertThat(result.getIds()).hasSize(3);
- assertThat(result.getFacets().getAll()).hasSize(3);
- assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java", "cobol");
-
- // 3 facet with 2 filters
- // -- lang facet for tag T2
- // -- tag facet for lang cpp
- // -- repository for cpp & T2
- result = index.search(new RuleQuery()
- .setLanguages(ImmutableList.of("cpp"))
- .setTags(ImmutableList.of("T2"))
- , new SearchOptions().addFacets(asList("languages", "repositories", "tags")));
- assertThat(result.getIds()).hasSize(1);
- assertThat(result.getFacets().getAll()).hasSize(3);
- assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java");
- assertThat(result.getFacets().get(FACET_REPOSITORIES).keySet()).containsOnly("foo");
- assertThat(result.getFacets().get(FACET_TAGS).keySet()).containsOnly("T2", "T3");
-
- // 4 facet with 2 filters
- // -- lang facet for tag T2
- // -- tag facet for lang cpp & java
- // -- repository for (cpp || java) & T2
- result = index.search(new RuleQuery()
- .setLanguages(ImmutableList.of("cpp", "java"))
- .setTags(ImmutableList.of("T2"))
- , new SearchOptions().addFacets(asList("languages", "repositories", "tags")));
- assertThat(result.getIds()).hasSize(2);
- assertThat(result.getFacets().getAll()).hasSize(3);
- assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java");
- assertThat(result.getFacets().get(FACET_REPOSITORIES).keySet()).containsOnly("foo", "xoo");
- assertThat(result.getFacets().get(FACET_TAGS).keySet()).containsOnly("T1", "T2", "T3");
- }
-
- @Test
- public void sort_by_name() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setName("abcd"),
- newDoc(RuleKey.of("java", "S002")).setName("ABC"),
- newDoc(RuleKey.of("java", "S003")).setName("FGH"));
-
- // ascending
- RuleQuery query = new RuleQuery().setSortField(RuleIndexDefinition.FIELD_RULE_NAME);
- SearchIdResult<RuleKey> results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsExactly(RuleKey.of("java", "S002"), RuleKey.of("java", "S001"), RuleKey.of("java", "S003"));
-
- // descending
- query = new RuleQuery().setSortField(RuleIndexDefinition.FIELD_RULE_NAME).setAscendingSort(false);
- results = index.search(query, new SearchOptions());
- assertThat(results.getIds()).containsExactly(RuleKey.of("java", "S003"), RuleKey.of("java", "S001"), RuleKey.of("java", "S002"));
- }
-
- @Test
- public void default_sort_is_by_updated_at_desc() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")).setCreatedAt(1000L).setUpdatedAt(1000L),
- newDoc(RuleKey.of("java", "S002")).setCreatedAt(1000L).setUpdatedAt(3000L),
- newDoc(RuleKey.of("java", "S003")).setCreatedAt(1000L).setUpdatedAt(2000L));
-
- SearchIdResult<RuleKey> results = index.search(new RuleQuery(), new SearchOptions());
- assertThat(results.getIds()).containsExactly(RuleKey.of("java", "S002"), RuleKey.of("java", "S003"), RuleKey.of("java", "S001"));
- }
-
- @Test
- public void fail_sort_by_language() {
- try {
- // Sorting on a field not tagged as sortable
- new RuleQuery().setSortField(RuleIndexDefinition.FIELD_RULE_LANGUAGE);
- fail();
- } catch (IllegalStateException e) {
- assertThat(e).hasMessage("Field 'lang' is not sortable");
- }
- }
-
- @Test
- public void paging() {
- indexRules(
- newDoc(RuleKey.of("java", "S001")),
- newDoc(RuleKey.of("java", "S002")),
- newDoc(RuleKey.of("java", "S003")));
-
- // from 0 to 1 included
- SearchOptions options = new SearchOptions();
- options.setOffset(0).setLimit(2);
- SearchIdResult results = index.search(new RuleQuery(), options);
- assertThat(results.getTotal()).isEqualTo(3);
- assertThat(results.getIds()).hasSize(2);
-
- // from 0 to 9 included
- options.setOffset(0).setLimit(10);
- results = index.search(new RuleQuery(), options);
- assertThat(results.getTotal()).isEqualTo(3);
- assertThat(results.getIds()).hasSize(3);
-
- // from 2 to 11 included
- options.setOffset(2).setLimit(10);
- results = index.search(new RuleQuery(), options);
- assertThat(results.getTotal()).isEqualTo(3);
- assertThat(results.getIds()).hasSize(1);
-
- // from 2 to 11 included
- options.setOffset(2).setLimit(0);
- results = index.search(new RuleQuery(), options);
- assertThat(results.getTotal()).isEqualTo(3);
- assertThat(results.getIds()).hasSize(1);
- }
-
- @Test
- public void search_all_keys_by_query() {
- indexRules(
- newDoc(RuleKey.of("javascript", "X001")),
- newDoc(RuleKey.of("cobol", "X001")),
- newDoc(RuleKey.of("php", "S002")));
-
- // key
- assertThat(index.searchAll(new RuleQuery().setQueryText("X001"))).hasSize(2);
-
- // partial key does not match
- assertThat(index.searchAll(new RuleQuery().setQueryText("X00"))).isEmpty();
-
- // repo:key -> nice-to-have !
- assertThat(index.searchAll(new RuleQuery().setQueryText("javascript:X001"))).hasSize(1);
- }
-
- private void indexRules(RuleDoc... rules) {
- ruleIndexer.index(asList(rules).iterator());
- }
-
- private void indexActiveRules(ActiveRuleDoc... docs) {
- activeRuleIndexer.index(asList(docs).iterator());
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.rule.index;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.db.qualityprofile.ActiveRuleKey;
+import org.sonar.db.rule.RuleTesting;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.es.SearchIdResult;
+import org.sonar.server.es.SearchOptions;
+import org.sonar.server.qualityprofile.index.ActiveRuleDoc;
+import org.sonar.server.qualityprofile.index.ActiveRuleDocTesting;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singleton;
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.data.MapEntry.entry;
+import static org.junit.Assert.fail;
+import static org.sonar.api.rule.Severity.BLOCKER;
+import static org.sonar.api.rule.Severity.CRITICAL;
+import static org.sonar.api.rule.Severity.INFO;
+import static org.sonar.api.rule.Severity.MAJOR;
+import static org.sonar.api.rule.Severity.MINOR;
+import static org.sonar.server.qualityprofile.ActiveRule.Inheritance.INHERITED;
+import static org.sonar.server.qualityprofile.ActiveRule.Inheritance.OVERRIDES;
+import static org.sonar.server.rule.index.RuleDocTesting.newDoc;
+import static org.sonar.server.rule.index.RuleIndex.FACET_LANGUAGES;
+import static org.sonar.server.rule.index.RuleIndex.FACET_REPOSITORIES;
+import static org.sonar.server.rule.index.RuleIndex.FACET_TAGS;
+import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX;
+import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE;
+
+public class RuleIndexTest {
+
+ static final RuleKey RULE_KEY_1 = RuleTesting.XOO_X1;
+ static final RuleKey RULE_KEY_2 = RuleTesting.XOO_X2;
+ static final RuleKey RULE_KEY_3 = RuleTesting.XOO_X3;
+ static final RuleKey RULE_KEY_4 = RuleKey.of("xoo", "x4");
+
+ static final String QUALITY_PROFILE_KEY1 = "qp1";
+ static final String QUALITY_PROFILE_KEY2 = "qp2";
+
+ @ClassRule
+ public static EsTester tester = new EsTester().addDefinitions(new RuleIndexDefinition(new Settings()));
+
+ RuleIndex index;
+
+ RuleIndexer ruleIndexer;
+ ActiveRuleIndexer activeRuleIndexer;
+
+ @Before
+ public void setUp() {
+ tester.truncateIndices();
+ ruleIndexer = new RuleIndexer(null, tester.client());
+ activeRuleIndexer = new ActiveRuleIndexer(null, tester.client());
+ index = new RuleIndex(tester.client());
+ }
+
+ @Test
+ public void search_all_rules() {
+ indexRules(
+ newDoc(RuleKey.of("javascript", "S001")),
+ newDoc(RuleKey.of("java", "S002")));
+
+ SearchIdResult results = index.search(new RuleQuery(), new SearchOptions());
+
+ assertThat(results.getTotal()).isEqualTo(2);
+ assertThat(results.getIds()).hasSize(2);
+ }
+
+ @Test
+ public void search_key_by_query() {
+ indexRules(
+ newDoc(RuleKey.of("javascript", "X001")),
+ newDoc(RuleKey.of("cobol", "X001")),
+ newDoc(RuleKey.of("php", "S002")));
+
+ // key
+ RuleQuery query = new RuleQuery().setQueryText("X001");
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+
+ // partial key does not match
+ query = new RuleQuery().setQueryText("X00");
+ assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
+
+ // repo:key -> nice-to-have !
+ query = new RuleQuery().setQueryText("javascript:X001");
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(1);
+ }
+
+ @Test
+ public void filter_by_key() {
+ indexRules(
+ newDoc(RuleKey.of("javascript", "X001")),
+ newDoc(RuleKey.of("cobol", "X001")),
+ newDoc(RuleKey.of("php", "S002")));
+
+ // key
+ RuleQuery query = new RuleQuery().setKey(RuleKey.of("javascript", "X001").toString());
+
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(1);
+
+ // partial key does not match
+ query = new RuleQuery().setKey("X001");
+ assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
+ }
+
+ @Test
+ public void search_name_by_query() {
+ indexRules(newDoc(RuleKey.of("javascript", "S001"))
+ .setName("testing the partial match and matching of rule"));
+
+ // substring
+ RuleQuery query = new RuleQuery().setQueryText("test");
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(1);
+
+ // substring
+ query = new RuleQuery().setQueryText("partial match");
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(1);
+
+ // case-insensitive
+ query = new RuleQuery().setQueryText("TESTING");
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(1);
+
+ // not found
+ query = new RuleQuery().setQueryText("not present");
+ assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
+ }
+
+ @Test
+ public void search_name_with_protected_chars() {
+ String nameWithProtectedChars = "ja#va&sc\"r:ipt";
+
+ indexRules(newDoc(RuleKey.of("javascript", "S001"))
+ .setName(nameWithProtectedChars));
+
+ RuleQuery protectedCharsQuery = new RuleQuery().setQueryText(nameWithProtectedChars);
+ List<RuleKey> results = index.search(protectedCharsQuery, new SearchOptions()).getIds();
+ assertThat(results).containsOnly(RuleKey.of("javascript", "S001"));
+ }
+
+ @Test
+ public void search_by_any_of_repositories() {
+ indexRules(
+ newDoc(RuleKey.of("findbugs", "S001")),
+ newDoc(RuleKey.of("pmd", "S002")));
+
+ RuleQuery query = new RuleQuery().setRepositories(asList("checkstyle", "pmd"));
+ SearchIdResult results = index.search(query, new SearchOptions());
+ assertThat(results.getIds()).containsOnly(RuleKey.of("pmd", "S002"));
+
+ // no results
+ query = new RuleQuery().setRepositories(singletonList("checkstyle"));
+ assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
+
+ // empty list => no filter
+ query = new RuleQuery().setRepositories(Collections.<String>emptyList());
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+ }
+
+ @Test
+ public void search_by_tag() {
+ indexRules(
+ newDoc(RuleKey.of("java", "S001")).setAllTags(singleton("tag1")),
+ newDoc(RuleKey.of("java", "S002")).setAllTags(singleton("tag2")));
+
+ // find all
+ RuleQuery query = new RuleQuery();
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+
+ // tag1 in query
+ query = new RuleQuery().setQueryText("tag1");
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RuleKey.of("java", "S001"));
+
+ // tag1 and tag2 in query
+ query = new RuleQuery().setQueryText("tag1 tag2");
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+
+ // tag2 in filter
+ query = new RuleQuery().setTags(ImmutableSet.of("tag2"));
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RuleKey.of("java", "S002"));
+
+ // tag2 in filter and tag1 tag2 in query
+ query = new RuleQuery().setTags(ImmutableSet.of("tag2")).setQueryText("tag1");
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(0);
+
+ // tag2 in filter and tag1 in query
+ query = new RuleQuery().setTags(ImmutableSet.of("tag2")).setQueryText("tag1 tag2");
+ assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RuleKey.of("java", "S002"));
+
+ // null list => no filter
+ query = new RuleQuery().setTags(Collections.<String>emptySet());
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+
+ // null list => no filter
+ query = new RuleQuery().setTags(null);
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+ }
+
+ @Test
+ public void search_by_is_template() {
+ indexRules(
+ newDoc(RuleKey.of("java", "S001")).setIsTemplate(false),
+ newDoc(RuleKey.of("java", "S002")).setIsTemplate(true));
+
+ // find all
+ RuleQuery query = new RuleQuery();
+ SearchIdResult results = index.search(query, new SearchOptions());
+ assertThat(results.getIds()).hasSize(2);
+
+ // Only template
+ query = new RuleQuery().setIsTemplate(true);
+ results = index.search(query, new SearchOptions());
+ assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S002"));
+
+ // Only not template
+ query = new RuleQuery().setIsTemplate(false);
+ results = index.search(query, new SearchOptions());
+ assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S001"));
+
+ // null => no filter
+ query = new RuleQuery().setIsTemplate(null);
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+ }
+
+ @Test
+ public void search_by_template_key() {
+ indexRules(
+ newDoc(RuleKey.of("java", "S001")).setIsTemplate(true),
+ newDoc(RuleKey.of("java", "S001_MY_CUSTOM")).setTemplateKey("java:S001"));
+
+ // find all
+ RuleQuery query = new RuleQuery();
+ SearchIdResult results = index.search(query, new SearchOptions());
+ assertThat(results.getIds()).hasSize(2);
+
+ // Only custom rule
+ query = new RuleQuery().setTemplateKey("java:S001");
+ results = index.search(query, new SearchOptions());
+ assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S001_MY_CUSTOM"));
+
+ // null => no filter
+ query = new RuleQuery().setTemplateKey(null);
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+ }
+
+ @Test
+ public void search_by_any_of_languages() {
+ indexRules(
+ newDoc(RuleKey.of("java", "S001")).setLanguage("java"),
+ newDoc(RuleKey.of("javascript", "S002")).setLanguage("js"));
+
+ RuleQuery query = new RuleQuery().setLanguages(asList("cobol", "js"));
+ SearchIdResult results = index.search(query, new SearchOptions());
+ assertThat(results.getIds()).containsOnly(RuleKey.of("javascript", "S002"));
+
+ // no results
+ query = new RuleQuery().setLanguages(singletonList("cpp"));
+ assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
+
+ // empty list => no filter
+ query = new RuleQuery().setLanguages(Collections.<String>emptyList());
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+
+ // null list => no filter
+ query = new RuleQuery().setLanguages(null);
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+ }
+
+ @Test
+ public void search_by_any_of_severities() {
+ indexRules(
+ newDoc(RuleKey.of("java", "S001")).setSeverity(BLOCKER),
+ newDoc(RuleKey.of("java", "S002")).setSeverity(INFO));
+
+ RuleQuery query = new RuleQuery().setSeverities(asList(INFO, MINOR));
+ SearchIdResult results = index.search(query, new SearchOptions());
+ assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S002"));
+
+ // no results
+ query = new RuleQuery().setSeverities(singletonList(MINOR));
+ assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
+
+ // empty list => no filter
+ query = new RuleQuery().setSeverities(Collections.<String>emptyList());
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+
+ // null list => no filter
+ query = new RuleQuery().setSeverities();
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+ }
+
+ @Test
+ public void search_by_any_of_statuses() {
+ indexRules(
+ newDoc(RuleKey.of("java", "S001")).setStatus(RuleStatus.BETA.name()),
+ newDoc(RuleKey.of("java", "S002")).setStatus(RuleStatus.READY.name()));
+
+ RuleQuery query = new RuleQuery().setStatuses(asList(RuleStatus.DEPRECATED, RuleStatus.READY));
+ SearchIdResult<RuleKey> results = index.search(query, new SearchOptions());
+ assertThat(results.getIds()).containsOnly(RuleKey.of("java", "S002"));
+
+ // no results
+ query = new RuleQuery().setStatuses(singletonList(RuleStatus.DEPRECATED));
+ assertThat(index.search(query, new SearchOptions()).getIds()).isEmpty();
+
+ // empty list => no filter
+ query = new RuleQuery().setStatuses(Collections.<RuleStatus>emptyList());
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+
+ // null list => no filter
+ query = new RuleQuery().setStatuses(null);
+ assertThat(index.search(query, new SearchOptions()).getIds()).hasSize(2);
+ }
+
+ @Test
+ public void search_by_profile() throws InterruptedException {
+ indexRules(
+ newDoc(RULE_KEY_1),
+ newDoc(RULE_KEY_2),
+ newDoc(RULE_KEY_3));
+
+ indexActiveRules(
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2)));
+
+ assertThat(tester.countDocuments(INDEX, TYPE_ACTIVE_RULE)).isEqualTo(3);
+
+ // 1. get all active rules.
+ assertThat(index.search(new RuleQuery().setActivation(true), new SearchOptions()).getIds())
+ .containsOnly(RULE_KEY_1, RULE_KEY_2);
+
+ // 2. get all inactive rules.
+ assertThat(index.search(new RuleQuery().setActivation(false), new SearchOptions()).getIds())
+ .containsOnly(RULE_KEY_3);
+
+ // 3. get all rules not active on profile
+ assertThat(index.search(new RuleQuery().setActivation(false).setQProfileKey(QUALITY_PROFILE_KEY2), new SearchOptions()).getIds())
+ .containsOnly(RULE_KEY_2, RULE_KEY_3);
+
+ // 4. get all active rules on profile
+ assertThat(index.search(new RuleQuery().setActivation(true).setQProfileKey(QUALITY_PROFILE_KEY2), new SearchOptions()).getIds())
+ .containsOnly(RULE_KEY_1);
+ }
+
+ @Test
+ public void search_by_profile_and_inheritance() {
+ indexRules(
+ newDoc(RULE_KEY_1),
+ newDoc(RULE_KEY_2),
+ newDoc(RULE_KEY_3),
+ newDoc(RULE_KEY_4));
+
+ ActiveRuleKey activeRuleKey1 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1);
+ ActiveRuleKey activeRuleKey2 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2);
+ ActiveRuleKey activeRuleKey3 = ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_3);
+
+ indexActiveRules(
+ ActiveRuleDocTesting.newDoc(activeRuleKey1),
+ ActiveRuleDocTesting.newDoc(activeRuleKey2),
+ ActiveRuleDocTesting.newDoc(activeRuleKey3),
+ // Profile 2 is a child a profile 1
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1))
+ .setParentKey(activeRuleKey1.toString()).setInheritance(INHERITED.name()),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_2))
+ .setParentKey(activeRuleKey2.toString()).setInheritance(OVERRIDES.name()),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_3))
+ .setParentKey(activeRuleKey3.toString()).setInheritance(INHERITED.name()));
+
+ // 0. get all rules
+ assertThat(index.search(new RuleQuery(), new SearchOptions()).getIds())
+ .hasSize(4);
+
+ // 1. get all active rules
+ assertThat(index.search(new RuleQuery()
+ .setActivation(true), new SearchOptions()).getIds())
+ .hasSize(3);
+
+ // 2. get all inactive rules.
+ assertThat(index.search(new RuleQuery()
+ .setActivation(false), new SearchOptions()).getIds())
+ .containsOnly(RULE_KEY_4);
+
+ // 3. get Inherited Rules on profile1
+ assertThat(index.search(new RuleQuery().setActivation(true)
+ .setQProfileKey(QUALITY_PROFILE_KEY1)
+ .setInheritance(ImmutableSet.of(INHERITED.name())),
+ new SearchOptions()).getIds())
+ .isEmpty();
+
+ // 4. get Inherited Rules on profile2
+ assertThat(index.search(new RuleQuery().setActivation(true)
+ .setQProfileKey(QUALITY_PROFILE_KEY2)
+ .setInheritance(ImmutableSet.of(INHERITED.name())),
+ new SearchOptions()).getIds())
+ .hasSize(2);
+
+ // 5. get Overridden Rules on profile1
+ assertThat(index.search(new RuleQuery().setActivation(true)
+ .setQProfileKey(QUALITY_PROFILE_KEY1)
+ .setInheritance(ImmutableSet.of(OVERRIDES.name())),
+ new SearchOptions()).getIds())
+ .isEmpty();
+
+ // 6. get Overridden Rules on profile2
+ assertThat(index.search(new RuleQuery().setActivation(true)
+ .setQProfileKey(QUALITY_PROFILE_KEY2)
+ .setInheritance(ImmutableSet.of(OVERRIDES.name())),
+ new SearchOptions()).getIds())
+ .hasSize(1);
+
+ // 7. get Inherited AND Overridden Rules on profile1
+ assertThat(index.search(new RuleQuery().setActivation(true)
+ .setQProfileKey(QUALITY_PROFILE_KEY1)
+ .setInheritance(ImmutableSet.of(INHERITED.name(), OVERRIDES.name())),
+ new SearchOptions()).getIds())
+ .isEmpty();
+
+ // 8. get Inherited AND Overridden Rules on profile2
+ assertThat(index.search(new RuleQuery().setActivation(true)
+ .setQProfileKey(QUALITY_PROFILE_KEY2)
+ .setInheritance(ImmutableSet.of(INHERITED.name(), OVERRIDES.name())),
+ new SearchOptions()).getIds())
+ .hasSize(3);
+ }
+
+ @Test
+ public void search_by_profile_and_active_severity() {
+ indexRules(
+ newDoc(RULE_KEY_1).setSeverity(MAJOR),
+ newDoc(RULE_KEY_2).setSeverity(MINOR),
+ newDoc(RULE_KEY_3).setSeverity(INFO));
+
+ indexActiveRules(
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)).setSeverity(BLOCKER),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)).setSeverity(BLOCKER),
+ ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2)).setSeverity(CRITICAL));
+
+ // 1. get all active rules.
+ assertThat(index.search(new RuleQuery().setActivation(true).setQProfileKey(QUALITY_PROFILE_KEY1), new SearchOptions()).getIds())
+ .hasSize(2);
+
+ // 2. get rules with active severity critical.
+ SearchIdResult<RuleKey> result = index.search(new RuleQuery().setActivation(true)
+ .setQProfileKey(QUALITY_PROFILE_KEY1).setActiveSeverities(singletonList(CRITICAL)),
+ new SearchOptions().addFacets(singletonList(RuleIndex.FACET_ACTIVE_SEVERITIES)));
+ assertThat(result.getIds()).containsOnly(RULE_KEY_2);
+
+ // check stickyness of active severity facet
+ assertThat(result.getFacets().get(RuleIndex.FACET_ACTIVE_SEVERITIES)).containsOnly(entry(BLOCKER, 1L), entry(CRITICAL, 1L));
+
+ // 3. count activation severities of all active rules
+ result = index.search(new RuleQuery(), new SearchOptions().addFacets(singletonList(RuleIndex.FACET_ACTIVE_SEVERITIES)));
+ assertThat(result.getIds()).hasSize(3);
+ assertThat(result.getFacets().get(RuleIndex.FACET_ACTIVE_SEVERITIES)).containsOnly(entry(BLOCKER, 2L), entry(CRITICAL, 1L));
+ }
+
+ @Test
+ public void all_tags() {
+ indexRules(
+ newDoc(RuleKey.of("java", "S001")).setAllTags(asList("tag1", "sys1", "sys2")),
+ newDoc(RuleKey.of("java", "S002")).setAllTags(asList("tag2")));
+
+ assertThat(index.terms(RuleIndexDefinition.FIELD_RULE_ALL_TAGS, null, 10)).containsOnly("tag1", "tag2", "sys1", "sys2");
+ }
+
+ @Test
+ public void available_since() throws InterruptedException {
+ indexRules(
+ newDoc(RuleKey.of("java", "S001")).setCreatedAt(1000L),
+ newDoc(RuleKey.of("java", "S002")).setCreatedAt(2000L));
+
+ // 0. find all rules;
+ assertThat(index.search(new RuleQuery(), new SearchOptions()).getIds()).hasSize(2);
+
+ // 1. find all rules available since a date;
+ RuleQuery availableSinceQuery = new RuleQuery().setAvailableSince(2000L);
+ assertThat(index.search(availableSinceQuery, new SearchOptions()).getIds()).containsOnly(RuleKey.of("java", "S002"));
+
+ // 2. find no new rules since tomorrow.
+ RuleQuery availableSinceNowQuery = new RuleQuery().setAvailableSince(3000L);
+ assertThat(index.search(availableSinceNowQuery, new SearchOptions()).getIds()).hasSize(0);
+ }
+
+ @Test
+ public void global_facet_on_repositories_and_tags() {
+ indexRules(
+ newDoc(RuleKey.of("php", "S001")).setAllTags(singletonList("sysTag")),
+ newDoc(RuleKey.of("php", "S002")).setAllTags(singletonList("tag1")),
+ newDoc(RuleKey.of("javascript", "S002")).setAllTags(asList("tag1", "tag2")));
+
+ // should not have any facet!
+ RuleQuery query = new RuleQuery();
+ SearchIdResult result = index.search(query, new SearchOptions());
+ assertThat(result.getFacets().getAll()).isEmpty();
+
+ // should not have any facet on non matching query!
+ result = index.search(new RuleQuery().setQueryText("aeiou"), new SearchOptions().addFacets(singletonList("repositories")));
+ assertThat(result.getFacets().getAll()).hasSize(1);
+ assertThat(result.getFacets().getAll().get("repositories")).isEmpty();
+
+ // Repositories Facet is preset
+ result = index.search(query, new SearchOptions().addFacets(asList("repositories", "tags")));
+ assertThat(result.getFacets()).isNotNull();
+ assertThat(result.getFacets().getAll()).hasSize(2);
+
+ // Verify the value of a given facet
+ Map<String, Long> repoFacets = result.getFacets().get("repositories");
+ assertThat(repoFacets).containsOnly(entry("php", 2L), entry("javascript", 1L));
+
+ // Check that tag facet has both Tags and SystemTags values
+ Map<String, Long> tagFacets = result.getFacets().get("tags");
+ assertThat(tagFacets).containsOnly(entry("tag1", 2L), entry("sysTag", 1L), entry("tag2", 1L));
+ }
+
+ @Test
+ public void sticky_facets() {
+ indexRules(
+ newDoc(RuleKey.of("xoo", "S001")).setLanguage("java").setAllTags(Collections.<String>emptyList()),
+ newDoc(RuleKey.of("xoo", "S002")).setLanguage("java").setAllTags(Collections.<String>emptyList()),
+ newDoc(RuleKey.of("xoo", "S003")).setLanguage("java").setAllTags(asList("T1", "T2")),
+ newDoc(RuleKey.of("xoo", "S011")).setLanguage("cobol").setAllTags(Collections.<String>emptyList()),
+ newDoc(RuleKey.of("xoo", "S012")).setLanguage("cobol").setAllTags(Collections.<String>emptyList()),
+ newDoc(RuleKey.of("foo", "S013")).setLanguage("cobol").setAllTags(asList("T3", "T4")),
+ newDoc(RuleKey.of("foo", "S111")).setLanguage("cpp").setAllTags(Collections.<String>emptyList()),
+ newDoc(RuleKey.of("foo", "S112")).setLanguage("cpp").setAllTags(Collections.<String>emptyList()),
+ newDoc(RuleKey.of("foo", "S113")).setLanguage("cpp").setAllTags(asList("T2", "T3")));
+
+ // 0 assert Base
+ assertThat(index.search(new RuleQuery(), new SearchOptions()).getIds()).hasSize(9);
+
+ // 1 Facet with no filters at all
+ SearchIdResult result = index.search(new RuleQuery(), new SearchOptions().addFacets(asList("languages", "repositories", "tags")));
+ assertThat(result.getFacets().getAll()).hasSize(3);
+ assertThat(result.getFacets().getAll().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java", "cobol");
+ assertThat(result.getFacets().getAll().get(FACET_REPOSITORIES).keySet()).containsOnly("xoo", "foo");
+ assertThat(result.getFacets().getAll().get(FACET_TAGS).keySet()).containsOnly("T1", "T2", "T3", "T4");
+
+ // 2 Facet with a language filter
+ // -- lang facet should still have all language
+ result = index.search(new RuleQuery().setLanguages(ImmutableList.of("cpp"))
+ , new SearchOptions().addFacets(asList("languages", "repositories", "tags")));
+ assertThat(result.getIds()).hasSize(3);
+ assertThat(result.getFacets().getAll()).hasSize(3);
+ assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java", "cobol");
+
+ // 3 facet with 2 filters
+ // -- lang facet for tag T2
+ // -- tag facet for lang cpp
+ // -- repository for cpp & T2
+ result = index.search(new RuleQuery()
+ .setLanguages(ImmutableList.of("cpp"))
+ .setTags(ImmutableList.of("T2"))
+ , new SearchOptions().addFacets(asList("languages", "repositories", "tags")));
+ assertThat(result.getIds()).hasSize(1);
+ assertThat(result.getFacets().getAll()).hasSize(3);
+ assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java");
+ assertThat(result.getFacets().get(FACET_REPOSITORIES).keySet()).containsOnly("foo");
+ assertThat(result.getFacets().get(FACET_TAGS).keySet()).containsOnly("T2", "T3");
+
+ // 4 facet with 2 filters
+ // -- lang facet for tag T2
+ // -- tag facet for lang cpp & java
+ // -- repository for (cpp || java) & T2
+ result = index.search(new RuleQuery()
+ .setLanguages(ImmutableList.of("cpp", "java"))
+ .setTags(ImmutableList.of("T2"))
+ , new SearchOptions().addFacets(asList("languages", "repositories", "tags")));
+ assertThat(result.getIds()).hasSize(2);
+ assertThat(result.getFacets().getAll()).hasSize(3);
+ assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java");
+ assertThat(result.getFacets().get(FACET_REPOSITORIES).keySet()).containsOnly("foo", "xoo");
+ assertThat(result.getFacets().get(FACET_TAGS).keySet()).containsOnly("T1", "T2", "T3");
+ }
+
+ @Test
+ public void sort_by_name() {
+ indexRules(
+ newDoc(RuleKey.of("java", "S001")).setName("abcd"),
+ newDoc(RuleKey.of("java", "S002")).setName("ABC"),
+ newDoc(RuleKey.of("java", "S003")).setName("FGH"));
+
+ // ascending
+ RuleQuery query = new RuleQuery().setSortField(RuleIndexDefinition.FIELD_RULE_NAME);
+ SearchIdResult<RuleKey> results = index.search(query, new SearchOptions());
+ assertThat(results.getIds()).containsExactly(RuleKey.of("java", "S002"), RuleKey.of("java", "S001"), RuleKey.of("java", "S003"));
+
+ // descending
+ query = new RuleQuery().setSortField(RuleIndexDefinition.FIELD_RULE_NAME).setAscendingSort(false);
+ results = index.search(query, new SearchOptions());
+ assertThat(results.getIds()).containsExactly(RuleKey.of("java", "S003"), RuleKey.of("java", "S001"), RuleKey.of("java", "S002"));
+ }
+
+ @Test
+ public void default_sort_is_by_updated_at_desc() {
+ indexRules(
+ newDoc(RuleKey.of("java", "S001")).setCreatedAt(1000L).setUpdatedAt(1000L),
+ newDoc(RuleKey.of("java", "S002")).setCreatedAt(1000L).setUpdatedAt(3000L),
+ newDoc(RuleKey.of("java", "S003")).setCreatedAt(1000L).setUpdatedAt(2000L));
+
+ SearchIdResult<RuleKey> results = index.search(new RuleQuery(), new SearchOptions());
+ assertThat(results.getIds()).containsExactly(RuleKey.of("java", "S002"), RuleKey.of("java", "S003"), RuleKey.of("java", "S001"));
+ }
+
+ @Test
+ public void fail_sort_by_language() {
+ try {
+ // Sorting on a field not tagged as sortable
+ new RuleQuery().setSortField(RuleIndexDefinition.FIELD_RULE_LANGUAGE);
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e).hasMessage("Field 'lang' is not sortable");
+ }
+ }
+
+ @Test
+ public void paging() {
+ indexRules(
+ newDoc(RuleKey.of("java", "S001")),
+ newDoc(RuleKey.of("java", "S002")),
+ newDoc(RuleKey.of("java", "S003")));
+
+ // from 0 to 1 included
+ SearchOptions options = new SearchOptions();
+ options.setOffset(0).setLimit(2);
+ SearchIdResult results = index.search(new RuleQuery(), options);
+ assertThat(results.getTotal()).isEqualTo(3);
+ assertThat(results.getIds()).hasSize(2);
+
+ // from 0 to 9 included
+ options.setOffset(0).setLimit(10);
+ results = index.search(new RuleQuery(), options);
+ assertThat(results.getTotal()).isEqualTo(3);
+ assertThat(results.getIds()).hasSize(3);
+
+ // from 2 to 11 included
+ options.setOffset(2).setLimit(10);
+ results = index.search(new RuleQuery(), options);
+ assertThat(results.getTotal()).isEqualTo(3);
+ assertThat(results.getIds()).hasSize(1);
+
+ // from 2 to 11 included
+ options.setOffset(2).setLimit(0);
+ results = index.search(new RuleQuery(), options);
+ assertThat(results.getTotal()).isEqualTo(3);
+ assertThat(results.getIds()).hasSize(1);
+ }
+
+ @Test
+ public void search_all_keys_by_query() {
+ indexRules(
+ newDoc(RuleKey.of("javascript", "X001")),
+ newDoc(RuleKey.of("cobol", "X001")),
+ newDoc(RuleKey.of("php", "S002")));
+
+ // key
+ assertThat(index.searchAll(new RuleQuery().setQueryText("X001"))).hasSize(2);
+
+ // partial key does not match
+ assertThat(index.searchAll(new RuleQuery().setQueryText("X00"))).isEmpty();
+
+ // repo:key -> nice-to-have !
+ assertThat(index.searchAll(new RuleQuery().setQueryText("javascript:X001"))).hasSize(1);
+ }
+
+ private void indexRules(RuleDoc... rules) {
+ ruleIndexer.index(asList(rules).iterator());
+ }
+
+ private void indexActiveRules(ActiveRuleDoc... docs) {
+ activeRuleIndexer.index(asList(docs).iterator());
+ }
+}