]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-23250 Add facilitator method for impacts
authorLéo Geoffroy <leo.geoffroy@sonarsource.com>
Fri, 4 Oct 2024 09:38:02 +0000 (11:38 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 16 Oct 2024 20:03:00 +0000 (20:03 +0000)
server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/ActiveRuleDaoIT.java
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDto.java
server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDtoTest.java [new file with mode: 0644]

index c7d59c7ea978586acc9967b788bee9612f4d9000..3337acfe6b32916fca8938027fb710294729b458 100644 (file)
@@ -21,7 +21,9 @@ package org.sonar.db.qualityprofile;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.function.Consumer;
@@ -29,6 +31,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 import org.sonar.api.impl.utils.TestSystem2;
+import org.sonar.api.issue.impact.SoftwareQuality;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.rules.RuleType;
 import org.sonar.api.server.rule.RuleParamType;
@@ -59,7 +62,14 @@ import static org.sonar.db.qualityprofile.ActiveRuleDto.createFor;
 class ActiveRuleDaoIT {
 
   private static final long NOW = 10_000_000L;
-  public static final String IMPACTS = "{\\“SECURITY\\”:\\”BLOCKER\\”,\\”MAINTAINABILITY\\”:\\”INFO\\”}";
+
+  static {
+    Map<SoftwareQuality, org.sonar.api.issue.impact.Severity> map = new LinkedHashMap<>();
+    map.put(SoftwareQuality.MAINTAINABILITY, org.sonar.api.issue.impact.Severity.INFO);
+    map.put(SoftwareQuality.RELIABILITY, org.sonar.api.issue.impact.Severity.HIGH);
+    IMPACTS = map;
+  }
+  public static final Map<SoftwareQuality, org.sonar.api.issue.impact.Severity> IMPACTS;
 
   private QProfileDto profile1;
   private QProfileDto profile2;
@@ -121,9 +131,9 @@ class ActiveRuleDaoIT {
 
   @Test
   void selectByRuleIds() {
-    ActiveRuleDto activeRule1 = createFor(profile1, rule1).setSeverity(BLOCKER);
-    ActiveRuleDto activeRule2 = createFor(profile1, rule2).setSeverity(BLOCKER);
-    ActiveRuleDto activeRule3 = createFor(profile2, rule1).setSeverity(BLOCKER);
+    ActiveRuleDto activeRule1 = createFor(profile1, rule1).setSeverity(BLOCKER).setImpacts(Map.of(SoftwareQuality.MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW));
+    ActiveRuleDto activeRule2 = createFor(profile1, rule2).setSeverity(BLOCKER).setImpacts(Map.of(SoftwareQuality.MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW));
+    ActiveRuleDto activeRule3 = createFor(profile2, rule1).setSeverity(BLOCKER).setImpacts(Map.of(SoftwareQuality.MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW));
     underTest.insert(dbSession, activeRule1);
     underTest.insert(dbSession, activeRule2);
     underTest.insert(dbSession, activeRule3);
@@ -174,8 +184,8 @@ class ActiveRuleDaoIT {
 
     assertThat(underTest.selectByTypeAndProfileUuids(dbSession, singletonList(RuleType.VULNERABILITY.getDbConstant()),
       singletonList(profile1.getKee())))
-      .extracting(OrgActiveRuleDto::getOrgProfileUuid, OrgActiveRuleDto::getRuleUuid)
-      .contains(tuple(profile1.getKee(), rule1.getUuid()));
+        .extracting(OrgActiveRuleDto::getOrgProfileUuid, OrgActiveRuleDto::getRuleUuid)
+        .contains(tuple(profile1.getKee(), rule1.getUuid()));
   }
 
   @Test
@@ -187,7 +197,7 @@ class ActiveRuleDaoIT {
 
     assertThat(underTest.selectByTypeAndProfileUuids(dbSession, singletonList(RuleType.VULNERABILITY.getDbConstant()),
       singletonList(profile1.getKee())))
-      .isEmpty();
+        .isEmpty();
   }
 
   @Test
@@ -201,14 +211,14 @@ class ActiveRuleDaoIT {
       underTest.selectByTypeAndProfileUuids(dbSession,
         singletonList(RuleType.VULNERABILITY.getDbConstant()),
         singletonList(profile1.getKee())))
-      .extracting(OrgActiveRuleDto::getOrgProfileUuid, OrgActiveRuleDto::getRuleUuid)
-      .contains(tuple(profile1.getKee(), rule1.getUuid()));
+          .extracting(OrgActiveRuleDto::getOrgProfileUuid, OrgActiveRuleDto::getRuleUuid)
+          .contains(tuple(profile1.getKee(), rule1.getUuid()));
 
     assertThat(
       underTest.selectByTypeAndProfileUuids(dbSession,
         asList(RuleType.CODE_SMELL.getDbConstant(), RuleType.SECURITY_HOTSPOT.getDbConstant(), RuleType.BUG.getDbConstant()),
         singletonList(profile1.getKee())))
-      .isEmpty();
+          .isEmpty();
   }
 
   @Test
@@ -319,7 +329,7 @@ class ActiveRuleDaoIT {
     ActiveRuleDto activeRule = createFor(profile1, rule1)
       .setSeverity(BLOCKER)
       .setInheritance(INHERITED)
-      .setImpacts("{\"RELIABILITY\":\"INFO\"}")
+      .setImpactsString("{\"RELIABILITY\":\"INFO\"}")
       .setCreatedAt(1000L)
       .setUpdatedAt(2000L);
     underTest.insert(dbSession, activeRule);
@@ -630,8 +640,8 @@ class ActiveRuleDaoIT {
     assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(singletonList(profileWithoutActiveRule)).build())).isEmpty();
     assertThat(underTest.countActiveRulesByQuery(dbSession,
       builder.setProfiles(asList(profile1, profile2, profileWithoutActiveRule)).build())).containsOnly(
-      entry(profile1.getKee(), 2L),
-      entry(profile2.getKee(), 1L));
+        entry(profile1.getKee(), 2L),
+        entry(profile2.getKee(), 1L));
     assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(emptyList()).build())).isEmpty();
   }
 
