diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2021-11-04 16:01:17 -0500 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2021-11-09 20:03:16 +0000 |
commit | 411f4d9dcb09fefc23c03da7a108d090592e3fb9 (patch) | |
tree | 675fc61b1ea51c6b10ecbbfbf9610166a1e810de | |
parent | e939bcb62791d0d494731030806d5a7b9f21ad45 (diff) | |
download | sonarqube-411f4d9dcb09fefc23c03da7a108d090592e3fb9.tar.gz sonarqube-411f4d9dcb09fefc23c03da7a108d090592e3fb9.zip |
SONAR-15498 add IT and Purge should delete selected project if it only selects a branch being deleted
13 files changed, 279 insertions, 29 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java index feba85ea9e3..402bf9ef5b8 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java @@ -455,7 +455,11 @@ class PurgeCommands { public void deleteProjectInPortfolios(String rootUuid) { profiler.start("deleteProjectInPortfolios (portfolio_projects)"); + // delete selected project if it's only selecting a single branch corresponding to rootUuid + purgeMapper.deletePortfolioProjectsByBranchUuid(rootUuid); + // delete selected branches if branch is rootUuid or if it's part of a project that is rootUuid purgeMapper.deletePortfolioProjectBranchesByBranchUuid(rootUuid); + // delete selected project if project is rootUuid purgeMapper.deletePortfolioProjectsByProjectUuid(rootUuid); session.commit(); profiler.stop(); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java index 11a0ee7e67c..7e0d1efd9ac 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java @@ -165,7 +165,7 @@ public class PurgeDao implements Dao { private static final class NewCodePeriodAnalysisFilter implements Predicate<PurgeableAnalysisDto> { @Nullable - private String analysisUuid; + private final String analysisUuid; private NewCodePeriodAnalysisFilter(PurgeMapper mapper, String componentUuid) { this.analysisUuid = mapper.selectSpecificAnalysisNewCodePeriod(componentUuid); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java index 5270cec0721..348d043c7d5 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java @@ -147,6 +147,8 @@ public interface PurgeMapper { void deleteApplicationBranchProjectBranchesByProjectBranchUuid(@Param("projectBranchUuid") String projectBranchUuid); + void deletePortfolioProjectsByBranchUuid(@Param("branchUuid") String branchUuid); + void deletePortfolioProjectsByProjectUuid(@Param("projectUuid") String projectUuid); void deletePortfolioProjectBranchesByBranchUuid(@Param("branchUuid") String branchUuid); diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml index 32267058e04..604300faae0 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml @@ -349,6 +349,19 @@ WHERE project_branch_uuid=#{projectBranchUuid,jdbcType=VARCHAR} </delete> + <delete id="deletePortfolioProjectsByBranchUuid" parameterType="map"> + <!-- deletes selected projects that were only selecting the branch being deleted --> + DELETE + FROM portfolio_projects + WHERE uuid in ( + SELECT ppb.portfolio_project_uuid FROM portfolio_proj_branches ppb + <!-- branch was selected --> + WHERE ppb.branch_uuid = #{branchUuid,jdbcType=VARCHAR} + <!-- and was the only one selected in the project --> + AND (SELECT count(*) FROM portfolio_proj_branches ppb2 WHERE ppb2.portfolio_project_uuid = ppb.portfolio_project_uuid) = 1 + ) + </delete> + <delete id="deletePortfolioProjectsByProjectUuid" parameterType="map"> DELETE FROM portfolio_projects diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java index 33c0475e5e5..f0851b0858c 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java @@ -56,7 +56,6 @@ import org.sonar.db.user.UserDto; import static com.google.common.collect.Lists.newArrayList; import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; import static java.util.Collections.singleton; import static java.util.Collections.singletonList; import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; @@ -654,7 +653,7 @@ public class PurgeCommandsTest { } @Test - public void deleteProjectInPortfolios_deletes_project_and_branch_from_portfolios() { + public void deleteProjectInPortfolios_deletes_project_and_branch_from_portfolios_if_root_is_branch() { var portfolio1 = dbTester.components().insertPrivatePortfolioDto(); var portfolio2 = dbTester.components().insertPrivatePortfolioDto(); dbTester.components().insertPrivatePortfolio(); @@ -677,6 +676,24 @@ public class PurgeCommandsTest { } @Test + public void deleteProjectInPortfolios_deletes_project_and_branch_from_portfolios_if_root_is_project_only_selecting_a_single_branch() { + var portfolio1 = dbTester.components().insertPrivatePortfolioDto(); + dbTester.components().insertPrivatePortfolio(); + ProjectDto project = dbTester.components().insertPrivateProjectDto(); + + dbTester.components().addPortfolioProject(portfolio1, project); + dbTester.components().addPortfolioProjectBranch(portfolio1, project, "projectBranch"); + + PurgeCommands purgeCommands = new PurgeCommands(dbTester.getSession(), profiler, system2); + + purgeCommands.deleteProjectInPortfolios(project.getUuid()); + + assertThat(dbTester.getDbClient().portfolioDao().selectAllPortfolioProjects(dbTester.getSession())).isEmpty(); + assertThat(dbTester.countRowsOfTable("portfolio_proj_branches")).isZero(); + assertThat(dbTester.countRowsOfTable("portfolio_projects")).isZero(); + } + + @Test public void deleteProjectInPortfolios_deletes_branch_from_portfolios_if_root_is_branch() { var portfolio1 = dbTester.components().insertPrivatePortfolioDto(); ProjectDto project = dbTester.components().insertPrivateProjectDto(); diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/AddProjectBranchRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/AddProjectBranchRequest.java new file mode 100644 index 00000000000..0f3f63608f9 --- /dev/null +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/AddProjectBranchRequest.java @@ -0,0 +1,74 @@ +/* + * SonarQube + * Copyright (C) 2009-2021 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.sonarqube.ws.client.views; + +import javax.annotation.Generated; + +/** + * This is part of the internal API. + * This is a POST request. + * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/add_project_branch">Further information about this action online (including a response example)</a> + * @since 9.2 + */ +@Generated("sonar-ws-generator") +public class AddProjectBranchRequest { + + private String branch; + private String key; + private String project; + + /** + * This is a mandatory parameter. + * Example value: "feature/my_branch" + */ + public AddProjectBranchRequest setBranch(String branch) { + this.branch = branch; + return this; + } + + public String getBranch() { + return branch; + } + + /** + * This is a mandatory parameter. + */ + public AddProjectBranchRequest setKey(String key) { + this.key = key; + return this; + } + + public String getKey() { + return key; + } + + /** + * This is a mandatory parameter. + * Example value: "my_project" + */ + public AddProjectBranchRequest setProject(String project) { + this.project = project; + return this; + } + + public String getProject() { + return project; + } +} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/CreateRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/CreateRequest.java index 05c6bb4849e..97b58d3adf3 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/CreateRequest.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/CreateRequest.java @@ -19,6 +19,7 @@ */ package org.sonarqube.ws.client.views; +import java.util.List; import javax.annotation.Generated; /** @@ -33,6 +34,7 @@ public class CreateRequest { private String description; private String key; private String name; + private String qualifier; private String visibility; /** @@ -72,6 +74,24 @@ public class CreateRequest { /** * Possible values: * <ul> + * <li>"VW"</li> + * <li>"APP"</li> + * </ul> + * @deprecated since 7.3 + */ + @Deprecated + public CreateRequest setQualifier(String qualifier) { + this.qualifier = qualifier; + return this; + } + + public String getQualifier() { + return qualifier; + } + + /** + * Possible values: + * <ul> * <li>"private"</li> * <li>"public"</li> * </ul> diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/RemoveProjectBranchRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/RemoveProjectBranchRequest.java new file mode 100644 index 00000000000..c807a8b1d96 --- /dev/null +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/RemoveProjectBranchRequest.java @@ -0,0 +1,74 @@ +/* + * SonarQube + * Copyright (C) 2009-2021 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.sonarqube.ws.client.views; + +import javax.annotation.Generated; + +/** + * This is part of the internal API. + * This is a POST request. + * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/remove_project_branch">Further information about this action online (including a response example)</a> + * @since 9.2 + */ +@Generated("sonar-ws-generator") +public class RemoveProjectBranchRequest { + + private String branch; + private String key; + private String project; + + /** + * This is a mandatory parameter. + * Example value: "feature/my_branch" + */ + public RemoveProjectBranchRequest setBranch(String branch) { + this.branch = branch; + return this; + } + + public String getBranch() { + return branch; + } + + /** + * This is a mandatory parameter. + */ + public RemoveProjectBranchRequest setKey(String key) { + this.key = key; + return this; + } + + public String getKey() { + return key; + } + + /** + * This is a mandatory parameter. + * Example value: "my_project" + */ + public RemoveProjectBranchRequest setProject(String project) { + this.project = project; + return this; + } + + public String getProject() { + return project; + } +} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SearchRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SearchRequest.java index cc4158edcaf..ae9f2d4e4ee 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SearchRequest.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SearchRequest.java @@ -93,7 +93,6 @@ public class SearchRequest { /** * Possible values: * <ul> - * <li>"APP"</li> * <li>"VW"</li> * <li>"SVW"</li> * </ul> diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetRegexpModeRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetRegexpModeRequest.java index a2c330d6b3b..5ff689812b4 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetRegexpModeRequest.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetRegexpModeRequest.java @@ -30,10 +30,22 @@ import javax.annotation.Generated; @Generated("sonar-ws-generator") public class SetRegexpModeRequest { + private String branch; private String portfolio; private String regexp; /** + */ + public SetRegexpModeRequest setBranch(String branch) { + this.branch = branch; + return this; + } + + public String getBranch() { + return branch; + } + + /** * This is a mandatory parameter. */ public SetRegexpModeRequest setPortfolio(String portfolio) { diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetRemainingProjectsModeRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetRemainingProjectsModeRequest.java index 866c9340d85..c4ff5c99b26 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetRemainingProjectsModeRequest.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetRemainingProjectsModeRequest.java @@ -30,9 +30,21 @@ import javax.annotation.Generated; @Generated("sonar-ws-generator") public class SetRemainingProjectsModeRequest { + private String branch; private String portfolio; /** + */ + public SetRemainingProjectsModeRequest setBranch(String branch) { + this.branch = branch; + return this; + } + + public String getBranch() { + return branch; + } + + /** * This is a mandatory parameter. */ public SetRemainingProjectsModeRequest setPortfolio(String portfolio) { @@ -43,5 +55,4 @@ public class SetRemainingProjectsModeRequest { public String getPortfolio() { return portfolio; } - } diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetTagsModeRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetTagsModeRequest.java index 8fcfbff1b6f..33e239820b9 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetTagsModeRequest.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetTagsModeRequest.java @@ -31,10 +31,22 @@ import javax.annotation.Generated; @Generated("sonar-ws-generator") public class SetTagsModeRequest { + private String branch; private String portfolio; private List<String> tags; /** + */ + public SetTagsModeRequest setBranch(String branch) { + this.branch = branch; + return this; + } + + public String getBranch() { + return branch; + } + + /** * This is a mandatory parameter. */ public SetTagsModeRequest setPortfolio(String portfolio) { diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/ViewsService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/ViewsService.java index d81260983b8..9ab8d60c5c2 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/ViewsService.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/ViewsService.java @@ -73,16 +73,15 @@ public class ViewsService extends BaseService { * * This is part of the internal API. * This is a POST request. - * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/add_sub_view">Further information about this action online (including a response example)</a> - * @since 1.0 + * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/add_project_branch">Further information about this action online (including a response example)</a> + * @since 9.2 */ - public void addSubView(AddSubViewRequest request) { + public void addProjectBranch(AddProjectBranchRequest request) { call( - new PostRequest(path("add_sub_view")) - .setParam("description", request.getDescription()) + new PostRequest(path("add_project_branch")) + .setParam("branch", request.getBranch()) .setParam("key", request.getKey()) - .setParam("name", request.getName()) - .setParam("subKey", request.getSubKey()) + .setParam("project", request.getProject()) .setMediaType(MediaTypes.JSON) ).content(); } @@ -90,13 +89,17 @@ public class ViewsService extends BaseService { /** * * This is part of the internal API. - * This is a GET request. - * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/app">Further information about this action online (including a response example)</a> + * This is a POST request. + * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/add_sub_view">Further information about this action online (including a response example)</a> * @since 1.0 */ - public String app() { - return call( - new GetRequest(path("app")) + public void addSubView(AddSubViewRequest request) { + call( + new PostRequest(path("add_sub_view")) + .setParam("description", request.getDescription()) + .setParam("key", request.getKey()) + .setParam("name", request.getName()) + .setParam("subKey", request.getSubKey()) .setMediaType(MediaTypes.JSON) ).content(); } @@ -114,6 +117,7 @@ public class ViewsService extends BaseService { .setParam("description", request.getDescription()) .setParam("key", request.getKey()) .setParam("name", request.getName()) + .setParam("qualifier", request.getQualifier()) .setParam("visibility", request.getVisibility()) .setMediaType(MediaTypes.JSON) ).content(); @@ -125,7 +129,9 @@ public class ViewsService extends BaseService { * This is a POST request. * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/define">Further information about this action online (including a response example)</a> * @since 1.0 + * @deprecated since 9.2 */ + @Deprecated public void define(DefineRequest request) { call( new PostRequest(path("define")) @@ -140,7 +146,9 @@ public class ViewsService extends BaseService { * This is a GET request. * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/definition">Further information about this action online (including a response example)</a> * @since 2.0 + * @deprecated since 9.2 */ + @Deprecated public String definition() { return call( new GetRequest(path("definition")) @@ -277,14 +285,15 @@ public class ViewsService extends BaseService { * * This is part of the internal API. * This is a POST request. - * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/run">Further information about this action online (including a response example)</a> - * @since 1.0 - * @deprecated since 7.1 + * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/remove_project_branch">Further information about this action online (including a response example)</a> + * @since 9.2 */ - @Deprecated - public String run() { - return call( - new PostRequest(path("run")) + public void removeProjectBranch(RemoveProjectBranchRequest request) { + call( + new PostRequest(path("remove_project_branch")) + .setParam("branch", request.getBranch()) + .setParam("key", request.getKey()) + .setParam("project", request.getProject()) .setMediaType(MediaTypes.JSON) ).content(); } @@ -320,7 +329,7 @@ public class ViewsService extends BaseService { new PostRequest(path("set_manual_mode")) .setParam("portfolio", request.getPortfolio()) .setMediaType(MediaTypes.JSON) - ).content(); + ).content(); } /** @@ -335,23 +344,24 @@ public class ViewsService extends BaseService { new PostRequest(path("set_none_mode")) .setParam("portfolio", request.getPortfolio()) .setMediaType(MediaTypes.JSON) - ).content(); + ).content(); } /** * * This is part of the internal API. * This is a POST request. - * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/set_remaining_projects_mode">Further information about this action online (including a response example)</a> + * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/set_regexp_mode">Further information about this action online (including a response example)</a> * @since 7.4 */ public void setRegexpMode(SetRegexpModeRequest request) { call( new PostRequest(path("set_regexp_mode")) + .setParam("branch", request.getBranch()) .setParam("portfolio", request.getPortfolio()) .setParam("regexp", request.getRegexp()) .setMediaType(MediaTypes.JSON) - ).content(); + ).content(); } /** @@ -364,9 +374,10 @@ public class ViewsService extends BaseService { public void setRemainingProjectsMode(SetRemainingProjectsModeRequest request) { call( new PostRequest(path("set_remaining_projects_mode")) + .setParam("branch", request.getBranch()) .setParam("portfolio", request.getPortfolio()) .setMediaType(MediaTypes.JSON) - ).content(); + ).content(); } /** @@ -379,6 +390,7 @@ public class ViewsService extends BaseService { public void setTagsMode(SetTagsModeRequest request) { call( new PostRequest(path("set_tags_mode")) + .setParam("branch", request.getBranch()) .setParam("portfolio", request.getPortfolio()) .setParam("tags", request.getTags() == null ? null : request.getTags().stream().collect(Collectors.joining(","))) .setMediaType(MediaTypes.JSON) |