Browse Source

SONAR-15498 add IT and Purge should delete selected project if it only selects a branch being deleted

tags/9.2.0.49834
Duarte Meneses 2 years ago
parent
commit
411f4d9dcb

+ 4
- 0
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java View File

@@ -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();

+ 1
- 1
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java View File

@@ -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);

+ 2
- 0
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java View File

@@ -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);

+ 13
- 0
server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml View File

@@ -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

+ 19
- 2
server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java View File

@@ -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();
@@ -676,6 +675,24 @@ public class PurgeCommandsTest {
.containsExactlyInAnyOrder(tuple(portfolio1.getUuid(), anotherProject.getUuid(), singleton("anotherProjectBranch")));
}

@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();

+ 74
- 0
sonar-ws/src/main/java/org/sonarqube/ws/client/views/AddProjectBranchRequest.java View File

@@ -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;
}
}

+ 20
- 0
sonar-ws/src/main/java/org/sonarqube/ws/client/views/CreateRequest.java View File

@@ -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;

/**
@@ -69,6 +71,24 @@ public class CreateRequest {
return name;
}

/**
* 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>

+ 74
- 0
sonar-ws/src/main/java/org/sonarqube/ws/client/views/RemoveProjectBranchRequest.java View File

@@ -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;
}
}

+ 0
- 1
sonar-ws/src/main/java/org/sonarqube/ws/client/views/SearchRequest.java View File

@@ -93,7 +93,6 @@ public class SearchRequest {
/**
* Possible values:
* <ul>
* <li>"APP"</li>
* <li>"VW"</li>
* <li>"SVW"</li>
* </ul>

+ 12
- 0
sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetRegexpModeRequest.java View File

@@ -30,9 +30,21 @@ 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.
*/

+ 12
- 1
sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetRemainingProjectsModeRequest.java View File

@@ -30,8 +30,20 @@ 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.
*/
@@ -43,5 +55,4 @@ public class SetRemainingProjectsModeRequest {
public String getPortfolio() {
return portfolio;
}

}

+ 12
- 0
sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetTagsModeRequest.java View File

@@ -31,9 +31,21 @@ 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.
*/

+ 36
- 24
sonar-ws/src/main/java/org/sonarqube/ws/client/views/ViewsService.java View File

@@ -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)

Loading…
Cancel
Save