Browse Source

SONAR-20630 set projects creation method

tags/10.3.0.82913
Aurelien Poscia 8 months ago
parent
commit
50039e6c42
33 changed files with 503 additions and 200 deletions
  1. 0
    1
      server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/IgnoreOrphanBranchStepIT.java
  2. 2
    0
      server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/steps/LoadProjectStepIT.java
  3. 2
    0
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/AnticipatedTransitionRepositoryImplTest.java
  4. 2
    1
      server/sonar-ce/src/it/java/org/sonar/ce/notification/ReportAnalysisFailureNotificationExecutionListenerIT.java
  5. 2
    0
      server/sonar-db-dao/src/it/java/org/sonar/db/component/ApplicationProjectsDaoIT.java
  6. 18
    0
      server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectDaoIT.java
  7. 28
    0
      server/sonar-db-dao/src/main/java/org/sonar/db/project/CreationMethod.java
  8. 10
    0
      server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDto.java
  9. 3
    0
      server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml
  10. 3
    1
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java
  11. 4
    1
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentTesting.java
  12. 2
    0
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ProjectTesting.java
  13. 1
    1
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/PopulateCreationMethodColumnInProjectsTable.java
  14. 2
    2
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v103/PopulateCreationMethodColumnInProjectsTableTest.java
  15. 2
    0
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/azure/ImportAzureProjectActionIT.java
  16. 3
    0
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/bitbucketcloud/ImportBitbucketCloudRepoActionIT.java
  17. 3
    0
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/bitbucketserver/ImportBitbucketServerProjectActionIT.java
  18. 23
    0
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectActionIT.java
  19. 49
    52
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/gitlab/ImportGitLabProjectActionIT.java
  20. 14
    2
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/BranchReportSubmitterIT.java
  21. 4
    3
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/ReportSubmitterIT.java
  22. 155
    81
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ComponentUpdaterIT.java
  23. 7
    5
      server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/CreateActionIT.java
  24. 10
    3
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/azure/ImportAzureProjectAction.java
  25. 10
    3
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/bitbucketcloud/ImportBitbucketCloudRepoAction.java
  26. 10
    3
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/bitbucketserver/ImportBitbucketServerProjectAction.java
  27. 11
    6
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectAction.java
  28. 10
    3
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/gitlab/ImportGitLabProjectAction.java
  29. 9
    2
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java
  30. 78
    0
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentCreationParameters.java
  31. 16
    14
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentUpdater.java
  32. 0
    13
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ProjectCreationData.java
  33. 10
    3
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/CreateAction.java

+ 0
- 1
server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/IgnoreOrphanBranchStepIT.java View File

@@ -27,7 +27,6 @@ import org.sonar.ce.task.CeTask;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.component.BranchDto;
import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.project.ProjectDto;

+ 2
- 0
server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/steps/LoadProjectStepIT.java View File

@@ -28,6 +28,7 @@ import org.sonar.ce.task.projectexport.taskprocessor.ProjectDescriptor;
import org.sonar.ce.task.step.TestComputationStepContext;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.project.CreationMethod;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -58,6 +59,7 @@ public class LoadProjectStepIT {
"qualifier", Qualifiers.APP,
"uuid", "not_used",
"private", false,
"creation_method", CreationMethod.LOCAL.name(),
"created_at", 1L,
"updated_at", 1L);


+ 2
- 0
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/AnticipatedTransitionRepositoryImplTest.java View File

@@ -34,6 +34,7 @@ import org.sonar.db.component.BranchDto;
import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.issue.AnticipatedTransitionDto;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;

import static org.assertj.core.api.Assertions.assertThat;
@@ -138,6 +139,7 @@ public class AnticipatedTransitionRepositoryImplTest {
projectDto.setUuid(projectUuid);
projectDto.setQualifier("TRK");
projectDto.setName("project");
projectDto.setCreationMethod(CreationMethod.LOCAL);
return projectDto;
}


+ 2
- 1
server/sonar-ce/src/it/java/org/sonar/ce/notification/ReportAnalysisFailureNotificationExecutionListenerIT.java View File

@@ -46,6 +46,7 @@ import org.sonar.db.component.BranchDto;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.component.ProjectData;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;
import org.sonar.server.notification.NotificationService;

@@ -145,7 +146,7 @@ public class ReportAnalysisFailureNotificationExecutionListenerIT {
@Test
public void onEnd_fails_with_ISE_if_branch_does_not_exist_in_DB() {
String componentUuid = randomAlphanumeric(6);
ProjectDto project = new ProjectDto().setUuid(componentUuid).setKey(randomAlphanumeric(5)).setQualifier(Qualifiers.PROJECT);
ProjectDto project = new ProjectDto().setUuid(componentUuid).setKey(randomAlphanumeric(5)).setQualifier(Qualifiers.PROJECT).setCreationMethod(CreationMethod.LOCAL);
dbTester.getDbClient().projectDao().insert(dbTester.getSession(), project);
dbTester.getSession().commit();
when(ceTaskMock.getType()).thenReturn(CeTaskTypes.REPORT);

+ 2
- 0
server/sonar-db-dao/src/it/java/org/sonar/db/component/ApplicationProjectsDaoIT.java View File

@@ -28,6 +28,7 @@ import org.sonar.api.utils.System2;
import org.sonar.core.util.UuidFactoryFast;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;

import static org.assertj.core.api.Assertions.assertThat;
@@ -169,6 +170,7 @@ public class ApplicationProjectsDaoIT {
"kee", appUuid,
"qualifier", "APP",
"private", true,
"creation_method", CreationMethod.LOCAL.name(),
"updated_at", 1000L,
"created_at", 1000L);
}

+ 18
- 0
server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectDaoIT.java View File

@@ -25,6 +25,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
@@ -46,6 +47,7 @@ import org.sonar.db.component.BranchDto;
import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ProjectData;
import org.sonar.db.entity.EntityDto;
import org.sonar.db.measure.LiveMeasureDto;
import org.sonar.db.metric.MetricDto;
import org.sonar.db.qualityprofile.QProfileDto;
@@ -121,6 +123,21 @@ public class ProjectDaoIT {
List<ProjectDto> projects = projectDao.selectProjects(db.getSession());
assertThat(projects).extracting(ProjectDto::getKey).containsExactlyInAnyOrder("projectKee_o1_p1", "projectKee_o1_p2");
}
@Test
public void selectProjects_returnsCreationMethod() {
ProjectDto dto1 = createProject("o1", "p1").setCreationMethod(CreationMethod.SCANNER);
ProjectDto dto2 = createProject("o1", "p2").setCreationMethod(CreationMethod.UNKNOWN);

projectDao.insert(db.getSession(), dto1);
projectDao.insert(db.getSession(), dto2);

List<ProjectDto> projects = projectDao.selectProjects(db.getSession());
Map<String, CreationMethod> projectToCreationMethod = projects.stream().collect(Collectors.toMap(EntityDto::getName, ProjectDto::getCreationMethod));
assertThat(projectToCreationMethod)
.hasSize(2)
.containsEntry("projectName_p1", CreationMethod.SCANNER)
.containsEntry("projectName_p2", CreationMethod.UNKNOWN);
}

@Test
public void select_all() {
@@ -452,6 +469,7 @@ public class ProjectDaoIT {
.setUuid("uuid_" + org + "_" + name)
.setTags(Arrays.asList("tag1", "tag2"))
.setDescription("desc_" + name)
.setCreationMethod(CreationMethod.LOCAL)
.setPrivate(false);
}
}

+ 28
- 0
server/sonar-db-dao/src/main/java/org/sonar/db/project/CreationMethod.java View File

@@ -0,0 +1,28 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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.project;

public enum CreationMethod {
UNKNOWN,
LOCAL,
ALM_IMPORT_API,
ALM_IMPORT_UI,
SCANNER
}

+ 10
- 0
server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDto.java View File

@@ -31,6 +31,7 @@ import static org.sonar.db.component.DbTagsReader.readDbTags;
public class ProjectDto extends EntityDto {
private static final String TAGS_SEPARATOR = ",";
private String tags;
private CreationMethod creationMethod;
private long createdAt;
private long updatedAt;

@@ -113,4 +114,13 @@ public class ProjectDto extends EntityDto {
this.qualifier = qualifier;
return this;
}

public CreationMethod getCreationMethod() {
return creationMethod;
}

public ProjectDto setCreationMethod(CreationMethod creationMethod) {
this.creationMethod = creationMethod;
return this;
}
}

+ 3
- 0
server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml View File

@@ -10,6 +10,7 @@
p.description as description,
p.tags as tagsString,
p.private as isPrivate,
p.creation_method as creationMethod,
p.created_at as createdAt,
p.updated_at as updatedAt
</sql>
@@ -162,6 +163,7 @@
description,
private,
tags,
creation_method,
created_at,
updated_at
)
@@ -173,6 +175,7 @@
#{description,jdbcType=VARCHAR},
#{isPrivate,jdbcType=BOOLEAN},
#{tagsString, jdbcType=VARCHAR},
#{creationMethod, jdbcType=VARCHAR},
#{createdAt,jdbcType=BIGINT},
#{updatedAt,jdbcType=BIGINT}
)

