diff options
author | Dejan Milisavljevic <dejan.milisavljevic@sonarsource.com> | 2024-12-06 16:27:58 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-12-06 20:03:27 +0000 |
commit | d39f81fbe2eef34cf078a1f7459bff6f14360af8 (patch) | |
tree | f5a41065aa3ed50f7b3768104dacc9916e1b3358 /server/sonar-server-common/src | |
parent | d81c86acf04859937a0da345c35b2536ad586271 (diff) | |
download | sonarqube-d39f81fbe2eef34cf078a1f7459bff6f14360af8.tar.gz sonarqube-d39f81fbe2eef34cf078a1f7459bff6f14360af8.zip |
SONAR-23688 Index active rules impacts
Diffstat (limited to 'server/sonar-server-common/src')
4 files changed, 85 insertions, 57 deletions
diff --git a/server/sonar-server-common/src/it/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexerIT.java b/server/sonar-server-common/src/it/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexerIT.java index b355bee3307..f4d1537cccc 100644 --- a/server/sonar-server-common/src/it/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexerIT.java +++ b/server/sonar-server-common/src/it/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexerIT.java @@ -23,12 +23,13 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import org.assertj.core.groups.Tuple; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; import org.sonar.db.es.EsQueueDto; +import org.sonar.db.issue.ImpactDto; import org.sonar.db.qualityprofile.ActiveRuleDto; import org.sonar.db.qualityprofile.QProfileDto; import org.sonar.db.rule.RuleDto; @@ -39,45 +40,49 @@ import static java.util.Arrays.stream; import static java.util.Collections.emptySet; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.issue.impact.Severity.BLOCKER; +import static org.sonar.api.issue.impact.Severity.LOW; +import static org.sonar.api.issue.impact.SoftwareQuality.RELIABILITY; +import static org.sonar.api.issue.impact.SoftwareQuality.SECURITY; import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE; -public class ActiveRuleIndexerIT { +class ActiveRuleIndexerIT { - private System2 system2 = System2.INSTANCE; + private final System2 system2 = System2.INSTANCE; - @Rule - public DbTester db = DbTester.create(system2); + @RegisterExtension + private final DbTester db = DbTester.create(system2); - @Rule - public EsTester es = EsTester.create(); + @RegisterExtension + private final EsTester es = EsTester.create(); - private ActiveRuleIndexer underTest = new ActiveRuleIndexer(db.getDbClient(), es.client()); + private final ActiveRuleIndexer underTest = new ActiveRuleIndexer(db.getDbClient(), es.client()); private RuleDto rule1; private RuleDto rule2; private QProfileDto profile1; private QProfileDto profile2; - @Before - public void before() { - rule1 = db.rules().insert(); + @BeforeEach + void before() { + rule1 = db.rules().insert(r -> r.replaceAllDefaultImpacts(List.of(new ImpactDto(SECURITY, BLOCKER), new ImpactDto(RELIABILITY, LOW)))); rule2 = db.rules().insert(); profile1 = db.qualityProfiles().insert(); profile2 = db.qualityProfiles().insert(); } @Test - public void getIndexTypes() { + void getIndexTypes() { assertThat(underTest.getIndexTypes()).containsExactly(TYPE_ACTIVE_RULE); } @Test - public void indexOnStartup_does_nothing_if_no_data() { + void indexOnStartup_does_nothing_if_no_data() { underTest.indexOnStartup(emptySet()); assertThat(es.countDocuments(TYPE_ACTIVE_RULE)).isZero(); } @Test - public void indexOnStartup_indexes_all_data() { + void indexOnStartup_indexes_all_data() { ActiveRuleDto activeRule = db.qualityProfiles().activateRule(profile1, rule1); underTest.indexOnStartup(emptySet()); @@ -89,7 +94,7 @@ public class ActiveRuleIndexerIT { } @Test - public void indexAll_indexes_all_data() { + void indexAll_indexes_all_data() { ActiveRuleDto activeRule = db.qualityProfiles().activateRule(profile1, rule1); underTest.indexAll(); @@ -101,7 +106,7 @@ public class ActiveRuleIndexerIT { } @Test - public void test_commitAndIndex() { + void test_commitAndIndex() { ActiveRuleDto ar1 = db.qualityProfiles().activateRule(profile1, rule1); ActiveRuleDto ar2 = db.qualityProfiles().activateRule(profile2, rule1); db.qualityProfiles().activateRule(profile2, rule2); @@ -113,7 +118,7 @@ public class ActiveRuleIndexerIT { } @Test - public void commitAndIndex_empty_list() { + void commitAndIndex_empty_list() { db.qualityProfiles().activateRule(profile1, rule1); underTest.commitAndIndex(db.getSession(), Collections.emptyList()); @@ -123,7 +128,7 @@ public class ActiveRuleIndexerIT { } @Test - public void commitAndIndex_keeps_elements_to_recover_in_ES_QUEUE_on_errors() { + void commitAndIndex_keeps_elements_to_recover_in_ES_QUEUE_on_errors() { ActiveRuleDto ar = db.qualityProfiles().activateRule(profile1, rule1); es.lockWrites(TYPE_ACTIVE_RULE); @@ -135,7 +140,7 @@ public class ActiveRuleIndexerIT { } @Test - public void commitAndIndex_deletes_the_documents_that_dont_exist_in_database() { + void commitAndIndex_deletes_the_documents_that_dont_exist_in_database() { ActiveRuleDto ar = db.qualityProfiles().activateRule(profile1, rule1); indexAll(); assertThat(es.countDocuments(TYPE_ACTIVE_RULE)).isOne(); @@ -148,7 +153,7 @@ public class ActiveRuleIndexerIT { } @Test - public void index_fails_and_deletes_doc_if_docIdType_is_unsupported() { + void index_fails_and_deletes_doc_if_docIdType_is_unsupported() { EsQueueDto item = EsQueueDto.create(TYPE_ACTIVE_RULE.format(), "the_id", "unsupported", "the_routing"); db.getDbClient().esQueueDao().insert(db.getSession(), item); @@ -159,7 +164,7 @@ public class ActiveRuleIndexerIT { } @Test - public void commitDeletionOfProfiles() { + void commitDeletionOfProfiles() { ActiveRuleDto ar1 = db.qualityProfiles().activateRule(profile1, rule1); db.qualityProfiles().activateRule(profile2, rule1); db.qualityProfiles().activateRule(profile2, rule2); @@ -172,7 +177,7 @@ public class ActiveRuleIndexerIT { } @Test - public void commitDeletionOfProfiles_does_nothing_if_profiles_are_not_indexed() { + void commitDeletionOfProfiles_does_nothing_if_profiles_are_not_indexed() { db.qualityProfiles().activateRule(profile1, rule1); indexAll(); assertThat(es.countDocuments(TYPE_ACTIVE_RULE)).isOne(); @@ -211,7 +216,8 @@ public class ActiveRuleIndexerIT { assertThat(doc1) .matches(doc -> doc.getId().equals("ar_" + activeRule.getUuid())) .matches(doc -> doc.getRuleProfileUuid().equals(profile.getRulesProfileUuid())) - .matches(doc -> doc.getSeverity().equals(activeRule.getSeverityString())); + .matches(doc -> doc.getSeverity().equals(activeRule.getSeverityString())) + .matches(doc -> doc.getImpacts().equals(activeRule.getImpacts())); } private void indexAll() { diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleDoc.java b/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleDoc.java index 59596fa730c..eccf9820dfc 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleDoc.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleDoc.java @@ -20,19 +20,24 @@ package org.sonar.server.qualityprofile.index; import com.google.common.collect.Maps; +import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import javax.annotation.Nullable; +import org.sonar.api.issue.impact.Severity; +import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.server.es.BaseDoc; -import org.sonar.server.qualityprofile.ActiveRuleInheritance; -import static org.apache.commons.lang3.StringUtils.containsIgnoreCase; +import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_IMPACTS; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_INHERITANCE; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_UUID; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_UUID; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_PRIORITIZED_RULE; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_UUID; +import static org.sonar.server.rule.index.RuleIndexDefinition.SUB_FIELD_SEVERITY; +import static org.sonar.server.rule.index.RuleIndexDefinition.SUB_FIELD_SOFTWARE_QUALITY; import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE; public class ActiveRuleDoc extends BaseDoc { @@ -44,6 +49,7 @@ public class ActiveRuleDoc extends BaseDoc { setField(FIELD_ACTIVE_RULE_UUID, uuid); } + // Invoked dynamically public ActiveRuleDoc(Map<String, Object> source) { super(TYPE_ACTIVE_RULE, source); } @@ -95,17 +101,26 @@ public class ActiveRuleDoc extends BaseDoc { return this; } - ActiveRuleInheritance getInheritance() { - String inheritance = getNullableField(FIELD_ACTIVE_RULE_INHERITANCE); - if (inheritance == null || inheritance.isEmpty() || - containsIgnoreCase(inheritance, "none")) { - return ActiveRuleInheritance.NONE; - } else if (containsIgnoreCase(inheritance, "herit")) { - return ActiveRuleInheritance.INHERITED; - } else if (containsIgnoreCase(inheritance, "over")) { - return ActiveRuleInheritance.OVERRIDES; + public ActiveRuleDoc setImpacts(Map<SoftwareQuality, Severity> impacts) { + List<Map<String, String>> convertedMap = impacts + .entrySet() + .stream() + .map(entry -> Map.of( + SUB_FIELD_SOFTWARE_QUALITY, entry.getKey().name(), + SUB_FIELD_SEVERITY, entry.getValue().name())) + .toList(); + setField(FIELD_ACTIVE_RULE_IMPACTS, convertedMap); + return this; + } + + public Map<SoftwareQuality, Severity> getImpacts() { + Object objectValue = getField(FIELD_ACTIVE_RULE_IMPACTS); + if (objectValue instanceof List<?> valueList) { + return valueList.stream() + .map(v -> (Map<String, String>) v) + .collect(Collectors.toMap(v -> SoftwareQuality.valueOf(v.get(SUB_FIELD_SOFTWARE_QUALITY)), v -> Severity.valueOf(v.get(SUB_FIELD_SEVERITY)))); } else { - throw new IllegalStateException("Value \"" + inheritance + "\" is not valid for rule's inheritance"); + return Map.of(); } } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexer.java b/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexer.java index d21651b379e..e7ab11b0f9a 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexer.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexer.java @@ -226,7 +226,8 @@ public class ActiveRuleIndexer implements ResilientIndexer { .setRuleUuid(dto.getRuleUuid()) .setRuleProfileUuid(dto.getRuleProfileUuid()) .setSeverity(SeverityUtil.getSeverityFromOrdinal(dto.getSeverity())) - .setPrioritizedRule(dto.getPrioritizedRule()); + .setPrioritizedRule(dto.getPrioritizedRule()) + .setImpacts(dto.getImpacts()); // all the fields must be present, even if value is null String inheritance = dto.getInheritance(); doc.setInheritance(inheritance == null ? ActiveRuleInheritance.NONE.name() : inheritance); diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java index 6da248e2eac..7304e98016e 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java @@ -66,12 +66,12 @@ public class RuleIndexDefinition implements IndexDefinition { public static final String FIELD_RULE_SANS_TOP_25 = "sansTop25"; public static final String FIELD_RULE_SONARSOURCE_SECURITY = "sonarsourceSecurity"; public static final String FIELD_RULE_TAGS = "tags"; - - public static final Set<String> SORT_FIELDS = Set.of( - FIELD_RULE_NAME, - FIELD_RULE_UPDATED_AT, - FIELD_RULE_CREATED_AT, - FIELD_RULE_KEY); + public static final String FIELD_RULE_CLEAN_CODE_ATTRIBUTE_CATEGORY = "cleanCodeAttributeCategory"; + public static final String FIELD_RULE_IMPACTS = "impacts"; + public static final String SUB_FIELD_SOFTWARE_QUALITY = "softwareQuality"; + public static final String SUB_FIELD_SEVERITY = "severity"; + public static final String FIELD_RULE_IMPACT_SOFTWARE_QUALITY = FIELD_RULE_IMPACTS + "." + SUB_FIELD_SOFTWARE_QUALITY; + public static final String FIELD_RULE_IMPACT_SEVERITY = FIELD_RULE_IMPACTS + "." + SUB_FIELD_SEVERITY; // Active rule fields public static final IndexRelationType TYPE_ACTIVE_RULE = IndexType.relation(TYPE_RULE, "activeRule"); @@ -79,14 +79,16 @@ public class RuleIndexDefinition implements IndexDefinition { public static final String FIELD_ACTIVE_RULE_INHERITANCE = "activeRule_inheritance"; public static final String FIELD_ACTIVE_RULE_PROFILE_UUID = "activeRule_ruleProfile"; public static final String FIELD_ACTIVE_RULE_SEVERITY = "activeRule_severity"; - - public static final String FIELD_RULE_CLEAN_CODE_ATTRIBUTE_CATEGORY = "cleanCodeAttributeCategory"; - public static final String FIELD_RULE_IMPACTS = "impacts"; - public static final String SUB_FIELD_SOFTWARE_QUALITY = "softwareQuality"; - public static final String SUB_FIELD_SEVERITY = "severity"; - public static final String FIELD_RULE_IMPACT_SOFTWARE_QUALITY = FIELD_RULE_IMPACTS + "." + SUB_FIELD_SOFTWARE_QUALITY; - public static final String FIELD_RULE_IMPACT_SEVERITY = FIELD_RULE_IMPACTS + "." + SUB_FIELD_SEVERITY; public static final String FIELD_PRIORITIZED_RULE = "activeRule_prioritizedRule"; + public static final String FIELD_ACTIVE_RULE_IMPACTS = "activeRule_impacts"; + public static final String FIELD_ACTIVE_RULE_IMPACT_SOFTWARE_QUALITY = FIELD_ACTIVE_RULE_IMPACTS + "." + SUB_FIELD_SOFTWARE_QUALITY; + public static final String FIELD_ACTIVE_RULE_IMPACT_SEVERITY = FIELD_ACTIVE_RULE_IMPACTS + "." + SUB_FIELD_SEVERITY; + + public static final Set<String> SORT_FIELDS = Set.of( + FIELD_RULE_NAME, + FIELD_RULE_UPDATED_AT, + FIELD_RULE_CREATED_AT, + FIELD_RULE_KEY); private final Configuration config; private final boolean enableSource; @@ -163,11 +165,15 @@ public class RuleIndexDefinition implements IndexDefinition { .build(); // Active rule - index.createTypeMapping(TYPE_ACTIVE_RULE) - .keywordFieldBuilder(FIELD_ACTIVE_RULE_UUID).disableNorms().build() - .keywordFieldBuilder(FIELD_ACTIVE_RULE_PROFILE_UUID).disableNorms().build() - .keywordFieldBuilder(FIELD_ACTIVE_RULE_INHERITANCE).disableNorms().build() - .keywordFieldBuilder(FIELD_ACTIVE_RULE_SEVERITY).disableNorms().build() - .createBooleanField(FIELD_PRIORITIZED_RULE); + TypeMapping activeRuleMapping = index.createTypeMapping(TYPE_ACTIVE_RULE); + activeRuleMapping.keywordFieldBuilder(FIELD_ACTIVE_RULE_UUID).disableNorms().build(); + activeRuleMapping.keywordFieldBuilder(FIELD_ACTIVE_RULE_PROFILE_UUID).disableNorms().build(); + activeRuleMapping.keywordFieldBuilder(FIELD_ACTIVE_RULE_INHERITANCE).disableNorms().build(); + activeRuleMapping.keywordFieldBuilder(FIELD_ACTIVE_RULE_SEVERITY).disableNorms().build(); + activeRuleMapping.createBooleanField(FIELD_PRIORITIZED_RULE); + activeRuleMapping.nestedFieldBuilder(FIELD_ACTIVE_RULE_IMPACTS) + .addKeywordField(SUB_FIELD_SOFTWARE_QUALITY) + .addKeywordField(SUB_FIELD_SEVERITY).build() + ; } } |