aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server-common/src
diff options
context:
space:
mode:
authorDejan Milisavljevic <dejan.milisavljevic@sonarsource.com>2024-12-06 16:27:58 +0100
committersonartech <sonartech@sonarsource.com>2024-12-06 20:03:27 +0000
commitd39f81fbe2eef34cf078a1f7459bff6f14360af8 (patch)
treef5a41065aa3ed50f7b3768104dacc9916e1b3358 /server/sonar-server-common/src
parentd81c86acf04859937a0da345c35b2536ad586271 (diff)
downloadsonarqube-d39f81fbe2eef34cf078a1f7459bff6f14360af8.tar.gz
sonarqube-d39f81fbe2eef34cf078a1f7459bff6f14360af8.zip
SONAR-23688 Index active rules impacts
Diffstat (limited to 'server/sonar-server-common/src')
-rw-r--r--server/sonar-server-common/src/it/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexerIT.java56
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleDoc.java39
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexer.java3
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java44
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()
+ ;
}
}