*/
package org.sonar.server.qualityprofile;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
import org.sonar.api.ServerComponent;
import org.sonar.api.rule.RuleKey;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
import org.sonar.server.rule.index.RuleQuery;
+import org.sonar.server.search.FacetValue;
import org.sonar.server.search.IndexClient;
import org.sonar.server.user.UserSession;
}
return counts;
}
+
+ public Multimap<QualityProfileKey, FacetValue> getAllProfileStats() {
+
+ List<QualityProfileKey> keys = Lists.newArrayList();
+ for (QualityProfileDto profile : this.findAll()) {
+ keys.add(profile.getKey());
+ }
+
+ Multimap<QualityProfileKey, FacetValue> stats = ArrayListMultimap.create();
+
+ Collection<FacetValue> profilesStats = index.get(ActiveRuleIndex.class).getStatsByProfileKey(keys);
+ for (FacetValue profileStat : profilesStats) {
+ stats.put(QualityProfileKey.parse(profileStat.getKey()), profileStat);
+ }
+ return stats;
+ }
}
*/
package org.sonar.server.qualityprofile.index;
+import com.google.common.collect.Multimap;
import org.elasticsearch.action.count.CountRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
+import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.sonar.api.rule.RuleKey;
import org.sonar.core.cluster.WorkQueue;
import org.sonar.core.profiling.Profiling;
import org.sonar.server.qualityprofile.ActiveRule;
import org.sonar.server.search.BaseIndex;
import org.sonar.server.search.ESNode;
+import org.sonar.server.search.FacetValue;
import org.sonar.server.search.IndexDefinition;
import org.sonar.server.search.IndexField;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Override
protected Settings getIndexSettings() throws IOException {
return ImmutableSettings.builder()
- .put("index.number_of_replicas",0)
- .put("index.number_of_shards",1)
+ .put("index.number_of_replicas", 0)
+ .put("index.number_of_shards", 1)
.build();
}
}
@Override
- protected Map mapDomain(){
+ protected Map mapDomain() {
Map<String, Object> mapping = new HashMap<String, Object>();
mapping.put("dynamic", false);
mapping.put("_id", mapKey());
mapping.put("_parent", mapParent());
- mapping.put("_routing",mapRouting());
+ mapping.put("_routing", mapRouting());
mapping.put("properties", mapProperties());
return mapping;
}
SearchRequestBuilder request = getClient().prepareSearch(getIndexName())
.setQuery(QueryBuilders.termQuery(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field(), key.toString()))
.setRouting(key.toString())
- // TODO replace by scrolling
+ // TODO replace by scrolling
.setSize(Integer.MAX_VALUE);
SearchResponse response = request.get();
return request.get().getCount();
}
- public Map getStatsByProfileKey(QualityProfileKey... keys) {
+
+ public Collection<FacetValue> getStatsByProfileKey(List<QualityProfileKey> keys) {
+
// Get QProfiles keys as Strings
- String[] stringKeys = new String[keys.length];
- for(int i=0; i<keys.length; i++){
- stringKeys[i]=keys[i].toString();
+ String[] stringKeys = new String[keys.size()];
+ for (int i = 0; i < keys.size(); i++) {
+ stringKeys[i] = keys.get(i).toString();
}
-// getClient().prepareSearch(this.getIndexName())
-// .setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),
-// FilterBuilders.termsFilter(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field(), stringKeys)))
-// .addAggregation(AggregationBuilders.terms("").)
-// .setAggregations()
-// .setRouting(key.toString());
-// return request.get().getCount();
-
- return null;
+ SearchResponse response = getClient().prepareSearch(this.getIndexName())
+ .setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(),
+ FilterBuilders.termsFilter(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field(), stringKeys)))
+ .addAggregation(AggregationBuilders.terms(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field())
+ .field(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field())
+ .subAggregation(AggregationBuilders.terms(ActiveRuleNormalizer.ActiveRuleField.INHERITANCE.field())
+ .field(ActiveRuleNormalizer.ActiveRuleField.INHERITANCE.field())
+ .subAggregation(AggregationBuilders.terms(ActiveRuleNormalizer.ActiveRuleField.SEVERITY.field())
+ .field(ActiveRuleNormalizer.ActiveRuleField.SEVERITY.field()))))
+ .setSize(0)
+ .setTypes(this.getIndexType())
+ .get();
+
+ Multimap<String, FacetValue> stats = this.processAggregations(response.getAggregations());
+
+ return stats.get(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.field());
}
}
import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
import org.sonar.core.qualityprofile.db.QualityProfileDto;
import org.sonar.server.db.DbClient;
+import org.sonar.server.qualityprofile.ActiveRule;
import org.sonar.server.search.BaseNormalizer;
import org.sonar.server.search.IndexDefinition;
import org.sonar.server.search.IndexField;
newRule.put("_parent", key.ruleKey().toString());
newRule.put(ActiveRuleField.RULE_KEY.field(), key.ruleKey().toString());
newRule.put(ActiveRuleField.KEY.field(), key.toString());
- newRule.put(ActiveRuleField.INHERITANCE.field(), activeRuleDto.getInheritance());
+ newRule.put(ActiveRuleField.INHERITANCE.field(),
+ (activeRuleDto.getInheritance() != null) ?
+ activeRuleDto.getInheritance() :
+ ActiveRule.Inheritance.NONE.name());
newRule.put(ActiveRuleField.SEVERITY.field(), activeRuleDto.getSeverityString());
DbSession session = db.openSession(false);
*/
package org.sonar.server.search;
+import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Multimap;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
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.Terms;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
return counts;
}
+
+ // Response helpers
+ protected Multimap<String, FacetValue> processAggregations(Aggregations aggregations) {
+ Multimap<String, FacetValue> stats = ArrayListMultimap.create();
+ if (aggregations != null) {
+ for (Aggregation aggregation : aggregations.asList()) {
+ for (Terms.Bucket value : ((Terms) aggregation).getBuckets()) {
+ FacetValue facetValue = new FacetValue(value.getKey(), (int) value.getDocCount());
+ facetValue.setSubFacets(processAggregations(value.getAggregations()));
+ stats.put(aggregation.getName(), facetValue);
+ }
+ }
+ }
+ return stats;
+ }
}
*/
package org.sonar.server.search;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
-public class FacetValue {
+public class FacetValue implements Comparable<FacetValue> {
- String key;
- Integer value;
+ public static enum Sort {
+ BY_KEY, BY_VALUE
+ }
+
+ private String key;
+ private Integer value;
+ private Sort sort;
+ private Multimap<String, FacetValue> subFacets;
public FacetValue(String key, Integer value){
this.key = key;
this.value = value;
+ this.subFacets = ArrayListMultimap.create();
+ this.sort = Sort.BY_VALUE;
}
public String getKey() {
this.value = value;
}
+ public Multimap<String, FacetValue> getSubFacets() {
+ return subFacets;
+ }
+
+ public void setSubFacets(Multimap<String, FacetValue> subFacets) {
+ this.subFacets = subFacets;
+ }
+
@Override
public String toString() {
- return ReflectionToStringBuilder.toString(this);
+ return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+ }
+
+ @Override
+ public int compareTo(FacetValue other) {
+ if (this.sort.equals(Sort.BY_KEY)) {
+ return this.getKey().compareTo(other.getKey());
+ } else {
+ return this.getValue().compareTo(other.getValue());
+ }
}
}
*/
package org.sonar.server.qualityprofile;
+import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
import org.sonar.server.rule.RuleTesting;
+import org.sonar.server.search.FacetValue;
import org.sonar.server.tester.ServerTester;
import java.util.Collection;
db.ruleDao().insert(dbSession, ruleDto1, ruleDto2);
db.activeRuleDao().insert(dbSession,
- ActiveRuleDto.createFor(profileDto1, ruleDto1).setSeverity(Severity.BLOCKER),
- ActiveRuleDto.createFor(profileDto2, ruleDto1).setSeverity(Severity.MINOR),
- ActiveRuleDto.createFor(profileDto1, ruleDto2).setSeverity(Severity.MAJOR),
- ActiveRuleDto.createFor(profileDto2, ruleDto2).setSeverity(Severity.BLOCKER)
+ ActiveRuleDto.createFor(profileDto1, ruleDto1)
+ .setInheritance(ActiveRule.Inheritance.INHERITED.name())
+ .setSeverity(Severity.BLOCKER),
+ ActiveRuleDto.createFor(profileDto2, ruleDto1)
+ .setInheritance(ActiveRule.Inheritance.INHERITED.name())
+ .setSeverity(Severity.MINOR),
+ ActiveRuleDto.createFor(profileDto1, ruleDto2)
+ .setInheritance(ActiveRule.Inheritance.OVERRIDES.name())
+ .setSeverity(Severity.MAJOR),
+ ActiveRuleDto.createFor(profileDto2, ruleDto2)
+ .setInheritance(ActiveRule.Inheritance.INHERITED.name())
+ .setSeverity(Severity.BLOCKER)
);
dbSession.commit();
// 0. Test base case
- assertThat(index.countAll()).isEqualTo(2);
+ assertThat(index.countAll()).isEqualTo(4);
// 1. Assert by term aggregation;
- Map stats = index.getStatsByProfileKey(
- profileDto1.getKey(),
- profileDto2.getKey());
+ Collection<FacetValue> stats = index.getStatsByProfileKey(
+ ImmutableList.of(profileDto1.getKey(),
+ profileDto2.getKey()));
+
+ assertThat(stats).hasSize(2);
}
*/
package org.sonar.server.qualityprofile;
+import com.google.common.collect.Multimap;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.sonar.server.db.DbClient;
import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.rule.RuleTesting;
+import org.sonar.server.search.FacetValue;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.user.MockUserSession;
assertThat(counts.values()).containsOnly(1L, 1L);
}
+
+ @Test
+ public void stat_for_all_profiles() {
+ MockUserSession.set().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN).setLogin("me");
+
+ service.activate(new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_1, XOO_RULE_1))
+ .setSeverity("MINOR"));
+
+ service.activate(new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_2, XOO_RULE_1))
+ .setSeverity("BLOCKER"));
+
+ dbSession.commit();
+
+ Multimap<QualityProfileKey, FacetValue> stats = service.getAllProfileStats();
+ assertThat(stats.size()).isEqualTo(2);
+ assertThat(stats.get(XOO_PROFILE_1).size()).isEqualTo(1);
+ }
}
import org.sonar.core.template.LoadedTemplateDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.platform.Platform;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.qualityprofile.db.ActiveRuleDao;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.tester.ServerTester;
import java.util.Map;
assertThat(params.get("acceptWhitespace").getValue()).isEqualTo("true");
// default value
assertThat(params.get("max").getValue()).isEqualTo("10");
+
}
@Test
// Check ActiveRuleParameters in DB
Map<String, ActiveRuleParamDto> params =
- ActiveRuleParamDto.groupByKey(activeRuleDao.findParamsByActiveRuleKey(dbSession, activeRule.getKey() ));
+ ActiveRuleParamDto.groupByKey(activeRuleDao.findParamsByActiveRuleKey(dbSession, activeRule.getKey()));
assertThat(params).hasSize(2);
// set by profile
assertThat(params.get("acceptWhitespace").getValue()).isEqualTo("true");