@@ -665,10 +675,10 @@ class ActiveRuleDaoIT {
     ActiveRuleCountQuery.Builder builder = ActiveRuleCountQuery.builder();
     assertThat(underTest.countActiveRulesByQuery(dbSession,
       builder.setProfiles(asList(profile1, profile2)).setInheritance(OVERRIDES).build()))
-      .containsOnly(entry(profile1.getKee(), 1L), entry(profile2.getKee(), 1L));
+        .containsOnly(entry(profile1.getKee(), 1L), entry(profile2.getKee(), 1L));
     assertThat(underTest.countActiveRulesByQuery(dbSession,
       builder.setProfiles(asList(profile1, profile2)).setInheritance(INHERITED).build()))
-      .containsOnly(entry(profile2.getKee(), 1L));
+        .containsOnly(entry(profile2.getKee(), 1L));
   }
 
   @Test
index b8cff56f10fee886704b1e0ee58145e54d01f665..8e08e754dc5ec3424bbccafba733ab8ebddbd09d 100644 (file)
  */
 package org.sonar.db.qualityprofile;
 
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import java.lang.reflect.Type;
+import java.util.Map;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
+import org.sonar.api.issue.impact.Severity;
+import org.sonar.api.issue.impact.SoftwareQuality;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rules.ActiveRule;
 import org.sonar.db.rule.RuleDto;
