diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2013-12-17 11:33:29 +0100 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2013-12-17 11:33:29 +0100 |
commit | 15daf634efb55ce0fe4e651483c7fbc8098db116 (patch) | |
tree | 443c405d41066aa3c53ca3b4c42646cd8a6aa42d | |
parent | 5072079eee5072af70d379f42ce384c7f2aab012 (diff) | |
download | sonarqube-15daf634efb55ce0fe4e651483c7fbc8098db116.tar.gz sonarqube-15daf634efb55ce0fe4e651483c7fbc8098db116.zip |
SONAR-4535 Index active rules when creating profile from xml
8 files changed, 164 insertions, 54 deletions
diff --git a/sonar-check-api/src/main/java/org/sonar/check/Priority.java b/sonar-check-api/src/main/java/org/sonar/check/Priority.java index 94e301481e4..e7b562dcad2 100644 --- a/sonar-check-api/src/main/java/org/sonar/check/Priority.java +++ b/sonar-check-api/src/main/java/org/sonar/check/Priority.java @@ -19,6 +19,11 @@ */ package org.sonar.check; +/** + * @deprecated since 4.2 + * @see org.sonar.api.rule.Severity + */ +@Deprecated public enum Priority { /** * WARNING : DO NOT CHANGE THE ENUMERATION ORDER diff --git a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/ActiveRuleParamDto.java b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/ActiveRuleParamDto.java index 20dcad77895..babadef3556 100644 --- a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/ActiveRuleParamDto.java +++ b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/ActiveRuleParamDto.java @@ -25,6 +25,7 @@ public class ActiveRuleParamDto { private Integer id; private Integer activeRuleId; private Integer rulesParameterId; + private String key; private String value; public Integer getId() { @@ -54,6 +55,15 @@ public class ActiveRuleParamDto { return this; } + public String getKey() { + return key; + } + + public ActiveRuleParamDto setKey(String key) { + this.key = key; + return this; + } + public String getValue() { return value; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rule/Severity.java b/sonar-plugin-api/src/main/java/org/sonar/api/rule/Severity.java index 775f76d189e..7fe9fe68348 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/rule/Severity.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/rule/Severity.java @@ -39,6 +39,10 @@ public final class Severity { */ public static final List<String> ALL = ImmutableList.of(INFO, MINOR, MAJOR, CRITICAL, BLOCKER); + public static String get(int ordinal) { + return ALL.get(ordinal); + } + private Severity() { // utility } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rules/RulePriority.java b/sonar-plugin-api/src/main/java/org/sonar/api/rules/RulePriority.java index faf640d4ac1..35f0a000582 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/rules/RulePriority.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/rules/RulePriority.java @@ -22,7 +22,8 @@ package org.sonar.api.rules; import org.sonar.check.Priority; /** - * A class to hold rules priority + * @deprecated since 4.2 + * @see org.sonar.api.rule.Severity */ public enum RulePriority { diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java index f35a723ae18..dddee702a9c 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileOperations.java @@ -22,8 +22,10 @@ package org.sonar.server.qualityprofile; import com.google.common.base.Function; import com.google.common.base.Strings; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; import org.apache.commons.lang.StringUtils; import org.apache.ibatis.session.SqlSession; import org.sonar.api.ServerComponent; @@ -45,6 +47,7 @@ import org.sonar.core.qualityprofile.db.*; import org.sonar.core.resource.ResourceDao; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.rule.RuleRegistry; import org.sonar.server.user.UserSession; import org.sonar.server.util.Validation; @@ -69,14 +72,15 @@ public class QProfileOperations implements ServerComponent { private final List<ProfileExporter> exporters; private final List<ProfileImporter> importers; private final PreviewCache dryRunCache; + private final RuleRegistry ruleRegistry; public QProfileOperations(MyBatis myBatis, QualityProfileDao dao, ActiveRuleDao activeRuleDao, ResourceDao resourceDao, PropertiesDao propertiesDao, - PreviewCache dryRunCache) { - this(myBatis, dao, activeRuleDao, resourceDao, propertiesDao, Lists.<ProfileExporter>newArrayList(), Lists.<ProfileImporter>newArrayList(), dryRunCache); + PreviewCache dryRunCache, RuleRegistry ruleRegistry) { + this(myBatis, dao, activeRuleDao, resourceDao, propertiesDao, Lists.<ProfileExporter>newArrayList(), Lists.<ProfileImporter>newArrayList(), dryRunCache, ruleRegistry); } public QProfileOperations(MyBatis myBatis, QualityProfileDao dao, ActiveRuleDao activeRuleDao, ResourceDao resourceDao, PropertiesDao propertiesDao, - List<ProfileExporter> exporters, List<ProfileImporter> importers, PreviewCache dryRunCache) { + List<ProfileExporter> exporters, List<ProfileImporter> importers, PreviewCache dryRunCache, RuleRegistry ruleRegistry) { this.myBatis = myBatis; this.dao = dao; this.activeRuleDao = activeRuleDao; @@ -85,6 +89,7 @@ public class QProfileOperations implements ServerComponent { this.exporters = exporters; this.importers = importers; this.dryRunCache = dryRunCache; + this.ruleRegistry = ruleRegistry; } public NewProfileResult newProfile(String name, String language, Map<String, String> xmlProfilesByPlugin, UserSession userSession) { @@ -180,13 +185,19 @@ public class QProfileOperations implements ServerComponent { } private void importProfile(QualityProfileDto qualityProfileDto, RulesProfile rulesProfile, SqlSession sqlSession) { + List<ActiveRuleDto> activeRuleDtos = newArrayList(); + Multimap<Integer, ActiveRuleParamDto> paramsByActiveRule = ArrayListMultimap.create(); for (ActiveRule activeRule : rulesProfile.getActiveRules()) { ActiveRuleDto activeRuleDto = toActiveRuleDto(activeRule, qualityProfileDto); activeRuleDao.insert(activeRuleDto, sqlSession); + activeRuleDtos.add(activeRuleDto); for (ActiveRuleParam activeRuleParam : activeRule.getActiveRuleParams()) { - activeRuleDao.insert(toActiveRuleParamDto(activeRuleParam, activeRuleDto), sqlSession); + ActiveRuleParamDto activeRuleParamDto = toActiveRuleParamDto(activeRuleParam, activeRuleDto); + activeRuleDao.insert(activeRuleParamDto, sqlSession); + paramsByActiveRule.put(activeRuleDto.getId(), activeRuleParamDto); } } + ruleRegistry.bulkIndexActiveRules(activeRuleDtos, paramsByActiveRule); } public ProfileImporter getProfileImporter(String exporterKey) { @@ -219,13 +230,14 @@ public class QProfileOperations implements ServerComponent { } private Integer toSeverityLevel(RulePriority rulePriority) { - return rulePriority.ordinal() + 1; + return rulePriority.ordinal(); } private ActiveRuleParamDto toActiveRuleParamDto(ActiveRuleParam activeRuleParam, ActiveRuleDto activeRuleDto) { return new ActiveRuleParamDto() .setActiveRuleId(activeRuleDto.getId()) .setRulesParameterId(activeRuleParam.getRuleParam().getId()) + .setKey(activeRuleParam.getKey()) .setValue(activeRuleParam.getValue()); } diff --git a/sonar-server/src/main/java/org/sonar/server/rule/RuleRegistry.java b/sonar-server/src/main/java/org/sonar/server/rule/RuleRegistry.java index 708281476b1..71e9085607c 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule/RuleRegistry.java +++ b/sonar-server/src/main/java/org/sonar/server/rule/RuleRegistry.java @@ -29,10 +29,13 @@ import org.elasticsearch.common.io.BytesStream; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.sonar.api.database.DatabaseSession; +import org.sonar.api.rule.Severity; import org.sonar.api.rules.ActiveRule; import org.sonar.api.rules.ActiveRuleParam; import org.sonar.api.rules.Rule; import org.sonar.api.utils.TimeProfiler; +import org.sonar.core.qualityprofile.db.ActiveRuleDto; +import org.sonar.core.qualityprofile.db.ActiveRuleParamDto; import org.sonar.core.rule.RuleDao; import org.sonar.core.rule.RuleDto; import org.sonar.core.rule.RuleParamDto; @@ -47,6 +50,7 @@ import java.util.Map; /** * Fill search index with rules + * * @since 4.1 */ public class RuleRegistry { @@ -82,13 +86,13 @@ public class RuleRegistry { profiler.stop(); Multimap<Long, RuleParamDto> paramsByRule = ArrayListMultimap.create(); - for (RuleParamDto param: flatParams) { + for (RuleParamDto param : flatParams) { paramsByRule.put(param.getRuleId(), param); } try { bulkIndex(rules, paramsByRule); - } catch(IOException ioe) { + } catch (IOException ioe) { throw new IllegalStateException("Unable to index rules", ioe); } } @@ -108,13 +112,14 @@ public class RuleRegistry { /** * <p>Find rule IDs matching the given criteria.</p> + * * @param query <p>A collection of (optional) criteria with the following meaning: - * <ul> - * <li><em>nameOrKey</em>: will be used as a query string over the "name" field</li> - * <li><em><anyField></em>: will be used to match the given field against the passed value(s); - * mutiple values must be separated by the '<code>|</code>' (vertical bar) character</li> - * </ul> - * </p> + * <ul> + * <li><em>nameOrKey</em>: will be used as a query string over the "name" field</li> + * <li><em><anyField></em>: will be used to match the given field against the passed value(s); + * mutiple values must be separated by the '<code>|</code>' (vertical bar) character</li> + * </ul> + * </p> * @return */ public List<Integer> findIds(Map<String, String> query) { @@ -126,27 +131,28 @@ public class RuleRegistry { if (params.containsKey(PARAM_NAMEORKEY)) { searchQuery.searchString(params.remove(PARAM_NAMEORKEY)); } - if (! params.containsKey(PARAM_STATUS)) { + if (!params.containsKey(PARAM_STATUS)) { searchQuery.notField(PARAM_STATUS, Rule.STATUS_REMOVED); } - for(Map.Entry<String, String> param: params.entrySet()) { + for (Map.Entry<String, String> param : params.entrySet()) { searchQuery.field(param.getKey(), param.getValue().split("\\|")); } try { List<Integer> result = Lists.newArrayList(); - for(String docId: searchIndex.findDocumentIds(searchQuery)) { + for (String docId : searchIndex.findDocumentIds(searchQuery)) { result.add(Integer.parseInt(docId)); } return result; - } catch(ElasticSearchException searchException) { + } catch (ElasticSearchException searchException) { throw new IllegalArgumentException("Unable to perform search, please check query", searchException); } } /** * Create or update definition of rule identified by <code>ruleId</code> + * * @param ruleId */ public void saveOrUpdate(int ruleId) { @@ -154,8 +160,8 @@ public class RuleRegistry { Collection<RuleParamDto> params = ruleDao.selectParameters(rule.getId()); try { searchIndex.putSynchronous(INDEX_RULES, TYPE_RULE, Long.toString(rule.getId()), ruleDocument(rule, params)); - } catch(IOException ioexception) { - throw new IllegalStateException("Unable to index rule with id="+ruleId, ioexception); + } catch (IOException ioexception) { + throw new IllegalStateException("Unable to index rule with id=" + ruleId, ioexception); } } @@ -165,14 +171,14 @@ public class RuleRegistry { int index = 0; TimeProfiler profiler = new TimeProfiler(); profiler.start("Build rules documents"); - for (RuleDto rule: rules) { + for (RuleDto rule : rules) { ids[index] = rule.getId().toString(); docs[index] = ruleDocument(rule, paramsByRule.get(rule.getId())); - index ++; + index++; } profiler.stop(); - if (! rules.isEmpty()) { + if (!rules.isEmpty()) { profiler.start("Index rules"); searchIndex.bulkIndex(INDEX_RULES, TYPE_RULE, ids, docs); profiler.stop(); @@ -180,7 +186,7 @@ public class RuleRegistry { List<String> indexIds = searchIndex.findDocumentIds(SearchQuery.create().index(INDEX_RULES).type(TYPE_RULE)); indexIds.removeAll(Arrays.asList(ids)); - if (! indexIds.isEmpty()) { + if (!indexIds.isEmpty()) { profiler.start("Remove deleted rule documents"); searchIndex.bulkDelete(INDEX_RULES, TYPE_RULE, indexIds.toArray(new String[0])); profiler.stop(); @@ -194,11 +200,11 @@ public class RuleRegistry { int index = 0; TimeProfiler profiler = new TimeProfiler(); profiler.start("Build active rules documents"); - for (ActiveRule rule: rules) { + for (ActiveRule rule : rules) { ids[index] = rule.getId().toString(); docs[index] = activeRuleDocument(rule); parentIds[index] = rule.getRule().getId().toString(); - index ++; + index++; } profiler.stop(); profiler.start("Index active rules"); @@ -207,31 +213,30 @@ public class RuleRegistry { List<String> indexIds = searchIndex.findDocumentIds(SearchQuery.create().index(INDEX_RULES).type(TYPE_ACTIVE_RULE)); indexIds.removeAll(Arrays.asList(ids)); - if (! indexIds.isEmpty()) { + if (!indexIds.isEmpty()) { profiler.start("Remove deleted active rule documents"); searchIndex.bulkDelete(INDEX_RULES, TYPE_ACTIVE_RULE, indexIds.toArray(new String[0])); profiler.stop(); } } - private XContentBuilder ruleDocument(RuleDto rule, Collection<RuleParamDto> params) throws IOException { XContentBuilder document = XContentFactory.jsonBuilder() - .startObject() - .field(RuleDocument.FIELD_ID, rule.getId()) - .field(RuleDocument.FIELD_KEY, rule.getRuleKey()) - .field(RuleDocument.FIELD_LANGUAGE, rule.getLanguage()) - .field(RuleDocument.FIELD_NAME, rule.getName()) - .field(RuleDocument.FIELD_DESCRIPTION, rule.getDescription()) - .field(RuleDocument.FIELD_PARENT_KEY, rule.getParentId() == null ? null : rule.getParentId()) - .field(RuleDocument.FIELD_REPOSITORY_KEY, rule.getRepositoryKey()) - .field(RuleDocument.FIELD_SEVERITY, rule.getPriority()) - .field(RuleDocument.FIELD_STATUS, rule.getStatus()) - .field(RuleDocument.FIELD_CREATED_AT, rule.getCreatedAt()) - .field(RuleDocument.FIELD_UPDATED_AT, rule.getUpdatedAt()); - if(!params.isEmpty()) { + .startObject() + .field(RuleDocument.FIELD_ID, rule.getId()) + .field(RuleDocument.FIELD_KEY, rule.getRuleKey()) + .field(RuleDocument.FIELD_LANGUAGE, rule.getLanguage()) + .field(RuleDocument.FIELD_NAME, rule.getName()) + .field(RuleDocument.FIELD_DESCRIPTION, rule.getDescription()) + .field(RuleDocument.FIELD_PARENT_KEY, rule.getParentId() == null ? null : rule.getParentId()) + .field(RuleDocument.FIELD_REPOSITORY_KEY, rule.getRepositoryKey()) + .field(RuleDocument.FIELD_SEVERITY, rule.getPriority()) + .field(RuleDocument.FIELD_STATUS, rule.getStatus()) + .field(RuleDocument.FIELD_CREATED_AT, rule.getCreatedAt()) + .field(RuleDocument.FIELD_UPDATED_AT, rule.getUpdatedAt()); + if (!params.isEmpty()) { document.startArray(RuleDocument.FIELD_PARAMS); - for (RuleParamDto param: params) { + for (RuleParamDto param : params) { document.startObject() .field(RuleDocument.FIELD_PARAM_KEY, param.getName()) .field(RuleDocument.FIELD_PARAM_TYPE, param.getType()) @@ -247,14 +252,54 @@ public class RuleRegistry { private XContentBuilder activeRuleDocument(ActiveRule rule) throws IOException { XContentBuilder document = XContentFactory.jsonBuilder() - .startObject() - .field(ActiveRuleDocument.FIELD_ID, rule.getId()) - .field(ActiveRuleDocument.FIELD_SEVERITY, rule.getSeverity()) - .field(ActiveRuleDocument.FIELD_PROFILE_ID, rule.getRulesProfile().getId()) - .field(ActiveRuleDocument.FIELD_INHERITANCE, rule.getInheritance()); - if(!rule.getActiveRuleParams().isEmpty()) { + .startObject() + .field(ActiveRuleDocument.FIELD_ID, rule.getId()) + .field(ActiveRuleDocument.FIELD_SEVERITY, rule.getSeverity()) + .field(ActiveRuleDocument.FIELD_PROFILE_ID, rule.getRulesProfile().getId()) + .field(ActiveRuleDocument.FIELD_INHERITANCE, rule.getInheritance()); + if (!rule.getActiveRuleParams().isEmpty()) { + document.startArray(ActiveRuleDocument.FIELD_PARAMS); + for (ActiveRuleParam param : rule.getActiveRuleParams()) { + document.startObject() + .field(ActiveRuleDocument.FIELD_PARAM_KEY, param.getKey()) + .field(ActiveRuleDocument.FIELD_PARAM_VALUE, param.getValue()) + .endObject(); + } + document.endArray(); + } + document.endObject(); + return document; + } + + public void bulkIndexActiveRules(List<ActiveRuleDto> activeRules, Multimap<Integer, ActiveRuleParamDto> paramsByActiveRule) { + try { + int size = activeRules.size(); + String[] ids = new String[size]; + BytesStream[] docs = new BytesStream[size]; + String[] parentIds = new String[size]; + int index = 0; + for (ActiveRuleDto activeRule : activeRules) { + ids[index] = activeRule.getId().toString(); + docs[index] = activeRuleDocument(activeRule, paramsByActiveRule.get(activeRule.getId())); + parentIds[index] = activeRule.getRulId().toString(); + index++; + } + searchIndex.bulkIndex(INDEX_RULES, TYPE_ACTIVE_RULE, ids, docs, parentIds); + } catch (IOException e) { + throw new IllegalStateException("Unable to index active rules", e); + } + } + + private XContentBuilder activeRuleDocument(ActiveRuleDto activeRule, Collection<ActiveRuleParamDto> params) throws IOException { + XContentBuilder document = XContentFactory.jsonBuilder() + .startObject() + .field(ActiveRuleDocument.FIELD_ID, activeRule.getId()) + .field(ActiveRuleDocument.FIELD_SEVERITY, Severity.get(activeRule.getSeverity())) + .field(ActiveRuleDocument.FIELD_PROFILE_ID, activeRule.getProfileId()) + .field(ActiveRuleDocument.FIELD_INHERITANCE, activeRule.getInheritance()); + if (!params.isEmpty()) { document.startArray(ActiveRuleDocument.FIELD_PARAMS); - for (ActiveRuleParam param: rule.getActiveRuleParams()) { + for (ActiveRuleParamDto param : params) { document.startObject() .field(ActiveRuleDocument.FIELD_PARAM_KEY, param.getKey()) .field(ActiveRuleDocument.FIELD_PARAM_VALUE, param.getValue()) diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileOperationsTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileOperationsTest.java index 37f3e86f92c..3cf15824308 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileOperationsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileOperationsTest.java @@ -21,6 +21,7 @@ package org.sonar.server.qualityprofile; import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import org.apache.ibatis.session.SqlSession; import org.junit.Before; import org.junit.Test; @@ -48,6 +49,7 @@ import org.sonar.core.resource.ResourceDao; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.rule.RuleRegistry; import org.sonar.server.user.MockUserSession; import java.io.Reader; @@ -84,6 +86,9 @@ public class QProfileOperationsTest { @Mock PreviewCache dryRunCache; + @Mock + RuleRegistry ruleRegistry; + List<ProfileExporter> exporters = newArrayList(); List<ProfileImporter> importers = newArrayList(); @@ -93,7 +98,7 @@ public class QProfileOperationsTest { @Before public void setUp() throws Exception { when(myBatis.openSession()).thenReturn(session); - operations = new QProfileOperations(myBatis, dao, activeRuleDao, resourceDao, propertiesDao, exporters, importers, dryRunCache); + operations = new QProfileOperations(myBatis, dao, activeRuleDao, resourceDao, propertiesDao, exporters, importers, dryRunCache, ruleRegistry); } @Test @@ -174,11 +179,14 @@ public class QProfileOperationsTest { ArgumentCaptor<ActiveRuleDto> activeRuleArgument = ArgumentCaptor.forClass(ActiveRuleDto.class); verify(activeRuleDao).insert(activeRuleArgument.capture(), eq(session)); assertThat(activeRuleArgument.getValue().getRulId()).isEqualTo(10); - assertThat(activeRuleArgument.getValue().getSeverity()).isEqualTo(5); + assertThat(activeRuleArgument.getValue().getSeverity()).isEqualTo(4); ArgumentCaptor<ActiveRuleParamDto> activeRuleParamArgument = ArgumentCaptor.forClass(ActiveRuleParamDto.class); verify(activeRuleDao).insert(activeRuleParamArgument.capture(), eq(session)); + assertThat(activeRuleParamArgument.getValue().getKey()).isEqualTo("paramKey"); assertThat(activeRuleParamArgument.getValue().getValue()).isEqualTo("paramValue"); + + verify(ruleRegistry).bulkIndexActiveRules(anyListOf(ActiveRuleDto.class), any(Multimap.class)); } @Test diff --git a/sonar-server/src/test/java/org/sonar/server/rule/RuleRegistryTest.java b/sonar-server/src/test/java/org/sonar/server/rule/RuleRegistryTest.java index 66ee278bf1a..d2f1972e0c2 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule/RuleRegistryTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule/RuleRegistryTest.java @@ -21,8 +21,10 @@ package org.sonar.server.rule; import com.github.tlrx.elasticsearch.test.EsSetup; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Multimap; import org.apache.commons.io.IOUtils; import org.elasticsearch.common.collect.Lists; import org.elasticsearch.search.SearchHit; @@ -36,6 +38,8 @@ import org.sonar.api.rules.ActiveRule; import org.sonar.api.rules.ActiveRuleParam; import org.sonar.api.rules.Rule; import org.sonar.core.profiling.Profiling; +import org.sonar.core.qualityprofile.db.ActiveRuleDto; +import org.sonar.core.qualityprofile.db.ActiveRuleParamDto; import org.sonar.core.rule.RuleDao; import org.sonar.core.rule.RuleDto; import org.sonar.core.rule.RuleParamDto; @@ -43,12 +47,12 @@ import org.sonar.server.search.SearchIndex; import org.sonar.server.search.SearchNode; import org.sonar.test.TestUtils; +import java.io.IOException; import java.util.HashMap; import java.util.List; -import static org.elasticsearch.index.query.FilterBuilders.hasChildFilter; -import static org.elasticsearch.index.query.FilterBuilders.hasParentFilter; -import static org.elasticsearch.index.query.FilterBuilders.termFilter; +import static com.google.common.collect.Lists.newArrayList; +import static org.elasticsearch.index.query.FilterBuilders.*; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -258,6 +262,27 @@ public class RuleRegistryTest { ).execute().actionGet().getHits().getHits(); assertThat(childHit).hasSize(1); assertThat(childHit[0].getId()).isEqualTo("1"); + } + + @Test + public void bulk_index_active_rules() throws IOException { + List<ActiveRuleDto> activeRules = newArrayList(new ActiveRuleDto().setId(1).setProfileId(10).setRuleId(1).setSeverity(2)); + Multimap<Integer, ActiveRuleParamDto> paramsByActiveRule = ArrayListMultimap.create(); + paramsByActiveRule.putAll(1, newArrayList(new ActiveRuleParamDto().setId(1).setActiveRuleId(1).setRulesParameterId(1).setKey("key").setValue("RuleWithParameters"))); + + registry.bulkIndexActiveRules(activeRules, paramsByActiveRule); + assertThat(esSetup.exists("rules", "active_rule", "1")); + SearchHit[] parentHit = esSetup.client().prepareSearch("rules").setFilter( + hasChildFilter("active_rule", termFilter("profileId", 10)) + ).execute().actionGet().getHits().getHits(); + assertThat(parentHit).hasSize(1); + assertThat(parentHit[0].getId()).isEqualTo("1"); + + SearchHit[] childHit = esSetup.client().prepareSearch("rules").setFilter( + hasParentFilter("rule", termFilter("key", "RuleWithParameters")) + ).execute().actionGet().getHits().getHits(); + assertThat(childHit).hasSize(1); + assertThat(childHit[0].getId()).isEqualTo("1"); } } |