From b8a42fed352a0349caf85393b2e4c60ceb647e72 Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Wed, 4 Oct 2017 12:13:07 +0200 Subject: [PATCH] SONAR-9887 Reuse information from issues in short living branches targeting current branch * Add ShortBranchComponentsWithIssues * Load only required component fields from dto * Keep only uuid and branch from analysisMetadataHolder * No need for branch in ShortBranchComponentsWithIssues * Add IssueDao.selectResolvedOrConfirmedByComponentUuid * Add ResolvedShortBranchIssuesFactory * Add components to ProjectAnalysisTaskContainerPopulator * issue info from short branches * Do not open db session for nothing * Get issues for all uuids at once * Select only fields required for issue tracking * Improvements * Add ShortBranchIssue with only the fields needed for issue tracking * fix test * Add missed license * minor improvements * Fix IssueStatusCopierTest and move ShortBranchIssue class * Clean up ShortBranchIssueDto and its query * Fix mapping of dto class * Verify that required fields are correctly mapped * fixes * Fix issues loader * Do not use "key" as field name in db operations * Should find issues to merge only in short branches * Strip branch from component key --- .../sonar/core/issue/ShortBranchIssue.java | 75 ++++++ .../src/main/java/org/sonar/db/MyBatis.java | 2 + .../org/sonar/db/component/ComponentDao.java | 4 + .../org/sonar/db/component/ComponentDto.java | 6 + .../sonar/db/component/ComponentMapper.java | 2 + .../java/org/sonar/db/issue/IssueDao.java | 4 + .../java/org/sonar/db/issue/IssueMapper.java | 2 + .../sonar/db/issue/ShortBranchIssueDto.java | 125 ++++++++++ .../sonar/db/component/ComponentMapper.xml | 11 + .../org/sonar/db/issue/IssueMapper.xml | 19 ++ .../java/org/sonar/db/issue/IssueDaoTest.java | 44 ++++ .../analysis/AnalysisMetadataHolder.java | 7 + .../analysis/AnalysisMetadataHolderImpl.java | 12 +- .../component/MergeBranchComponentUuids.java | 7 +- .../ShortBranchComponentsWithIssues.java | 66 ++++++ ...ProjectAnalysisTaskContainerPopulator.java | 6 + .../issue/IntegrateIssuesVisitor.java | 26 ++- .../projectanalysis/issue/IssueLifecycle.java | 6 + .../issue/IssueStatusCopier.java | 54 +++++ .../ResolvedShortBranchIssuesLoader.java | 57 +++++ .../task/projectanalysis/scm/ScmInfoImpl.java | 2 +- .../analysis/AnalysisMetadataHolderRule.java | 6 + .../MutableAnalysisMetadataHolderRule.java | 5 + .../ShortBranchComponentsWithIssuesTest.java | 177 ++++++++++++++ .../issue/IntegrateIssuesVisitorTest.java | 18 +- .../issue/IssueLifecycleTest.java | 8 + .../issue/IssueStatusCopierTest.java | 96 ++++++++ .../core/issue/tracking/AbstractTracker.java | 216 ++++++++++++++++++ .../core/issue/tracking/SimpleTracker.java | 41 ++++ .../sonar/core/issue/tracking/Tracker.java | 197 +--------------- .../sonar/core/issue/tracking/Tracking.java | 7 +- 31 files changed, 1092 insertions(+), 216 deletions(-) create mode 100644 server/sonar-db-dao/src/main/java/org/sonar/core/issue/ShortBranchIssue.java create mode 100644 server/sonar-db-dao/src/main/java/org/sonar/db/issue/ShortBranchIssueDto.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/ShortBranchComponentsWithIssues.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/IssueStatusCopier.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/ResolvedShortBranchIssuesLoader.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ShortBranchComponentsWithIssuesTest.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/IssueStatusCopierTest.java create mode 100644 sonar-core/src/main/java/org/sonar/core/issue/tracking/AbstractTracker.java create mode 100644 sonar-core/src/main/java/org/sonar/core/issue/tracking/SimpleTracker.java diff --git a/server/sonar-db-dao/src/main/java/org/sonar/core/issue/ShortBranchIssue.java b/server/sonar-db-dao/src/main/java/org/sonar/core/issue/ShortBranchIssue.java new file mode 100644 index 00000000000..f13c0167797 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/core/issue/ShortBranchIssue.java @@ -0,0 +1,75 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.core.issue; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; +import org.sonar.api.rule.RuleKey; +import org.sonar.core.issue.tracking.Trackable; + +@Immutable +public class ShortBranchIssue implements Trackable { + private final Integer line; + private final String message; + private final String lineHash; + private final RuleKey ruleKey; + private final String status; + private final String resolution; + + public ShortBranchIssue(@Nullable Integer line, String message, @Nullable String lineHash, RuleKey ruleKey, String status, @Nullable String resolution) { + this.line = line; + this.message = message; + this.lineHash = lineHash; + this.ruleKey = ruleKey; + this.status = status; + this.resolution = resolution; + } + + @CheckForNull + @Override + public Integer getLine() { + return line; + } + + @Override + public String getMessage() { + return message; + } + + @CheckForNull + @Override + public String getLineHash() { + return lineHash; + } + + @Override + public RuleKey getRuleKey() { + return ruleKey; + } + + public String getStatus() { + return status; + } + + public String getResolution() { + return resolution; + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java index c1bbe7fb0d9..7cd8e4ab309 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java @@ -59,6 +59,7 @@ import org.sonar.db.issue.IssueChangeDto; import org.sonar.db.issue.IssueChangeMapper; import org.sonar.db.issue.IssueDto; import org.sonar.db.issue.IssueMapper; +import org.sonar.db.issue.ShortBranchIssueDto; import org.sonar.db.loadedtemplate.LoadedTemplateDto; import org.sonar.db.loadedtemplate.LoadedTemplateMapper; import org.sonar.db.measure.MeasureDto; @@ -162,6 +163,7 @@ public class MyBatis implements Startable { confBuilder.loadAlias("IssueChange", IssueChangeDto.class); confBuilder.loadAlias("KeyLongValue", KeyLongValue.class); confBuilder.loadAlias("Issue", IssueDto.class); + confBuilder.loadAlias("ShortBranchIssue", ShortBranchIssueDto.class); confBuilder.loadAlias("LoadedTemplate", LoadedTemplateDto.class); confBuilder.loadAlias("Measure", MeasureDto.class); confBuilder.loadAlias("NotificationQueue", NotificationQueueDto.class); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java index 9e11072f09e..b52280819cf 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java @@ -343,4 +343,8 @@ public class ComponentDao implements Dao { public void delete(DbSession session, long componentId) { mapper(session).delete(componentId); } + + public List selectComponentKeysHavingIssuesToMerge(DbSession dbSession, String mergeBranchUuid) { + return mapper(dbSession).selectComponentKeysHavingIssuesToMerge(mergeBranchUuid); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java index 6d00aff0956..230515e95c0 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java @@ -27,6 +27,7 @@ import java.util.Date; import java.util.List; import javax.annotation.CheckForNull; import javax.annotation.Nullable; +import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.ToStringBuilder; import org.sonar.api.resources.Scopes; @@ -532,4 +533,9 @@ public class ComponentDto { public static String generateBranchKey(String componentKey, String branch) { return format("%s%s%s", componentKey, BRANCH_KEY_SEPARATOR, branch); } + + public static String removeBranchFromKey(String componentKey) { + return StringUtils.substringBeforeLast(componentKey, ComponentDto.BRANCH_KEY_SEPARATOR); + } + } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentMapper.java index c99bab08f13..b317e0179a8 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentMapper.java @@ -151,4 +151,6 @@ public interface ComponentMapper { void delete(long componentId); void updateTags(ComponentDto component); + + List selectComponentKeysHavingIssuesToMerge(@Param("mergeBranchUuid") String mergeBranchUuid); } 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 40d148ec741..164f56d5b35 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 @@ -103,6 +103,10 @@ public class IssueDao implements Dao { mapper(dbSession).scrollNonClosedByModuleOrProject(module.projectUuid(), likeModuleUuidPath, handler); } + public List selectResolvedOrConfirmedByComponentUuids(DbSession dbSession, Collection componentUuids) { + return executeLargeInputs(componentUuids, mapper(dbSession)::selectResolvedOrConfirmedByComponentUuids); + } + public void insert(DbSession session, IssueDto dto) { mapper(session).insert(dto); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueMapper.java index d08d71999ab..4335a471126 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueMapper.java @@ -32,6 +32,8 @@ public interface IssueMapper { List selectByKeys(List keys); + List selectResolvedOrConfirmedByComponentUuids(List componentUuids); + void insert(IssueDto issue); int update(IssueDto issue); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/ShortBranchIssueDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/ShortBranchIssueDto.java new file mode 100644 index 00000000000..3674cdc7af8 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/ShortBranchIssueDto.java @@ -0,0 +1,125 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.issue; + +import com.google.common.base.Preconditions; +import java.io.Serializable; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; +import org.sonar.api.rule.RuleKey; +import org.sonar.core.issue.ShortBranchIssue; +import org.sonar.db.rule.RuleDefinitionDto; + +import static com.google.common.base.Preconditions.checkArgument; + +public final class ShortBranchIssueDto implements Serializable { + + private String kee; + private String message; + private Integer line; + private String checksum; + private String status; + private String resolution; + + // joins + private String ruleKey; + private String ruleRepo; + + public String getKey() { + return kee; + } + + public ShortBranchIssueDto setKee(String s) { + this.kee = s; + return this; + } + + @CheckForNull + public String getMessage() { + return message; + } + + public ShortBranchIssueDto setMessage(@Nullable String s) { + this.message = s; + return this; + } + + @CheckForNull + public Integer getLine() { + return line; + } + + public ShortBranchIssueDto setLine(@Nullable Integer i) { + this.line = i; + return this; + } + + public String getStatus() { + return status; + } + + public ShortBranchIssueDto setStatus(@Nullable String s) { + this.status = s; + return this; + } + + @CheckForNull + public String getResolution() { + return resolution; + } + + public ShortBranchIssueDto setResolution(@Nullable String s) { + this.resolution = s; + return this; + } + + @CheckForNull + public String getChecksum() { + return checksum; + } + + public ShortBranchIssueDto setChecksum(@Nullable String s) { + this.checksum = s; + return this; + } + + public void setRuleRepo(String ruleRepo) { + this.ruleRepo = ruleRepo; + } + + public void setRuleKey(String ruleKey) { + this.ruleKey = ruleKey; + } + + public RuleKey getRuleKey() { + return RuleKey.of(ruleRepo, ruleKey); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); + } + + public static ShortBranchIssue toShortBranchIssue(ShortBranchIssueDto dto) { + return new ShortBranchIssue(dto.getLine(), dto.getMessage(), dto.getChecksum(), dto.getRuleKey(), dto.getStatus(), dto.getResolution()); + } +} diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml index 2aaadf4d956..d35ba1ef4d6 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml @@ -655,4 +655,15 @@ DELETE FROM projects WHERE id=#{id,jdbcType=BIGINT} + + 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 744482c6cb1..fa9c34ec2d0 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 @@ -213,6 +213,25 @@ + +