From 5ab4879d3fbfe97e2fd4f29cab57c7c415576b35 Mon Sep 17 00:00:00 2001 From: Zipeng WU Date: Mon, 20 Dec 2021 12:36:27 +0100 Subject: [PATCH] SONAR-15802 Update computation of portfolios --- .../db/component/ApplicationProjectsDao.java | 8 +- .../component/ApplicationProjectsMapper.java | 4 +- .../org/sonar/db/portfolio/PortfolioDao.java | 26 +++-- .../sonar/db/portfolio/PortfolioMapper.java | 17 +-- .../component/ApplicationProjectsMapper.xml | 37 +++++-- .../sonar/db/portfolio/PortfolioMapper.xml | 52 +++++++-- .../component/ApplicationProjectsDaoTest.java | 14 ++- .../sonar/db/portfolio/PortfolioDaoTest.java | 102 +++++++++++++----- .../sonar/server/hotspot/ws/SearchAction.java | 2 +- 9 files changed, 196 insertions(+), 66 deletions(-) diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ApplicationProjectsDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ApplicationProjectsDao.java index 2247ea08e94..7aebe16a83d 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ApplicationProjectsDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ApplicationProjectsDao.java @@ -82,8 +82,12 @@ public class ApplicationProjectsDao implements Dao { getMapper(dbSession).removeProjectBranchFromAppBranch(applicationBranchUuid, projectBranchUuid); } - public Set selectProjectBranchesFromAppBranch(DbSession dbSession, String applicationBranchUuid) { - return getMapper(dbSession).selectProjectBranchesFromAppBranch(applicationBranchUuid); + public Set selectProjectBranchesFromAppBranchUuid(DbSession dbSession, String applicationBranchUuid) { + return getMapper(dbSession).selectProjectBranchesFromAppBranchUuid(applicationBranchUuid); + } + + public Set selectProjectBranchesFromAppBranchKey(DbSession dbSession, String applicationUuid, String applicationBranchKey) { + return getMapper(dbSession).selectProjectBranchesFromAppBranchKey(applicationUuid, applicationBranchKey); } public Set selectApplicationsFromProjectBranch(DbSession dbSession, String projectUuid, String branchKey) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ApplicationProjectsMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ApplicationProjectsMapper.java index 261d377b1d0..0764b951a1a 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ApplicationProjectsMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ApplicationProjectsMapper.java @@ -55,7 +55,9 @@ public interface ApplicationProjectsMapper { void removeProjectBranchFromAppBranch(@Param("applicationBranchUuid") String applicationBranchUuid, @Param("projectBranchUuid") String projectBranchUuid); - Set selectProjectBranchesFromAppBranch(@Param("applicationBranchUuid") String applicationBranchUuid); + Set selectProjectBranchesFromAppBranchUuid(@Param("applicationBranchUuid") String applicationBranchUuid); + + Set selectProjectBranchesFromAppBranchKey(@Param("applicationUuid") String applicationUuid, @Param("applicationBranchKey") String applicationBranchKey); int countApplicationProjects(@Param("applicationUuid") String applicationUuid); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDao.java index 8e5a8bed10e..35a56b845ac 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDao.java @@ -31,7 +31,6 @@ import org.sonar.db.DbSession; import org.sonar.db.audit.AuditPersister; import org.sonar.db.audit.model.ComponentNewValue; import org.sonar.db.project.ApplicationProjectDto; -import org.sonar.db.project.ProjectDto; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; @@ -140,16 +139,20 @@ public class PortfolioDao implements Dao { return mapper(dbSession).selectAllReferencesToApplications(); } - public List selectAllDirectChildApplications(DbSession dbSession, String portfolioUuid) { - return mapper(dbSession).selectAllDirectChildApplications(portfolioUuid); + public List selectAllReferencesToPortfoliosInHierarchy(DbSession dbSession, String rootUuid) { + return mapper(dbSession).selectAllReferencesToPortfoliosInHierarchy(rootUuid); } - public Set selectReferenceUuids(DbSession dbSession, String portfolioUuid) { - return mapper(dbSession).selectReferenceUuids(portfolioUuid); + public List selectAllReferencesToApplicationsInHierarchy(DbSession dbSession, String rootUuid) { + return mapper(dbSession).selectAllReferencesToApplicationsInHierarchy(rootUuid); + } + + public List selectApplicationReferenceUuids(DbSession dbSession, String portfolioUuid) { + return mapper(dbSession).selectApplicationReferenceUuids(portfolioUuid); } - public List selectAllReferencesInHierarchy(DbSession dbSession, String uuid) { - return mapper(dbSession).selectAllReferencesInHierarchy(uuid); + public Set selectReferenceUuids(DbSession dbSession, String portfolioUuid) { + return mapper(dbSession).selectReferenceUuids(portfolioUuid); } public List selectReferencers(DbSession dbSession, String referenceUuid) { @@ -160,6 +163,14 @@ public class PortfolioDao implements Dao { return mapper(dbSession).selectRootOfReferencers(referenceUuid); } + public List selectRootOfReferencersToMainBranch(DbSession dbSession, String referenceUuid) { + return mapper(dbSession).selectRootOfReferencersToMainBranch(referenceUuid); + } + + public List selectRootOfReferencersToAppBranch(DbSession dbSession, String appUuid, String appBranchKey) { + return mapper(dbSession).selectRootOfReferencersToAppBranch(appUuid, appBranchKey); + } + public void deleteReferencesTo(DbSession dbSession, String referenceUuid) { mapper(dbSession).deleteReferencesTo(referenceUuid); } @@ -251,4 +262,5 @@ public class PortfolioDao implements Dao { private static String qualifier(PortfolioDto portfolioDto) { return portfolioDto.isRoot() ? Qualifiers.VIEW : Qualifiers.SUBVIEW; } + } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioMapper.java index d345a46ef5e..201e3eff0bd 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioMapper.java @@ -26,7 +26,6 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.apache.ibatis.annotations.Param; import org.sonar.db.project.ApplicationProjectDto; -import org.sonar.db.project.ProjectDto; public interface PortfolioMapper { @CheckForNull @@ -44,7 +43,7 @@ public interface PortfolioMapper { void deleteReferencesByPortfolioOrReferenceUuids(@Param("uuids") Set uuids); void insertReference(@Param("uuid") String uuid, @Param("portfolioUuid") String portfolioUuid, @Param("referenceUuid") String referenceUuid, - @Nullable @Param("branchUuid") String branchUuid, @Param("createdAt") long createdAt); + @Nullable @Param("branchUuid") String branchUuid, @Param("createdAt") long createdAt); void insertProject(@Param("uuid") String uuid, @Param("portfolioUuid") String portfolioUuid, @Param("projectUuid") String projectUuid, @Param("createdAt") long createdAt); @@ -76,6 +75,8 @@ public interface PortfolioMapper { List selectRootOfReferencers(String referenceUuid); + List selectRootOfReferencersToMainBranch(String referenceUuid); + void deleteReferencesTo(String referenceUuid); void deleteProjects(String portfolioUuid); @@ -96,14 +97,18 @@ public interface PortfolioMapper { List selectAllPortfolioProjects(); - List selectAllReferencesInHierarchy(String rootUuid); - void deleteBranch(@Param("portfolioUuid") String portfolioUuid, @Param("projectUuid") String projectUuid, @Param("branchUuid") String branchUuid); void insertBranch(@Param("uuid") String uuid, @Param("portfolioProjectUuid") String portfolioProjectUuid, @Param("branchUuid") String branchUuid, - @Param("createdAt") long createdAt); + @Param("createdAt") long createdAt); - List selectAllDirectChildApplications(@Param("portfolioUuid") String portfolioUuid); + List selectApplicationReferenceUuids(@Param("portfolioUuid") String portfolioUuid); int deleteReferenceBranch(@Param("portfolioUuid") String portfolioUuid, @Param("referenceUuid") String referenceUuid, @Param("branchUuid") String branchUuid); + + List selectAllReferencesToPortfoliosInHierarchy(String rootUuid); + + List selectAllReferencesToApplicationsInHierarchy(String rootUuid); + + List selectRootOfReferencersToAppBranch(@Param("appUuid") String appUuid, @Param("appBranchKey") String appBranchKey); } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ApplicationProjectsMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ApplicationProjectsMapper.xml index 6a8f8a7011f..747ce122c2b 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ApplicationProjectsMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ApplicationProjectsMapper.xml @@ -117,26 +117,45 @@ app_branch_project_branch.project_branch_uuid = #{projectBranchUuid,jdbcType=VARCHAR} - SELECT - + FROM - app_branch_project_branch + app_branch_project_branch INNER JOIN - project_branches pb + project_branches pb ON - app_branch_project_branch.project_branch_uuid = pb.uuid + app_branch_project_branch.project_branch_uuid = pb.uuid WHERE - app_branch_project_branch.application_branch_uuid = #{applicationBranchUuid,jdbcType=VARCHAR} + app_branch_project_branch.application_branch_uuid = #{applicationBranchUuid,jdbcType=VARCHAR} + + + diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/portfolio/PortfolioMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/portfolio/PortfolioMapper.xml index 1ab2f4ae208..be38d220f1b 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/portfolio/PortfolioMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/portfolio/PortfolioMapper.xml @@ -194,6 +194,34 @@ pr.reference_uuid=#{referenceUuid,jdbcType=VARCHAR} + + + + ap.application_uuid as appUuid, ap.project_uuid as projectUuid, @@ -308,29 +336,31 @@ WHERE target.qualifier = 'APP' - SELECT - - FROM portfolio_references pr - JOIN projects p ON p.uuid = pr.reference_uuid - WHERE pr.portfolio_uuid = #{portfolioUuid,jdbcType=VARCHAR} - - - + + + + diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ApplicationProjectsDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ApplicationProjectsDaoTest.java index 2978143ebda..35914872d8c 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ApplicationProjectsDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ApplicationProjectsDaoTest.java @@ -74,7 +74,19 @@ public class ApplicationProjectsDaoTest { insertApplication("app1"); insertBranch("app1", "app-b1"); underTest.addProjectBranchToAppBranch(dbSession, "app1", "app-b1", "p1", "b1"); - assertThat(underTest.selectProjectBranchesFromAppBranch(dbSession, "app-b1")).extracting(BranchDto::getUuid).containsOnly("b1"); + assertThat(underTest.selectProjectBranchesFromAppBranchUuid(dbSession, "app-b1")).extracting(BranchDto::getUuid).containsOnly("b1"); + } + + @Test + public void select_project_branches_from_application_branch() { + var project = db.components().insertPublicProjectDto(p -> p.setDbKey("project")); + var projectBranch = db.components().insertProjectBranch(project, b -> b.setKey("project-branch")); + var app = db.components().insertPrivateApplicationDto(a -> a.setDbKey("app1")); + var appBranch = db.components().insertProjectBranch(app, b -> b.setKey("app-branch")); + db.components().addApplicationProject(app, project); + underTest.addProjectBranchToAppBranch(dbSession, app.getUuid(), appBranch.getUuid(), project.getUuid(), projectBranch.getUuid()); + assertThat(underTest.selectProjectBranchesFromAppBranchUuid(dbSession, appBranch.getUuid())).extracting(BranchDto::getKey).containsOnly("project-branch"); + assertThat(underTest.selectProjectBranchesFromAppBranchKey(dbSession, app.getUuid(), appBranch.getKey())).extracting(BranchDto::getKey).containsOnly("project-branch"); } @Test diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/portfolio/PortfolioDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/portfolio/PortfolioDaoTest.java index 29e28520900..45aebe2513c 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/portfolio/PortfolioDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/portfolio/PortfolioDaoTest.java @@ -267,17 +267,50 @@ public class PortfolioDaoTest { portfolioDao.addReference(session, "portfolio2", app2.getUuid()); portfolioDao.addReference(session, "portfolio3", app3.getUuid()); - assertThat(portfolioDao.selectAllDirectChildApplications(session, p1.getUuid())) - .extracting(ProjectDto::getKee) - .containsOnly("app1"); + assertThat(portfolioDao.selectApplicationReferenceUuids(session, p1.getUuid())) + .containsOnly(app1.getUuid()); - assertThat(portfolioDao.selectAllDirectChildApplications(session, p2.getUuid())) - .extracting(ProjectDto::getKee) - .containsOnly("app2"); + assertThat(portfolioDao.selectApplicationReferenceUuids(session, p2.getUuid())) + .containsOnly(app2.getUuid()); - assertThat(portfolioDao.selectAllDirectChildApplications(session, p3.getUuid())) - .extracting(ProjectDto::getKee) - .containsOnly("app3"); + assertThat(portfolioDao.selectApplicationReferenceUuids(session, p3.getUuid())) + .containsOnly(app3.getUuid()); + } + + @Test + public void selectAllReferencesToApplicationsInHierarchy() { + var p1 = db.components().insertPrivatePortfolioDto("portfolio1"); + var p2 = db.components().insertPrivatePortfolioDto("portfolio2", p -> p.setRootUuid(p1.getUuid()).setParentUuid(p1.getUuid())); + var p3 = db.components().insertPrivatePortfolioDto("portfolio3", p -> p.setRootUuid(p1.getUuid()).setParentUuid(p1.getUuid())); + ProjectDto app1 = db.components().insertPrivateApplicationDto(p -> p.setDbKey("app1")); + ProjectDto app2 = db.components().insertPrivateApplicationDto(p -> p.setDbKey("app2")); + ProjectDto app3 = db.components().insertPrivateApplicationDto(p -> p.setDbKey("app3")); + + portfolioDao.addReference(session, "portfolio1", app1.getUuid()); + portfolioDao.addReference(session, "portfolio2", app2.getUuid()); + portfolioDao.addReference(session, "portfolio3", app3.getUuid()); + + assertThat(portfolioDao.selectAllReferencesToApplicationsInHierarchy(session, p1.getUuid())) + .extracting(ReferenceDto::getTargetUuid) + .containsExactlyInAnyOrder(app1.getUuid(), app2.getUuid(), app3.getUuid()); + } + + @Test + public void selectAllReferencesToPortfoliosInHierarchy() { + var p1 = db.components().insertPrivatePortfolioDto("portfolio1"); + var p2 = db.components().insertPrivatePortfolioDto("portfolio2", p -> p.setRootUuid(p1.getUuid()).setParentUuid(p1.getUuid())); + var p3 = db.components().insertPrivatePortfolioDto("portfolio3", p -> p.setRootUuid(p1.getUuid()).setParentUuid(p1.getUuid())); + var p4 = db.components().insertPrivatePortfolioDto("portfolio4"); + var p5 = db.components().insertPrivatePortfolioDto("portfolio5"); + var p6 = db.components().insertPrivatePortfolioDto("portfolio6"); + + portfolioDao.addReference(session, "portfolio1", p4.getUuid()); + portfolioDao.addReference(session, "portfolio2", p5.getUuid()); + portfolioDao.addReference(session, "portfolio3", p6.getUuid()); + + assertThat(portfolioDao.selectAllReferencesToPortfoliosInHierarchy(session, p1.getUuid())) + .extracting(ReferenceDto::getTargetUuid) + .containsExactlyInAnyOrder(p4.getUuid(), p5.getUuid(), p6.getUuid()); } @Test @@ -355,6 +388,38 @@ public class PortfolioDaoTest { } + @Test + public void select_root_reference_to_app_main_branch() { + PortfolioDto portfolio1 = db.components().insertPrivatePortfolioDto("portfolio1"); + ProjectDto app1 = db.components().insertPrivateApplicationDto(p -> p.setDbKey("app1")); + db.components().addPortfolioReference(portfolio1, app1.getUuid()); + + assertThat(portfolioDao.selectRootOfReferencersToMainBranch(db.getSession(), app1.getUuid())) + .extracting(PortfolioDto::getKey) + .containsExactly(portfolio1.getKey()); + + PortfolioDto portfolio2 = db.components().insertPrivatePortfolioDto("portfolio2"); + ProjectDto app2 = db.components().insertPrivateApplicationDto(p -> p.setDbKey("app2")); + db.components().addPortfolioApplicationBranch(portfolio2.getUuid(), app2.getUuid(), app2.getUuid()); + + assertThat(portfolioDao.selectRootOfReferencersToMainBranch(db.getSession(), app2.getUuid())) + .extracting(PortfolioDto::getKey) + .containsExactly(portfolio2.getKey()); + } + + @Test + public void select_root_reference_to_app_with_branches() { + PortfolioDto portfolio = db.components().insertPrivatePortfolioDto("portfolio1"); + ProjectDto app = db.components().insertPrivateApplicationDto(p -> p.setDbKey("app").setName("app")); + BranchDto branch = db.components().insertProjectBranch(app, b -> b.setExcludeFromPurge(true)); + + db.components().addPortfolioApplicationBranch(portfolio.getUuid(), app.getUuid(), branch.getUuid()); + + assertThat(portfolioDao.selectRootOfReferencersToAppBranch(db.getSession(), app.getUuid(), branch.getKey())) + .extracting(PortfolioDto::getKey) + .containsExactly(portfolio.getKey()); + } + @Test public void select_reference_to_portfolio_by_key() { PortfolioDto portfolio1 = db.components().insertPrivatePortfolioDto("portfolio1"); @@ -373,25 +438,6 @@ public class PortfolioDaoTest { assertThat(portfolioDao.selectReferenceToApp(db.getSession(), portfolio1.getUuid(), portfolio2.getKey())).isEmpty(); } - @Test - public void selectAllReferencesInHierarchy() { - PortfolioDto root1 = db.components().insertPrivatePortfolioDto("root1"); - PortfolioDto root2 = db.components().insertPrivatePortfolioDto("root2"); - PortfolioDto sub1 = addPortfolio(root1, "sub1"); - PortfolioDto sub11 = addPortfolio(sub1, "sub11"); - ProjectDto app1 = db.components().insertPrivateApplicationDto(p -> p.setUuid("app1")); - - db.components().addPortfolioReference("root1", "app1"); - db.components().addPortfolioReference("root2", "app1"); - db.components().addPortfolioReference("sub11", "root2"); - - assertThat(portfolioDao.selectAllReferencesInHierarchy(session, root1.getUuid())) - .extracting(ReferenceDto::getSourceUuid, ReferenceDto::getTargetUuid) - .containsOnly( - tuple(root1.getUuid(), app1.getUuid()), - tuple(sub11.getUuid(), root2.getUuid())); - } - @Test public void selectReferencers() { PortfolioDto portfolio1 = db.components().insertPrivatePortfolioDto("portfolio1"); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java index 9790b3775e7..076bab9027e 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java @@ -406,7 +406,7 @@ public class SearchAction implements HotspotsWsAction { .map(ProjectDto::getUuid) .collect(Collectors.toSet()); } else { - projectUuids = dbClient.applicationProjectsDao().selectProjectBranchesFromAppBranch(dbSession, application.uuid()).stream() + projectUuids = dbClient.applicationProjectsDao().selectProjectBranchesFromAppBranchUuid(dbSession, application.uuid()).stream() .map(BranchDto::getUuid) .collect(Collectors.toSet()); } -- 2.39.5