Browse Source

SONAR-20699 Infer GitHub DevOps Platform from scanner information

tags/10.3.0.82913
Antoine Vigneau 7 months ago
parent
commit
da75e87d29

+ 6
- 0
server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClient.java View File

@@ -46,6 +46,12 @@ public interface GithubApplicationClient {

GithubBinding.GsonApp getApp(GithubAppConfiguration githubAppConfiguration);

/**
* Retrieve the installation id for the given accountName.
* @throws IllegalArgumentException if one of the arguments is invalid (for example, wrong private key)
*/
Optional<Long> getInstallationId(GithubAppConfiguration githubAppConfiguration, String repositorySlug);

/**
* Lists all the organizations accessible to the access token provided.
*/

+ 8
- 0
server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClientImpl.java View File

@@ -145,6 +145,14 @@ public class GithubApplicationClientImpl implements GithubApplicationClient {
}
}

@Override
public Optional<Long> getInstallationId(GithubAppConfiguration githubAppConfiguration, String repositorySlug) {
AppToken appToken = appSecurity.createAppToken(githubAppConfiguration.getId(), githubAppConfiguration.getPrivateKey());
String endpoint = String.format("/repos/%s/installation", repositorySlug);
return get(githubAppConfiguration.getApiEndpoint(), appToken, endpoint, GithubBinding.GsonInstallation.class)
.map(GithubBinding.GsonInstallation::getId);
}

