From: Janos Gyerik Date: Tue, 12 Jun 2018 11:20:07 +0000 (+0200) Subject: SONAR-10868 Add issues.from_hotspot for security hotspots X-Git-Tag: 7.5~890 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=0129e930295d74255d727574f2ef08148156c6ad;p=sonarqube.git SONAR-10868 Add issues.from_hotspot for security hotspots --- diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycle.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycle.java index 52855f4234b..c1166f7d55a 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycle.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycle.java @@ -23,6 +23,7 @@ import com.google.common.annotations.VisibleForTesting; import java.util.Date; import java.util.Optional; import org.sonar.api.issue.Issue; +import org.sonar.api.rules.RuleType; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.DefaultIssueComment; import org.sonar.core.issue.FieldDiffs; @@ -131,6 +132,9 @@ public class IssueLifecycle { public void mergeExistingOpenIssue(DefaultIssue raw, DefaultIssue base) { raw.setKey(base.key()); raw.setNew(false); + if (raw.type() == RuleType.SECURITY_HOTSPOT) { + raw.setIsFromHotspot(true); + } copyFields(raw, base); if (base.manualSeverity()) { diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleTypeCopier.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleTypeCopier.java index 7a6fddb6d72..de0a30cd9da 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleTypeCopier.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleTypeCopier.java @@ -19,9 +19,9 @@ */ package org.sonar.ce.task.projectanalysis.issue; +import org.sonar.api.rules.RuleType; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.core.issue.DefaultIssue; -import org.sonar.ce.task.projectanalysis.component.Component; public class RuleTypeCopier extends IssueVisitor { @@ -40,5 +40,6 @@ public class RuleTypeCopier extends IssueVisitor { issue.setType(rule.getType()); } } + issue.setIsFromHotspot(issue.type() == RuleType.SECURITY_HOTSPOT); } } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueAssignerTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueAssignerTest.java index 9480f5c53e9..ea259383695 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueAssignerTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueAssignerTest.java @@ -213,7 +213,7 @@ public class IssueAssignerTest { "moduleUuid=,moduleUuidPath=,projectUuid=,projectKey=,ruleKey=,language=,severity=," + "manualSeverity=false,message=,line=2,gap=,effort=,status=,resolution=," + "assigneeUuid=,checksum=,attributes=,authorLogin=,comments=,tags=," + - "locations=,isFromExternalRuleEngine=false,creationDate=,updateDate=,closeDate=,currentChange=,changes=,isNew=true,isCopied=false," + + "locations=,isFromExternalRuleEngine=false,creationDate=,updateDate=,closeDate=,isFromHotspot=false,currentChange=,changes=,isNew=true,isCopied=false," + "beingClosed=false,onDisabledRule=false,isChanged=false,sendNotifications=false,selectedAt=]"); } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycleTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycleTest.java index e76865e0c92..23de9153071 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycleTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycleTest.java @@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableMap; import java.util.Date; import org.junit.Rule; import org.junit.Test; +import org.sonar.api.rules.RuleType; import org.sonar.api.utils.Duration; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule; import org.sonar.ce.task.projectanalysis.analysis.Branch; @@ -84,6 +85,38 @@ public class IssueLifecycleTest { assertThat(issue.isCopied()).isFalse(); } + @Test + public void set_fromHotspot_flag_for_existing_vulnerability() { + DefaultIssue raw = new DefaultIssue() + .setNew(true) + .setKey("RAW_KEY") + .setType(RuleType.SECURITY_HOTSPOT) + .setCreationDate(parseDate("2015-10-01")) + .setUpdateDate(parseDate("2015-10-02")) + .setCloseDate(parseDate("2015-10-03")); + + DefaultIssue base = new DefaultIssue() + .setKey("BASE_KEY") + .setType(RuleType.VULNERABILITY) + .setResolution(RESOLUTION_FIXED) + .setStatus(STATUS_CLOSED) + .setSeverity(BLOCKER) + .setCreationDate(parseDate("2015-01-01")) + .setUpdateDate(parseDate("2015-01-02")) + .setCloseDate(parseDate("2015-01-03")); + + underTest.mergeExistingOpenIssue(raw, base); + + assertThat(raw.isNew()).isFalse(); + assertThat(raw.key()).isNotNull(); + assertThat(raw.key()).isEqualTo(base.key()); + assertThat(raw.creationDate()).isEqualTo(base.creationDate()); + assertThat(raw.updateDate()).isEqualTo(base.updateDate()); + assertThat(raw.closeDate()).isEqualTo(base.closeDate()); + assertThat(raw.type()).isEqualTo(RuleType.VULNERABILITY); + assertThat(raw.isFromHotspot()).isTrue(); + } + @Test public void mergeIssueFromShortLivingBranch() { DefaultIssue raw = new DefaultIssue() diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RuleTypeCopierTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RuleTypeCopierTest.java index 906a15cd4e3..f29f69f3755 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RuleTypeCopierTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RuleTypeCopierTest.java @@ -45,6 +45,7 @@ public class RuleTypeCopierTest { underTest.onIssue(mock(Component.class), issue); assertThat(issue.type()).isEqualTo(RuleType.BUG); + assertThat(issue.isFromHotspot()).isEqualTo(false); } @Test @@ -55,5 +56,16 @@ public class RuleTypeCopierTest { underTest.onIssue(mock(Component.class), issue); assertThat(issue.type()).isEqualTo(RuleType.VULNERABILITY); + assertThat(issue.isFromHotspot()).isEqualTo(false); + } + + @Test + public void set_from_hotspot_flag_for_hotspot() { + rule.setType(RuleType.SECURITY_HOTSPOT); + + underTest.onIssue(mock(Component.class), issue); + + assertThat(issue.type()).isEqualTo(RuleType.SECURITY_HOTSPOT); + assertThat(issue.isFromHotspot()).isEqualTo(true); } } diff --git a/server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl b/server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl index c9ae525b88d..628f2af41db 100644 --- a/server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl +++ b/server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl @@ -552,7 +552,8 @@ CREATE TABLE "ISSUES" ( "CREATED_AT" BIGINT, "UPDATED_AT" BIGINT, "LOCATIONS" BLOB, - "ISSUE_TYPE" TINYINT + "ISSUE_TYPE" TINYINT, + "FROM_HOTSPOT" BOOLEAN NULL ); CREATE UNIQUE INDEX "ISSUES_KEE" ON "ISSUES" ("KEE"); CREATE INDEX "ISSUES_COMPONENT_UUID" ON "ISSUES" ("COMPONENT_UUID"); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java index 0ec0627178f..df8b2f9fb07 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java @@ -96,6 +96,7 @@ public final class IssueDto implements Serializable { private String projectKey; private String filePath; private String tags; + private boolean isFromHotspot; /** * On batch side, component keys and uuid are useless @@ -118,6 +119,7 @@ public final class IssueDto implements Serializable { .setRuleId(ruleId) .setRuleKey(issue.ruleKey().repository(), issue.ruleKey().rule()) .setExternal(issue.isFromExternalRuleEngine()) + .setIsFromHotspot(issue.isFromHotspot()) .setTags(issue.tags()) .setComponentUuid(issue.componentUuid()) .setComponentKey(issue.componentKey()) @@ -166,6 +168,7 @@ public final class IssueDto implements Serializable { .setAuthorLogin(issue.authorLogin()) .setRuleKey(issue.ruleKey().repository(), issue.ruleKey().rule()) .setExternal(issue.isFromExternalRuleEngine()) + .setIsFromHotspot(issue.isFromHotspot()) .setTags(issue.tags()) .setComponentUuid(issue.componentUuid()) .setComponentKey(issue.componentKey()) @@ -483,6 +486,15 @@ public final class IssueDto implements Serializable { return this; } + public boolean isFromHotspot() { + return isFromHotspot; + } + + public IssueDto setIsFromHotspot(boolean value) { + isFromHotspot = value; + return this; + } + public String getComponentKey() { return componentKey; } @@ -723,6 +735,7 @@ public final class IssueDto implements Serializable { issue.setSelectedAt(selectedAt); issue.setLocations(parseLocations()); issue.setIsFromExternalRuleEngine(isExternal); + issue.setIsFromHotspot(isFromHotspot); return issue; } } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml index 122f92b4944..63468133dd1 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml @@ -38,7 +38,8 @@ p.path as filePath, root.kee as projectKey, i.project_uuid as projectUuid, - i.issue_type as type + i.issue_type as type, + i.from_hotspot as "isFromHotspot" @@ -95,7 +96,8 @@ p.scope, p.organization_uuid as "organizationUuid", i.tags, - i.issue_type as "issueType" + i.issue_type as "issueType", + i.from_hotspot as "isFromHotspot" @@ -103,7 +105,7 @@ INSERT INTO issues (kee, rule_id, severity, manual_severity, message, line, locations, gap, effort, status, tags, resolution, checksum, assignee, author_login, issue_attributes, issue_creation_date, issue_update_date, - issue_close_date, created_at, updated_at, component_uuid, project_uuid, issue_type) + issue_close_date, created_at, updated_at, component_uuid, project_uuid, issue_type, from_hotspot) VALUES (#{kee,jdbcType=VARCHAR}, #{ruleId,jdbcType=INTEGER}, #{severity,jdbcType=VARCHAR}, #{manualSeverity,jdbcType=BOOLEAN}, #{message,jdbcType=VARCHAR}, #{line,jdbcType=INTEGER}, @@ -116,7 +118,7 @@ #{issueAttributes,jdbcType=VARCHAR}, #{issueCreationTime,jdbcType=BIGINT},#{issueUpdateTime,jdbcType=BIGINT}, #{issueCloseTime,jdbcType=BIGINT}, #{createdAt,jdbcType=BIGINT}, #{updatedAt,jdbcType=BIGINT}, - #{componentUuid,jdbcType=VARCHAR}, #{projectUuid,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}) + #{componentUuid,jdbcType=VARCHAR}, #{projectUuid,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}, #{isFromHotspot,jdbcType=BOOLEAN})