@@ -35,6 +41,9 @@ public class ActiveRuleDto {
 
   public static final String INHERITED = ActiveRule.INHERITED;
   public static final String OVERRIDES = ActiveRule.OVERRIDES;
+  private static final Gson GSON = new Gson();
+  private static final Type TYPE = new TypeToken<Map<SoftwareQuality, Severity>>() {
+  }.getType();
 
   private String uuid;
   private String profileUuid;
@@ -162,16 +171,24 @@ public class ActiveRuleDto {
     return this;
   }
 
-  @CheckForNull
-  public String getImpacts() {
-    return impacts;
+  public Map<SoftwareQuality, Severity> getImpacts() {
+    return impacts != null ? GSON.fromJson(impacts, TYPE) : Map.of();
+  }
+
+  public String getImpactsString() {
+    return this.impacts;
   }
 
-  public ActiveRuleDto setImpacts(@Nullable String impacts) {
+  public ActiveRuleDto setImpactsString(@Nullable String impacts) {
     this.impacts = impacts;
     return this;
   }
 
+  public ActiveRuleDto setImpacts(Map<SoftwareQuality, Severity> impacts) {
+    this.impacts = !impacts.isEmpty() ? GSON.toJson(impacts, TYPE) : null;
+    return this;
+  }
+
   public boolean isExternal() {
     return this.isExternal;
   }
index 4ac4ed02af189b713883436225e730920f705803..92a9b7fca53738a2e0fa1c763d1e1acc65430a1d 100644 (file)
@@ -9,7 +9,7 @@
     a.rule_uuid as "ruleUuid",
     a.failure_level as "severity",
     a.inheritance as "inheritance",
-    a.impacts as "impacts",
+    a.impacts as "impactsString",
     r.plugin_rule_key as "rulefield",
     r.plugin_name as "repository",
     rp.uuid as "ruleProfileUuid",
@@ -24,7 +24,7 @@
     a.rule_uuid as "ruleUuid",
     a.failure_level as "severity",
     a.inheritance as "inheritance",
-    a.impacts as "impacts",
+    a.impacts as "impactsString",
     a.prioritized_rule as "prioritizedRule",
     r.plugin_rule_key as "rulefield",
     r.plugin_name as "repository",
@@ -58,7 +58,7 @@
       #{ruleUuid, jdbcType=VARCHAR},
       #{severity, jdbcType=INTEGER},
       #{inheritance, jdbcType=VARCHAR},
-      #{impacts, jdbcType=VARCHAR},
+      #{impactsString, jdbcType=VARCHAR},
       #{prioritizedRule, jdbcType=BOOLEAN},
       #{createdAt, jdbcType=BIGINT},
       #{updatedAt, jdbcType=BIGINT}
@@ -70,7 +70,7 @@
     set
       failure_level = #{severity, jdbcType=INTEGER},
       inheritance = #{inheritance, jdbcType=VARCHAR},
-      impacts = #{impacts, jdbcType=VARCHAR},
+      impacts = #{impactsString, jdbcType=VARCHAR},
       prioritized_rule = #{prioritizedRule, jdbcType=BOOLEAN},
       updated_at = #{updatedAt, jdbcType=BIGINT}
     where
@@ -90,7 +90,8 @@
       from rules_profiles rp
       where rp.uuid = profile_uuid
       and rp.uuid in
-        <foreach collection="rulesProfileUuids" open="(" close=")" item="rulesProfileUuid" separator=",">#{rulesProfileUuid, jdbcType=VARCHAR}</foreach>
+        <foreach collection="rulesProfileUuids" open="(" close=")" item="rulesProfileUuid"
+                 separator=",">#{rulesProfileUuid, jdbcType=VARCHAR}</foreach>
       )
   </delete>
 
     <include refid="activeRuleKeyJoin"/>
     where
     r.uuid in <foreach collection="ruleUuids" item="ruleUuid" separator="," open="(" close=")">#{ruleUuid, jdbcType=VARCHAR}</foreach>
-    and rp.uuid in <foreach collection="ruleProfileUuids" item="ruleProfileUuid" separator="," open="(" close=")">#{ruleProfileUuid, jdbcType=VARCHAR}</foreach>
+    and rp.uuid in <foreach collection="ruleProfileUuids" item="ruleProfileUuid" separator="," open="("
+                            close=")">#{ruleProfileUuid, jdbcType=VARCHAR}</foreach>
   </select>
 
   <select id="selectPrioritizedRules" parameterType="map" resultType="org.sonar.db.qualityprofile.OrgActiveRuleDto">
     ar.uuid as "uuid",
     ar.failure_level as "severity",
     ar.inheritance as "inheritance",
-    ar.impacts as "impacts",
+    ar.impacts as "impactsString",
     ar.prioritized_rule as "prioritizedRule",
     r.uuid as "ruleUuid",
     r.plugin_name as "repository",
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDtoTest.java
new file mode 100644 (file)
index 0000000..aa652fb
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 SonarSource SA
+ * mailto:info 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.db.qualityprofile;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+import org.sonar.api.issue.impact.Severity;
+import org.sonar.api.issue.impact.SoftwareQuality;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class ActiveRuleDtoTest {
+
+  @Test
+  void setImpacts_shouldStoreAsString() {
+    ActiveRuleDto activeRuleDto = new ActiveRuleDto();
+    Map<SoftwareQuality, Severity> map = new LinkedHashMap<>();
+    map.put(SoftwareQuality.MAINTAINABILITY, Severity.INFO);
+    map.put(SoftwareQuality.RELIABILITY, Severity.INFO);
+
+    activeRuleDto.setImpacts(map);
+
+    assertThat(activeRuleDto.getImpactsString()).isEqualTo("{\"MAINTAINABILITY\":\"INFO\",\"RELIABILITY\":\"INFO\"}");
+    assertThat(activeRuleDto.getImpacts()).containsEntry(SoftwareQuality.MAINTAINABILITY, Severity.INFO)
+      .containsEntry(SoftwareQuality.RELIABILITY, Severity.INFO);
+  }
+
+  @Test
+  void setImpacts_shouldReturnEmpty() {
+    ActiveRuleDto activeRuleDto = new ActiveRuleDto();
+    Map<SoftwareQuality, Severity> map = new LinkedHashMap<>();
+    activeRuleDto.setImpacts(map);
+
+    assertThat(activeRuleDto.getImpactsString()).isNull();
+    assertThat(activeRuleDto.getImpacts()).isEmpty();
+  }
+
+}