From 2e6289d6bc22fcdae70d7cbcf6d7cba546c49a46 Mon Sep 17 00:00:00 2001 From: Jacek Poreda Date: Fri, 18 Aug 2023 10:34:02 +0200 Subject: [PATCH] SONAR-20021 Fix performance regression - execute delete issue impacts only when updating issues --- .../step/PersistIssuesStepIT.java | 327 +++++++++++------- .../step/PersistIssuesStep.java | 13 +- .../issue/UpdateConflictResolverTest.java | 9 + .../java/org/sonar/db/issue/IssueDao.java | 6 +- 4 files changed, 221 insertions(+), 134 deletions(-) diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStepIT.java index ae12303dc0a..882eb4c1729 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStepIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStepIT.java @@ -22,6 +22,9 @@ package org.sonar.ce.task.projectanalysis.step; import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.assertj.core.groups.Tuple; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -40,7 +43,7 @@ import org.sonar.ce.task.projectanalysis.issue.RuleRepositoryImpl; import org.sonar.ce.task.projectanalysis.issue.UpdateConflictResolver; import org.sonar.ce.task.projectanalysis.period.Period; import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule; -import org.sonar.ce.task.projectanalysis.util.cache.DiskCache; +import org.sonar.ce.task.projectanalysis.util.cache.DiskCache.CacheAppender; import org.sonar.ce.task.step.ComputationStep; import org.sonar.ce.task.step.TestComputationStepContext; import org.sonar.core.issue.DefaultIssue; @@ -52,6 +55,7 @@ import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.issue.AnticipatedTransitionDto; +import org.sonar.db.issue.ImpactDto; import org.sonar.db.issue.IssueChangeDto; import org.sonar.db.issue.IssueDao; import org.sonar.db.issue.IssueDto; @@ -90,14 +94,14 @@ public class PersistIssuesStepIT extends BaseStepTest { @Rule public PeriodHolderRule periodHolder = new PeriodHolderRule(); - private System2 system2 = mock(System2.class); - private DbSession session = db.getSession(); - private DbClient dbClient = db.getDbClient(); - private UpdateConflictResolver conflictResolver = mock(UpdateConflictResolver.class); + private final System2 system2 = mock(System2.class); + private final DbSession session = db.getSession(); + private final DbClient dbClient = db.getDbClient(); + private final UpdateConflictResolver conflictResolver = mock(UpdateConflictResolver.class); private ProtoIssueCache protoIssueCache; private ComputationStep underTest; - private AdHocRuleCreator adHocRuleCreator = mock(AdHocRuleCreator.class); + private final AdHocRuleCreator adHocRuleCreator = mock(AdHocRuleCreator.class); @Override protected ComputationStep step() { @@ -130,35 +134,36 @@ public class PersistIssuesStepIT extends BaseStepTest { String issueKey = "ISSUE-1"; protoIssueCache.newAppender().append(new DefaultIssue() - .setKey(issueKey) - .setType(RuleType.CODE_SMELL) - .setRuleKey(rule.getKey()) - .setComponentUuid(file.uuid()) - .setComponentKey(file.getKey()) - .setProjectUuid(project.uuid()) - .setProjectKey(project.getKey()) - .setSeverity(BLOCKER) - .setStatus(STATUS_OPEN) - .setTags(singletonList("test")) - .setNew(false) - .setCopied(true) - .setType(RuleType.BUG) - .setCreationDate(new Date(NOW)) - .setSelectedAt(NOW) - .addComment(new DefaultIssueComment() - .setKey("COMMENT") + .setKey(issueKey) + .setType(RuleType.CODE_SMELL) + .setRuleKey(rule.getKey()) + .setComponentUuid(file.uuid()) + .setComponentKey(file.getKey()) + .setProjectUuid(project.uuid()) + .setProjectKey(project.getKey()) + .setSeverity(BLOCKER) + .setStatus(STATUS_OPEN) + .setTags(singletonList("test")) + .setNew(false) + .setCopied(true) + .setType(RuleType.BUG) + .setCreationDate(new Date(NOW)) + .setSelectedAt(NOW) + .addComment(new DefaultIssueComment() + .setKey("COMMENT") + .setIssueKey(issueKey) + .setUserUuid("john_uuid") + .setMarkdownText("Some text") + .setCreatedAt(new Date(NOW)) + .setUpdatedAt(new Date(NOW)) + .setNew(true)) + .setCurrentChange( + new FieldDiffs() .setIssueKey(issueKey) .setUserUuid("john_uuid") - .setMarkdownText("Some text") - .setCreatedAt(new Date(NOW)) - .setUpdatedAt(new Date(NOW)) - .setNew(true)) - .setCurrentChange( - new FieldDiffs() - .setIssueKey(issueKey) - .setUserUuid("john_uuid") - .setDiff("technicalDebt", null, 1L) - .setCreationDate(new Date(NOW)))) + .setDiff("technicalDebt", null, 1L) + .setCreationDate(new Date(NOW))) + .addImpact(SoftwareQuality.SECURITY, Severity.MEDIUM)) .close(); TestComputationStepContext context = new TestComputationStepContext(); @@ -175,6 +180,9 @@ public class PersistIssuesStepIT extends BaseStepTest { assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant()); assertThat(result.getTags()).containsExactlyInAnyOrder("test"); assertThat(result.isNewCodeReferenceIssue()).isFalse(); + assertThat(result.getImpacts()) + .extracting(ImpactDto::getSoftwareQuality, ImpactDto::getSeverity) + .containsExactlyInAnyOrder(Tuple.tuple(SoftwareQuality.SECURITY, Severity.MEDIUM)); List changes = dbClient.issueChangeDao().selectByIssueKeys(session, Arrays.asList(issueKey)); assertThat(changes).extracting(IssueChangeDto::getChangeType).containsExactly(IssueChangeDto.TYPE_COMMENT, IssueChangeDto.TYPE_FIELD_CHANGE); @@ -194,20 +202,21 @@ public class PersistIssuesStepIT extends BaseStepTest { String issueKey = "ISSUE-2"; protoIssueCache.newAppender().append(new DefaultIssue() - .setKey(issueKey) - .setType(RuleType.CODE_SMELL) - .setRuleKey(rule.getKey()) - .setComponentUuid(file.uuid()) - .setComponentKey(file.getKey()) - .setProjectUuid(project.uuid()) - .setProjectKey(project.getKey()) - .setSeverity(BLOCKER) - .setStatus(STATUS_OPEN) - .setNew(false) - .setCopied(true) - .setType(RuleType.BUG) - .setCreationDate(new Date(NOW)) - .setSelectedAt(NOW)) + .setKey(issueKey) + .setType(RuleType.CODE_SMELL) + .setRuleKey(rule.getKey()) + .setComponentUuid(file.uuid()) + .setComponentKey(file.getKey()) + .setProjectUuid(project.uuid()) + .setProjectKey(project.getKey()) + .setSeverity(BLOCKER) + .setStatus(STATUS_OPEN) + .setNew(false) + .setCopied(true) + .setType(RuleType.BUG) + .setCreationDate(new Date(NOW)) + .setSelectedAt(NOW) + .addImpact(SoftwareQuality.SECURITY, Severity.MEDIUM)) .close(); TestComputationStepContext context = new TestComputationStepContext(); @@ -223,6 +232,9 @@ public class PersistIssuesStepIT extends BaseStepTest { assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant()); assertThat(result.getTags()).isEmpty(); assertThat(result.isNewCodeReferenceIssue()).isFalse(); + assertThat(result.getImpacts()) + .extracting(ImpactDto::getSoftwareQuality, ImpactDto::getSeverity) + .containsExactlyInAnyOrder(Tuple.tuple(SoftwareQuality.SECURITY, Severity.MEDIUM)); assertThat(dbClient.issueChangeDao().selectByIssueKeys(session, Arrays.asList(issueKey))).isEmpty(); assertThat(context.getStatistics().getAll()).contains( @@ -240,34 +252,35 @@ public class PersistIssuesStepIT extends BaseStepTest { String issueKey = "ISSUE-3"; protoIssueCache.newAppender().append(new DefaultIssue() - .setKey(issueKey) - .setType(RuleType.CODE_SMELL) - .setRuleKey(rule.getKey()) - .setComponentUuid(file.uuid()) - .setComponentKey(file.getKey()) - .setProjectUuid(project.uuid()) - .setProjectKey(project.getKey()) - .setSeverity(BLOCKER) - .setStatus(STATUS_OPEN) - .setNew(true) - .setIsOnChangedLine(true) - .setCopied(true) - .setType(RuleType.BUG) - .setCreationDate(new Date(NOW)) - .setSelectedAt(NOW) - .addComment(new DefaultIssueComment() - .setKey("COMMENT") - .setIssueKey(issueKey) - .setUserUuid("john_uuid") - .setMarkdownText("Some text") - .setUpdatedAt(new Date(NOW)) - .setCreatedAt(new Date(NOW)) - .setNew(true)) - .setCurrentChange(new FieldDiffs() - .setIssueKey(issueKey) - .setUserUuid("john_uuid") - .setDiff("technicalDebt", null, 1L) - .setCreationDate(new Date(NOW)))) + .setKey(issueKey) + .setType(RuleType.CODE_SMELL) + .setRuleKey(rule.getKey()) + .setComponentUuid(file.uuid()) + .setComponentKey(file.getKey()) + .setProjectUuid(project.uuid()) + .setProjectKey(project.getKey()) + .setSeverity(BLOCKER) + .setStatus(STATUS_OPEN) + .setNew(true) + .setIsOnChangedLine(true) + .setCopied(true) + .setType(RuleType.BUG) + .setCreationDate(new Date(NOW)) + .setSelectedAt(NOW) + .addComment(new DefaultIssueComment() + .setKey("COMMENT") + .setIssueKey(issueKey) + .setUserUuid("john_uuid") + .setMarkdownText("Some text") + .setUpdatedAt(new Date(NOW)) + .setCreatedAt(new Date(NOW)) + .setNew(true)) + .setCurrentChange(new FieldDiffs() + .setIssueKey(issueKey) + .setUserUuid("john_uuid") + .setDiff("technicalDebt", null, 1L) + .setCreationDate(new Date(NOW))) + .addImpact(SoftwareQuality.SECURITY, Severity.MEDIUM)) .close(); TestComputationStepContext context = new TestComputationStepContext(); @@ -282,6 +295,9 @@ public class PersistIssuesStepIT extends BaseStepTest { assertThat(result.getStatus()).isEqualTo(STATUS_OPEN); assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant()); assertThat(result.isNewCodeReferenceIssue()).isTrue(); + assertThat(result.getImpacts()) + .extracting(ImpactDto::getSoftwareQuality, ImpactDto::getSeverity) + .containsExactlyInAnyOrder(Tuple.tuple(SoftwareQuality.SECURITY, Severity.MEDIUM)); List changes = dbClient.issueChangeDao().selectByIssueKeys(session, Arrays.asList(issueKey)); assertThat(changes).extracting(IssueChangeDto::getChangeType).containsExactly(IssueChangeDto.TYPE_COMMENT, IssueChangeDto.TYPE_FIELD_CHANGE); @@ -302,7 +318,7 @@ public class PersistIssuesStepIT extends BaseStepTest { // simulate the issue has been updated after the analysis ran .setUpdatedAt(NOW + 1_000_000_000L)); issue = dbClient.issueDao().selectByKey(db.getSession(), issue.getKey()).get(); - DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender(); + CacheAppender issueCacheAppender = protoIssueCache.newAppender(); when(system2.now()).thenReturn(NOW); DefaultIssue defaultIssue = issue.toDefaultIssue() @@ -360,13 +376,78 @@ public class PersistIssuesStepIT extends BaseStepTest { assertThat(result.getSeverity()).isEqualTo(BLOCKER); assertThat(result.getStatus()).isEqualTo(STATUS_OPEN); assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant()); - assertThat(result.getImpacts()).extracting(i -> i.getSoftwareQuality(), i -> i.getSeverity()) + assertThat(result.getImpacts()).extracting(ImpactDto::getSoftwareQuality, ImpactDto::getSeverity) .containsExactly(tuple(SoftwareQuality.SECURITY, Severity.MEDIUM)); assertThat(context.getStatistics().getAll()).contains( entry("inserts", "1"), entry("updates", "0"), entry("merged", "0")); assertThat(result.isNewCodeReferenceIssue()).isTrue(); } + @Test + public void execute_shouldInsertNewIssuesInBatchesWhenGreaterThan500() { + periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null)); + RuleDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01")); + db.rules().insert(rule); + ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); + ComponentDto file = db.components().insertComponent(newFileDto(project)); + session.commit(); + String issueKey = "ISSUE-"; + CacheAppender appender = protoIssueCache.newAppender(); + IntStream.range(1, 501).forEach(i -> appender.append(new DefaultIssue() + .setKey(issueKey + i) + .setType(RuleType.CODE_SMELL) + .setRuleKey(rule.getKey()) + .setComponentUuid(file.uuid()) + .setComponentKey(file.getKey()) + .setProjectUuid(project.uuid()) + .setProjectKey(project.getKey()) + .setSeverity(BLOCKER) + .setStatus(STATUS_OPEN) + .setCreationDate(new Date(NOW)) + .setNew(true) + .setIsOnChangedLine(true) + .addImpact(SoftwareQuality.SECURITY, Severity.MEDIUM) + .setType(RuleType.BUG))); + appender.close(); + + TestComputationStepContext context = new TestComputationStepContext(); + underTest.execute(context); + + assertThat(context.getStatistics().getAll()).contains( + entry("inserts", "500"), entry("updates", "0"), entry("merged", "0")); + } + + @Test + public void execute_shouldUpdateIssuesInBatchesWhenGreaterThan500() { + ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); + ComponentDto file = db.components().insertComponent(newFileDto(project)); + RuleDto rule = db.rules().insert(); + List issues = IntStream.range(1, 501) + .mapToObj(value -> db.issues().insert(rule, project, file, + i -> i.setStatus(STATUS_OPEN) + .setResolution(null) + .setCreatedAt(NOW - 1_000_000_000L) + .setUpdatedAt(NOW - 1_000_000_000L))) + .collect(Collectors.toList()); + + CacheAppender issueCacheAppender = protoIssueCache.newAppender(); + issues.forEach(issue -> issueCacheAppender.append(issue.toDefaultIssue() + .setStatus(STATUS_CLOSED) + .setResolution(RESOLUTION_FIXED) + .setSelectedAt(NOW) + .addImpact(SoftwareQuality.SECURITY, Severity.MEDIUM) + .setNew(false) + .setChanged(true))); + + issueCacheAppender.close(); + + TestComputationStepContext context = new TestComputationStepContext(); + underTest.execute(context); + + assertThat(context.getStatistics().getAll()).contains( + entry("inserts", "0"), entry("updates", "500"), entry("merged", "0")); + } + @Test public void close_issue() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); @@ -377,15 +458,15 @@ public class PersistIssuesStepIT extends BaseStepTest { .setResolution(null) .setCreatedAt(NOW - 1_000_000_000L) .setUpdatedAt(NOW - 1_000_000_000L)); - DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender(); + CacheAppender issueCacheAppender = protoIssueCache.newAppender(); issueCacheAppender.append( - issue.toDefaultIssue() - .setStatus(STATUS_CLOSED) - .setResolution(RESOLUTION_FIXED) - .setSelectedAt(NOW) - .setNew(false) - .setChanged(true)) + issue.toDefaultIssue() + .setStatus(STATUS_CLOSED) + .setResolution(RESOLUTION_FIXED) + .setSelectedAt(NOW) + .setNew(false) + .setChanged(true)) .close(); TestComputationStepContext context = new TestComputationStepContext(); @@ -436,9 +517,9 @@ public class PersistIssuesStepIT extends BaseStepTest { assertThat(result.isNewCodeReferenceIssue()).isTrue(); protoIssueCache.newAppender().append(defaultIssue.setNew(false) - .setIsOnChangedLine(false) - .setIsNewCodeReferenceIssue(false) - .setIsNoLongerNewCodeReferenceIssue(true)) + .setIsOnChangedLine(false) + .setIsNewCodeReferenceIssue(false) + .setIsNoLongerNewCodeReferenceIssue(true)) .close(); TestComputationStepContext context = new TestComputationStepContext(); @@ -485,9 +566,9 @@ public class PersistIssuesStepIT extends BaseStepTest { assertThat(result.isNewCodeReferenceIssue()).isFalse(); protoIssueCache.newAppender().append(defaultIssue.setNew(false) - .setIsOnChangedLine(true) - .setIsNewCodeReferenceIssue(false) - .setIsNoLongerNewCodeReferenceIssue(false)) + .setIsOnChangedLine(true) + .setIsNewCodeReferenceIssue(false) + .setIsNoLongerNewCodeReferenceIssue(false)) .close(); TestComputationStepContext context = new TestComputationStepContext(); @@ -538,10 +619,10 @@ public class PersistIssuesStepIT extends BaseStepTest { assertThat(result.isNewCodeReferenceIssue()).isTrue(); protoIssueCache.newAppender().append(defaultIssue.setNew(false) - .setIsOnChangedLine(false) - .setIsNewCodeReferenceIssue(true) - .setIsOnChangedLine(true) - .setIsNoLongerNewCodeReferenceIssue(false)) + .setIsOnChangedLine(false) + .setIsNewCodeReferenceIssue(true) + .setIsOnChangedLine(true) + .setIsNoLongerNewCodeReferenceIssue(false)) .close(); TestComputationStepContext context = new TestComputationStepContext(); @@ -564,23 +645,23 @@ public class PersistIssuesStepIT extends BaseStepTest { .setResolution(null) .setCreatedAt(NOW - 1_000_000_000L) .setUpdatedAt(NOW - 1_000_000_000L)); - DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender(); + CacheAppender issueCacheAppender = protoIssueCache.newAppender(); issueCacheAppender.append( - issue.toDefaultIssue() - .setStatus(STATUS_CLOSED) - .setResolution(RESOLUTION_FIXED) - .setSelectedAt(NOW) - .setNew(false) - .setChanged(true) - .addComment(new DefaultIssueComment() - .setKey("COMMENT") - .setIssueKey(issue.getKey()) - .setUserUuid("john_uuid") - .setMarkdownText("Some text") - .setCreatedAt(new Date(NOW)) - .setUpdatedAt(new Date(NOW)) - .setNew(true))) + issue.toDefaultIssue() + .setStatus(STATUS_CLOSED) + .setResolution(RESOLUTION_FIXED) + .setSelectedAt(NOW) + .setNew(false) + .setChanged(true) + .addComment(new DefaultIssueComment() + .setKey("COMMENT") + .setIssueKey(issue.getKey()) + .setUserUuid("john_uuid") + .setMarkdownText("Some text") + .setCreatedAt(new Date(NOW)) + .setUpdatedAt(new Date(NOW)) + .setNew(true))) .close(); TestComputationStepContext context = new TestComputationStepContext(); @@ -605,22 +686,22 @@ public class PersistIssuesStepIT extends BaseStepTest { .setResolution(null) .setCreatedAt(NOW - 1_000_000_000L) .setUpdatedAt(NOW - 1_000_000_000L)); - DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender(); + CacheAppender issueCacheAppender = protoIssueCache.newAppender(); issueCacheAppender.append( - issue.toDefaultIssue() - .setStatus(STATUS_CLOSED) - .setResolution(RESOLUTION_FIXED) - .setSelectedAt(NOW) - .setNew(false) - .setChanged(true) - .setIsOnChangedLine(false) - .setIsNewCodeReferenceIssue(false) - .setCurrentChange(new FieldDiffs() - .setIssueKey("ISSUE") - .setUserUuid("john_uuid") - .setDiff("technicalDebt", null, 1L) - .setCreationDate(new Date(NOW)))) + issue.toDefaultIssue() + .setStatus(STATUS_CLOSED) + .setResolution(RESOLUTION_FIXED) + .setSelectedAt(NOW) + .setNew(false) + .setChanged(true) + .setIsOnChangedLine(false) + .setIsNewCodeReferenceIssue(false) + .setCurrentChange(new FieldDiffs() + .setIssueKey("ISSUE") + .setUserUuid("john_uuid") + .setDiff("technicalDebt", null, 1L) + .setCreationDate(new Date(NOW)))) .close(); TestComputationStepContext context = new TestComputationStepContext(); diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStep.java index 9a7fea9364e..5c6978e032e 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStep.java @@ -40,7 +40,6 @@ import org.sonar.db.issue.AnticipatedTransitionMapper; import org.sonar.db.issue.IssueChangeMapper; import org.sonar.db.issue.IssueDao; import org.sonar.db.issue.IssueDto; -import org.sonar.db.issue.IssueMapper; import org.sonar.db.issue.NewCodeReferenceIssueDto; import org.sonar.db.newcodeperiod.NewCodePeriodType; import org.sonar.server.issue.IssueStorage; @@ -79,7 +78,7 @@ public class PersistIssuesStep implements ComputationStep { context.getStatistics().add("cacheSize", humanReadableByteCountSI(protoIssueCache.fileSize())); IssueStatistics statistics = new IssueStatistics(); try (DbSession dbSession = dbClient.openSession(true); - CloseableIterator issues = protoIssueCache.traverse()) { + CloseableIterator issues = protoIssueCache.traverse()) { List addedIssues = new ArrayList<>(ISSUE_BATCHING_SIZE); List updatedIssues = new ArrayList<>(ISSUE_BATCHING_SIZE); List noLongerNewIssues = new ArrayList<>(ISSUE_BATCHING_SIZE); @@ -144,8 +143,8 @@ public class PersistIssuesStep implements ComputationStep { }); } - private void persistUpdatedIssues(IssueStatistics statistics, List updatedIssues, IssueDao - issueDao, IssueChangeMapper changeMapper, DbSession dbSession) { + private void persistUpdatedIssues(IssueStatistics statistics, List updatedIssues, IssueDao issueDao, + IssueChangeMapper changeMapper, DbSession dbSession) { if (updatedIssues.isEmpty()) { return; } @@ -173,8 +172,7 @@ public class PersistIssuesStep implements ComputationStep { updatedIssues.forEach(i -> issueStorage.insertChanges(changeMapper, i, uuidFactory)); } - private static void persistNoLongerNewIssues(IssueStatistics - statistics, List noLongerNewIssues, IssueDao issueDao, DbSession dbSession) { + private static void persistNoLongerNewIssues(IssueStatistics statistics, List noLongerNewIssues, IssueDao issueDao, DbSession dbSession) { if (noLongerNewIssues.isEmpty()) { return; } @@ -186,8 +184,7 @@ public class PersistIssuesStep implements ComputationStep { } - private void persistNewCodeIssuesToMigrate(IssueStatistics - statistics, List newCodeIssuesToMigrate, IssueDao issueDao, DbSession dbSession) { + private void persistNewCodeIssuesToMigrate(IssueStatistics statistics, List newCodeIssuesToMigrate, IssueDao issueDao, DbSession dbSession) { if (newCodeIssuesToMigrate.isEmpty()) { return; } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/UpdateConflictResolverTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/UpdateConflictResolverTest.java index 19ebc222006..d2dfc17be48 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/UpdateConflictResolverTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/UpdateConflictResolverTest.java @@ -19,14 +19,18 @@ */ package org.sonar.ce.task.projectanalysis.issue; +import org.assertj.core.groups.Tuple; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.sonar.api.issue.Issue; +import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; import org.sonar.api.utils.DateUtils; import org.sonar.core.issue.DefaultIssue; +import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbSession; +import org.sonar.db.issue.ImpactDto; import org.sonar.db.issue.IssueDao; import org.sonar.db.issue.IssueDto; @@ -47,6 +51,7 @@ public class UpdateConflictResolverTest { .setRuleKey(RuleKey.of("java", "AvoidCycles")) .setProjectUuid("U1") .setComponentUuid("U2") + .addImpact(SoftwareQuality.SECURITY, org.sonar.api.issue.impact.Severity.HIGH) .setNew(false) .setStatus(STATUS_OPEN); @@ -60,6 +65,7 @@ public class UpdateConflictResolverTest { .setRuleKey("java", "AvoidCycles") .setProjectUuid("U1") .setComponentUuid("U2") + .addImpact(new ImpactDto(UuidFactoryFast.getInstance().create(), SoftwareQuality.SECURITY, org.sonar.api.issue.impact.Severity.HIGH)) .setLine(10) .setStatus(STATUS_OPEN) @@ -73,6 +79,9 @@ public class UpdateConflictResolverTest { IssueDto updatedIssue = argument.getValue(); assertThat(updatedIssue.getKee()).isEqualTo("ABCDE"); assertThat(updatedIssue.getAssigneeUuid()).isEqualTo("arthur-uuid"); + assertThat(updatedIssue.getImpacts()) + .extracting(ImpactDto::getSoftwareQuality, ImpactDto::getSeverity) + .containsExactlyInAnyOrder(Tuple.tuple(SoftwareQuality.SECURITY, org.sonar.api.issue.impact.Severity.HIGH)); } @Test diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDao.java index af95135fb9f..b2b99b31d19 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDao.java @@ -101,15 +101,15 @@ public class IssueDao implements Dao { public void insert(DbSession session, IssueDto dto) { mapper(session).insert(dto); - updateIssueImpacts(dto, mapper(session)); + insertIssueImpacts(dto, mapper(session)); } private static void updateIssueImpacts(IssueDto issueDto, IssueMapper mapper) { mapper.deleteIssueImpacts(issueDto.getKey()); - insertIssueImpact(issueDto, mapper); + insertIssueImpacts(issueDto, mapper); } - private static void insertIssueImpact(IssueDto issueDto, IssueMapper mapper) { + private static void insertIssueImpacts(IssueDto issueDto, IssueMapper mapper) { issueDto.getImpacts() .forEach(impact -> mapper.insertIssueImpact(issueDto.getKey(), impact)); } -- 2.39.5