diff options
author | Mathieu Suen <59278745+mathieu-suen-sonarsource@users.noreply.github.com> | 2021-04-26 09:44:58 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2021-04-26 20:03:35 +0000 |
commit | ef4e8f0650d828b862810e4365c70f3fd2201ecd (patch) | |
tree | 1a4a12273f9a884b229de2177a01ff73c2c13cd3 /server/sonar-webserver-webapi | |
parent | e929b40a53123764ec730dce09e659c09a1d8c01 (diff) | |
download | sonarqube-ef4e8f0650d828b862810e4365c70f3fd2201ecd.tar.gz sonarqube-ef4e8f0650d828b862810e4365c70f3fd2201ecd.zip |
SONAR-13645 Make github onboarding resiliant to project name/key change
Co-authored-by: Pierre <pierre.guillot@sonarsource.com>
Diffstat (limited to 'server/sonar-webserver-webapi')
2 files changed, 56 insertions, 14 deletions
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/github/ListGithubRepositoriesAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/github/ListGithubRepositoriesAction.java index a0872a6a4cb..1451788e347 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/github/ListGithubRepositoriesAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/github/ListGithubRepositoriesAction.java @@ -19,8 +19,14 @@ */ package org.sonar.server.almintegration.ws.github; +import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.Set; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.stream.Collectors; import org.sonar.alm.client.github.GithubApplicationClient; import org.sonar.alm.client.github.GithubApplicationClient.Repository; import org.sonar.alm.client.github.GithubApplicationClientImpl; @@ -33,6 +39,8 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.alm.pat.AlmPatDto; import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.alm.setting.ProjectAlmSettingDao; +import org.sonar.db.alm.setting.ProjectAlmSettingDto; import org.sonar.db.project.ProjectDto; import org.sonar.server.almintegration.ws.AlmIntegrationsWsAction; import org.sonar.server.exceptions.NotFoundException; @@ -45,7 +53,6 @@ import static org.sonar.api.server.ws.WebService.Param.PAGE; import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE; import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; -import static org.sonar.server.almintegration.ws.github.ImportGithubProjectAction.getProjectKeyFromRepository; import static org.sonar.server.ws.WsUtils.writeProtobuf; public class ListGithubRepositoriesAction implements AlmIntegrationsWsAction { @@ -56,11 +63,13 @@ public class ListGithubRepositoriesAction implements AlmIntegrationsWsAction { private final DbClient dbClient; private final UserSession userSession; private final GithubApplicationClient githubApplicationClient; + private final ProjectAlmSettingDao projectAlmSettingDao; - public ListGithubRepositoriesAction(DbClient dbClient, UserSession userSession, GithubApplicationClientImpl githubApplicationClient) { + public ListGithubRepositoriesAction(DbClient dbClient, UserSession userSession, GithubApplicationClientImpl githubApplicationClient, ProjectAlmSettingDao projectAlmSettingDao) { this.dbClient = dbClient; this.userSession = userSession; this.githubApplicationClient = githubApplicationClient; + this.projectAlmSettingDao = projectAlmSettingDao; } @Override @@ -131,20 +140,46 @@ public class ListGithubRepositoriesAction implements AlmIntegrationsWsAction { List<Repository> repositoryList = repositories.getRepositories(); if (repositoryList != null) { - repositoryList.forEach(repository -> { - Optional<String> sonarQubeKey = dbClient.projectDao().selectProjectByKey(dbSession, getProjectKeyFromRepository(repository)).map(ProjectDto::getKey); - response.addRepositories(AlmIntegrations.GithubRepository.newBuilder() - .setId(repository.getId()) - .setKey(repository.getFullName()) - .setName(repository.getName()) - .setUrl(repository.getUrl()) - .setSqProjectKey(sonarQubeKey.orElse("")) - .build()); - } - ); + + Set<String> repo = repositoryList.stream().map(Repository::getFullName).collect(Collectors.toSet()); + List<ProjectAlmSettingDto> projectAlmSettingDtos = projectAlmSettingDao.selectByAlmSettingAndRepos(dbSession, almSettingDto, repo); + + Map<String, ProjectDto> projectsDtoByAlmRepo = getProjectDtoByAlmRepo(dbSession, projectAlmSettingDtos); + + for (Repository repository : repositoryList) { + AlmIntegrations.GithubRepository.Builder builder = AlmIntegrations.GithubRepository.newBuilder() + .setId(repository.getId()) + .setKey(repository.getFullName()) + .setName(repository.getName()) + .setUrl(repository.getUrl()); + + if (projectsDtoByAlmRepo.containsKey(repository.getFullName())) { + Optional.ofNullable(projectsDtoByAlmRepo.get(repository.getFullName())) + .ifPresent(p -> builder.setSqProjectKey(p.getKey())); + } + + response.addRepositories(builder.build()); + } } return response.build(); } } + + private Map<String, ProjectDto> getProjectDtoByAlmRepo(DbSession dbSession, List<ProjectAlmSettingDto> projectAlmSettingDtos) { + Map<String, ProjectAlmSettingDto> projectAlmSettingDtoByProjectUuid = projectAlmSettingDtos.stream() + .collect(Collectors.toMap(ProjectAlmSettingDto::getProjectUuid, Function.identity())); + + Set<String> projectUuids = projectAlmSettingDtos.stream().map(ProjectAlmSettingDto::getProjectUuid).collect(Collectors.toSet()); + + return dbClient.projectDao().selectByUuids(dbSession, projectUuids) + .stream() + .collect(Collectors.toMap(projectDto -> projectAlmSettingDtoByProjectUuid.get(projectDto.getUuid()).getAlmRepo(), + Function.identity(), resolveNameCollisionOperatorByNaturalOrder())); + } + + private static BinaryOperator<ProjectDto> resolveNameCollisionOperatorByNaturalOrder() { + Comparator<ProjectDto> comparator = Comparator.comparing(ProjectDto::getKey); + return (a, b) -> comparator.compare(a, b) > 0 ? b : a; + } } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almintegration/ws/github/ListGithubRepositoriesActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almintegration/ws/github/ListGithubRepositoriesActionTest.java index 66fd47a2ad2..9e73e35f682 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almintegration/ws/github/ListGithubRepositoriesActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almintegration/ws/github/ListGithubRepositoriesActionTest.java @@ -29,6 +29,7 @@ import org.sonar.api.utils.System2; import org.sonar.db.DbTester; import org.sonar.db.alm.pat.AlmPatDto; import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.alm.setting.ProjectAlmSettingDao; import org.sonar.db.permission.GlobalPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.UserDto; @@ -63,7 +64,9 @@ public class ListGithubRepositoriesActionTest { @Rule public DbTester db = DbTester.create(system2); - private final WsActionTester ws = new WsActionTester(new ListGithubRepositoriesAction(db.getDbClient(), userSession, appClient)); + private final ProjectAlmSettingDao projectAlmSettingDao = db.getDbClient().projectAlmSettingDao(); + + private final WsActionTester ws = new WsActionTester(new ListGithubRepositoriesAction(db.getDbClient(), userSession, appClient, projectAlmSettingDao)); @Test public void fail_when_missing_create_project_permission() { @@ -112,6 +115,10 @@ public class ListGithubRepositoriesActionTest { .collect(Collectors.toList()))); ProjectDto project = db.components().insertPrivateProjectDto(componentDto -> componentDto.setDbKey("github_HelloWorld")); + db.almSettings().insertGitHubProjectAlmSetting(githubAlmSettings, project, projectAlmSettingDto -> projectAlmSettingDto.setAlmRepo("github/HelloWorld")); + + ProjectDto project2 = db.components().insertPrivateProjectDto(componentDto -> componentDto.setDbKey("github_HelloWorld2")); + db.almSettings().insertGitHubProjectAlmSetting(githubAlmSettings, project2, projectAlmSettingDto -> projectAlmSettingDto.setAlmRepo("github/HelloWorld")); ListGithubRepositoriesWsResponse response = ws.newRequest() .setParam(ListGithubRepositoriesAction.PARAM_ALM_SETTING, githubAlmSettings.getKey()) |