]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16614 add ruleDescriptionContextKey to IssueDto and adapt mybatis mapping
authorAurelien Poscia <aurelien.poscia@sonarsource.com>
Tue, 5 Jul 2022 09:13:23 +0000 (11:13 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 8 Jul 2022 20:02:48 +0000 (20:02 +0000)
server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java
server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueTesting.java
server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDaoTest.java
sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java

index ef374054f5538700f7756c2225fb0f0728b9fb60..8e6ad9f5a36280c9ace1f6c518d072adccdd4c37 100644 (file)
@@ -75,6 +75,7 @@ public final class IssueDto implements Serializable {
   private long updatedAt;
   private boolean quickFixAvailable;
   private boolean isNewCodeReferenceIssue;
+  private String ruleDescriptionContextKey;
 
   // functional dates stored as Long
   private Long issueCreationDate;
@@ -698,6 +699,15 @@ public final class IssueDto implements Serializable {
     return Optional.ofNullable(closedChangeData);
   }
 
+  public Optional<String> getOptionalRuleDescriptionContextKey() {
+    return Optional.ofNullable(ruleDescriptionContextKey);
+  }
+
+  public IssueDto setRuleDescriptionContextKey(@Nullable String ruleDescriptionContextKey) {
+    this.ruleDescriptionContextKey = ruleDescriptionContextKey;
+    return this;
+  }
+
   @Override
   public String toString() {
     return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
index 0577ae6452bcbd397537139117fdce1b18da8b7b..056a1651b2dfc33439fb76d6589501135c348bc6 100644 (file)
@@ -75,6 +75,7 @@ public class IssueTesting {
       .setMessage("message_" + randomAlphabetic(5))
       .setChecksum("checksum_" + randomAlphabetic(5))
       .setTags(newHashSet("tag_" + randomAlphanumeric(5), "tag_" + randomAlphanumeric(5)))
+      .setRuleDescriptionContextKey("context_" + randomAlphabetic(5))
       .setIssueCreationDate(new Date(System.currentTimeMillis() - 2_000))
       .setIssueUpdateDate(new Date(System.currentTimeMillis() - 1_500))
       .setCreatedAt(System.currentTimeMillis() - 1_000)
index 7cd7edc76f6d4d6fa1b8762d6e5c482f63cbab0c..d78ed8ec0b16c696981495ff02798b1486ac397b 100644 (file)
@@ -20,6 +20,7 @@
     i.assignee as assigneeUuid,
     i.author_login as authorLogin,
     i.tags as tagsString,
+    i.rule_description_context_key as ruleDescriptionContextKey,
     i.issue_creation_date as issueCreationTime,
     i.issue_update_date as issueUpdateTime,
     i.issue_close_date as issueCloseTime,
@@ -57,6 +58,7 @@
     i.assignee,
     i.author_login,
     i.tags,
+    i.rule_description_context_key,
     i.issue_creation_date,
     i.issue_update_date,
     i.issue_close_date,
 
   <insert id="insert" parameterType="Issue" useGeneratedKeys="false">
     INSERT INTO issues (kee, rule_uuid, severity, manual_severity,
-    message, line, locations, gap, effort, status, tags,
+    message, line, locations, gap, effort, status, tags, rule_description_context_key,
     resolution, checksum, assignee, author_login, issue_creation_date, issue_update_date,
     issue_close_date, created_at, updated_at, component_uuid, project_uuid, issue_type, quick_fix_available)
     VALUES (
     #{manualSeverity,jdbcType=BOOLEAN}, #{message,jdbcType=VARCHAR}, #{line,jdbcType=INTEGER},
     #{locations,jdbcType=BINARY},
     #{gap,jdbcType=DOUBLE}, #{effort,jdbcType=INTEGER}, #{status,jdbcType=VARCHAR},
-    #{tagsString,jdbcType=VARCHAR}, #{resolution,jdbcType=VARCHAR},
+    #{tagsString,jdbcType=VARCHAR},
+    #{ruleDescriptionContextKey,jdbcType=VARCHAR},
+    #{resolution,jdbcType=VARCHAR},
     #{checksum,jdbcType=VARCHAR},
     #{assigneeUuid,jdbcType=VARCHAR},
     #{authorLogin,jdbcType=VARCHAR},
     assignee=#{assigneeUuid,jdbcType=VARCHAR},
     author_login=#{authorLogin,jdbcType=VARCHAR},
     tags=#{tagsString,jdbcType=VARCHAR},
+    rule_description_context_key=#{ruleDescriptionContextKey,jdbcType=VARCHAR},
     project_uuid=#{projectUuid,jdbcType=VARCHAR},
     issue_creation_date=#{issueCreationTime,jdbcType=BIGINT},
     issue_update_date=#{issueUpdateTime,jdbcType=BIGINT},
     assignee=#{assigneeUuid,jdbcType=VARCHAR},
     author_login=#{authorLogin,jdbcType=VARCHAR},
     tags=#{tagsString,jdbcType=VARCHAR},
+    rule_description_context_key=#{ruleDescriptionContextKey,jdbcType=VARCHAR},
     component_uuid=#{componentUuid,jdbcType=VARCHAR},
     project_uuid=#{projectUuid,jdbcType=VARCHAR},
     issue_creation_date=#{issueCreationTime,jdbcType=BIGINT},
index 607df35387a94acd77e0fd821f6d28665ab11168..c74730f99a4fa8d812377cf492375cab894d4646 100644 (file)
@@ -71,6 +71,7 @@ public class IssueDaoTest {
   private static final RuleDto RULE = RuleTesting.newXooX1();
   private static final String ISSUE_KEY1 = "I1";
   private static final String ISSUE_KEY2 = "I2";
+  private static final String TEST_CONTEXT_KEY = "test_context_key";
 
   private static final RuleType[] RULE_TYPES_EXCEPT_HOTSPOT = Stream.of(RuleType.values())
     .filter(r -> r != RuleType.SECURITY_HOTSPOT)
@@ -95,6 +96,7 @@ public class IssueDaoTest {
     assertThat(issue.getType()).isEqualTo(2);
     assertThat(issue.isManualSeverity()).isFalse();
     assertThat(issue.getMessage()).isEqualTo("the message");
+    assertThat(issue.getOptionalRuleDescriptionContextKey()).contains(TEST_CONTEXT_KEY);
     assertThat(issue.getLine()).isEqualTo(500);
     assertThat(issue.getEffort()).isEqualTo(10L);
     assertThat(issue.getGap()).isEqualTo(3.14);
@@ -376,12 +378,8 @@ public class IssueDaoTest {
   @Test
   public void selectByKey_givenOneIssueWithoutQuickFix_selectOneIssueWithoutQuickFix() {
     prepareIssuesComponent();
-    underTest.insert(db.getSession(), newIssueDto(ISSUE_KEY1)
-      .setMessage("the message")
-      .setRuleUuid(RULE.getUuid())
-      .setComponentUuid(FILE_UUID)
-      .setProjectUuid(PROJECT_UUID)
-      .setQuickFixAvailable(false));
+    String issueKey = ISSUE_KEY1;
+    underTest.insert(db.getSession(), createIssueWithKey(issueKey));
 
     IssueDto issue = underTest.selectOrFailByKey(db.getSession(), ISSUE_KEY1);
 
@@ -670,6 +668,83 @@ public class IssueDaoTest {
     assertThat(underTest.selectOrFailByKey(db.getSession(), ISSUE_KEY1).isNewCodeReferenceIssue()).isFalse();
   }
 
+  @Test
+  public void selectByKey_givenOneIssueWithoutRuleDescriptionContextKey_returnsEmptyOptional() {
+    prepareIssuesComponent();
+    underTest.insert(db.getSession(), createIssueWithKey(ISSUE_KEY1)
+      .setRuleDescriptionContextKey(null)
+    );
+    IssueDto issue1 = underTest.selectOrFailByKey(db.getSession(), ISSUE_KEY1);
+
+    assertThat(issue1.getOptionalRuleDescriptionContextKey()).isEmpty();
+  }
+
+  @Test
+  public void selectByKey_givenOneIssueWithRuleDescriptionContextKey_returnsContextKey() {
+    prepareIssuesComponent();
+    underTest.insert(db.getSession(), createIssueWithKey(ISSUE_KEY1)
+      .setRuleDescriptionContextKey(TEST_CONTEXT_KEY)
+    );
+
+    IssueDto issue1 = underTest.selectOrFailByKey(db.getSession(), ISSUE_KEY1);
+
+    assertThat(issue1.getOptionalRuleDescriptionContextKey()).contains(TEST_CONTEXT_KEY);
+  }
+
+  @Test
+  public void update_whenUpdatingRuleDescriptionContextKeyToNull_returnsEmptyContextKey() {
+    prepareIssuesComponent();
+    IssueDto issue = createIssueWithKey(ISSUE_KEY1).setRuleDescriptionContextKey(TEST_CONTEXT_KEY);
+    underTest.insert(db.getSession(), issue);
+
+    issue.setRuleDescriptionContextKey(null);
+    underTest.update(db.getSession(), issue);
+
+    issue = underTest.selectOrFailByKey(db.getSession(), ISSUE_KEY1);
+    assertThat(issue.getOptionalRuleDescriptionContextKey()).isEmpty();
+  }
+
+  @Test
+  public void update_whenUpdatingRuleDescriptionContextKeyToNotNull_returnsContextKey() {
+    prepareIssuesComponent();
+    IssueDto issue = createIssueWithKey(ISSUE_KEY1).setRuleDescriptionContextKey(null);
+    underTest.insert(db.getSession(), issue);
+
+    issue.setRuleDescriptionContextKey(TEST_CONTEXT_KEY);
+    underTest.update(db.getSession(), issue);
+
+    issue = underTest.selectOrFailByKey(db.getSession(), ISSUE_KEY1);
+    assertThat(issue.getOptionalRuleDescriptionContextKey()).contains(TEST_CONTEXT_KEY);
+  }
+
+  @Test
+  public void update_givenOneIssueWithoutRuleDescriptionContextKey_returnsContextKey() {
+    prepareIssuesComponent();
+    IssueDto issue = createIssueWithKey(ISSUE_KEY1).setRuleDescriptionContextKey(TEST_CONTEXT_KEY);
+    underTest.insert(db.getSession(), issue);
+
+    issue.setRuleDescriptionContextKey(null);
+    underTest.update(db.getSession(), issue);
+
+    issue = underTest.selectOrFailByKey(db.getSession(), ISSUE_KEY1);
+    assertThat(issue.getOptionalRuleDescriptionContextKey()).isEmpty();
+
+    issue.setRuleDescriptionContextKey(TEST_CONTEXT_KEY);
+    underTest.update(db.getSession(), issue);
+
+    issue = underTest.selectOrFailByKey(db.getSession(), ISSUE_KEY1);
+    assertThat(issue.getOptionalRuleDescriptionContextKey()).contains(TEST_CONTEXT_KEY);
+  }
+
+  private static IssueDto createIssueWithKey(String issueKey) {
+    return newIssueDto(issueKey)
+      .setMessage("the message")
+      .setRuleUuid(RULE.getUuid())
+      .setComponentUuid(FILE_UUID)
+      .setProjectUuid(PROJECT_UUID)
+      .setQuickFixAvailable(false);
+  }
+
   private static IssueDto newIssueDto(String key) {
     IssueDto dto = new IssueDto();
     dto.setComponent(new ComponentDto().setDbKey("struts:Action").setUuid("component-uuid"));
@@ -687,6 +762,7 @@ public class IssueDaoTest {
     dto.setAssigneeUuid("karadoc");
     dto.setChecksum("123456789");
     dto.setMessage("the message");
+    dto.setRuleDescriptionContextKey(TEST_CONTEXT_KEY);
     dto.setCreatedAt(1_440_000_000_000L);
     dto.setUpdatedAt(1_440_000_000_000L);
     dto.setIssueCreationTime(1_450_000_000_000L);
index 69cdd39962f51a12016df9a898d4dca8745596fc..dde978b82c32a1008c3c32ee614dd9616e918d52 100644 (file)
@@ -33,6 +33,7 @@ import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
@@ -51,40 +52,40 @@ import static org.sonar.api.utils.DateUtils.truncateToSeconds;
 
 public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.Issue {
 
-  private String key;
-  private RuleType type;
-  private String componentUuid;
-  private String componentKey;
+  private String key = null;
+  private RuleType type = null;
+  private String componentUuid = null;
+  private String componentKey = null;
 
-  private String moduleUuidPath;
+  private String moduleUuidPath = null;
 
-  private String projectUuid;
-  private String projectKey;
+  private String projectUuid = null;
+  private String projectKey = null;
 
-  private RuleKey ruleKey;
-  private String language;
-  private String severity;
+  private RuleKey ruleKey = null;
+  private String language = null;
+  private String severity = null;
   private boolean manualSeverity = false;
-  private String message;
-  private Integer line;
-  private Double gap;
-  private Duration effort;
-  private String status;
-  private String resolution;
-  private String assigneeUuid;
-  private String checksum;
+  private String message = null;
+  private Integer line = null;
+  private Double gap = null;
+  private Duration effort = null;
+  private String status = null;
+  private String resolution = null;
+  private String assigneeUuid = null;
+  private String checksum = null;
   private String authorLogin = null;
   private List<DefaultIssueComment> comments = null;
   private Set<String> tags = null;
   // temporarily an Object as long as DefaultIssue is used by sonar-batch
   private Object locations = null;
 
-  private boolean isFromExternalRuleEngine;
+  private boolean isFromExternalRuleEngine = false;
 
   // FUNCTIONAL DATES
-  private Date creationDate;
-  private Date updateDate;
-  private Date closeDate;
+  private Date creationDate = null;
+  private Date updateDate = null;
+  private Date closeDate = null;
 
   // Current changes
   private FieldDiffs currentChange = null;
@@ -116,14 +117,16 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.
   private boolean sendNotifications = false;
 
   // Date when issue was loaded from db (only when isNew=false)
-  private Long selectedAt;
+  private Long selectedAt = null;
 
-  private boolean quickFixAvailable;
-  private boolean isNewCodeReferenceIssue;
+  private boolean quickFixAvailable = false;
+  private boolean isNewCodeReferenceIssue = false;
 
   // true if the issue is no longer new in its branch
   private boolean isNoLongerNewCodeReferenceIssue = false;
 
+  private String ruleDescriptionContextKey = null;
+
   @Override
   public String key() {
     return key;
@@ -640,6 +643,15 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.
     return this;
   }
 
+  public Optional<String> getRuleDescriptionContextKey() {
+    return Optional.ofNullable(ruleDescriptionContextKey);
+  }
+
+  public DefaultIssue setRuleDescriptionContextKey(@Nullable String ruleDescriptionContextKey) {
+    this.ruleDescriptionContextKey = ruleDescriptionContextKey;
+    return this;
+  }
+
   @Override
   public Integer getLine() {
     return line;