@Override
public Organizations listOrganizations(String appUrl, AccessToken accessToken, int page, int pageSize) {
checkPageArgs(page, pageSize);

+ 33
- 0
server/sonar-alm-client/src/test/java/org/sonar/alm/client/github/GithubApplicationClientImplTest.java View File

@@ -235,6 +235,39 @@ public class GithubApplicationClientImplTest {
assertThatCode(() -> underTest.checkAppPermissions(githubAppConfiguration)).isNull();
}

@Test
public void getInstallationId_returns_installation_id_of_given_account() throws IOException {
AppToken appToken = new AppToken(APP_JWT_TOKEN);
when(appSecurity.createAppToken(githubAppConfiguration.getId(), githubAppConfiguration.getPrivateKey())).thenReturn(appToken);
when(httpClient.get(appUrl, appToken, "/repos/torvalds/linux/installation"))
.thenReturn(new OkGetResponse("{" +
" \"id\": 2," +
" \"account\": {" +
" \"login\": \"torvalds\"" +
" }" +
"}"));

assertThat(underTest.getInstallationId(githubAppConfiguration, "torvalds/linux")).hasValue(2L);
}

@Test
public void getInstallationId_throws_IAE_if_fail_to_create_app_token() {
when(appSecurity.createAppToken(githubAppConfiguration.getId(), githubAppConfiguration.getPrivateKey())).thenThrow(IllegalArgumentException.class);

assertThatThrownBy(() -> underTest.getInstallationId(githubAppConfiguration, "torvalds"))
.isInstanceOf(IllegalArgumentException.class);
}

@Test
public void getInstallationId_return_empty_if_no_installation_found_for_githubAccount() throws IOException {
AppToken appToken = new AppToken(APP_JWT_TOKEN);
when(appSecurity.createAppToken(githubAppConfiguration.getId(), githubAppConfiguration.getPrivateKey())).thenReturn(appToken);
when(httpClient.get(appUrl, appToken, "/repos/torvalds/linux/installation"))
.thenReturn(new ErrorGetResponse(404, null));

assertThat(underTest.getInstallationId(githubAppConfiguration, "torvalds")).isEmpty();
}

@Test
@UseDataProvider("githubServers")
public void createUserAccessToken_returns_empty_if_access_token_cant_be_created(String apiUrl, String appUrl) throws IOException {

+ 66
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/DelegatingDevOpsPlatformService.java View File

@@ -0,0 +1,66 @@
/*
* 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.almsettings.ws;

import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Priority;
import org.apache.commons.lang.NotImplementedException;
import org.sonar.api.server.ServerSide;
import org.sonar.db.DbSession;
import org.sonar.db.alm.setting.ALM;
import org.sonar.db.alm.setting.AlmSettingDto;

@ServerSide
@Priority(1)
public class DelegatingDevOpsPlatformService implements DevOpsPlatformService {

private final Set<DevOpsPlatformService> delegates;

public DelegatingDevOpsPlatformService(Set<DevOpsPlatformService> delegates) {
this.delegates = delegates;
}

@Override
public ALM getDevOpsPlatform() {
throw new NotImplementedException();
}

@Override
public Optional<DevOpsProjectDescriptor> getDevOpsProjectDescriptor(Map<String, String> characteristics) {
return delegates.stream()
.flatMap(delegate -> delegate.getDevOpsProjectDescriptor(characteristics).stream())
.findFirst();
}

@Override
public Optional<AlmSettingDto> getValidAlmSettingDto(DbSession dbSession, DevOpsProjectDescriptor devOpsProjectDescriptor) {
return findDelegate(devOpsProjectDescriptor.alm())
.flatMap(delegate -> delegate.getValidAlmSettingDto(dbSession, devOpsProjectDescriptor));
}

private Optional<DevOpsPlatformService> findDelegate(ALM alm) {
return delegates.stream()
.filter(delegate -> delegate.getDevOpsPlatform().equals(alm))
.findFirst();
}

}

+ 36
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/DevOpsPlatformService.java View File

@@ -0,0 +1,36 @@
/*
* 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.almsettings.ws;

import java.util.Map;
import java.util.Optional;
import org.sonar.db.DbSession;
import org.sonar.db.alm.setting.ALM;
import org.sonar.db.alm.setting.AlmSettingDto;

public interface DevOpsPlatformService {

ALM getDevOpsPlatform();

Optional<DevOpsProjectDescriptor> getDevOpsProjectDescriptor(Map<String, String> characteristics);

Optional<AlmSettingDto> getValidAlmSettingDto(DbSession dbSession, DevOpsProjectDescriptor devOpsProjectDescriptor);

}

+ 25
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/DevOpsProjectDescriptor.java View File

@@ -0,0 +1,25 @@
/*
* 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.almsettings.ws;

import org.sonar.db.alm.setting.ALM;

public record DevOpsProjectDescriptor(ALM alm, String url, String projectIdentifier) {
}

+ 78
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GitHubDevOpsPlatformService.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.almsettings.ws;

import java.util.Map;
import java.util.Optional;
import org.sonar.alm.client.github.GithubApplicationClient;
import org.sonar.alm.client.github.GithubGlobalSettingsValidator;
import org.sonar.alm.client.github.config.GithubAppConfiguration;
import org.sonar.api.server.ServerSide;
import org.sonar.db.DbSession;
import org.sonar.db.alm.setting.ALM;
import org.sonar.db.alm.setting.AlmSettingDao;
import org.sonar.db.alm.setting.AlmSettingDto;

@ServerSide
public class GitHubDevOpsPlatformService implements DevOpsPlatformService {

public static final String DEVOPS_PLATFORM_URL = "devOpsPlatformUrl";
public static final String DEVOPS_PLATFORM_PROJECT_IDENTIFIER = "devOpsPlatformProjectIdentifier";

private final AlmSettingDao almSettingDao;
private final GithubGlobalSettingsValidator githubGlobalSettingsValidator;
private final GithubApplicationClient githubApplicationClient;

public GitHubDevOpsPlatformService(AlmSettingDao almSettingDao, GithubGlobalSettingsValidator githubGlobalSettingsValidator,
GithubApplicationClient githubApplicationClient) {
this.almSettingDao = almSettingDao;
this.githubGlobalSettingsValidator = githubGlobalSettingsValidator;
this.githubApplicationClient = githubApplicationClient;
}

@Override
public ALM getDevOpsPlatform() {
return ALM.GITHUB;
}

@Override
public Optional<DevOpsProjectDescriptor> getDevOpsProjectDescriptor(Map<String, String> characteristics) {
String githubApiUrl = characteristics.get(DEVOPS_PLATFORM_URL);
String githubRepository = characteristics.get(DEVOPS_PLATFORM_PROJECT_IDENTIFIER);
if (githubApiUrl != null && githubRepository != null) {
return Optional.of(new DevOpsProjectDescriptor(ALM.GITHUB, githubApiUrl, githubRepository));
}
return Optional.empty();
}

@Override
public Optional<AlmSettingDto> getValidAlmSettingDto(DbSession dbSession, DevOpsProjectDescriptor devOpsProjectDescriptor) {
return almSettingDao.selectByAlm(dbSession, getDevOpsPlatform()).stream()
.filter(almSettingDto -> devOpsProjectDescriptor.url().equals(almSettingDto.getUrl()))
.filter(almSettingDto -> hasAccessToRepo(almSettingDto, devOpsProjectDescriptor.projectIdentifier()))
.findFirst();
}

private boolean hasAccessToRepo(AlmSettingDto almSettingDto, String repo) {
GithubAppConfiguration githubAppConfiguration = githubGlobalSettingsValidator.validate(almSettingDto);
return githubApplicationClient.getInstallationId(githubAppConfiguration, repo).isPresent();
}

}

+ 109
- 0
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/DelegatingDevOpsPlatformServiceTest.java View File

@@ -0,0 +1,109 @@
/*
* 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.almsettings.ws;

import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.apache.commons.lang.NotImplementedException;
import org.junit.Test;
import org.mockito.Mock;
import org.sonar.db.DbSession;
import org.sonar.db.alm.setting.ALM;
import org.sonar.db.alm.setting.AlmSettingDto;

import static java.util.Collections.emptySet;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class DelegatingDevOpsPlatformServiceTest {

private static final DelegatingDevOpsPlatformService NO_DEVOPS_PLATFORMS = new DelegatingDevOpsPlatformService(emptySet());
private static final DelegatingDevOpsPlatformService MULTIPLE_DEVOPS_PLATFORMS = new DelegatingDevOpsPlatformService(
Set.of(mockGitHubDevOpsPlatformService(), mockAzureDevOpsPlatformService()));

@Mock
private DbSession dbSession;

@Test
public void getDevOpsPlatform_shouldThrow() {
assertThatThrownBy(NO_DEVOPS_PLATFORMS::getDevOpsPlatform)
.isInstanceOf(NotImplementedException.class);
}

@Test
public void getDevOpsProjectDescriptor_whenNoDelegates_shouldReturnOptionalEmpty() {
Optional<DevOpsProjectDescriptor> devOpsProjectDescriptor = NO_DEVOPS_PLATFORMS.getDevOpsProjectDescriptor(Map.of());

assertThat(devOpsProjectDescriptor).isEmpty();
}

@Test
public void getDevOpsProjectDescriptor_whenDelegates_shouldReturnDelegateResponse() {
Optional<DevOpsProjectDescriptor> devOpsProjectDescriptor = MULTIPLE_DEVOPS_PLATFORMS.getDevOpsProjectDescriptor(Map.of(
"githubUrl", "githubUrl"
));

assertThat(devOpsProjectDescriptor)
.isPresent()
.get().usingRecursiveComparison().isEqualTo(new DevOpsProjectDescriptor(ALM.GITHUB, "githubUrl", "githubRepo"));
}

@Test
public void getValidAlmSettingDto_whenNoDelegates_shouldReturnOptionalEmpty() {
Optional<AlmSettingDto> almSettingDto = NO_DEVOPS_PLATFORMS.getValidAlmSettingDto(dbSession, mock(DevOpsProjectDescriptor.class));

assertThat(almSettingDto).isEmpty();
}

@Test
public void getValidAlmSettingDto_whenDelegates_shouldReturnDelegateResponse() {
Optional<AlmSettingDto> almSettingDto = MULTIPLE_DEVOPS_PLATFORMS.getValidAlmSettingDto(dbSession, new DevOpsProjectDescriptor(ALM.GITHUB, "githubUrl", "githubRepo"));

assertThat(almSettingDto)
.isPresent()
.get()
.usingRecursiveComparison().isEqualTo(new AlmSettingDto().setAlm(ALM.GITHUB));
}

private static DevOpsPlatformService mockGitHubDevOpsPlatformService() {
DevOpsPlatformService mockDevOpsPlatformService = mock();
when(mockDevOpsPlatformService.getDevOpsPlatform()).thenReturn(ALM.GITHUB);
when(mockDevOpsPlatformService.getDevOpsProjectDescriptor(Map.of("githubUrl", "githubUrl")))
.thenReturn(Optional.of(new DevOpsProjectDescriptor(ALM.GITHUB, "githubUrl", "githubRepo")));
when(mockDevOpsPlatformService.getValidAlmSettingDto(any(), any()))
.thenReturn(Optional.of(new AlmSettingDto().setAlm(ALM.GITHUB)));
return mockDevOpsPlatformService;
}

private static DevOpsPlatformService mockAzureDevOpsPlatformService() {
DevOpsPlatformService mockDevOpsPlatformService = mock();
when(mockDevOpsPlatformService.getDevOpsPlatform()).thenReturn(ALM.AZURE_DEVOPS);
when(mockDevOpsPlatformService.getDevOpsProjectDescriptor(Map.of("azureUrl", "azureUrl")))
.thenReturn(Optional.of(new DevOpsProjectDescriptor(ALM.AZURE_DEVOPS, "azureUrl", "azureProject")));
when(mockDevOpsPlatformService.getValidAlmSettingDto(any(), any()))
.thenReturn(Optional.of(new AlmSettingDto().setAlm(ALM.AZURE_DEVOPS)));
return mockDevOpsPlatformService;
}

}

+ 120
- 0
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/GitHubDevOpsPlatformServiceTest.java View File

@@ -0,0 +1,120 @@
/*
* 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.almsettings.ws;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.sonar.alm.client.github.GithubApplicationClient;
import org.sonar.alm.client.github.GithubGlobalSettingsValidator;
import org.sonar.alm.client.github.config.GithubAppConfiguration;
import org.sonar.db.DbSession;
import org.sonar.db.alm.setting.ALM;
import org.sonar.db.alm.setting.AlmSettingDao;
import org.sonar.db.alm.setting.AlmSettingDto;

import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.server.almsettings.ws.GitHubDevOpsPlatformService.DEVOPS_PLATFORM_PROJECT_IDENTIFIER;
import static org.sonar.server.almsettings.ws.GitHubDevOpsPlatformService.DEVOPS_PLATFORM_URL;


@RunWith(MockitoJUnitRunner.class)
public class GitHubDevOpsPlatformServiceTest {

private static final DevOpsProjectDescriptor GITHUB_PROJECT_DESCRIPTOR = new DevOpsProjectDescriptor(ALM.GITHUB, "url", "repo");

@Mock
private DbSession dbSession;
@Mock
private AlmSettingDao almSettingDao;
@Mock
private GithubGlobalSettingsValidator githubGlobalSettingsValidator;
@Mock
private GithubApplicationClient githubApplicationClient;
@InjectMocks
private GitHubDevOpsPlatformService gitHubDevOpsPlatformService;

@Test
public void getDevOpsPlatform_shouldReturnGitHub() {
assertThat(gitHubDevOpsPlatformService.getDevOpsPlatform())
.isEqualTo(ALM.GITHUB);
}

@Test
public void getDevOpsProjectDescriptor_whenNoCharacteristics_shouldReturnEmpty() {
Optional<DevOpsProjectDescriptor> devOpsProjectDescriptor = gitHubDevOpsPlatformService.getDevOpsProjectDescriptor(Map.of());

assertThat(devOpsProjectDescriptor).isEmpty();
}

@Test
public void getDevOpsProjectDescriptor_whenValidCharacteristics_shouldReturn() {
Optional<DevOpsProjectDescriptor> devOpsProjectDescriptor = gitHubDevOpsPlatformService.getDevOpsProjectDescriptor(Map.of(
DEVOPS_PLATFORM_URL, GITHUB_PROJECT_DESCRIPTOR.url(),
DEVOPS_PLATFORM_PROJECT_IDENTIFIER, GITHUB_PROJECT_DESCRIPTOR.projectIdentifier()
));

assertThat(devOpsProjectDescriptor)
.isPresent()
.get().usingRecursiveComparison().isEqualTo(GITHUB_PROJECT_DESCRIPTOR);
}

@Test
public void getValidAlmSettingDto_whenNoAlmSetting_shouldReturnEmpty() {
when(almSettingDao.selectByAlm(dbSession, ALM.GITHUB)).thenReturn(emptyList());

Optional<AlmSettingDto> almSettingDto = gitHubDevOpsPlatformService.getValidAlmSettingDto(dbSession, GITHUB_PROJECT_DESCRIPTOR);

assertThat(almSettingDto).isEmpty();
}

@Test
public void getValidAlmSettingDto_whenMultipleAlmSetting_shouldReturnTheRightOne() {
AlmSettingDto mockGitHubAlmSettingDtoNoAccess = mockGitHubAlmSettingDto(false);
AlmSettingDto mockGitHubAlmSettingDtoAccess = mockGitHubAlmSettingDto(true);
when(almSettingDao.selectByAlm(dbSession, ALM.GITHUB)).thenReturn(List.of(mockGitHubAlmSettingDtoNoAccess, mockGitHubAlmSettingDtoAccess));

Optional<AlmSettingDto> almSettingDto = gitHubDevOpsPlatformService.getValidAlmSettingDto(dbSession, GITHUB_PROJECT_DESCRIPTOR);

assertThat(almSettingDto)
.isPresent()
.get().isEqualTo(mockGitHubAlmSettingDtoAccess);
}

private AlmSettingDto mockGitHubAlmSettingDto(boolean repoAccess) {
AlmSettingDto mockAlmSettingDto = mock();
when(mockAlmSettingDto.getUrl()).thenReturn(GITHUB_PROJECT_DESCRIPTOR.url());
GithubAppConfiguration mockGithubAppConfiguration = mock(GithubAppConfiguration.class);
when(githubGlobalSettingsValidator.validate(mockAlmSettingDto)).thenReturn(mockGithubAppConfiguration);
when(githubApplicationClient.getInstallationId(eq(mockGithubAppConfiguration), any())).thenReturn(repoAccess ? Optional.of(1L) : Optional.empty());
return mockAlmSettingDto;
}

}

+ 4
- 0
server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java View File

@@ -62,6 +62,8 @@ import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
import org.sonar.server.almintegration.ws.github.GithubProvisioningWs;
import org.sonar.server.almsettings.MultipleAlmFeature;
import org.sonar.server.almsettings.ws.AlmSettingsWsModule;
import org.sonar.server.almsettings.ws.DelegatingDevOpsPlatformService;
import org.sonar.server.almsettings.ws.GitHubDevOpsPlatformService;
import org.sonar.server.authentication.AuthenticationModule;
import org.sonar.server.authentication.DefaultAdminCredentialsVerifierImpl;
import org.sonar.server.authentication.DefaultAdminCredentialsVerifierNotificationHandler;
@@ -307,6 +309,7 @@ public class PlatformLevel4 extends PlatformLevel {
DefaultBranchNameResolver.class,
DefaultDocumentationLinkGenerator.class,
DelegatingManagedServices.class,
DelegatingDevOpsPlatformService.class,

// batch
new BatchWsModule(),
@@ -548,6 +551,7 @@ public class PlatformLevel4 extends PlatformLevel {
GithubApplicationHttpClientImpl.class,
GithubProvisioningConfigValidator.class,
GithubProvisioningWs.class,
GitHubDevOpsPlatformService.class,
BitbucketCloudRestClientConfiguration.class,
BitbucketServerRestClient.class,
GitlabHttpClient.class,

Loading…
Cancel
Save