+ 3
- 1
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java View File

@@ -32,6 +32,7 @@ import org.sonar.db.DbTester;
import org.sonar.db.entity.EntityDto;
import org.sonar.db.portfolio.PortfolioDto;
import org.sonar.db.portfolio.PortfolioProjectDto;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;

import static com.google.common.base.Preconditions.checkArgument;
@@ -580,7 +581,8 @@ public class ComponentDbTester {
.setUpdatedAt(createTime)
.setPrivate(componentDto.isPrivate())
.setDescription(componentDto.description())
.setName(componentDto.name());
.setName(componentDto.name())
.setCreationMethod(CreationMethod.LOCAL);
}

public static PortfolioDto toPortfolioDto(ComponentDto componentDto, long createTime) {

+ 4
- 1
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentTesting.java View File

@@ -25,6 +25,7 @@ import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.core.util.Uuids;
import org.sonar.db.portfolio.PortfolioDto;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;

import static com.google.common.base.Preconditions.checkArgument;
@@ -268,7 +269,7 @@ public class ComponentTesting {
}

public static ProjectDto newProjectDto() {
return newProjectDto("uuid").setPrivate(true);
return newProjectDto("uuid").setPrivate(true).setCreationMethod(CreationMethod.LOCAL);
}

public static ProjectDto newProjectDto(String projectUuid) {
@@ -276,6 +277,7 @@ public class ComponentTesting {
.setKey("projectKey")
.setUuid(projectUuid)
.setName("projectName")
.setCreationMethod(CreationMethod.LOCAL)
.setQualifier(Qualifiers.PROJECT);
}

@@ -284,6 +286,7 @@ public class ComponentTesting {
.setKey("appKey")
.setUuid("uuid")
.setName("appName")
.setCreationMethod(CreationMethod.LOCAL)
.setQualifier(Qualifiers.APP);
}


+ 2
- 0
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ProjectTesting.java View File

@@ -21,6 +21,7 @@ package org.sonar.db.component;

import org.sonar.api.resources.Qualifiers;
import org.sonar.core.util.Uuids;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;

public class ProjectTesting {
@@ -47,6 +48,7 @@ public class ProjectTesting {
.setName("NAME_" + uuid)
.setDescription("DESCRIPTION_" + uuid)
.setQualifier(Qualifiers.PROJECT)
.setCreationMethod(CreationMethod.LOCAL)
.setPrivate(isPrivate);
}


+ 1
- 1
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/PopulateCreationMethodColumnInProjectsTable.java View File

@@ -27,7 +27,7 @@ import org.sonar.server.platform.db.migration.step.Upsert;
public class PopulateCreationMethodColumnInProjectsTable extends DataChange {

private static final String UPDATE_QUERY = """
update projects set creation_method='unknown'
update projects set creation_method='UNKNOWN'
""";

public PopulateCreationMethodColumnInProjectsTable(Database db) {

+ 2
- 2
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v103/PopulateCreationMethodColumnInProjectsTableTest.java View File

@@ -50,7 +50,7 @@ public class PopulateCreationMethodColumnInProjectsTableTest {

assertThat(db.select("select creation_method from projects"))
.extracting(stringObjectMap -> stringObjectMap.get("CREATION_METHOD"))
.containsExactlyInAnyOrder("unknown", "unknown");
.containsExactlyInAnyOrder("UNKNOWN", "UNKNOWN");
}

@Test
@@ -62,7 +62,7 @@ public class PopulateCreationMethodColumnInProjectsTableTest {

assertThat(db.select("select creation_method from projects"))
.extracting(stringObjectMap -> stringObjectMap.get("CREATION_METHOD"))
.containsExactlyInAnyOrder("unknown");
.containsExactlyInAnyOrder("UNKNOWN");
}

private void insertProject(String uuid) {

+ 2
- 0
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/azure/ImportAzureProjectActionIT.java View File

@@ -38,6 +38,7 @@ import org.sonar.db.alm.setting.AlmSettingDto;
import org.sonar.db.alm.setting.ProjectAlmSettingDto;
import org.sonar.db.component.BranchDto;
import org.sonar.db.newcodeperiod.NewCodePeriodDto;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.almintegration.ws.ImportHelper;
@@ -143,6 +144,7 @@ public class ImportAzureProjectActionIT {

Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
assertThat(projectDto).isPresent();
assertThat(projectDto.orElseThrow().getCreationMethod()).isEqualTo(CreationMethod.ALM_IMPORT_API);

Optional<ProjectAlmSettingDto> projectAlmSettingDto = db.getDbClient().projectAlmSettingDao().selectByProject(db.getSession(),
projectDto.get());

+ 3
- 0
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/bitbucketcloud/ImportBitbucketCloudRepoActionIT.java View File

@@ -38,6 +38,7 @@ import org.sonar.db.alm.setting.AlmSettingDto;
import org.sonar.db.alm.setting.ProjectAlmSettingDto;
import org.sonar.db.component.BranchDto;
import org.sonar.db.newcodeperiod.NewCodePeriodDto;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.almintegration.ws.ImportHelper;
@@ -133,6 +134,8 @@ public class ImportBitbucketCloudRepoActionIT {

Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
assertThat(projectDto).isPresent();
assertThat(projectDto.orElseThrow().getCreationMethod()).isEqualTo(CreationMethod.ALM_IMPORT_API);

Optional<ProjectAlmSettingDto> projectAlmSettingDto = db.getDbClient().projectAlmSettingDao().selectByProject(db.getSession(), projectDto.get());
assertThat(projectAlmSettingDto).isPresent();
assertThat(projectAlmSettingDto.get().getAlmRepo()).isEqualTo("repo-slug-1");

+ 3
- 0
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/bitbucketserver/ImportBitbucketServerProjectActionIT.java View File

@@ -42,6 +42,7 @@ import org.sonar.db.alm.pat.AlmPatDto;
import org.sonar.db.alm.setting.AlmSettingDto;
import org.sonar.db.component.BranchDto;
import org.sonar.db.newcodeperiod.NewCodePeriodDto;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.almintegration.ws.ImportHelper;
@@ -150,6 +151,8 @@ public class ImportBitbucketServerProjectActionIT {

Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
assertThat(projectDto).isPresent();
assertThat(projectDto.orElseThrow().getCreationMethod()).isEqualTo(CreationMethod.ALM_IMPORT_API);

assertThat(db.getDbClient().projectAlmSettingDao().selectByProject(db.getSession(), projectDto.get())).isPresent();
verify(projectKeyGenerator).generateUniqueProjectKey(requireNonNull(project.getKey()), repo.getSlug());
}

+ 23
- 0
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectActionIT.java View File

@@ -43,6 +43,7 @@ import org.sonar.db.component.ResourceTypesRule;
import org.sonar.db.entity.EntityDto;
import org.sonar.db.newcodeperiod.NewCodePeriodDto;
import org.sonar.db.permission.GlobalPermission;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.almintegration.ws.ImportHelper;
@@ -368,6 +369,28 @@ public class ImportGithubProjectActionIT {

}

@Test
public void importProject_shouldSetCreationMethod() {
AlmSettingDto githubAlmSetting = setupAlm();
db.almPats().insert(p -> p.setAlmSettingUuid(githubAlmSetting.getUuid()).setUserUuid(userSession.getUuid()));

GithubApplicationClient.Repository repository = new GithubApplicationClient.Repository(1L, PROJECT_KEY_NAME, false,
"octocat/" + PROJECT_KEY_NAME,
"https://github.sonarsource.com/api/v3/repos/octocat/" + PROJECT_KEY_NAME, "default-branch");
when(appClient.getRepository(any(), any(), any(), any())).thenReturn(Optional.of(repository));
when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn(PROJECT_KEY_NAME);
when(gitHubSettings.isProvisioningEnabled()).thenReturn(true);

Projects.CreateWsResponse response = ws.newRequest()
.setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey())
.setParam(PARAM_ORGANIZATION, "octocat")
.setParam(PARAM_REPOSITORY_KEY, "octocat/" + PROJECT_KEY_NAME)
.executeProtobuf(Projects.CreateWsResponse.class);

Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), response.getProject().getKey());
assertThat(projectDto.orElseThrow().getCreationMethod()).isEqualTo(CreationMethod.ALM_IMPORT_API);
}

@Test
public void fail_when_not_logged_in() {
TestRequest request = ws.newRequest()

+ 49
- 52
server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/gitlab/ImportGitLabProjectActionIT.java View File

@@ -19,6 +19,7 @@
*/
package org.sonar.server.almintegration.ws.gitlab;

import java.util.List;
import java.util.Optional;
import org.assertj.core.api.Assertions;
import org.junit.Before;
@@ -36,6 +37,7 @@ import org.sonar.db.DbTester;
import org.sonar.db.alm.setting.AlmSettingDto;
import org.sonar.db.component.BranchDto;
import org.sonar.db.newcodeperiod.NewCodePeriodDto;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.almintegration.ws.ImportHelper;
@@ -111,16 +113,8 @@ public class ImportGitLabProjectActionIT {

UserDto user = db.users().insertUser();
userSession.logIn(user).addPermission(PROVISION_PROJECTS);
AlmSettingDto almSetting = db.almSettings().insertGitlabAlmSetting();
db.almPats().insert(dto -> {
dto.setAlmSettingUuid(almSetting.getUuid());
dto.setUserUuid(user.getUuid());
dto.setPersonalAccessToken("PAT");
});
Project project = getGitlabProject();
when(gitlabHttpClient.getProject(any(), any(), any())).thenReturn(project);
when(gitlabHttpClient.getBranches(any(), any(), any())).thenReturn(singletonList(new GitLabBranch("master", true)));
when(projectKeyGenerator.generateUniqueProjectKey(project.getPathWithNamespace())).thenReturn(PROJECT_KEY_NAME);
AlmSettingDto almSetting = insertGitLabConfigurationAndPat(user);
Project project = mockGitlabProject(singletonList(new GitLabBranch("master", true)));

Projects.CreateWsResponse response = ws.newRequest()
.setParam("almSetting", almSetting.getKey())
@@ -152,16 +146,8 @@ public class ImportGitLabProjectActionIT {

UserDto user = db.users().insertUser();
userSession.logIn(user).addPermission(PROVISION_PROJECTS);
AlmSettingDto almSetting = db.almSettings().insertGitlabAlmSetting();
db.almPats().insert(dto -> {
dto.setAlmSettingUuid(almSetting.getUuid());
dto.setUserUuid(user.getUuid());
dto.setPersonalAccessToken("PAT");
});
Project project = getGitlabProject();
when(gitlabHttpClient.getProject(any(), any(), any())).thenReturn(project);
when(gitlabHttpClient.getBranches(any(), any(), any())).thenReturn(singletonList(new GitLabBranch("master", true)));
when(projectKeyGenerator.generateUniqueProjectKey(project.getPathWithNamespace())).thenReturn(PROJECT_KEY_NAME);
AlmSettingDto almSetting = insertGitLabConfigurationAndPat(user);
mockGitlabProject(singletonList(new GitLabBranch("master", true)));

Projects.CreateWsResponse response = ws.newRequest()
.setParam("almSetting", almSetting.getKey())
@@ -181,22 +167,18 @@ public class ImportGitLabProjectActionIT {
.get()
.extracting(NewCodePeriodDto::getType, NewCodePeriodDto::getValue, NewCodePeriodDto::getBranchUuid)
.containsExactly(NUMBER_OF_DAYS, "30", branchDto.getUuid());

assertThat(projectDto.orElseThrow().getCreationMethod()).isEqualTo(CreationMethod.ALM_IMPORT_API);
}



@Test
public void import_project_with_specific_different_default_branch() {
UserDto user = db.users().insertUser();
userSession.logIn(user).addPermission(PROVISION_PROJECTS);
AlmSettingDto almSetting = db.almSettings().insertGitlabAlmSetting();
db.almPats().insert(dto -> {
dto.setAlmSettingUuid(almSetting.getUuid());
dto.setUserUuid(user.getUuid());
dto.setPersonalAccessToken("PAT");
});
Project project = getGitlabProject();
when(gitlabHttpClient.getProject(any(), any(), any())).thenReturn(project);
when(gitlabHttpClient.getBranches(any(), any(), any())).thenReturn(singletonList(new GitLabBranch("main", true)));
when(projectKeyGenerator.generateUniqueProjectKey(project.getPathWithNamespace())).thenReturn(PROJECT_KEY_NAME);
AlmSettingDto almSetting = insertGitLabConfigurationAndPat(user);
Project project = mockGitlabProject(singletonList(new GitLabBranch("main", true)));

Projects.CreateWsResponse response = ws.newRequest()
.setParam("almSetting", almSetting.getKey())
@@ -223,16 +205,8 @@ public class ImportGitLabProjectActionIT {
public void import_project_no_gitlab_default_branch() {
UserDto user = db.users().insertUser();
userSession.logIn(user).addPermission(PROVISION_PROJECTS);
AlmSettingDto almSetting = db.almSettings().insertGitlabAlmSetting();
db.almPats().insert(dto -> {
dto.setAlmSettingUuid(almSetting.getUuid());
dto.setUserUuid(user.getUuid());
dto.setPersonalAccessToken("PAT");
});
Project project = getGitlabProject();
when(gitlabHttpClient.getProject(any(), any(), any())).thenReturn(project);
when(gitlabHttpClient.getBranches(any(), any(), any())).thenReturn(emptyList());
when(projectKeyGenerator.generateUniqueProjectKey(project.getPathWithNamespace())).thenReturn(PROJECT_KEY_NAME);
AlmSettingDto almSetting = insertGitLabConfigurationAndPat(user);
Project project = mockGitlabProject(emptyList());

Projects.CreateWsResponse response = ws.newRequest()
.setParam("almSetting", almSetting.getKey())
@@ -259,16 +233,8 @@ public class ImportGitLabProjectActionIT {
public void import_project_without_NCD() {
UserDto user = db.users().insertUser();
userSession.logIn(user).addPermission(PROVISION_PROJECTS);
AlmSettingDto almSetting = db.almSettings().insertGitlabAlmSetting();
db.almPats().insert(dto -> {
dto.setAlmSettingUuid(almSetting.getUuid());
dto.setUserUuid(user.getUuid());
dto.setPersonalAccessToken("PAT");
});
Project project = getGitlabProject();
when(gitlabHttpClient.getProject(any(), any(), any())).thenReturn(project);
when(gitlabHttpClient.getBranches(any(), any(), any())).thenReturn(singletonList(new GitLabBranch("master", true)));
when(projectKeyGenerator.generateUniqueProjectKey(project.getPathWithNamespace())).thenReturn(PROJECT_KEY_NAME);
AlmSettingDto almSetting = insertGitLabConfigurationAndPat(user);
Project project = mockGitlabProject(singletonList(new GitLabBranch("master", true)));

Projects.CreateWsResponse response = ws.newRequest()
.setParam("almSetting", almSetting.getKey())
@@ -286,7 +252,38 @@ public class ImportGitLabProjectActionIT {
assertThat(db.getDbClient().projectAlmSettingDao().selectByProject(db.getSession(), projectDto.get())).isPresent();
}

private Project getGitlabProject() {
return new Project(randomAlphanumeric(5), randomAlphanumeric(5));
@Test
public void import_project_setsCreationMethod() {
UserDto user = db.users().insertUser();
userSession.logIn(user).addPermission(PROVISION_PROJECTS);
AlmSettingDto almSetting = insertGitLabConfigurationAndPat(user);
mockGitlabProject(singletonList(new GitLabBranch("master", true)));

Projects.CreateWsResponse response = ws.newRequest()
.setParam("almSetting", almSetting.getKey())
.setParam("gitlabProjectId", "12345")
.executeProtobuf(Projects.CreateWsResponse.class);

Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), response.getProject().getKey());
assertThat(projectDto.orElseThrow().getCreationMethod()).isEqualTo(CreationMethod.ALM_IMPORT_API);
}

private AlmSettingDto insertGitLabConfigurationAndPat(UserDto user) {
AlmSettingDto almSetting = db.almSettings().insertGitlabAlmSetting();
db.almPats().insert(dto -> {
dto.setAlmSettingUuid(almSetting.getUuid());
dto.setUserUuid(user.getUuid());
dto.setPersonalAccessToken("PAT");
});
return almSetting;
}

private Project mockGitlabProject(List<GitLabBranch> master) {
Project project = new Project(randomAlphanumeric(5), randomAlphanumeric(5));
when(gitlabHttpClient.getProject(any(), any(), any())).thenReturn(project);
when(gitlabHttpClient.getBranches(any(), any(), any())).thenReturn(master);
when(projectKeyGenerator.generateUniqueProjectKey(project.getPathWithNamespace())).thenReturn(PROJECT_KEY_NAME);
return project;
}

}

+ 14
- 2
server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/BranchReportSubmitterIT.java View File

@@ -46,11 +46,12 @@ import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.component.ProjectData;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentCreationData;
import org.sonar.server.component.ComponentCreationParameters;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.component.ProjectCreationData;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.favorite.FavoriteUpdater;
import org.sonar.server.permission.PermissionTemplateService;
@@ -146,6 +147,9 @@ public class BranchReportSubmitterIT {
verify(branchSupportDelegate, times(0)).createBranchComponent(any(), any(), any(), any());
verifyNoMoreInteractions(branchSupportDelegate);
verifyQueueSubmit(mainBranch, branch, user, randomCharacteristics, taskUuid);

ProjectDto projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), componentKey.getKey()).orElseThrow();
assertThat(projectDto.getCreationMethod()).isEqualTo(CreationMethod.LOCAL);
}

@Test
@@ -192,7 +196,7 @@ public class BranchReportSubmitterIT {
ComponentCreationData componentCreationData = mock(ComponentCreationData.class);
when(componentCreationData.mainBranchComponent())
.thenAnswer((Answer<ComponentDto>) invocation -> db.components().insertPrivateProject(PROJECT_UUID, nonExistingBranch).getMainBranchComponent());
when(componentUpdater.createWithoutCommit(any(), new ProjectCreationData(any(), eq(user.getUuid()), eq(user.getLogin()))))
when(componentUpdater.createWithoutCommit(any(), any()))
.thenReturn(componentCreationData);
when(branchSupportDelegate.createBranchComponent(any(DbSession.class), same(componentKey), any(), any())).thenReturn(createdBranch);
when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), any(), eq(nonExistingBranch.getKey()))).thenReturn(true);
@@ -208,6 +212,14 @@ public class BranchReportSubmitterIT {
verifyNoMoreInteractions(branchSupportDelegate);
verifyQueueSubmit(nonExistingBranch, createdBranch, user, randomCharacteristics, taskUuid);
verify(componentUpdater).commitAndIndex(any(DbSession.class), eq(componentCreationData));

assertProjectCreatedWithCreationMethodEqualsScanner();
}

private void assertProjectCreatedWithCreationMethodEqualsScanner() {
ArgumentCaptor<ComponentCreationParameters> componentCreationParametersCaptor = ArgumentCaptor.forClass(ComponentCreationParameters.class);
verify(componentUpdater).createWithoutCommit(any(), componentCreationParametersCaptor.capture());
assertThat(componentCreationParametersCaptor.getValue().creationMethod()).isEqualTo(CreationMethod.SCANNER);
}

@Test

+ 4
- 3
server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/ReportSubmitterIT.java View File

@@ -39,8 +39,8 @@ import org.sonar.db.DbTester;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ProjectData;
import org.sonar.db.entity.EntityDto;
import org.sonar.db.permission.GlobalPermission;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentUpdater;
@@ -169,12 +169,13 @@ public class ReportSubmitterIT {
underTest.submit(PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}", UTF_8));

ComponentDto createdProject = db.getDbClient().componentDao().selectByKey(db.getSession(), PROJECT_KEY).get();
EntityDto entityDto = db.getDbClient().entityDao().selectByKey(db.getSession(), PROJECT_KEY).get();
ProjectDto projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), PROJECT_KEY).orElseThrow();

verifyReportIsPersisted(TASK_UUID);
verify(queue).submit(argThat(submit -> submit.getType().equals(CeTaskTypes.REPORT)
&& submit.getComponent().filter(cpt -> cpt.getUuid().equals(createdProject.uuid()) && cpt.getEntityUuid().equals(entityDto.getUuid())).isPresent()
&& submit.getComponent().filter(cpt -> cpt.getUuid().equals(createdProject.uuid()) && cpt.getEntityUuid().equals(projectDto.getUuid())).isPresent()
&& submit.getUuid().equals(TASK_UUID)));
assertThat(projectDto.getCreationMethod()).isEqualTo(CreationMethod.SCANNER);
}

@Test

+ 155
- 81
server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ComponentUpdaterIT.java View File

@@ -38,6 +38,7 @@ import org.sonar.db.component.BranchDto;
import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ResourceTypesRule;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.EsTester;
@@ -77,6 +78,15 @@ public class ComponentUpdaterIT {

private static final String DEFAULT_PROJECT_KEY = "project-key";
private static final String DEFAULT_PROJECT_NAME = "project-name";
private static final NewComponent DEFAULT_COMPONENT = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.build();
private static final NewComponent PRIVATE_COMPONENT = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setPrivate(true)
.build();
private static final String DEFAULT_USER_UUID = "user-uuid";
public static final String DEFAULT_USER_LOGIN = "user-login";

@@ -110,12 +120,11 @@ public class ComponentUpdaterIT {

@Test
public void persist_and_index_when_creating_project() {
NewComponent mainBranchComponent = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setPrivate(true)
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(PRIVATE_COMPONENT)
.creationMethod(CreationMethod.LOCAL)
.build();
ComponentCreationData returned = underTest.create(db.getSession(), mainBranchComponent, null, null);
ComponentCreationData returned = underTest.create(db.getSession(), creationParameters);

ComponentDto loaded = db.getDbClient().componentDao().selectOrFailByUuid(db.getSession(), returned.mainBranchComponent().uuid());
assertThat(loaded.getKey()).isEqualTo(DEFAULT_PROJECT_KEY);
@@ -125,7 +134,7 @@ public class ComponentUpdaterIT {
assertThat(loaded.scope()).isEqualTo(Scopes.PROJECT);
assertThat(loaded.uuid()).isNotNull();
assertThat(loaded.branchUuid()).isEqualTo(loaded.uuid());
assertThat(loaded.isPrivate()).isEqualTo(mainBranchComponent.isPrivate());
assertThat(loaded.isPrivate()).isEqualTo(PRIVATE_COMPONENT.isPrivate());
assertThat(loaded.getCreatedAt()).isNotNull();
assertThat(db.getDbClient().componentDao().selectByKey(db.getSession(), DEFAULT_PROJECT_KEY)).isPresent();

@@ -143,13 +152,12 @@ public class ComponentUpdaterIT {
@Test
public void create_project_with_main_branch_global_property() {
when(defaultBranchNameResolver.getEffectiveMainBranchName()).thenReturn("main-branch-global");
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setPrivate(true)
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(PRIVATE_COMPONENT)
.creationMethod(CreationMethod.LOCAL)
.build();

ComponentDto returned = underTest.create(db.getSession(), project, null, null).mainBranchComponent();
ComponentDto returned = underTest.create(db.getSession(), creationParameters).mainBranchComponent();

Optional<BranchDto> branch = db.getDbClient().branchDao().selectByUuid(db.getSession(), returned.branchUuid());
assertThat(branch).get().extracting(BranchDto::getBranchKey).isEqualTo("main-branch-global");
@@ -157,14 +165,13 @@ public class ComponentUpdaterIT {

@Test
public void persist_private_flag_true_when_creating_project() {
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setPrivate(true)
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(PRIVATE_COMPONENT)
.creationMethod(CreationMethod.LOCAL)
.build();
ComponentDto returned = underTest.create(db.getSession(), project, null, null).mainBranchComponent();
ComponentDto returned = underTest.create(db.getSession(), creationParameters).mainBranchComponent();
ComponentDto loaded = db.getDbClient().componentDao().selectOrFailByUuid(db.getSession(), returned.uuid());
assertThat(loaded.isPrivate()).isEqualTo(project.isPrivate());
assertThat(loaded.isPrivate()).isEqualTo(PRIVATE_COMPONENT.isPrivate());
}

@Test
@@ -174,7 +181,11 @@ public class ComponentUpdaterIT {
.setName(DEFAULT_PROJECT_NAME)
.setPrivate(false)
.build();
ComponentDto returned = underTest.create(db.getSession(), project, null, null).mainBranchComponent();
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(project)
.creationMethod(CreationMethod.LOCAL)
.build();
ComponentDto returned = underTest.create(db.getSession(), creationParameters).mainBranchComponent();
ComponentDto loaded = db.getDbClient().componentDao().selectOrFailByUuid(db.getSession(), returned.uuid());
assertThat(loaded.isPrivate()).isEqualTo(project.isPrivate());
}
@@ -187,7 +198,11 @@ public class ComponentUpdaterIT {
.setQualifier(VIEW)
.build();

ComponentDto returned = underTest.create(db.getSession(), view, null, null).mainBranchComponent();
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(view)
.creationMethod(CreationMethod.LOCAL)
.build();
ComponentDto returned = underTest.create(db.getSession(), creationParameters).mainBranchComponent();

ComponentDto loaded = db.getDbClient().componentDao().selectOrFailByUuid(db.getSession(), returned.uuid());
assertThat(loaded.getKey()).isEqualTo("view-key");
@@ -205,8 +220,11 @@ public class ComponentUpdaterIT {
.setName("app-name")
.setQualifier(APP)
.build();

ComponentCreationData returned = underTest.create(db.getSession(), application, null, null);
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(application)
.creationMethod(CreationMethod.LOCAL)
.build();
ComponentCreationData returned = underTest.create(db.getSession(), creationParameters);

ProjectDto loaded = db.getDbClient().projectDao().selectByUuid(db.getSession(), returned.projectDto().getUuid()).get();
assertThat(loaded.getKey()).isEqualTo("app-key");
@@ -224,11 +242,14 @@ public class ComponentUpdaterIT {

@Test
public void apply_default_permission_template() {
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(DEFAULT_COMPONENT)
.userLogin(DEFAULT_USER_LOGIN)
.userUuid(DEFAULT_USER_UUID)
.creationMethod(CreationMethod.LOCAL)
.build();
ProjectDto dto = underTest.create(db.getSession(), project, DEFAULT_USER_UUID, DEFAULT_USER_LOGIN).projectDto();

ProjectDto dto = underTest.create(db.getSession(), componentCreationParameters).projectDto();

verify(permissionTemplateService).applyDefaultToNewComponent(db.getSession(), dto, DEFAULT_USER_UUID);
}
@@ -236,14 +257,17 @@ public class ComponentUpdaterIT {
@Test
public void add_project_to_user_favorites_if_project_creator_is_defined_in_permission_template() {
UserDto userDto = db.users().insertUser();
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(DEFAULT_COMPONENT)
.userLogin(userDto.getLogin())
.userUuid(userDto.getUuid())
.creationMethod(CreationMethod.LOCAL)
.build();

when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ProjectDto.class)))
.thenReturn(true);

ProjectDto dto = underTest.create(db.getSession(), project, userDto.getUuid(), userDto.getLogin()).projectDto();
ProjectDto dto = underTest.create(db.getSession(), creationParameters).projectDto();

assertThat(db.favorites().hasFavorite(dto, userDto.getUuid())).isTrue();
}
@@ -252,55 +276,47 @@ public class ComponentUpdaterIT {
public void do_not_add_project_to_user_favorites_if_project_creator_is_defined_in_permission_template_and_already_100_favorites() {
UserDto user = db.users().insertUser();
rangeClosed(1, 100).forEach(i -> db.favorites().add(db.components().insertPrivateProject().getProjectDto(), user.getUuid(), user.getLogin()));
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(DEFAULT_COMPONENT)
.userLogin(user.getLogin())
.userUuid(user.getUuid())
.creationMethod(CreationMethod.LOCAL)
.build();

when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(eq(db.getSession()), any(ProjectDto.class)))
.thenReturn(true);

ProjectDto dto = underTest.create(db.getSession(),
project,
user.getUuid(),
user.getLogin()).projectDto();
ProjectDto dto = underTest.create(db.getSession(), creationParameters).projectDto();

assertThat(db.favorites().hasFavorite(dto, user.getUuid())).isFalse();
}

@Test
public void does_not_add_project_to_favorite_when_anonymously_created() {
ProjectDto project = underTest.create(db.getSession(),
NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.build(),
null, null).projectDto();

assertThat(db.favorites().hasNoFavorite(project)).isTrue();
}
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(DEFAULT_COMPONENT)
.creationMethod(CreationMethod.LOCAL)
.build();
ProjectDto projectDto = underTest.create(db.getSession(), creationParameters).projectDto();

@Test
public void does_not_add_project_to_favorite_when_project_has_no_permission_on_template() {
ProjectDto project = underTest.create(db.getSession(),
NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.build(),
null, null).projectDto();

assertThat(db.favorites().hasNoFavorite(project)).isTrue();
assertThat(db.favorites().hasNoFavorite(projectDto)).isTrue();
}

@Test
public void fail_when_project_key_already_exists() {
ComponentDto existing = db.components().insertPrivateProject().getMainBranchComponent();

DbSession session = db.getSession();
NewComponent newComponent = NewComponent.newComponentBuilder()

NewComponent project = NewComponent.newComponentBuilder()
.setKey(existing.getKey())
.setName(DEFAULT_PROJECT_NAME)
.build();
assertThatThrownBy(() -> underTest.create(session, newComponent, null, null))
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(project)
.creationMethod(CreationMethod.LOCAL)
.build();

assertThatThrownBy(() -> underTest.create(session, creationParameters))
.isInstanceOf(BadRequestException.class)
.hasMessage("Could not create Project with key: \"%s\". A similar key already exists: \"%s\"", existing.getKey(), existing.getKey());
}
@@ -308,11 +324,16 @@ public class ComponentUpdaterIT {
@Test
public void fail_when_key_has_bad_format() {
DbSession session = db.getSession();
NewComponent newComponent = NewComponent.newComponentBuilder()
NewComponent project = NewComponent.newComponentBuilder()
.setKey("1234")
.setName(DEFAULT_PROJECT_NAME)
.build();
assertThatThrownBy(() -> underTest.create(session, newComponent, null, null))
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(project)
.creationMethod(CreationMethod.LOCAL)
.build();

assertThatThrownBy(() -> underTest.create(session, creationParameters))
.isInstanceOf(BadRequestException.class)
.hasMessageContaining("Malformed key for Project: '1234'");
}
@@ -320,11 +341,16 @@ public class ComponentUpdaterIT {
@Test
public void fail_when_key_contains_percent_character() {
DbSession session = db.getSession();
NewComponent newComponent = NewComponent.newComponentBuilder()
NewComponent project = NewComponent.newComponentBuilder()
.setKey("roject%Key")
.setName(DEFAULT_PROJECT_NAME)
.build();
assertThatThrownBy(() -> underTest.create(session, newComponent, null, null))
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(project)
.creationMethod(CreationMethod.LOCAL)
.build();

assertThatThrownBy(() -> underTest.create(session, creationParameters))
.isInstanceOf(BadRequestException.class)
.hasMessageContaining("Malformed key for Project: 'roject%Key'");
}
@@ -349,14 +375,18 @@ public class ComponentUpdaterIT {
db.components().insertPrivateProject(component -> component.setKey(existingKey));
String newKey = existingKey.toLowerCase();

NewComponent newComponent = NewComponent.newComponentBuilder()
NewComponent project = NewComponent.newComponentBuilder()
.setKey(newKey)
.setName(DEFAULT_PROJECT_NAME)
.setQualifier(qualifier)
.build();
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(project)
.creationMethod(CreationMethod.LOCAL)
.build();

DbSession dbSession = db.getSession();
assertThatThrownBy(() -> underTest.create(dbSession, newComponent, null, null))
assertThatThrownBy(() -> underTest.create(dbSession, creationParameters))
.isInstanceOf(BadRequestException.class)
.hasMessage("Could not create Project with key: \"%s\". A similar key already exists: \"%s\"", newKey, existingKey);
}
@@ -369,13 +399,17 @@ public class ComponentUpdaterIT {
db.components().insertPrivateProject(component -> component.setKey(existingKeyLowerCase));
String newKey = StringUtils.capitalize(existingKeyLowerCase);

NewComponent newComponent = NewComponent.newComponentBuilder()
NewComponent project = NewComponent.newComponentBuilder()
.setKey(newKey)
.setName(DEFAULT_PROJECT_NAME)
.build();
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(project)
.creationMethod(CreationMethod.LOCAL)
.build();

DbSession dbSession = db.getSession();
assertThatThrownBy(() -> underTest.create(dbSession, newComponent, null, null))
assertThatThrownBy(() -> underTest.create(dbSession, creationParameters))
.isInstanceOf(BadRequestException.class)
.hasMessage("Could not create Project with key: \"%s\". A similar key already exists: \"%s, %s\"", newKey, existingKey, existingKeyLowerCase);
}
@@ -388,13 +422,17 @@ public class ComponentUpdaterIT {
db.components().insertPrivatePortfolio(portfolio -> portfolio.setKey(existingKeyLowerCase));
String newKey = StringUtils.capitalize(existingKeyLowerCase);

NewComponent newComponent = NewComponent.newComponentBuilder()
NewComponent project = NewComponent.newComponentBuilder()
.setKey(newKey)
.setName(DEFAULT_PROJECT_NAME)
.build();
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(project)
.creationMethod(CreationMethod.LOCAL)
.build();

DbSession dbSession = db.getSession();
assertThatThrownBy(() -> underTest.create(dbSession, newComponent, null, null))
assertThatThrownBy(() -> underTest.create(dbSession, creationParameters))
.isInstanceOf(BadRequestException.class)
.hasMessage("Could not create Project with key: \"%s\". A similar key already exists: \"%s, %s\"", newKey, existingKey, existingKeyLowerCase);
}
@@ -402,10 +440,19 @@ public class ComponentUpdaterIT {
@Test
public void create_createsComponentWithMasterBranchName() {
String componentNameAndKey = "createApplicationOrPortfolio";
ComponentDto app = underTest.create(db.getSession(), NewComponent.newComponentBuilder().setName(componentNameAndKey)
.setKey(componentNameAndKey).setQualifier("APP").build(), null, null).mainBranchComponent();
NewComponent app = NewComponent.newComponentBuilder()
.setKey(componentNameAndKey)
.setName(componentNameAndKey)
.setQualifier("APP")
.build();
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(app)
.creationMethod(CreationMethod.LOCAL)
.build();

ComponentDto appDto = underTest.create(db.getSession(), creationParameters).mainBranchComponent();

Optional<BranchDto> branch = db.getDbClient().branchDao().selectByUuid(db.getSession(), app.branchUuid());
Optional<BranchDto> branch = db.getDbClient().branchDao().selectByUuid(db.getSession(), appDto.branchUuid());
assertThat(branch).isPresent();
assertThat(branch.get().getBranchKey()).isEqualTo(DEFAULT_MAIN_BRANCH_NAME);
}
@@ -413,11 +460,15 @@ public class ComponentUpdaterIT {
@Test
public void createWithoutCommit_whenProjectIsManaged_doesntApplyPermissionTemplate() {
UserDto userDto = db.users().insertUser();
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(DEFAULT_COMPONENT)
.userLogin(userDto.getLogin())
.userUuid(userDto.getUuid())
.mainBranchName(null)
.isManaged(true)
.creationMethod(CreationMethod.LOCAL)
.build();
underTest.createWithoutCommit(db.getSession(), new ProjectCreationData(project, userDto.getUuid(), userDto.getLogin(), null, true));
underTest.createWithoutCommit(db.getSession(), componentCreationParameters);

verify(permissionTemplateService, never()).applyDefaultToNewComponent(any(), any(), any());
}
@@ -425,18 +476,41 @@ public class ComponentUpdaterIT {
@Test
public void createWithoutCommit_whenProjectIsManagedAndPrivate_applyPublicPermissionsToCreator() {
UserDto userDto = db.users().insertUser();
NewComponent newComponent = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setPrivate(true)
.build();

DbSession session = db.getSession();
ComponentCreationData componentCreationData = underTest.createWithoutCommit(session, new ProjectCreationData(newComponent, userDto.getUuid(), userDto.getLogin(), null, true));

ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(PRIVATE_COMPONENT)
.userLogin(userDto.getLogin())
.userUuid(userDto.getUuid())
.mainBranchName(null)
.isManaged(true)
.creationMethod(CreationMethod.LOCAL)
.build();
ComponentCreationData componentCreationData = underTest.createWithoutCommit(session, componentCreationParameters);

List<String> permissions = db.getDbClient().userPermissionDao().selectEntityPermissionsOfUser(session, userDto.getUuid(), componentCreationData.projectDto().getUuid());
assertThat(permissions)
.containsExactlyInAnyOrder(UserRole.USER, UserRole.CODEVIEWER);
}

@Test
public void create_whenCreationMethodIsLocal_persistsIt() {
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(DEFAULT_COMPONENT)
.creationMethod(CreationMethod.LOCAL)
.build();
ProjectDto projectDto = underTest.create(db.getSession(), creationParameters).projectDto();
assertThat(projectDto.getCreationMethod()).isEqualTo(CreationMethod.LOCAL);
}

@Test
public void create_whenCreationMethodIsAlmImportUi_persistsIt() {
ComponentCreationParameters creationParameters = ComponentCreationParameters.builder()
.newComponent(DEFAULT_COMPONENT)
.creationMethod(CreationMethod.ALM_IMPORT_UI)
.build();
ProjectDto projectDto = underTest.create(db.getSession(), creationParameters).projectDto();
assertThat(projectDto.getCreationMethod()).isEqualTo(CreationMethod.ALM_IMPORT_UI);
}
}

+ 7
- 5
server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/CreateActionIT.java View File

@@ -35,6 +35,7 @@ import org.sonar.db.DbTester;
import org.sonar.db.component.BranchDto;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.newcodeperiod.NewCodePeriodDto;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentUpdater;
@@ -131,12 +132,13 @@ public class CreateActionIT {
assertThat(response.getProject())
.extracting(Project::getKey, Project::getName, Project::getQualifier, Project::getVisibility)
.containsOnly(DEFAULT_PROJECT_KEY, DEFAULT_PROJECT_NAME, "TRK", "public");
ComponentDto component = db.getDbClient().componentDao().selectByKey(db.getSession(), DEFAULT_PROJECT_KEY).get();
assertThat(component)
.extracting(ComponentDto::getKey, ComponentDto::name, ComponentDto::qualifier, ComponentDto::scope, ComponentDto::isPrivate)
.containsOnly(DEFAULT_PROJECT_KEY, DEFAULT_PROJECT_NAME, "TRK", "PRJ", false);
ProjectDto projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), DEFAULT_PROJECT_KEY).orElseThrow();
assertThat(projectDto)
.extracting(ProjectDto::getKey, ProjectDto::getName, ProjectDto::getQualifier, ProjectDto::isPrivate, ProjectDto::getCreationMethod)
.containsOnly(DEFAULT_PROJECT_KEY, DEFAULT_PROJECT_NAME, "TRK", false, CreationMethod.LOCAL);

BranchDto branch = db.getDbClient().branchDao().selectByUuid(db.getSession(), component.branchUuid()).get();
ComponentDto component = db.getDbClient().componentDao().selectByKey(db.getSession(), DEFAULT_PROJECT_KEY).orElseThrow();
BranchDto branch = db.getDbClient().branchDao().selectByUuid(db.getSession(), component.branchUuid()).orElseThrow();
assertThat(branch)
.extracting(BranchDto::getKey)
.isEqualTo(MAIN_BRANCH);

+ 10
- 3
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/azure/ImportAzureProjectAction.java View File

@@ -39,8 +39,9 @@ import org.sonar.server.almintegration.ws.ImportHelper;
import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
import org.sonar.server.component.ComponentCreationData;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.db.project.CreationMethod;
import org.sonar.server.component.NewComponent;
import org.sonar.server.component.ProjectCreationData;
import org.sonar.server.component.ComponentCreationParameters;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.sonar.server.project.ProjectDefaultVisibility;
@@ -184,8 +185,14 @@ public class ImportAzureProjectAction implements AlmIntegrationsWsAction {
.setPrivate(visibility)
.setQualifier(PROJECT)
.build();
ProjectCreationData projectCreationData = new ProjectCreationData(newProject, userSession.getUuid(), userSession.getLogin(), repo.getDefaultBranchName());
return componentUpdater.createWithoutCommit(dbSession, projectCreationData);
ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(newProject)
.userUuid(userSession.getUuid())
.userLogin(userSession.getLogin())
.mainBranchName(repo.getDefaultBranchName())
.creationMethod(CreationMethod.ALM_IMPORT_API)
.build();
return componentUpdater.createWithoutCommit(dbSession, componentCreationParameters);
}

private void populatePRSetting(DbSession dbSession, GsonAzureRepo repo, ProjectDto projectDto, AlmSettingDto almSettingDto) {

+ 10
- 3
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/bitbucketcloud/ImportBitbucketCloudRepoAction.java View File

@@ -40,8 +40,9 @@ import org.sonar.server.almintegration.ws.ImportHelper;
import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
import org.sonar.server.component.ComponentCreationData;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.db.project.CreationMethod;
import org.sonar.server.component.NewComponent;
import org.sonar.server.component.ProjectCreationData;
import org.sonar.server.component.ComponentCreationParameters;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.sonar.server.project.ProjectDefaultVisibility;
@@ -182,8 +183,14 @@ public class ImportBitbucketCloudRepoAction implements AlmIntegrationsWsAction {
.setPrivate(visibility)
.setQualifier(PROJECT)
.build();
ProjectCreationData projectCreationData = new ProjectCreationData(newProject, userSession.getUuid(), userSession.getLogin(), defaultBranchName);
return componentUpdater.createWithoutCommit(dbSession, projectCreationData);
ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(newProject)
.userUuid(userSession.getUuid())
.userLogin(userSession.getLogin())
.mainBranchName(defaultBranchName)
.creationMethod(CreationMethod.ALM_IMPORT_API)
.build();
return componentUpdater.createWithoutCommit(dbSession, componentCreationParameters);
}

private void populatePRSetting(DbSession dbSession, Repository repo, ProjectDto projectDto, AlmSettingDto almSettingDto) {

+ 10
- 3
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/bitbucketserver/ImportBitbucketServerProjectAction.java View File

@@ -42,8 +42,9 @@ import org.sonar.server.almintegration.ws.ImportHelper;
import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
import org.sonar.server.component.ComponentCreationData;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.db.project.CreationMethod;
import org.sonar.server.component.NewComponent;
import org.sonar.server.component.ProjectCreationData;
import org.sonar.server.component.ComponentCreationParameters;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.sonar.server.project.ProjectDefaultVisibility;
@@ -200,8 +201,14 @@ public class ImportBitbucketServerProjectAction implements AlmIntegrationsWsActi
.setPrivate(visibility)
.setQualifier(PROJECT)
.build();
ProjectCreationData projectCreationData = new ProjectCreationData(newProject, userSession.getUuid(), userSession.getLogin(), defaultBranchName);
return componentUpdater.createWithoutCommit(dbSession, projectCreationData);
ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(newProject)
.userUuid(userSession.getUuid())
.userLogin(userSession.getLogin())
.mainBranchName(defaultBranchName)
.creationMethod(CreationMethod.ALM_IMPORT_API)
.build();
return componentUpdater.createWithoutCommit(dbSession, componentCreationParameters);
}

private void populatePRSetting(DbSession dbSession, Repository repo, ProjectDto componentDto, AlmSettingDto almSettingDto) {

+ 11
- 6
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectAction.java View File

@@ -45,7 +45,7 @@ import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
import org.sonar.server.component.ComponentCreationData;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.component.NewComponent;
import org.sonar.server.component.ProjectCreationData;
import org.sonar.server.component.ComponentCreationParameters;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.management.ManagedProjectService;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
@@ -59,6 +59,7 @@ import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.server.almintegration.ws.ImportHelper.PARAM_ALM_SETTING;
import static org.sonar.server.almintegration.ws.ImportHelper.toCreateResponse;
import static org.sonar.server.component.NewComponent.newComponentBuilder;
import static org.sonar.db.project.CreationMethod.ALM_IMPORT_API;
import static org.sonar.server.newcodeperiod.NewCodeDefinitionResolver.NEW_CODE_PERIOD_TYPE_DESCRIPTION_PROJECT_CREATION;
import static org.sonar.server.newcodeperiod.NewCodeDefinitionResolver.NEW_CODE_PERIOD_VALUE_DESCRIPTION_PROJECT_CREATION;
import static org.sonar.server.newcodeperiod.NewCodeDefinitionResolver.checkNewCodeDefinitionParam;
@@ -204,11 +205,15 @@ public class ImportGithubProjectAction implements AlmIntegrationsWsAction {
.setPrivate(visibility)
.setQualifier(PROJECT)
.build();
ProjectCreationData projectCreationData = new ProjectCreationData(projectComponent, userSession.getUuid(), userSession.getLogin(), mainBranchName,
gitHubSettings.isProvisioningEnabled());
return componentUpdater.createWithoutCommit(
dbSession,
projectCreationData);
ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(projectComponent)
.userLogin(userSession.getLogin())
.userUuid(userSession.getUuid())
.mainBranchName(mainBranchName)
.isManaged(gitHubSettings.isProvisioningEnabled())
.creationMethod(ALM_IMPORT_API)
.build();
return componentUpdater.createWithoutCommit(dbSession, componentCreationParameters);
}

private void populatePRSetting(DbSession dbSession, Repository repo, ProjectDto projectDto, AlmSettingDto almSettingDto) {

+ 10
- 3
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/gitlab/ImportGitLabProjectAction.java View File

@@ -41,7 +41,7 @@ import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
import org.sonar.server.component.ComponentCreationData;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.component.NewComponent;
import org.sonar.server.component.ProjectCreationData;
import org.sonar.server.component.ComponentCreationParameters;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.sonar.server.project.ProjectDefaultVisibility;
@@ -51,6 +51,7 @@ import org.sonarqube.ws.Projects.CreateWsResponse;
import static java.util.Objects.requireNonNull;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.server.component.NewComponent.newComponentBuilder;
import static org.sonar.db.project.CreationMethod.ALM_IMPORT_API;
import static org.sonar.server.newcodeperiod.NewCodeDefinitionResolver.NEW_CODE_PERIOD_TYPE_DESCRIPTION_PROJECT_CREATION;
import static org.sonar.server.newcodeperiod.NewCodeDefinitionResolver.NEW_CODE_PERIOD_VALUE_DESCRIPTION_PROJECT_CREATION;
import static org.sonar.server.newcodeperiod.NewCodeDefinitionResolver.checkNewCodeDefinitionParam;
@@ -186,8 +187,14 @@ public class ImportGitLabProjectAction implements AlmIntegrationsWsAction {
.setPrivate(visibility)
.setQualifier(PROJECT)
.build();
ProjectCreationData projectCreationData = new ProjectCreationData(newProject, userSession.getUuid(), userSession.getLogin(), mainBranchName);
return componentUpdater.createWithoutCommit(dbSession, projectCreationData);
ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(newProject)
.userUuid(userSession.getUuid())
.userLogin(userSession.getLogin())
.mainBranchName(mainBranchName)
.creationMethod(ALM_IMPORT_API)
.build();
return componentUpdater.createWithoutCommit(dbSession, componentCreationParameters);
}

}

+ 9
- 2
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java View File

@@ -41,7 +41,7 @@ import org.sonar.db.permission.GlobalPermission;
import org.sonar.server.component.ComponentCreationData;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.component.NewComponent;
import org.sonar.server.component.ProjectCreationData;
import org.sonar.server.component.ComponentCreationParameters;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.permission.PermissionTemplateService;
import org.sonar.server.project.ProjectDefaultVisibility;
@@ -51,6 +51,7 @@ import org.sonar.server.user.UserSession;
import static java.lang.String.format;
import static org.apache.commons.lang.StringUtils.defaultIfBlank;
import static org.sonar.server.component.NewComponent.newComponentBuilder;
import static org.sonar.db.project.CreationMethod.SCANNER;
import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;

@ServerSide
@@ -169,7 +170,13 @@ public class ReportSubmitter {
.setQualifier(Qualifiers.PROJECT)
.setPrivate(getDefaultVisibility(dbSession).isPrivate())
.build();
return componentUpdater.createWithoutCommit(dbSession, new ProjectCreationData(newProject, userUuid, userName));
ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(newProject)
.userLogin(userName)
.userUuid(userUuid)
.creationMethod(SCANNER)
.build();
return componentUpdater.createWithoutCommit(dbSession, componentCreationParameters);
}

private Visibility getDefaultVisibility(DbSession dbSession) {

+ 78
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentCreationParameters.java View File

@@ -0,0 +1,78 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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.server.component;

import javax.annotation.Nullable;
import org.sonar.db.project.CreationMethod;

public record ComponentCreationParameters(NewComponent newComponent,
@Nullable String userUuid,
@Nullable String userLogin,
@Nullable String mainBranchName,
boolean isManaged,
CreationMethod creationMethod) {

public static ProjectCreationDataBuilder builder() {
return new ProjectCreationDataBuilder();
}

public static final class ProjectCreationDataBuilder {
private NewComponent newComponent;
private String userUuid = null;
private String userLogin = null;
private String mainBranchName = null;
private boolean isManaged = false;
private CreationMethod creationMethod;

public ProjectCreationDataBuilder newComponent(NewComponent newComponent) {
this.newComponent = newComponent;
return this;
}

public ProjectCreationDataBuilder userUuid(@Nullable String userUuid) {
this.userUuid = userUuid;
return this;
}

public ProjectCreationDataBuilder userLogin(@Nullable String userLogin) {
this.userLogin = userLogin;
return this;
}

public ProjectCreationDataBuilder mainBranchName(@Nullable String mainBranchName) {
this.mainBranchName = mainBranchName;
return this;
}

public ProjectCreationDataBuilder isManaged(boolean isManaged) {
this.isManaged = isManaged;
return this;
}

public ProjectCreationDataBuilder creationMethod(CreationMethod creationMethod) {
this.creationMethod = creationMethod;
return this;
}

public ComponentCreationParameters build() {
return new ComponentCreationParameters(newComponent, userUuid, userLogin, mainBranchName, isManaged, creationMethod);
}
}
}

+ 16
- 14
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentUpdater.java View File

@@ -38,6 +38,7 @@ import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.portfolio.PortfolioDto;
import org.sonar.db.portfolio.PortfolioDto.SelectionMode;
import org.sonar.db.project.CreationMethod;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.Indexers;
@@ -95,8 +96,8 @@ public class ComponentUpdater {
* - Add component to favorite if the component has the 'Project Creators' permission
* - Index component in es indexes
*/
public ComponentCreationData create(DbSession dbSession, NewComponent newComponent, @Nullable String userUuid, @Nullable String userLogin) {
ComponentCreationData componentCreationData = createWithoutCommit(dbSession, new ProjectCreationData(newComponent, userUuid, userLogin));
public ComponentCreationData create(DbSession dbSession, ComponentCreationParameters componentCreationParameters) {
ComponentCreationData componentCreationData = createWithoutCommit(dbSession, componentCreationParameters);
commitAndIndex(dbSession, componentCreationData);
return componentCreationData;
}
@@ -113,32 +114,32 @@ public class ComponentUpdater {
* Create component without committing.
* Don't forget to call commitAndIndex(...) when ready to commit.
*/
public ComponentCreationData createWithoutCommit(DbSession dbSession, ProjectCreationData projectCreationData) {
checkKeyFormat(projectCreationData.newComponent().qualifier(), projectCreationData.newComponent().key());
checkKeyAlreadyExists(dbSession, projectCreationData.newComponent());
public ComponentCreationData createWithoutCommit(DbSession dbSession, ComponentCreationParameters componentCreationParameters) {
checkKeyFormat(componentCreationParameters.newComponent().qualifier(), componentCreationParameters.newComponent().key());
checkKeyAlreadyExists(dbSession, componentCreationParameters.newComponent());

long now = system2.now();

ComponentDto componentDto = createRootComponent(dbSession, projectCreationData.newComponent(), now);
ComponentDto componentDto = createRootComponent(dbSession, componentCreationParameters.newComponent(), now);

BranchDto mainBranch = null;
ProjectDto projectDto = null;
PortfolioDto portfolioDto = null;

if (isProjectOrApp(componentDto)) {
projectDto = toProjectDto(componentDto, now);
projectDto = toProjectDto(componentDto, now, componentCreationParameters.creationMethod());
dbClient.projectDao().insert(dbSession, projectDto);
addToFavourites(dbSession, projectDto, projectCreationData.userUuid(), projectCreationData.userLogin());
mainBranch = createMainBranch(dbSession, componentDto.uuid(), projectDto.getUuid(), projectCreationData.mainBranchName());
if (projectCreationData.isManaged()) {
applyPublicPermissionsForCreator(dbSession, projectDto, projectCreationData.userUuid());
addToFavourites(dbSession, projectDto, componentCreationParameters.userUuid(), componentCreationParameters.userLogin());
mainBranch = createMainBranch(dbSession, componentDto.uuid(), projectDto.getUuid(), componentCreationParameters.mainBranchName());
if (componentCreationParameters.isManaged()) {
applyPublicPermissionsForCreator(dbSession, projectDto, componentCreationParameters.userUuid());
} else {
permissionTemplateService.applyDefaultToNewComponent(dbSession, projectDto, projectCreationData.userUuid());
permissionTemplateService.applyDefaultToNewComponent(dbSession, projectDto, componentCreationParameters.userUuid());
}
} else if (isPortfolio(componentDto)) {
portfolioDto = toPortfolioDto(componentDto, now);
dbClient.portfolioDao().insert(dbSession, portfolioDto);
permissionTemplateService.applyDefaultToNewComponent(dbSession, portfolioDto, projectCreationData.userUuid());
permissionTemplateService.applyDefaultToNewComponent(dbSession, portfolioDto, componentCreationParameters.userUuid());
} else {
throw new IllegalArgumentException("Component " + componentDto + " is not a top level entity");
}
@@ -203,7 +204,7 @@ public class ComponentUpdater {
return component;
}

private ProjectDto toProjectDto(ComponentDto component, long now) {
private ProjectDto toProjectDto(ComponentDto component, long now, CreationMethod creationMethod) {
return new ProjectDto()
.setUuid(uuidFactory.create())
.setKey(component.getKey())
@@ -211,6 +212,7 @@ public class ComponentUpdater {
.setName(component.name())
.setPrivate(component.isPrivate())
.setDescription(component.description())
.setCreationMethod(creationMethod)
.setUpdatedAt(now)
.setCreatedAt(now);
}

+ 0
- 13
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ProjectCreationData.java View File

@@ -1,13 +0,0 @@
package org.sonar.server.component;

import javax.annotation.Nullable;

public record ProjectCreationData(NewComponent newComponent, @Nullable String userUuid, @Nullable String userLogin, @Nullable String mainBranchName, boolean isManaged) {
public ProjectCreationData(NewComponent newComponent, @Nullable String userUuid, @Nullable String userLogin, @Nullable String mainBranchName) {
this(newComponent, userUuid, userLogin, mainBranchName, false);
}

public ProjectCreationData(NewComponent newComponent, @Nullable String userUuid, @Nullable String userLogin) {
this(newComponent, userUuid, userLogin, null, false);
}
}

+ 10
- 3
server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/CreateAction.java View File

@@ -33,8 +33,9 @@ import org.sonar.db.entity.EntityDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.server.component.ComponentCreationData;
import org.sonar.server.component.ComponentUpdater;
import org.sonar.db.project.CreationMethod;
import org.sonar.server.component.NewComponent;
import org.sonar.server.component.ProjectCreationData;
import org.sonar.server.component.ComponentCreationParameters;
import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
import org.sonar.server.project.DefaultBranchNameResolver;
import org.sonar.server.project.ProjectDefaultVisibility;
@@ -163,8 +164,14 @@ public class CreateAction implements ProjectsWsAction {
.setPrivate(changeToPrivate)
.setQualifier(PROJECT)
.build();
ProjectCreationData projectCreationData = new ProjectCreationData(newProject, userSession.getUuid(), userSession.getLogin(), request.getMainBranchKey());
return componentUpdater.createWithoutCommit(dbSession, projectCreationData);
ComponentCreationParameters componentCreationParameters = ComponentCreationParameters.builder()
.newComponent(newProject)
.userUuid(userSession.getUuid())
.userLogin(userSession.getLogin())
.mainBranchName(request.getMainBranchKey())
.creationMethod(CreationMethod.LOCAL)
.build();
return componentUpdater.createWithoutCommit(dbSession, componentCreationParameters);

}


Loading…
Cancel
Save