diff options
Diffstat (limited to 'server')
1031 files changed, 7439 insertions, 25987 deletions
diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubPermissionConverter.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubPermissionConverter.java index 0d8a63a0d18..5e1084a95ec 100644 --- a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubPermissionConverter.java +++ b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubPermissionConverter.java @@ -24,15 +24,16 @@ import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.auth.github.GsonRepositoryPermissions; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.provisioning.DevOpsPermissionsMappingDto; import static java.util.function.Function.identity; import static java.util.stream.Collectors.toMap; -import static org.sonar.server.permission.PermissionServiceImpl.ALL_PROJECT_PERMISSIONS; public class GithubPermissionConverter { private static final Logger LOG = LoggerFactory.getLogger(GithubPermissionConverter.class); @@ -63,12 +64,12 @@ public class GithubPermissionConverter { new GsonRepositoryPermissions(true, true, true, true, true), ADMIN_GITHUB_ROLE ); - public Map<String, Boolean> toSonarqubeRolesToHasPermissions(Set<String> sonarqubeRoles) { - return ALL_PROJECT_PERMISSIONS.stream() + public Map<ProjectPermission, Boolean> toSonarqubeRolesToHasPermissions(Set<ProjectPermission> sonarqubeRoles) { + return Stream.of(ProjectPermission.values()) .collect(toMap(identity(), sonarqubeRoles::contains)); } - public Set<String> toSonarqubeRolesWithFallbackOnRepositoryPermissions(Set<DevOpsPermissionsMappingDto> allPermissionsMappings, + public Set<ProjectPermission> toSonarqubeRolesWithFallbackOnRepositoryPermissions(Set<DevOpsPermissionsMappingDto> allPermissionsMappings, String githubRoleOrPermission, GsonRepositoryPermissions repositoryPermissions) { String roleName = toRoleName(githubRoleOrPermission); return toSonarqubeRoles(allPermissionsMappings, roleName, repositoryPermissions); @@ -78,19 +79,19 @@ public class GithubPermissionConverter { return GITHUB_GROUP_PERMISSION_TO_ROLE_NAME.getOrDefault(permission, permission); } - public Set<String> toSonarqubeRolesForDefaultRepositoryPermission(Set<DevOpsPermissionsMappingDto> allPermissionsMappings, String roleName) { + public Set<ProjectPermission> toSonarqubeRolesForDefaultRepositoryPermission(Set<DevOpsPermissionsMappingDto> allPermissionsMappings, String roleName) { return toSonarqubeRoles(allPermissionsMappings, roleName, null); } - private static Set<String> toSonarqubeRoles(Set<DevOpsPermissionsMappingDto> allPermissionsMappings, String githubRoleName, + private static Set<ProjectPermission> toSonarqubeRoles(Set<DevOpsPermissionsMappingDto> allPermissionsMappings, String githubRoleName, @Nullable GsonRepositoryPermissions repositoryPermissions) { Map<String, List<DevOpsPermissionsMappingDto>> permissionMappings = allPermissionsMappings.stream() .collect(Collectors.groupingBy(DevOpsPermissionsMappingDto::role)); - Set<String> sonarqubePermissions = Optional.ofNullable(permissionMappings.get(githubRoleName)) + Set<ProjectPermission> sonarqubePermissions = Optional.ofNullable(permissionMappings.get(githubRoleName)) .orElse(GithubPermissionConverter.computeBaseRoleAndGetSqPermissions(permissionMappings, repositoryPermissions)) .stream() - .map(DevOpsPermissionsMappingDto::sonarqubePermission) + .map(DevOpsPermissionsMappingDto::projectPermission) .collect(Collectors.toSet()); if (sonarqubePermissions.isEmpty()) { diff --git a/server/sonar-alm-client/src/test/java/org/sonar/alm/client/github/GithubPermissionConverterTest.java b/server/sonar-alm-client/src/test/java/org/sonar/alm/client/github/GithubPermissionConverterTest.java index 2a236b312cf..8b93d90668c 100644 --- a/server/sonar-alm-client/src/test/java/org/sonar/alm/client/github/GithubPermissionConverterTest.java +++ b/server/sonar-alm-client/src/test/java/org/sonar/alm/client/github/GithubPermissionConverterTest.java @@ -26,6 +26,7 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Suite; import org.sonar.auth.github.GsonRepositoryPermissions; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.provisioning.DevOpsPermissionsMappingDto; import static org.assertj.core.api.Assertions.assertThat; @@ -38,11 +39,11 @@ import static org.assertj.core.api.Assertions.assertThat; public class GithubPermissionConverterTest { private static final Set<DevOpsPermissionsMappingDto> ALL_PERMISSIONS_MAPPING_FROM_DB = Set.of( - new DevOpsPermissionsMappingDto("uuid1", "github", "read", "roleRead"), - new DevOpsPermissionsMappingDto("uuid2", "github", "triage", "roleTriage"), - new DevOpsPermissionsMappingDto("uuid3", "github", "write", "roleWrite"), - new DevOpsPermissionsMappingDto("uuid4", "github", "maintain", "roleMaintain"), - new DevOpsPermissionsMappingDto("uuid5", "github", "admin", "roleAdmin") + new DevOpsPermissionsMappingDto("uuid1", "github", "read", ProjectPermission.CODEVIEWER), + new DevOpsPermissionsMappingDto("uuid2", "github", "triage", ProjectPermission.SECURITYHOTSPOT_ADMIN), + new DevOpsPermissionsMappingDto("uuid3", "github", "write", ProjectPermission.ISSUE_ADMIN), + new DevOpsPermissionsMappingDto("uuid4", "github", "maintain", ProjectPermission.SCAN), + new DevOpsPermissionsMappingDto("uuid5", "github", "admin", ProjectPermission.ADMIN) ) ; private static final GsonRepositoryPermissions NO_PERMS = new GsonRepositoryPermissions(false, false, false, false, false); @@ -63,19 +64,19 @@ public class GithubPermissionConverterTest { public static Iterable<Object[]> testData() { return Arrays.asList(new Object[][] { {"none", NO_PERMS, Set.of()}, - {"read", NO_PERMS, Set.of("roleRead")}, - {"read", READ_PERMS, Set.of("roleRead")}, - {"pull", NO_PERMS, Set.of("roleRead")}, - {"triage", NO_PERMS, Set.of("roleTriage")}, - {"write", NO_PERMS, Set.of("roleWrite")}, - {"push", NO_PERMS, Set.of("roleWrite")}, - {"maintain", NO_PERMS, Set.of("roleMaintain")}, - {"admin", NO_PERMS, Set.of("roleAdmin")}, - {"custom_role_extending_read", READ_PERMS, Set.of("roleRead")}, - {"custom_role_extending_triage", TRIAGE_PERMS, Set.of("roleTriage")}, - {"custom_role_extending_write", WRITE_PERMS, Set.of("roleWrite")}, - {"custom_role_extending_maintain", MAINTAIN_PERMS, Set.of("roleMaintain")}, - {"custom_role_extending_admin", ADMIN_PERMS, Set.of("roleAdmin")}, + {"read", NO_PERMS, Set.of(ProjectPermission.CODEVIEWER)}, + {"read", READ_PERMS, Set.of(ProjectPermission.CODEVIEWER)}, + {"pull", NO_PERMS, Set.of(ProjectPermission.CODEVIEWER)}, + {"triage", NO_PERMS, Set.of(ProjectPermission.SECURITYHOTSPOT_ADMIN)}, + {"write", NO_PERMS, Set.of(ProjectPermission.ISSUE_ADMIN)}, + {"push", NO_PERMS, Set.of(ProjectPermission.ISSUE_ADMIN)}, + {"maintain", NO_PERMS, Set.of(ProjectPermission.SCAN)}, + {"admin", NO_PERMS, Set.of(ProjectPermission.ADMIN)}, + {"custom_role_extending_read", READ_PERMS, Set.of(ProjectPermission.CODEVIEWER)}, + {"custom_role_extending_triage", TRIAGE_PERMS, Set.of(ProjectPermission.SECURITYHOTSPOT_ADMIN)}, + {"custom_role_extending_write", WRITE_PERMS, Set.of(ProjectPermission.ISSUE_ADMIN)}, + {"custom_role_extending_maintain", MAINTAIN_PERMS, Set.of(ProjectPermission.SCAN)}, + {"custom_role_extending_admin", ADMIN_PERMS, Set.of(ProjectPermission.ADMIN)}, }); } @@ -87,7 +88,7 @@ public class GithubPermissionConverterTest { @Test public void toGithubRepositoryPermissions_convertsCorrectly() { - Set<String> actualPermissions = githubPermissionConverter.toSonarqubeRolesWithFallbackOnRepositoryPermissions(ALL_PERMISSIONS_MAPPING_FROM_DB, role, repositoryPermissions); + Set<ProjectPermission> actualPermissions = githubPermissionConverter.toSonarqubeRolesWithFallbackOnRepositoryPermissions(ALL_PERMISSIONS_MAPPING_FROM_DB, role, repositoryPermissions); assertThat(actualPermissions).isEqualTo(expectedSqPermissions); } } @@ -102,11 +103,11 @@ public class GithubPermissionConverterTest { public static Iterable<Object[]> testData() { return Arrays.asList(new Object[][] { {"none", Set.of()}, - {"read", Set.of("roleRead")}, - {"triage", Set.of("roleTriage")}, - {"write", Set.of("roleWrite")}, - {"maintain", Set.of("roleMaintain")}, - {"admin", Set.of("roleAdmin")} + {"read", Set.of(ProjectPermission.CODEVIEWER)}, + {"triage", Set.of(ProjectPermission.SECURITYHOTSPOT_ADMIN)}, + {"write", Set.of(ProjectPermission.ISSUE_ADMIN)}, + {"maintain", Set.of(ProjectPermission.SCAN)}, + {"admin", Set.of(ProjectPermission.ADMIN)} }); } @@ -117,7 +118,7 @@ public class GithubPermissionConverterTest { @Test public void toGithubRepositoryPermissions_convertsCorrectly() { - Set<String> actualPermissions = githubPermissionConverter.toSonarqubeRolesForDefaultRepositoryPermission(ALL_PERMISSIONS_MAPPING_FROM_DB, role); + Set<ProjectPermission> actualPermissions = githubPermissionConverter.toSonarqubeRolesForDefaultRepositoryPermission(ALL_PERMISSIONS_MAPPING_FROM_DB, role); assertThat(actualPermissions).isEqualTo(expectedSqPermissions); } } diff --git a/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubIdentityProvider.java b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubIdentityProvider.java index 699b525efa6..ba5e62567ad 100644 --- a/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubIdentityProvider.java +++ b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubIdentityProvider.java @@ -25,7 +25,10 @@ import com.github.scribejava.core.oauth.OAuth20Service; import java.io.IOException; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; +import org.jetbrains.annotations.NotNull; import org.sonar.api.server.authentication.Display; import org.sonar.api.server.authentication.OAuth2IdentityProvider; import org.sonar.api.server.authentication.UnauthorizedException; @@ -139,8 +142,8 @@ public class GitHubIdentityProvider implements OAuth2IdentityProvider { context.redirectToRequestedPage(); } - private void check(OAuth20Service scribe, OAuth2AccessToken accessToken, GsonUser user) throws InterruptedException, ExecutionException, IOException { - if (!isUserAuthorized(scribe, accessToken, user.getLogin())) { + private void check(OAuth20Service scribe, OAuth2AccessToken accessToken, GsonUser user) { + if (!isUserAuthorized(scribe, accessToken)) { String message = settings.getOrganizations().isEmpty() ? format("'%s' must be a member of at least one organization which has installed the SonarQube GitHub app", user.getLogin()) : format("'%s' must be a member of at least one organization: '%s'", user.getLogin(), String.join("', '", settings.getOrganizations().stream().sorted().toList())); @@ -148,37 +151,36 @@ public class GitHubIdentityProvider implements OAuth2IdentityProvider { } } - private boolean isUserAuthorized(OAuth20Service scribe, OAuth2AccessToken accessToken, String login) throws IOException, ExecutionException, InterruptedException { + private boolean isUserAuthorized(OAuth20Service scribe, OAuth2AccessToken accessToken) { + Set<String> userOrganizationNames = getUserOrganizationNames(scribe, accessToken); if (isOrganizationMembershipRequired()) { - return isOrganizationsMember(scribe, accessToken, login); + return isOrganizationsMember(settings.getOrganizations(), userOrganizationNames); } else { - return isMemberOfInstallationOrganization(scribe, accessToken, login); + return isMemberOfInstallationOrganization(userOrganizationNames); } } - private boolean isOrganizationMembershipRequired() { - return !settings.getOrganizations().isEmpty(); + private static boolean isOrganizationsMember(Set<String> organizations, Set<String> userOrganizationNames) { + return organizations.stream().anyMatch(userOrganizationNames::contains); } - private boolean isOrganizationsMember(OAuth20Service scribe, OAuth2AccessToken accessToken, String login) throws IOException, ExecutionException, InterruptedException { - for (String organization : settings.getOrganizations()) { - if (gitHubRestClient.isOrganizationMember(scribe, accessToken, organization, login)) { - return true; - } - } - return false; + @NotNull + private Set<String> getUserOrganizationNames(OAuth20Service scribe, OAuth2AccessToken accessToken) { + return gitHubRestClient.getUserOrganizations(scribe, accessToken).stream() + .map(GsonOrganization::organization) + .collect(Collectors.toSet()); + } + + private boolean isOrganizationMembershipRequired() { + return !settings.getOrganizations().isEmpty(); } - private boolean isMemberOfInstallationOrganization(OAuth20Service scribe, OAuth2AccessToken accessToken, String login) - throws IOException, ExecutionException, InterruptedException { + private boolean isMemberOfInstallationOrganization(Set<String> userOrganizationNames) { GithubAppConfiguration githubAppConfiguration = githubAppConfiguration(); List<GithubAppInstallation> githubAppInstallations = githubAppClient.getWhitelistedGithubAppInstallations(githubAppConfiguration); - for (GithubAppInstallation installation : githubAppInstallations) { - if (gitHubRestClient.isOrganizationMember(scribe, accessToken, installation.organizationName(), login)) { - return true; - } - } - return false; + return githubAppInstallations.stream() + .map(GithubAppInstallation::organizationName) + .anyMatch(userOrganizationNames::contains); } private GithubAppConfiguration githubAppConfiguration() { diff --git a/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubRestClient.java b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubRestClient.java index 3dfda2f973a..1642ca65097 100644 --- a/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubRestClient.java +++ b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubRestClient.java @@ -62,36 +62,13 @@ public class GitHubRestClient { .orElse(null); } - public List<GsonTeam> getTeams(OAuth20Service scribe, OAuth2AccessToken accessToken) { - return executePaginatedRequest(settings.apiURL() + "user/teams", scribe, accessToken, GsonTeam::parse); + public List<GsonOrganization> getUserOrganizations(OAuth20Service scribe, OAuth2AccessToken accessToken) { + List<GsonOrganization> gsonOrganizations = executePaginatedRequest(settings.apiURL() + "user/orgs", scribe, accessToken, GsonOrganization::parse); + LOGGER.trace("Organizations response received : {}", gsonOrganizations); + return gsonOrganizations; } - /** - * Check to see that login is a member of organization. - * - * A 204 response code indicates organization membership. 302 and 404 codes are not treated as exceptional, - * they indicate various ways in which a login is not a member of the organization. - * - * @see <a href="https://developer.github.com/v3/orgs/members/#response-if-requester-is-an-organization-member-and-user-is-a-member">GitHub members API</a> - */ - public boolean isOrganizationMember(OAuth20Service scribe, OAuth2AccessToken accessToken, String organization, String login) - throws IOException, ExecutionException, InterruptedException { - String requestUrl = settings.apiURL() + format("orgs/%s/members/%s", organization, login); - OAuthRequest request = new OAuthRequest(Verb.GET, requestUrl); - scribe.signRequest(accessToken, request); - - Response response = scribe.execute(request); - int code = response.getCode(); - switch (code) { - case HttpURLConnection.HTTP_MOVED_TEMP, HttpURLConnection.HTTP_NOT_FOUND, HttpURLConnection.HTTP_NO_CONTENT: - LOGGER.trace("Orgs response received : {}", code); - return code == HttpURLConnection.HTTP_NO_CONTENT; - default: - throw unexpectedResponseCode(requestUrl, response); - } - } - - private static IllegalStateException unexpectedResponseCode(String requestUrl, Response response) throws IOException { - return new IllegalStateException(format("Fail to execute request '%s'. HTTP code: %s, response: %s", requestUrl, response.getCode(), response.getBody())); + public List<GsonTeam> getTeams(OAuth20Service scribe, OAuth2AccessToken accessToken) { + return executePaginatedRequest(settings.apiURL() + "user/teams", scribe, accessToken, GsonTeam::parse); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexTaskUuidInWebhookDeliveries.java b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GsonOrganization.java index e547e7ebc60..5e9bc8fb44c 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexTaskUuidInWebhookDeliveries.java +++ b/server/sonar-auth-github/src/main/java/org/sonar/auth/github/GsonOrganization.java @@ -17,13 +17,17 @@ * 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.platform.db.migration.version.v102; +package org.sonar.auth.github; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import java.util.List; -public class DropIndexTaskUuidInWebhookDeliveries extends DropIndexChange { - public DropIndexTaskUuidInWebhookDeliveries(Database db) { - super(db, "ce_task_uuid", "webhook_deliveries"); +public record GsonOrganization (@SerializedName("login") String organization) { + public static List<GsonOrganization> parse(String json) { + Gson gson = new Gson(); + return gson.fromJson(json, new TypeToken<>() { + }); } } diff --git a/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubIdentityProviderTest.java b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubIdentityProviderTest.java index bb1dbb799d0..bd8dee965c5 100644 --- a/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubIdentityProviderTest.java +++ b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubIdentityProviderTest.java @@ -233,8 +233,7 @@ public class GitHubIdentityProviderTest { OAuth2AccessToken accessToken = mockAccessToken(scribeService, context, httpRequest, user); - when(gitHubRestClient.isOrganizationMember(scribeService, accessToken, "organization1", "login")).thenReturn(false); - when(gitHubRestClient.isOrganizationMember(scribeService, accessToken, "organization2", "login")).thenReturn(true); + when(gitHubRestClient.getUserOrganizations(scribeService, accessToken)).thenReturn(List.of(new GsonOrganization("organization2"))); when(userIdentityFactory.create(user, "email", null)).thenReturn(userIdentity); return context; @@ -249,8 +248,7 @@ public class GitHubIdentityProviderTest { OAuth2AccessToken accessToken = mockAccessToken(scribeService, context, httpRequest, user); - when(gitHubRestClient.isOrganizationMember(scribeService, accessToken, "organization1", "login")).thenReturn(false); - when(gitHubRestClient.isOrganizationMember(scribeService, accessToken, "organization2", "login")).thenReturn(false); + when(gitHubRestClient.getUserOrganizations(scribeService, accessToken)).thenReturn(List.of(new GsonOrganization("organization3"))); when(userIdentityFactory.create(user, "email", null)).thenReturn(userIdentity); return context; diff --git a/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GsonOrganizationTest.java b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GsonOrganizationTest.java new file mode 100644 index 00000000000..cd1f42f1372 --- /dev/null +++ b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/GsonOrganizationTest.java @@ -0,0 +1,66 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.auth.github; + +import java.util.List; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class GsonOrganizationTest { + + @Test + public void parse() { + List<GsonOrganization> underTest = GsonOrganization.parse(""" + [ + { + "login": "github", + "id": 1, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE=", + "url": "https://api.github.com/orgs/github", + "repos_url": "https://api.github.com/orgs/github/repos", + "events_url": "https://api.github.com/orgs/github/events", + "hooks_url": "https://api.github.com/orgs/github/hooks", + "issues_url": "https://api.github.com/orgs/github/issues", + "members_url": "https://api.github.com/orgs/github/members{/member}", + "public_members_url": "https://api.github.com/orgs/github/public_members{/member}", + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "description": "A great organization" + }, + { + "login": "github-org2", + "id": 1, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE=", + "url": "https://api.github.com/orgs/github", + "repos_url": "https://api.github.com/orgs/github/repos", + "events_url": "https://api.github.com/orgs/github/events", + "hooks_url": "https://api.github.com/orgs/github/hooks", + "issues_url": "https://api.github.com/orgs/github/issues", + "members_url": "https://api.github.com/orgs/github/members{/member}", + "public_members_url": "https://api.github.com/orgs/github/public_members{/member}", + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "description": "An even greater organization" + } + ]"""); + assertThat(underTest).hasSize(2); + assertThat(underTest).extracting(GsonOrganization::organization).containsExactly("github", "github-org2"); + } + +} diff --git a/server/sonar-auth-github/src/test/java/org/sonar/auth/github/IntegrationTest.java b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/IntegrationTest.java index ada79e3b0dc..83355eeb746 100644 --- a/server/sonar-auth-github/src/test/java/org/sonar/auth/github/IntegrationTest.java +++ b/server/sonar-auth-github/src/test/java/org/sonar/auth/github/IntegrationTest.java @@ -124,10 +124,13 @@ public class IntegrationTest { github.enqueue(newSuccessfulAccessTokenResponse()); // response of api.github.com/user github.enqueue(new MockResponse().setBody("{\"id\":\"ABCD\", \"login\":\"octocat\", \"name\":\"monalisa octocat\",\"email\":\"octocat@github.com\"}")); - // response of api.github.com/orgs/first_org/members/user - github.enqueue(new MockResponse().setResponseCode(404)); - // response of api.github.com/orgs/second_org/members/user - github.enqueue(new MockResponse().setResponseCode(204)); + // response of api.github.com/user/orgs + github.enqueue(new MockResponse().setBody(""" + [ + { + "login": "second_org" + } + ]""")); HttpServletRequest request = newRequest("the-verifier-code"); DumbCallbackContext callbackContext = new DumbCallbackContext(request); @@ -161,8 +164,13 @@ public class IntegrationTest { github.enqueue(newSuccessfulAccessTokenResponse()); // response of api.github.com/user github.enqueue(new MockResponse().setBody("{\"id\":\"ABCD\", \"login\":\"octocat\", \"name\":\"monalisa octocat\",\"email\":null}")); - // response of api.github.com/orgs/first_org/members/user - github.enqueue(new MockResponse().setResponseCode(204)); + // response of api.github.com/user/orgs + github.enqueue(new MockResponse().setBody(""" + [ + { + "login": "second_org" + } + ]""")); // response of api.github.com/user/emails github.enqueue(new MockResponse().setBody(""" [ @@ -198,7 +206,12 @@ public class IntegrationTest { // response of api.github.com/user github.enqueue(new MockResponse().setBody("{\"id\":\"ABCD\", \"login\":\"octocat\", \"name\":\"monalisa octocat\",\"email\":null}")); // response of api.github.com/orgs/first_org/members/user - github.enqueue(new MockResponse().setResponseCode(204)); + github.enqueue(new MockResponse().setBody(""" + [ + { + "login": "second_org" + } + ]""")); // response of api.github.com/user/emails github.enqueue(new MockResponse().setBody("[]")); @@ -238,8 +251,13 @@ public class IntegrationTest { github.enqueue(newSuccessfulAccessTokenResponse()); // response of api.github.com/user github.enqueue(new MockResponse().setBody("{\"id\":\"ABCD\", \"login\":\"octocat\", \"name\":\"monalisa octocat\",\"email\":\"octocat@github.com\"}")); - // response of api.github.com/orgs/first_org/members/user - github.enqueue(new MockResponse().setResponseCode(204)); + // response of api.github.com/user/orgs + github.enqueue(new MockResponse().setBody(""" + [ + { + "login": "second_org" + } + ]""")); // response of api.github.com/user/teams github.enqueue(new MockResponse().setBody(""" [ @@ -267,8 +285,13 @@ public class IntegrationTest { github.enqueue(newSuccessfulAccessTokenResponse()); // response of api.github.com/user github.enqueue(new MockResponse().setBody("{\"id\":\"ABCD\", \"login\":\"octocat\", \"name\":\"monalisa octocat\",\"email\":\"octocat@github.com\"}")); - // response of api.github.com/orgs/first_org/members/user - github.enqueue(new MockResponse().setResponseCode(204)); + // response of api.github.com/user/orgs + github.enqueue(new MockResponse().setBody(""" + [ + { + "login": "second_org" + } + ]""")); // responses of api.github.com/user/teams github.enqueue(new MockResponse() .setHeader("Link", "<" + gitHubUrl + "/user/teams?per_page=100&page=2>; rel=\"next\", <" + gitHubUrl + "/user/teams?per_page=100&page=2>; rel=\"last\"") @@ -324,8 +347,13 @@ public class IntegrationTest { github.enqueue(newSuccessfulAccessTokenResponse()); // response of api.github.com/user github.enqueue(new MockResponse().setBody("{\"id\":\"ABCD\", \"login\":\"octocat\", \"name\":\"monalisa octocat\",\"email\":\"octocat@github.com\"}")); - // response of api.github.com/orgs/example0/members/user - github.enqueue(new MockResponse().setResponseCode(204)); + // response of api.github.com/user/orgs + github.enqueue(new MockResponse().setBody(""" + [ + { + "login": "example1" + } + ]""")); HttpServletRequest request = newRequest("the-verifier-code"); DumbCallbackContext callbackContext = new DumbCallbackContext(request); @@ -343,10 +371,8 @@ public class IntegrationTest { github.enqueue(newSuccessfulAccessTokenResponse()); // response of api.github.com/user github.enqueue(new MockResponse().setBody("{\"id\":\"ABCD\", \"login\":\"octocat\", \"name\":\"monalisa octocat\",\"email\":\"octocat@github.com\"}")); - // response of api.github.com/orgs/first_org/members/user - github.enqueue(new MockResponse().setResponseCode(404).setBody("{}")); - // response of api.github.com/orgs/second_org/members/user - github.enqueue(new MockResponse().setResponseCode(404).setBody("{}")); + // response of api.github.com/user/orgs + github.enqueue(new MockResponse().setBody("[]")); HttpServletRequest request = newRequest("the-verifier-code"); DumbCallbackContext callbackContext = new DumbCallbackContext(request); @@ -381,7 +407,7 @@ public class IntegrationTest { github.enqueue(newSuccessfulAccessTokenResponse()); // response of api.github.com/user github.enqueue(new MockResponse().setBody("{\"id\":\"ABCD\", \"login\":\"octocat\", \"name\":\"monalisa octocat\",\"email\":\"octocat@github.com\"}")); - // crash of api.github.com/orgs/example/members/user + // crash of api.github.com/user/orgs github.enqueue(new MockResponse().setResponseCode(500).setBody("{error}")); HttpServletRequest request = newRequest("the-verifier-code"); @@ -390,7 +416,7 @@ public class IntegrationTest { underTest.callback(callbackContext); fail("exception expected"); } catch (IllegalStateException e) { - assertThat(e.getMessage()).isEqualTo("Fail to execute request '" + gitHubSettings.apiURL() + "orgs/example/members/octocat'. HTTP code: 500, response: {error}"); + assertThat(e.getMessage()).isEqualTo("Fail to execute request '" + gitHubSettings.apiURL() + "user/orgs?per_page=100'. HTTP code: 500, response: {error}"); } } diff --git a/server/sonar-ce-common/src/main/java/org/sonar/ce/common/scanner/ScannerReportReader.java b/server/sonar-ce-common/src/main/java/org/sonar/ce/common/scanner/ScannerReportReader.java index 9e6b660b5d0..459ba57009a 100644 --- a/server/sonar-ce-common/src/main/java/org/sonar/ce/common/scanner/ScannerReportReader.java +++ b/server/sonar-ce-common/src/main/java/org/sonar/ce/common/scanner/ScannerReportReader.java @@ -19,6 +19,7 @@ */ package org.sonar.ce.common.scanner; +import java.io.File; import java.io.InputStream; import java.util.Optional; import javax.annotation.CheckForNull; @@ -72,4 +73,8 @@ public interface ScannerReportReader { CloseableIterator<ScannerReport.AnalysisWarning> readAnalysisWarnings(); CloseableIterator<ScannerReport.TelemetryEntry> readTelemetryEntries(); + + File readDependencyFilesZip(); + + CloseableIterator<ScannerReport.AnalysisData> readAnalysisData(); } diff --git a/server/sonar-ce-common/src/testFixtures/java/org/sonar/ce/common/scanner/ScannerReportReaderRule.java b/server/sonar-ce-common/src/testFixtures/java/org/sonar/ce/common/scanner/ScannerReportReaderRule.java index 7eecf3c5803..29e718bfe96 100644 --- a/server/sonar-ce-common/src/testFixtures/java/org/sonar/ce/common/scanner/ScannerReportReaderRule.java +++ b/server/sonar-ce-common/src/testFixtures/java/org/sonar/ce/common/scanner/ScannerReportReaderRule.java @@ -21,6 +21,7 @@ package org.sonar.ce.common.scanner; import com.google.common.base.Preconditions; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; @@ -63,6 +64,8 @@ public class ScannerReportReaderRule implements TestRule, ScannerReportReader, A private List<ScannerReport.AnalysisWarning> analysisWarnings = Collections.emptyList(); private byte[] analysisCache; private List<ScannerReport.TelemetryEntry> telemetryEntries = new ArrayList<>(); + private File dependencyFilesZip; + private List<ScannerReport.AnalysisData> analysisData = new ArrayList<>(); @Override public Statement apply(final Statement statement, Description description) { @@ -337,4 +340,22 @@ public class ScannerReportReaderRule implements TestRule, ScannerReportReader, A this.telemetryEntries = telemetryEntries; return this; } + + @Override + public CloseableIterator<ScannerReport.AnalysisData> readAnalysisData() { + return CloseableIterator.from(analysisData.iterator()); + } + + @Override + public File readDependencyFilesZip() { + if (dependencyFilesZip == null) { + return null; + } + return this.dependencyFilesZip; + } + + public ScannerReportReaderRule putDependencyFilesZip(File dependencyFilesZip) { + this.dependencyFilesZip = dependencyFilesZip; + return this; + } } diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreatorIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreatorIT.java index c36e72cebfc..78ccfbf78c9 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreatorIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreatorIT.java @@ -25,7 +25,7 @@ import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.db.DbSession; diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/issue/ComponentIssuesLoaderIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/issue/ComponentIssuesLoaderIT.java index cf864d6b323..936edf1c2b6 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/issue/ComponentIssuesLoaderIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/issue/ComponentIssuesLoaderIT.java @@ -58,7 +58,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import static org.sonar.api.issue.Issue.STATUS_CLOSED; -import static org.sonar.api.rules.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.CODE_SMELL; import static org.sonar.api.utils.DateUtils.addDays; import static org.sonar.api.utils.DateUtils.parseDateTime; import static org.sonar.ce.task.projectanalysis.issue.ComponentIssuesLoader.NUMBER_STATUS_AND_BRANCH_CHANGES_TO_KEEP; diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStepIT.java index 9a30c9b4a14..33a0e39aa2a 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStepIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistIssuesStepIT.java @@ -33,7 +33,7 @@ import org.mockito.ArgumentCaptor; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.ce.common.scanner.ScannerReportReaderRule; import org.sonar.ce.task.projectanalysis.issue.AdHocRuleCreator; diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStepIT.java index 80d508db1ff..44315b90855 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStepIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStepIT.java @@ -21,12 +21,17 @@ package org.sonar.ce.task.projectanalysis.step; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Optional; +import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.mockito.ArgumentCaptor; import org.sonar.api.measures.Metric; import org.sonar.api.utils.System2; +import org.sonar.ce.task.log.CeTaskMessages; +import org.sonar.ce.task.log.CeTaskMessages.Message; import org.sonar.ce.task.projectanalysis.analysis.Analysis; import org.sonar.ce.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule; import org.sonar.ce.task.projectanalysis.component.Component; @@ -53,10 +58,14 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.sonar.api.measures.CoreMetrics.DUPLICATIONS_DATA; +import static org.sonar.api.measures.CoreMetrics.DUPLICATIONS_DATA_KEY; import static org.sonar.api.measures.CoreMetrics.EXECUTABLE_LINES_DATA; import static org.sonar.api.measures.CoreMetrics.EXECUTABLE_LINES_DATA_KEY; import static org.sonar.api.measures.CoreMetrics.NCLOC_DATA; import static org.sonar.api.measures.CoreMetrics.NCLOC_DATA_KEY; +import static org.sonar.api.measures.CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION; +import static org.sonar.api.measures.CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION_KEY; import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY; import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE; import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT; @@ -90,6 +99,7 @@ class PersistMeasuresStepIT { @RegisterExtension public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule(); private final ComputeDuplicationDataMeasure computeDuplicationDataMeasure = mock(ComputeDuplicationDataMeasure.class); + private final CeTaskMessages ceTaskMessages = mock(CeTaskMessages.class); private final TestComputationStepContext context = new TestComputationStepContext(); private final DbClient dbClient = db.getDbClient(); @@ -176,7 +186,7 @@ class PersistMeasuresStepIT { db.getSession().commit(); PersistMeasuresStep step = new PersistMeasuresStep(dbClient, metricRepository, treeRootHolder, measureRepository, - computeDuplicationDataMeasure, 100); + computeDuplicationDataMeasure, 100, ceTaskMessages); step.execute(context); // all measures are persisted, for project and all files @@ -281,6 +291,38 @@ class PersistMeasuresStepIT { verifyInsertsOrUpdates(0); } + @Test + void add_warning_when_persisting_large_measures() { + prepareProject(); + metricRepository.add(NCLOC_LANGUAGE_DISTRIBUTION); + metricRepository.add(DUPLICATIONS_DATA); + + measureRepository.addRawMeasure(REF_1, STRING_METRIC.getKey(), newMeasureBuilder().create("project-value")); + String largeValue = StringUtils.repeat("a", 100_001); + measureRepository.addRawMeasure(REF_1, NCLOC_LANGUAGE_DISTRIBUTION_KEY, newMeasureBuilder().create(largeValue)); + measureRepository.addRawMeasure(REF_1, DUPLICATIONS_DATA_KEY, newMeasureBuilder().create(largeValue)); + measureRepository.addRawMeasure(REF_4, STRING_METRIC.getKey(), newMeasureBuilder().create(largeValue)); + + step().execute(context); + + assertThat(db.countRowsOfTable("measures")).isEqualTo(3); + assertThat(selectMeasure("project-uuid")) + .hasValueSatisfying(measure -> assertThat(measure.getMetricValues()).containsExactlyInAnyOrderEntriesOf(Map.of( + STRING_METRIC.getKey(), "project-value", + NCLOC_LANGUAGE_DISTRIBUTION_KEY, largeValue, + DUPLICATIONS_DATA_KEY, largeValue))); + assertThat(selectMeasure("file-uuid")) + .hasValueSatisfying(measure -> assertThat(measure.getMetricValues()).containsEntry(STRING_METRIC.getKey(), largeValue)); + verifyInsertsOrUpdates(4); + + ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(ceTaskMessages).add(messageCaptor.capture()); + assertThat(messageCaptor.getValue().getText()).isEqualTo("A plugin is storing excessively large data in the following measure(s): " + + "'ncloc_language_distribution', 'string-metric'. This is likely to cause significant SonarQube performance degradation and UI " + + "slowness. It is recommended to contact your administrator to disable the plugin or corresponding feature and reach out to the " + + "plugin maintainer for further assistance."); + } + private void insertMeasure(String componentUuid, String projectUuid, Metric<?> metric, Object obj) { MeasureDto measure = new MeasureDto() .setComponentUuid(componentUuid) @@ -358,7 +400,8 @@ class PersistMeasuresStepIT { } private PersistMeasuresStep step() { - return new PersistMeasuresStep(dbClient, metricRepository, treeRootHolder, measureRepository, computeDuplicationDataMeasure); + return new PersistMeasuresStep(dbClient, metricRepository, treeRootHolder, measureRepository, computeDuplicationDataMeasure, + ceTaskMessages); } private void verifyInsertsOrUpdates(int expectedInsertsOrUpdates) { diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistPushEventsStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistPushEventsStepIT.java index 13760b56081..9b8cd500d04 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistPushEventsStepIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/PersistPushEventsStepIT.java @@ -29,7 +29,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.impl.utils.TestSystem2; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.MutableTreeRootHolderRule; diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/ProjectNclocComputationStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/ProjectNclocComputationStepIT.java index ce7d4ec2efb..6d36cf6fce5 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/ProjectNclocComputationStepIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/ProjectNclocComputationStepIT.java @@ -22,6 +22,7 @@ package org.sonar.ce.task.projectanalysis.step; import org.junit.Rule; import org.junit.Test; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule; +import org.sonar.ce.task.step.ComputationStep; import org.sonar.ce.task.step.TestComputationStepContext; import org.sonar.db.DbClient; import org.sonar.db.DbTester; @@ -54,7 +55,22 @@ public class ProjectNclocComputationStepIT { BranchDto branch2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH)); db.measures().insertMeasure(branch2, m -> m.addValue(ncloc.getKey(), 10d)); analysisMetadataHolder.setProject(new Project(project.getUuid(), project.getKey(), project.getName(), project.getDescription(), emptyList())); - step.execute(TestComputationStepContext.TestStatistics::new); + step.execute(new ComputationStep.Context() { + @Override + public ComputationStep.Statistics getStatistics() { + return new TestComputationStepContext.TestStatistics(); + } + + @Override + public void addTelemetryMetricOnly(String telemetryPrefix, String key, Object value) { + // do nothing + } + + @Override + public void addTelemetryWithStatistic(String telemetryPrefix, String key, Object value) { + // do nothing + } + }); assertThat(dbClient.projectDao().getNclocSum(db.getSession())).isEqualTo(200L); } diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/SendIssueNotificationsStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/SendIssueNotificationsStepIT.java index 72408231158..caa5936c8d2 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/SendIssueNotificationsStepIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/step/SendIssueNotificationsStepIT.java @@ -43,7 +43,7 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.sonar.api.notifications.Notification; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.api.utils.System2; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule; @@ -92,7 +92,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.ce.task.projectanalysis.component.Component.Type; import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder; import static org.sonar.ce.task.projectanalysis.step.SendIssueNotificationsStep.NOTIF_TYPES; diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/AuditPurgeStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/AuditPurgeStepIT.java index 2dbd3b402be..3c9353b5a60 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/AuditPurgeStepIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/AuditPurgeStepIT.java @@ -19,9 +19,6 @@ */ package org.sonar.ce.task.projectanalysis.taskprocessor; -import java.time.Instant; -import java.time.ZoneId; -import java.time.ZonedDateTime; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -37,16 +34,15 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.sonar.ce.task.projectanalysis.taskprocessor.ContextUtils.EMPTY_CONTEXT; import static org.sonar.core.config.Frequency.MONTHLY; import static org.sonar.core.config.PurgeConstants.AUDIT_HOUSEKEEPING_FREQUENCY; public class AuditPurgeStepIT { - private final static long NOW = 1_400_000_000_000L; - private final static long BEFORE = 1_300_000_000_000L; - private final static long LATER = 1_500_000_000_000L; - private final static ZonedDateTime thresholdDate = Instant.ofEpochMilli(NOW) - .atZone(ZoneId.systemDefault()); - private final static PropertyDto FREQUENCY_PROPERTY = new PropertyDto() + private static final long NOW = 1_400_000_000_000L; + private static final long BEFORE = 1_300_000_000_000L; + private static final long LATER = 1_500_000_000_000L; + private static final PropertyDto FREQUENCY_PROPERTY = new PropertyDto() .setKey(AUDIT_HOUSEKEEPING_FREQUENCY) .setValue(MONTHLY.name()); @@ -75,7 +71,7 @@ public class AuditPurgeStepIT { prepareRowsWithDeterministicCreatedAt(); assertThat(dbClient.auditDao().selectOlderThan(db.getSession(), LATER + 1)).hasSize(3); - underTest.execute(() -> null); + underTest.execute(EMPTY_CONTEXT); assertThat(dbClient.auditDao().selectOlderThan(db.getSession(), LATER + 1)).hasSize(2); } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v100/DbVersion100Test.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/ContextUtils.java index 261783f5a23..2a88a1984af 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v100/DbVersion100Test.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/ContextUtils.java @@ -17,24 +17,30 @@ * 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.platform.db.migration.version.v100; +package org.sonar.ce.task.projectanalysis.taskprocessor; -import org.junit.Test; +import org.sonar.ce.task.step.ComputationStep; -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationNotEmpty; -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber; +class ContextUtils { -public class DbVersion100Test { - private final DbVersion100 underTest = new DbVersion100(); - - @Test - public void migrationNumber_starts_at_10_0_000() { - verifyMinimumMigrationNumber(underTest, 10_0_000); + private ContextUtils() { + // utility class } - @Test - public void verify_migration_is_not_empty() { - verifyMigrationNotEmpty(underTest); - } + static final ComputationStep.Context EMPTY_CONTEXT = new ComputationStep.Context() { + @Override + public ComputationStep.Statistics getStatistics() { + return null; + } + + @Override + public void addTelemetryMetricOnly(String telemetryPrefix, String key, Object value) { + // do nothing + } + @Override + public void addTelemetryWithStatistic(String telemetryPrefix, String key, Object value) { + // do nothing + } + }; } diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/IgnoreOrphanBranchStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/IgnoreOrphanBranchStepIT.java index d19f8668caf..f47bc830ae9 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/IgnoreOrphanBranchStepIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/IgnoreOrphanBranchStepIT.java @@ -33,6 +33,7 @@ import org.sonar.db.project.ProjectDto; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.sonar.ce.task.projectanalysis.taskprocessor.ContextUtils.EMPTY_CONTEXT; import static org.sonar.db.component.BranchType.BRANCH; public class IgnoreOrphanBranchStepIT { @@ -66,7 +67,7 @@ public class IgnoreOrphanBranchStepIT { dbClient.branchDao().insert(dbTester.getSession(), branchDto); dbTester.commit(); - underTest.execute(() -> null); + underTest.execute(EMPTY_CONTEXT); Optional<BranchDto> branch = dbClient.branchDao().selectByUuid(dbTester.getSession(), BRANCH_UUID); assertThat(branch.get().isNeedIssueSync()).isFalse(); @@ -85,7 +86,7 @@ public class IgnoreOrphanBranchStepIT { dbClient.branchDao().insert(dbTester.getSession(), branchDto); dbTester.commit(); - underTest.execute(() -> null); + underTest.execute(EMPTY_CONTEXT); Optional<BranchDto> branch = dbClient.branchDao().selectByUuid(dbTester.getSession(), BRANCH_UUID); assertThat(branch.get().isNeedIssueSync()).isFalse(); @@ -102,7 +103,7 @@ public class IgnoreOrphanBranchStepIT { .build(); IgnoreOrphanBranchStep underTest = new IgnoreOrphanBranchStep(ceTask, dbClient); - assertThatThrownBy(() -> underTest.execute(() -> null)) + assertThatThrownBy(() -> underTest.execute(EMPTY_CONTEXT)) .isInstanceOf(UnsupportedOperationException.class) .hasMessage("entity not found in task"); } @@ -125,7 +126,7 @@ public class IgnoreOrphanBranchStepIT { dbClient.projectDao().insert(dbTester.getSession(), projectDto, false); dbTester.commit(); - underTest.execute(() -> null); + underTest.execute(EMPTY_CONTEXT); Optional<BranchDto> branch = dbClient.branchDao().selectByUuid(dbTester.getSession(), BRANCH_UUID); assertThat(branch.get().isNeedIssueSync()).isTrue(); @@ -145,7 +146,7 @@ public class IgnoreOrphanBranchStepIT { dbClient.branchDao().insert(dbTester.getSession(), branchDto); dbTester.commit(); - underTest.execute(() -> null); + underTest.execute(EMPTY_CONTEXT); Optional<BranchDto> branch = dbClient.branchDao().selectByUuid(dbTester.getSession(), BRANCH_UUID); assertThat(branch.get().isNeedIssueSync()).isFalse(); diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/IndexIssuesStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/IndexIssuesStepIT.java index 185a2e29827..c1937157d17 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/IndexIssuesStepIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectanalysis/taskprocessor/IndexIssuesStepIT.java @@ -35,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.sonar.ce.task.projectanalysis.taskprocessor.ContextUtils.EMPTY_CONTEXT; import static org.sonar.db.component.BranchType.BRANCH; public class IndexIssuesStepIT { @@ -72,7 +73,7 @@ public class IndexIssuesStepIT { dbClient.branchDao().insert(dbTester.getSession(), branchDto); dbTester.commit(); - underTest.execute(() -> null); + underTest.execute(EMPTY_CONTEXT); verify(issueIndexer, times(1)).indexOnAnalysis(BRANCH_UUID); Optional<BranchDto> branch = dbClient.branchDao().selectByUuid(dbTester.getSession(), BRANCH_UUID); @@ -91,7 +92,7 @@ public class IndexIssuesStepIT { dbClient.branchDao().insert(dbTester.getSession(), branchDto); dbTester.commit(); - underTest.execute(() -> null); + underTest.execute(EMPTY_CONTEXT); verify(issueIndexer, times(0)).indexOnAnalysis(BRANCH_UUID); } @@ -106,7 +107,7 @@ public class IndexIssuesStepIT { .build(); IndexIssuesStep underTest = new IndexIssuesStep(ceTask, dbClient, issueIndexer); - assertThatThrownBy(() -> underTest.execute(() -> null)) + assertThatThrownBy(() -> underTest.execute(EMPTY_CONTEXT)) .isInstanceOf(UnsupportedOperationException.class) .hasMessage("component not found in task"); } diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepIT.java index 3d109ce34eb..ca009b80c80 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/issue/ExportIssuesStepIT.java @@ -40,7 +40,7 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.testfixtures.log.LogTester; import org.sonar.api.utils.System2; import org.sonar.ce.task.projectexport.component.ComponentRepositoryImpl; diff --git a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/rule/ExportAdHocRulesStepIT.java b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/rule/ExportAdHocRulesStepIT.java index 0652740fa22..7851cb40446 100644 --- a/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/rule/ExportAdHocRulesStepIT.java +++ b/server/sonar-ce-task-projectanalysis/src/it/java/org/sonar/ce/task/projectexport/rule/ExportAdHocRulesStepIT.java @@ -36,7 +36,7 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.testfixtures.log.LogTester; import org.sonar.api.utils.System2; import org.sonar.ce.task.projectexport.steps.DumpElement; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/ProjectAnalysisTaskModule.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/ProjectAnalysisTaskModule.java index a683bc34656..2d31008477d 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/ProjectAnalysisTaskModule.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/ProjectAnalysisTaskModule.java @@ -23,6 +23,7 @@ import org.sonar.ce.task.projectanalysis.container.ContainerFactoryImpl; import org.sonar.ce.task.projectanalysis.taskprocessor.ReportTaskProcessor; import org.sonar.ce.task.projectexport.taskprocessor.ProjectExportTaskProcessor; import org.sonar.ce.task.step.ComputationStepExecutor; +import org.sonar.ce.task.telemetry.StepsTelemetryUnavailableHolderImpl; import org.sonar.core.platform.Module; public class ProjectAnalysisTaskModule extends Module { @@ -31,6 +32,7 @@ public class ProjectAnalysisTaskModule extends Module { add( // task ContainerFactoryImpl.class, + StepsTelemetryUnavailableHolderImpl.class, ComputationStepExecutor.class, ReportTaskProcessor.class, ProjectExportTaskProcessor.class); diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/api/measurecomputer/MeasureComputerContextImpl.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/api/measurecomputer/MeasureComputerContextImpl.java index 2161e7732eb..c129ba8087e 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/api/measurecomputer/MeasureComputerContextImpl.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/api/measurecomputer/MeasureComputerContextImpl.java @@ -21,6 +21,7 @@ package org.sonar.ce.task.projectanalysis.api.measurecomputer; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -34,12 +35,19 @@ import org.sonar.api.ce.measure.Measure; import org.sonar.api.ce.measure.MeasureComputer.MeasureComputerContext; import org.sonar.api.ce.measure.MeasureComputer.MeasureComputerDefinition; import org.sonar.api.ce.measure.Settings; +import org.sonar.api.issue.IssueStatus; +import org.sonar.api.issue.impact.Severity; +import org.sonar.api.issue.impact.SoftwareQuality; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rules.RuleType; +import org.sonar.api.utils.Duration; import org.sonar.ce.task.projectanalysis.component.ConfigurationRepository; import org.sonar.ce.task.projectanalysis.issue.ComponentIssuesRepository; import org.sonar.ce.task.projectanalysis.measure.MeasureRepository; import org.sonar.ce.task.projectanalysis.metric.Metric; import org.sonar.ce.task.projectanalysis.metric.MetricRepository; import org.sonar.core.issue.DefaultIssue; +import org.sonar.core.rule.RuleTypeMapper; import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder; @@ -175,7 +183,9 @@ public class MeasureComputerContextImpl implements MeasureComputerContext { @Override public List<? extends Issue> getIssues() { - return componentIssues; + return componentIssues.stream() + .map(CeApiIssueAdapter::new) + .toList(); } private static Component newComponent(org.sonar.ce.task.projectanalysis.component.Component component) { @@ -212,4 +222,58 @@ public class MeasureComputerContextImpl implements MeasureComputerContext { } } + static class CeApiIssueAdapter implements Issue { + + DefaultIssue defaultIssue; + + public CeApiIssueAdapter(DefaultIssue defaultIssue) { + this.defaultIssue = defaultIssue; + } + + @Override + public String key() { + return defaultIssue.key(); + } + + @Override + public RuleKey ruleKey() { + return defaultIssue.ruleKey(); + } + + @Override + public String status() { + return defaultIssue.status(); + } + + @Override + public String resolution() { + return defaultIssue.resolution(); + } + + @Override + public IssueStatus issueStatus() { + return defaultIssue.issueStatus(); + } + + @Override + public String severity() { + return defaultIssue.severity(); + } + + @Override + public Duration effort() { + return defaultIssue.effort(); + } + + @Override + public RuleType type() { + return RuleTypeMapper.toApiRuleType(defaultIssue.type()); + } + + @Override + public Map<SoftwareQuality, Severity> impacts() { + return defaultIssue.impacts(); + } + } + } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java index 2bc4f4f81bd..fc1c0787ea4 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java @@ -28,8 +28,6 @@ import org.sonar.ce.task.log.CeTaskMessagesImpl; import org.sonar.ce.task.projectanalysis.analysis.AnalysisFromSonarQube94Visitor; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderImpl; import org.sonar.ce.task.projectanalysis.api.posttask.PostProjectAnalysisTasksExecutor; -import org.sonar.ce.task.projectanalysis.scanner.ScannerReportDirectoryHolderImpl; -import org.sonar.ce.task.projectanalysis.scanner.ScannerReportReaderImpl; import org.sonar.ce.task.projectanalysis.component.BranchComponentUuidsDelegate; import org.sonar.ce.task.projectanalysis.component.BranchLoader; import org.sonar.ce.task.projectanalysis.component.BranchPersisterImpl; @@ -130,6 +128,8 @@ import org.sonar.ce.task.projectanalysis.qualityprofile.ActiveRulesHolderImpl; import org.sonar.ce.task.projectanalysis.qualityprofile.PrioritizedRulesHolderImpl; import org.sonar.ce.task.projectanalysis.qualityprofile.QProfileStatusRepositoryImpl; import org.sonar.ce.task.projectanalysis.qualityprofile.QualityProfileRuleChangeResolver; +import org.sonar.ce.task.projectanalysis.scanner.ScannerReportDirectoryHolderImpl; +import org.sonar.ce.task.projectanalysis.scanner.ScannerReportReaderImpl; import org.sonar.ce.task.projectanalysis.scm.ScmInfoDbLoader; import org.sonar.ce.task.projectanalysis.scm.ScmInfoRepositoryImpl; import org.sonar.ce.task.projectanalysis.source.DbLineHashVersion; @@ -145,6 +145,8 @@ import org.sonar.ce.task.projectanalysis.source.SourceLinesDiffImpl; import org.sonar.ce.task.projectanalysis.source.SourceLinesHashCache; import org.sonar.ce.task.projectanalysis.source.SourceLinesHashRepositoryImpl; import org.sonar.ce.task.projectanalysis.source.SourceLinesRepositoryImpl; +import org.sonar.ce.task.projectanalysis.step.DefaultPersistScaStepImpl; +import org.sonar.ce.task.projectanalysis.step.DefaultScaStepImpl; import org.sonar.ce.task.projectanalysis.step.ReportComputationSteps; import org.sonar.ce.task.projectanalysis.step.SmallChangesetQualityGateSpecialCase; import org.sonar.ce.task.projectanalysis.webhook.WebhookPostTask; @@ -152,6 +154,7 @@ import org.sonar.ce.task.setting.SettingsLoader; import org.sonar.ce.task.step.ComputationStepExecutor; import org.sonar.ce.task.step.ComputationSteps; import org.sonar.ce.task.taskprocessor.MutableTaskResultHolderImpl; +import org.sonar.ce.task.telemetry.StepsTelemetryHolderImpl; import org.sonar.core.issue.tracking.Tracker; import org.sonar.core.platform.ContainerPopulator; import org.sonar.server.issue.TaintChecker; @@ -179,7 +182,13 @@ public final class ProjectAnalysisTaskContainerPopulator implements ContainerPop for (ReportAnalysisComponentProvider componentProvider : componentProviders) { container.add(componentProvider.getComponents()); } - container.add(steps.orderedStepClasses()); + + // Exclude interfaces because they can't be instantiated directly. + // The concrete class for interfaces must be added to the container separately. + container.add(steps.orderedStepClasses() + .stream() + .filter(stepClass -> !stepClass.isInterface()) + .toList()); } /** @@ -223,6 +232,9 @@ public final class ProjectAnalysisTaskContainerPopulator implements ContainerPop NewCodeReferenceBranchComponentUuids.class, BranchComponentUuidsDelegate.class, SiblingComponentsWithOpenIssues.class, + DefaultScaStepImpl.class, + DefaultPersistScaStepImpl.class, + StepsTelemetryHolderImpl.class, // repositories PreviousSourceHashRepositoryImpl.class, diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreator.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreator.java index d42cf733b31..334c1b0c1bc 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreator.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/AdHocRuleCreator.java @@ -27,7 +27,7 @@ import java.util.stream.Collectors; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueCounter.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueCounter.java index 483767d7ec9..8db05a91639 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueCounter.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueCounter.java @@ -29,7 +29,7 @@ import javax.annotation.Nullable; import org.sonar.api.issue.IssueStatus; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.measure.Measure; import org.sonar.ce.task.projectanalysis.measure.MeasureRepository; @@ -80,10 +80,10 @@ import static org.sonar.api.rule.Severity.CRITICAL; import static org.sonar.api.rule.Severity.INFO; import static org.sonar.api.rule.Severity.MAJOR; import static org.sonar.api.rule.Severity.MINOR; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.VULNERABILITY; /** * For each component, computes the measures related to number of issues: diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycle.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycle.java index 81078898798..432ad9a3657 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycle.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycle.java @@ -27,7 +27,7 @@ import jakarta.inject.Inject; import org.jetbrains.annotations.NotNull; import org.sonar.api.issue.Issue; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; import org.sonar.core.issue.DefaultImpact; import org.sonar.core.issue.DefaultIssue; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/NewAdHocRule.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/NewAdHocRule.java index e5da858fabe..faa4684e8c9 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/NewAdHocRule.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/NewAdHocRule.java @@ -33,8 +33,9 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.internal.ImpactMapper; +import org.sonar.core.rule.RuleTypeMapper; import org.sonar.scanner.protocol.Constants; import org.sonar.scanner.protocol.output.ScannerReport; @@ -100,7 +101,7 @@ public class NewAdHocRule { } Map<SoftwareQuality, Severity> impacts = mapImpacts(ruleFromScannerReport.getDefaultImpactsList()); if (impacts.isEmpty()) { - return Map.of(ImpactMapper.convertToSoftwareQuality(this.ruleType), + return Map.of(ImpactMapper.convertToSoftwareQuality(RuleTypeMapper.toApiRuleType(this.ruleType)), ImpactMapper.convertToImpactSeverity(this.severity)); } else { return impacts; @@ -113,7 +114,7 @@ public class NewAdHocRule { } Map<SoftwareQuality, Severity> impacts = mapImpacts(ruleFromScannerReport.getDefaultImpactsList()); Map.Entry<SoftwareQuality, Severity> bestImpactForBackMapping = ImpactMapper.getBestImpactForBackmapping(impacts); - return ImpactMapper.convertToRuleType(bestImpactForBackMapping.getKey()); + return RuleTypeMapper.toRuleType(ImpactMapper.convertToRuleType(bestImpactForBackMapping.getKey())); } private static String determineSeverity(ScannerReport.AdHocRule ruleFromScannerReport) { diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/Rule.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/Rule.java index 8eb992ece8e..a612d45418f 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/Rule.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/Rule.java @@ -27,7 +27,7 @@ import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; public interface Rule { diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleImpl.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleImpl.java index 2fc108e2dc9..9d40ee1faf7 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleImpl.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleImpl.java @@ -32,7 +32,7 @@ import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction; import org.sonar.db.issue.ImpactDto; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryImpl.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryImpl.java index 68b1847efd5..d37b4a970fb 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryImpl.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryImpl.java @@ -32,7 +32,7 @@ import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.core.util.stream.MoreCollectors; import org.sonar.db.DbClient; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerRawInputFactory.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerRawInputFactory.java index a3f10efba3f..dc006242431 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerRawInputFactory.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerRawInputFactory.java @@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.internal.ImpactMapper; import org.sonar.api.utils.Duration; import org.sonar.ce.common.scanner.ScannerReportReader; @@ -47,6 +47,7 @@ import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.tracking.Input; import org.sonar.core.issue.tracking.LazyInput; import org.sonar.core.issue.tracking.LineHashSequence; +import org.sonar.core.rule.RuleTypeMapper; import org.sonar.core.util.CloseableIterator; import org.sonar.db.protobuf.DbCommons; import org.sonar.db.protobuf.DbIssues; @@ -380,7 +381,7 @@ public class TrackerRawInputFactory { return rule.getType(); } else if (!rule.getDefaultImpacts().isEmpty()) { SoftwareQuality impactSoftwareQuality = ImpactMapper.getBestImpactForBackmapping(rule.getDefaultImpacts()).getKey(); - return ImpactMapper.convertToRuleType(impactSoftwareQuality); + return RuleTypeMapper.toRuleType(ImpactMapper.convertToRuleType(impactSoftwareQuality)); } else { throw new IllegalArgumentException("Cannot determine the type for issue of rule %s".formatted(reportExternalIssue.getRuleId())); } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PostMeasuresComputationCheck.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PostMeasuresComputationCheck.java index 8daa288eb49..27ffc039b71 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PostMeasuresComputationCheck.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PostMeasuresComputationCheck.java @@ -21,7 +21,9 @@ package org.sonar.ce.task.projectanalysis.measure; import org.sonar.api.ExtensionPoint; import org.sonar.api.ce.ComputeEngineSide; +import org.sonar.ce.common.scanner.ScannerReportReader; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; +import org.sonar.ce.task.projectanalysis.analysis.Branch; import org.sonar.ce.task.projectanalysis.component.Component; /** @@ -50,6 +52,9 @@ public interface PostMeasuresComputationCheck { */ String getProjectUuid(); + Branch getBranch(); + + ScannerReportReader getReportReader(); /** * Return the ncloc computed for the current analysis */ diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PostMeasuresComputationChecksStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PostMeasuresComputationChecksStep.java index a5a998b685c..4ce9187cc70 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PostMeasuresComputationChecksStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PostMeasuresComputationChecksStep.java @@ -22,13 +22,14 @@ package org.sonar.ce.task.projectanalysis.measure; import java.util.Optional; import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.measures.CoreMetrics; +import org.sonar.ce.common.scanner.ScannerReportReader; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; +import org.sonar.ce.task.projectanalysis.analysis.Branch; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.TreeRootHolder; import org.sonar.ce.task.projectanalysis.metric.Metric; import org.sonar.ce.task.projectanalysis.metric.MetricRepository; import org.sonar.ce.task.step.ComputationStep; -import org.springframework.beans.factory.annotation.Autowired; /** * Execute {@link PostMeasuresComputationCheck} instances in no specific order. @@ -42,27 +43,19 @@ public class PostMeasuresComputationChecksStep implements ComputationStep { private final MetricRepository metricRepository; private final MeasureRepository measureRepository; private final AnalysisMetadataHolder analysisMetadataHolder; + private final ScannerReportReader reportReader; private final PostMeasuresComputationCheck[] extensions; - @Autowired(required = false) public PostMeasuresComputationChecksStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository, - AnalysisMetadataHolder analysisMetadataHolder, PostMeasuresComputationCheck[] extensions) { + AnalysisMetadataHolder analysisMetadataHolder, ScannerReportReader reportReader, PostMeasuresComputationCheck[] extensions) { this.treeRootHolder = treeRootHolder; this.metricRepository = metricRepository; this.measureRepository = measureRepository; this.analysisMetadataHolder = analysisMetadataHolder; + this.reportReader = reportReader; this.extensions = extensions; } - /** - * Used when zero {@link PostMeasuresComputationCheck} are registered into container. - */ - @Autowired(required = false) - public PostMeasuresComputationChecksStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository, - AnalysisMetadataHolder analysisMetadataHolder) { - this(treeRootHolder, metricRepository, measureRepository, analysisMetadataHolder, new PostMeasuresComputationCheck[0]); - } - @Override public void execute(ComputationStep.Context context) { PostMeasuresComputationCheck.Context extensionContext = new ContextImpl(); @@ -84,6 +77,16 @@ public class PostMeasuresComputationChecksStep implements ComputationStep { } @Override + public Branch getBranch() { + return analysisMetadataHolder.getBranch(); + } + + @Override + public ScannerReportReader getReportReader() { + return reportReader; + } + + @Override public int getNcloc() { Metric nclocMetric = metricRepository.getByKey(CoreMetrics.NCLOC_KEY); Optional<Measure> nclocMeasure = measureRepository.getRawMeasure(treeRootHolder.getRoot(), nclocMetric); diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PreMeasuresComputationCheck.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PreMeasuresComputationCheck.java index 68e1f8e56a4..f5df9c90078 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PreMeasuresComputationCheck.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PreMeasuresComputationCheck.java @@ -24,6 +24,7 @@ import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.config.Configuration; import org.sonar.ce.task.projectanalysis.analysis.Branch; + /** * Extension point that is called during processing of a task * by {@link PreMeasuresComputationChecksStep}. diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PreMeasuresComputationChecksStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PreMeasuresComputationChecksStep.java index b59dcd63cba..b97a6e2317d 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PreMeasuresComputationChecksStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/PreMeasuresComputationChecksStep.java @@ -85,6 +85,5 @@ public class PreMeasuresComputationChecksStep implements ComputationStep { public Configuration getConfiguration() { return configurationRepository.getConfiguration(); } - } } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/notification/ReportAnalysisFailureNotificationHandler.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/notification/ReportAnalysisFailureNotificationHandler.java index 1c4fc74c64c..ae9276ec2ba 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/notification/ReportAnalysisFailureNotificationHandler.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/notification/ReportAnalysisFailureNotificationHandler.java @@ -25,7 +25,7 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.server.notification.EmailNotificationHandler; import org.sonar.server.notification.NotificationDispatcherMetadata; import org.sonar.server.notification.NotificationManager; @@ -41,7 +41,7 @@ public class ReportAnalysisFailureNotificationHandler extends EmailNotificationH private static final NotificationDispatcherMetadata METADATA = NotificationDispatcherMetadata.create(KEY) .setProperty(NotificationDispatcherMetadata.GLOBAL_NOTIFICATION, String.valueOf(true)) .setProperty(NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION, String.valueOf(true)); - private static final SubscriberPermissionsOnProject REQUIRED_SUBSCRIBER_PERMISSIONS = new SubscriberPermissionsOnProject(UserRole.ADMIN, UserRole.USER); + private static final SubscriberPermissionsOnProject REQUIRED_SUBSCRIBER_PERMISSIONS = new SubscriberPermissionsOnProject(ProjectPermission.ADMIN, ProjectPermission.USER); private final NotificationManager notificationManager; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactory.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactory.java index ed179c45a85..0cc4a404408 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactory.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactory.java @@ -31,7 +31,7 @@ import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.TreeRootHolder; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitor.java index f3896d48d7b..2fe03272eba 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitor.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitor.java @@ -20,7 +20,6 @@ package org.sonar.ce.task.projectanalysis.qualitymodel; import java.util.Map; -import org.sonar.api.ce.measure.Issue; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.measures.CoreMetrics; @@ -33,8 +32,8 @@ import org.sonar.ce.task.projectanalysis.measure.MeasureRepository; import org.sonar.ce.task.projectanalysis.metric.Metric; import org.sonar.ce.task.projectanalysis.metric.MetricRepository; import org.sonar.core.issue.DefaultIssue; -import org.sonar.server.measure.Rating; import org.sonar.core.metric.SoftwareQualitiesMetrics; +import org.sonar.server.measure.Rating; import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_RATING_KEY; @@ -43,18 +42,18 @@ import static org.sonar.api.rule.Severity.CRITICAL; import static org.sonar.api.rule.Severity.INFO; import static org.sonar.api.rule.Severity.MAJOR; import static org.sonar.api.rule.Severity.MINOR; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.VULNERABILITY; import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER; import static org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit.LEAVES; import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder; +import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY; +import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.server.measure.Rating.A; import static org.sonar.server.measure.Rating.B; import static org.sonar.server.measure.Rating.C; import static org.sonar.server.measure.Rating.D; import static org.sonar.server.measure.Rating.E; -import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY; -import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY; /** * Compute following measures : @@ -168,8 +167,8 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitor extends PathAwareVis newRatingValueByMetric.forEach((metric, rating) -> rating.increment(otherCounter.newRatingValueByMetric.get(metric))); } - void processIssue(Issue issue) { - if (newIssueClassifier.isNew(component, (DefaultIssue) issue)) { + void processIssue(DefaultIssue issue) { + if (newIssueClassifier.isNew(component, issue)) { Rating rating = RATING_BY_SEVERITY.get(issue.severity()); if (issue.type().equals(BUG)) { newRatingValueByMetric.get(NEW_RELIABILITY_RATING_KEY).increment(rating); @@ -179,14 +178,14 @@ public class NewReliabilityAndSecurityRatingMeasuresVisitor extends PathAwareVis } } - void processIssueForSoftwareQuality(Issue issue) { - if (newIssueClassifier.isNew(component, (DefaultIssue) issue)) { + void processIssueForSoftwareQuality(DefaultIssue issue) { + if (newIssueClassifier.isNew(component, issue)) { processSoftwareQualityRating(issue, SoftwareQuality.RELIABILITY, NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY); processSoftwareQualityRating(issue, SoftwareQuality.SECURITY, NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY); } } - private void processSoftwareQualityRating(Issue issue, SoftwareQuality softwareQuality, String metricKey) { + private void processSoftwareQualityRating(DefaultIssue issue, SoftwareQuality softwareQuality, String metricKey) { Severity severity = issue.impacts().get(softwareQuality); if (severity != null) { Rating rating = Rating.RATING_BY_SOFTWARE_QUALITY_SEVERITY.get(severity); diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitor.java index 4df9b7a3e8e..434e7f7ddc2 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitor.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitor.java @@ -33,7 +33,7 @@ import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_HOTSPOTS_REVIEWED_ import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_HOTSPOTS_REVIEWED_STATUS_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_HOTSPOTS_TO_REVIEW_STATUS_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_REVIEW_RATING_KEY; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER; import static org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit.FILE; import static org.sonar.server.security.SecurityReviewRating.computePercent; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitor.java index ec5a481b83f..b7d75b21186 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitor.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitor.java @@ -37,8 +37,8 @@ import org.sonar.server.measure.Rating; import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING_KEY; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit.FILE; import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING_KEY; import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING_KEY; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewCounter.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewCounter.java index b5ada4fca56..5c2d33d858c 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewCounter.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewCounter.java @@ -19,7 +19,7 @@ */ package org.sonar.ce.task.projectanalysis.qualitymodel; -import org.sonar.api.ce.measure.Issue; +import org.sonar.core.issue.DefaultIssue; import static org.sonar.api.issue.Issue.STATUS_REVIEWED; import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW; @@ -32,7 +32,7 @@ final class SecurityReviewCounter { // prevents instantiation } - void processHotspot(Issue issue) { + void processHotspot(DefaultIssue issue) { if (issue.status().equals(STATUS_REVIEWED)) { hotspotsReviewed++; } else if (issue.status().equals(STATUS_TO_REVIEW)) { diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitor.java index 8106bc69b27..543d69ac66c 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitor.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitor.java @@ -33,7 +33,7 @@ import static org.sonar.api.measures.CoreMetrics.SECURITY_HOTSPOTS_REVIEWED_KEY; import static org.sonar.api.measures.CoreMetrics.SECURITY_HOTSPOTS_REVIEWED_STATUS_KEY; import static org.sonar.api.measures.CoreMetrics.SECURITY_HOTSPOTS_TO_REVIEW_STATUS_KEY; import static org.sonar.api.measures.CoreMetrics.SECURITY_REVIEW_RATING_KEY; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER; import static org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit.FILE; import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scanner/ScannerReportReaderImpl.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scanner/ScannerReportReaderImpl.java index 69861be786e..5f2627c31a0 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scanner/ScannerReportReaderImpl.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scanner/ScannerReportReaderImpl.java @@ -19,6 +19,8 @@ */ package org.sonar.ce.task.projectanalysis.scanner; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -36,8 +38,6 @@ import org.sonar.scanner.protocol.output.FileStructure; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.LineSgnificantCode; -import static java.nio.charset.StandardCharsets.UTF_8; - public class ScannerReportReaderImpl implements ScannerReportReader { private final ScannerReportDirectoryHolder scannerReportDirectoryHolder; @@ -233,4 +233,16 @@ public class ScannerReportReaderImpl implements ScannerReportReader { ensureInitialized(); return delegate.readTelemetryEntries(); } + + @Override + public File readDependencyFilesZip() { + ensureInitialized(); + return delegate.readDependencyFilesZip(); + } + + @Override + public CloseableIterator<ScannerReport.AnalysisData> readAnalysisData() { + ensureInitialized(); + return delegate.readAnalysisData(); + } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddMeasuresMigratedColumnToPortfoliosTable.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/DefaultPersistScaStepImpl.java index 72564514f70..566b47010bb 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddMeasuresMigratedColumnToPortfoliosTable.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/DefaultPersistScaStepImpl.java @@ -17,15 +17,18 @@ * 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.platform.db.migration.version.v108; +package org.sonar.ce.task.projectanalysis.step; -import org.sonar.db.Database; +// This will be overridden if another PersistScaStep implementation exists with Priority. +public class DefaultPersistScaStepImpl implements PersistScaStep { -public class AddMeasuresMigratedColumnToPortfoliosTable extends AbstractAddMeasuresMigratedColumnToTable { - - static final String PORTFOLIOS_TABLE_NAME = "portfolios"; + @Override + public String getDescription() { + return "Persist software composition analysis unavailable"; + } - public AddMeasuresMigratedColumnToPortfoliosTable(Database db) { - super(db, PORTFOLIOS_TABLE_NAME); + @Override + public void execute(Context context) { + // do nothing } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MigrateBranchesLiveMeasuresToMeasures.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/DefaultScaStepImpl.java index 5b259da9437..ca92da743b3 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MigrateBranchesLiveMeasuresToMeasures.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/DefaultScaStepImpl.java @@ -17,14 +17,18 @@ * 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.platform.db.migration.version.v108; +package org.sonar.ce.task.projectanalysis.step; -import org.sonar.api.utils.System2; -import org.sonar.db.Database; +// This will be overridden if another ScaStep implementation exists with Priority. +public class DefaultScaStepImpl implements ScaStep { -public class MigrateBranchesLiveMeasuresToMeasures extends AbstractMigrateLiveMeasuresToMeasures { + @Override + public String getDescription() { + return "Software composition analysis unavailable"; + } - public MigrateBranchesLiveMeasuresToMeasures(Database db, System2 system2) { - super(db, system2, "project_branches", "branch"); + @Override + public void execute(Context context) { + // do nothing } } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStep.java index c22645ab4f9..16f026509fa 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistMeasuresStep.java @@ -20,6 +20,7 @@ package org.sonar.ce.task.projectanalysis.step; import java.util.Collection; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -29,6 +30,9 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.ce.task.log.CeTaskMessages; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.Component.Type; import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit; @@ -53,10 +57,14 @@ import org.springframework.beans.factory.annotation.Autowired; import static org.sonar.api.measures.CoreMetrics.DUPLICATIONS_DATA_KEY; import static org.sonar.api.measures.CoreMetrics.EXECUTABLE_LINES_DATA_KEY; import static org.sonar.api.measures.CoreMetrics.NCLOC_DATA_KEY; +import static org.sonar.api.measures.CoreMetrics.QUALITY_GATE_DETAILS_KEY; +import static org.sonar.api.measures.CoreMetrics.QUALITY_PROFILES_KEY; import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER; public class PersistMeasuresStep implements ComputationStep { + private static final Logger LOGGER = LoggerFactory.getLogger(PersistMeasuresStep.class); + // 50 mb private static final int MAX_TRANSACTION_SIZE = 50_000_000; private static final Predicate<Measure> NON_EMPTY_MEASURE = measure -> @@ -69,27 +77,38 @@ public class PersistMeasuresStep implements ComputationStep { EXECUTABLE_LINES_DATA_KEY, NCLOC_DATA_KEY); + private static final Set<String> CORE_METRICS_WITH_LARGE_VALUES = Set.of( + DUPLICATIONS_DATA_KEY, + QUALITY_PROFILES_KEY, + QUALITY_GATE_DETAILS_KEY + ); + private final DbClient dbClient; private final MetricRepository metricRepository; private final TreeRootHolder treeRootHolder; private final MeasureRepository measureRepository; private final ComputeDuplicationDataMeasure computeDuplicationDataMeasure; private final int maxTransactionSize; + private final CeTaskMessages ceTaskMessages; @Autowired public PersistMeasuresStep(DbClient dbClient, MetricRepository metricRepository, TreeRootHolder treeRootHolder, - MeasureRepository measureRepository, @Nullable ComputeDuplicationDataMeasure computeDuplicationDataMeasure) { - this(dbClient, metricRepository, treeRootHolder, measureRepository, computeDuplicationDataMeasure, MAX_TRANSACTION_SIZE); + MeasureRepository measureRepository, @Nullable ComputeDuplicationDataMeasure computeDuplicationDataMeasure, + @Nullable CeTaskMessages ceTaskMessages) { + this(dbClient, metricRepository, treeRootHolder, measureRepository, computeDuplicationDataMeasure, MAX_TRANSACTION_SIZE, + ceTaskMessages); } PersistMeasuresStep(DbClient dbClient, MetricRepository metricRepository, TreeRootHolder treeRootHolder, - MeasureRepository measureRepository, @Nullable ComputeDuplicationDataMeasure computeDuplicationDataMeasure, int maxTransactionSize) { + MeasureRepository measureRepository, @Nullable ComputeDuplicationDataMeasure computeDuplicationDataMeasure, int maxTransactionSize, + @Nullable CeTaskMessages ceTaskMessages) { this.dbClient = dbClient; this.metricRepository = metricRepository; this.treeRootHolder = treeRootHolder; this.measureRepository = measureRepository; this.computeDuplicationDataMeasure = computeDuplicationDataMeasure; this.maxTransactionSize = maxTransactionSize; + this.ceTaskMessages = ceTaskMessages; } @Override @@ -108,12 +127,13 @@ public class PersistMeasuresStep implements ComputationStep { List<MeasureDto> inserts = new LinkedList<>(); List<MeasureDto> updates = new LinkedList<>(); + Set<String> largeValueMetrics = new HashSet<>(); int insertsOrUpdates = 0; int unchanged = 0; int size = 0; for (Component component : visitor.components) { - MeasureDto measure = createMeasure(component); + MeasureDto measure = createMeasure(component, largeValueMetrics); if (dbMeasureHashes.contains(new MeasureHash(measure.getComponentUuid(), measure.computeJsonValueHash()))) { unchanged += measure.getMetricValues().size(); @@ -136,6 +156,7 @@ public class PersistMeasuresStep implements ComputationStep { } persist(inserts, updates); + addLargeValueMetricsWarning(largeValueMetrics); context.getStatistics() .add("insertsOrUpdates", insertsOrUpdates) .add("unchanged", unchanged); @@ -147,7 +168,7 @@ public class PersistMeasuresStep implements ComputationStep { } } - private MeasureDto createMeasure(Component component) { + private MeasureDto createMeasure(Component component, Set<String> largeValueMetrics) { MeasureDto measureDto = new MeasureDto(); measureDto.setComponentUuid(component.getUuid()); measureDto.setBranchUuid(treeRootHolder.getRoot().getUuid()); @@ -166,7 +187,10 @@ public class PersistMeasuresStep implements ComputationStep { .filter(notBestValueOptimized) .map(MeasureToMeasureDto::getMeasureValue) .filter(Objects::nonNull) - .forEach(value -> measureDto.addValue(metric.getKey(), value)); + .forEach(value -> { + checkValueLength(value, metricKey, component, largeValueMetrics); + measureDto.addValue(metric.getKey(), value); + }); } if (component.getType() == Type.FILE) { @@ -180,6 +204,32 @@ public class PersistMeasuresStep implements ComputationStep { return measureDto; } + private static void checkValueLength(Object value, String metricKey, Component component, Set<String> largeValueMetrics) { + if (value instanceof String strValue) { + int valueLength = strValue.length(); + if (valueLength > 100_000) { + LOGGER.debug("Measure with large value persisted: metricKey={}, valueLength={}, componentKey={}, componentUuid={}", + metricKey, valueLength, component.getKey(), component.getUuid()); + if (!CORE_METRICS_WITH_LARGE_VALUES.contains(metricKey)) { + largeValueMetrics.add(metricKey); + } + } + } + } + + private void addLargeValueMetricsWarning(Set<String> largeValueMetrics) { + if (!largeValueMetrics.isEmpty()) { + String warningMessage = String.format("A plugin is storing excessively large data in the following measure(s): %s. This " + + "is likely to cause significant SonarQube performance degradation and UI slowness. It is recommended to contact your " + + "administrator to disable the plugin or corresponding feature and reach out to the plugin maintainer for further assistance.", + largeValueMetrics.stream().map(metric -> String.format("'%s'", metric)).collect(Collectors.joining(", "))); + LOGGER.warn(warningMessage); + if (ceTaskMessages != null) { + ceTaskMessages.add(new CeTaskMessages.Message(warningMessage, System.currentTimeMillis())); + } + } + } + private static boolean shouldNotPersist(String metricKey) { return NOT_TO_PERSIST.contains(metricKey); } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/package-info.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistScaStep.java index 935cf26a2c4..0f0c49df0a2 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/package-info.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistScaStep.java @@ -17,7 +17,9 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -@ParametersAreNonnullByDefault -package org.sonar.server.platform.db.migration.version.v101; +package org.sonar.ce.task.projectanalysis.step; -import javax.annotation.ParametersAreNonnullByDefault; +import org.sonar.ce.task.step.ComputationStep; + +public interface PersistScaStep extends ComputationStep { +} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java index eebfa3f2f46..775f3c5f036 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java @@ -52,7 +52,8 @@ public class ReportComputationSteps extends AbstractComputationSteps { ValidateProjectStep.class, LoadQualityProfilesStep.class, - SendAnalysisTelemetryStep.class, + // Dependencies + ScaStep.class, // Pre analysis operations PreMeasuresComputationChecksStep.class, @@ -118,6 +119,7 @@ public class ReportComputationSteps extends AbstractComputationSteps { PersistCrossProjectDuplicationIndexStep.class, EnableAnalysisStep.class, PersistPullRequestFixedIssueStep.class, + PersistScaStep.class, UpdateQualityProfilesLastUsedDateStep.class, PurgeDatastoresStep.class, @@ -132,7 +134,11 @@ public class ReportComputationSteps extends AbstractComputationSteps { ExecuteStatelessOnFinishStep.class, PublishTaskResultStep.class, - TriggerViewRefreshStep.class); + TriggerViewRefreshStep.class, + + // send analysis and steps statistics telemetry + SendAnalysisTelemetryStep.class + ); public ReportComputationSteps(TaskContainer taskContainer) { super(taskContainer); diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/package-info.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ScaStep.java index 58ad7e44d71..7724346805f 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/package-info.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ScaStep.java @@ -17,7 +17,9 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -@ParametersAreNonnullByDefault -package org.sonar.server.platform.db.migration.version.v100; +package org.sonar.ce.task.projectanalysis.step; -import javax.annotation.ParametersAreNonnullByDefault; +import org.sonar.ce.task.step.ComputationStep; + +public interface ScaStep extends ComputationStep { +} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStep.java index c80f5bf94bc..0d9a4967fc9 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStep.java @@ -20,12 +20,15 @@ package org.sonar.ce.task.projectanalysis.step; import java.util.HashSet; +import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.sonar.api.config.Configuration; import org.sonar.api.platform.Server; -import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; import org.sonar.ce.common.scanner.ScannerReportReader; +import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; import org.sonar.ce.task.step.ComputationStep; +import org.sonar.ce.task.telemetry.StepsTelemetryHolder; import org.sonar.core.util.CloseableIterator; import org.sonar.core.util.UuidFactory; import org.sonar.scanner.protocol.output.ScannerReport; @@ -40,21 +43,26 @@ import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_ENABL public class SendAnalysisTelemetryStep implements ComputationStep { + private static final int MAX_METRICS = 1000; + private final TelemetryClient telemetryClient; private final ScannerReportReader scannerReportReader; private final Server server; private final UuidFactory uuidFactory; private final Configuration config; private final AnalysisMetadataHolder analysisMetadataHolder; + private final StepsTelemetryHolder stepsTelemetryHolder; public SendAnalysisTelemetryStep(TelemetryClient telemetryClient, ScannerReportReader scannerReportReader, - UuidFactory uuidFactory, Server server, Configuration configuration, AnalysisMetadataHolder analysisMetadataHolder) { + UuidFactory uuidFactory, Server server, Configuration configuration, AnalysisMetadataHolder analysisMetadataHolder, + StepsTelemetryHolder stepsTelemetryHolder) { this.telemetryClient = telemetryClient; this.scannerReportReader = scannerReportReader; this.server = server; this.uuidFactory = uuidFactory; this.config = configuration; this.analysisMetadataHolder = analysisMetadataHolder; + this.stepsTelemetryHolder = stepsTelemetryHolder; } @Override @@ -62,32 +70,56 @@ public class SendAnalysisTelemetryStep implements ComputationStep { if (!config.getBoolean(SONAR_TELEMETRY_ENABLE.getKey()).orElse(false)) { return; } + + String projectUuid = analysisMetadataHolder.getProject().getUuid(); + String analysisType = analysisMetadataHolder.isPullRequest() ? "pull_request" : "branch"; + + // it was agreed to limit the number of telemetry entries to 1000 per one analysis among scanner report metrics and step metrics + Set<Metric> scannerReportMetrics = getScannerReportMetrics(projectUuid, analysisType); + Set<Metric> stepsStatisticsMetrics = getStepsTelemetryMetrics(projectUuid, analysisType, MAX_METRICS - scannerReportMetrics.size(), + stepsTelemetryHolder.getTelemetryMetrics()); + + Set<Metric> metrics = new HashSet<>(); + metrics.addAll(scannerReportMetrics); + metrics.addAll(stepsStatisticsMetrics); + sendMetrics(metrics); + } + + private void sendMetrics(Set<Metric> metrics) { + if (metrics.isEmpty()) { + return; + } + BaseMessage baseMessage = new BaseMessage.Builder() + .setMessageUuid(uuidFactory.create()) + .setInstallationId(server.getId()) + .setDimension(Dimension.ANALYSIS) + .setMetrics(metrics) + .build(); + + String jsonString = MessageSerializer.serialize(baseMessage); + telemetryClient.uploadMetricAsync(jsonString); + } + + private Set<Metric> getScannerReportMetrics(String projectUuid, String analysisType) { + Set<Metric> metrics = new HashSet<>(); try (CloseableIterator<ScannerReport.TelemetryEntry> it = scannerReportReader.readTelemetryEntries()) { - Set<Metric> metrics = new HashSet<>(); - String projectUuid = analysisMetadataHolder.getProject().getUuid(); - String analysisType = analysisMetadataHolder.isPullRequest() ? "pull_request" : "branch"; - // it was agreed to limit the number of telemetry entries to 1000 per one analysis - final int limit = 1000; int count = 0; - while (it.hasNext() && count++ < limit) { + while (it.hasNext() && count < MAX_METRICS) { ScannerReport.TelemetryEntry telemetryEntry = it.next(); metrics.add(new AnalysisMetric(telemetryEntry.getKey(), telemetryEntry.getValue(), projectUuid, analysisType)); + count++; } - - if (metrics.isEmpty()) { - return; - } - BaseMessage baseMessage = new BaseMessage.Builder() - .setMessageUuid(uuidFactory.create()) - .setInstallationId(server.getId()) - .setDimension(Dimension.ANALYSIS) - .setMetrics(metrics) - .build(); - - String jsonString = MessageSerializer.serialize(baseMessage); - telemetryClient.uploadMetricAsync(jsonString); } + return metrics; + } + private static Set<Metric> getStepsTelemetryMetrics(String projectUuid, String analysisType, int maxMetrics, Map<String, Object> telemetryMetrics) { + return telemetryMetrics.entrySet().stream() + .map(entry -> + new AnalysisMetric(entry.getKey(), String.valueOf(entry.getValue()), projectUuid, analysisType) + ) + .limit(maxMetrics) + .collect(Collectors.toSet()); } @Override diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/SendIssueNotificationsStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/SendIssueNotificationsStep.java index d109134682e..4ddef0ac9cf 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/SendIssueNotificationsStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/SendIssueNotificationsStep.java @@ -33,7 +33,7 @@ import java.util.stream.Collectors; import javax.annotation.CheckForNull; import org.sonar.api.issue.Issue; import org.sonar.api.notifications.Notification; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; import org.sonar.ce.task.projectanalysis.analysis.Branch; import org.sonar.ce.task.projectanalysis.component.Component; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/taskprocessor/AuditPurgeTaskProcessor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/taskprocessor/AuditPurgeTaskProcessor.java index 65f30d16709..ad3f3e72792 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/taskprocessor/AuditPurgeTaskProcessor.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/taskprocessor/AuditPurgeTaskProcessor.java @@ -19,7 +19,8 @@ */ package org.sonar.ce.task.projectanalysis.taskprocessor; -import java.util.Arrays; +import static org.sonar.db.ce.CeTaskTypes.AUDIT_PURGE; + import java.util.List; import java.util.Set; import javax.annotation.CheckForNull; @@ -35,8 +36,6 @@ import org.sonar.core.platform.Container; import org.sonar.core.platform.ContainerPopulator; import org.sonar.core.platform.SpringComponentContainer; -import static org.sonar.db.ce.CeTaskTypes.AUDIT_PURGE; - public class AuditPurgeTaskProcessor implements CeTaskProcessor { private static final Set<String> HANDLED_TYPES = Set.of(AUDIT_PURGE); @@ -79,7 +78,7 @@ public class AuditPurgeTaskProcessor implements CeTaskProcessor { @Override public List<Class<? extends ComputationStep>> orderedStepClasses() { - return Arrays.asList(AuditPurgeStep.class); + return List.of(AuditPurgeStep.class); } } } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/taskprocessor/IssueSyncTaskProcessor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/taskprocessor/IssueSyncTaskProcessor.java index f896a6566d8..8aeda2c806e 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/taskprocessor/IssueSyncTaskProcessor.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/taskprocessor/IssueSyncTaskProcessor.java @@ -32,6 +32,7 @@ import org.sonar.ce.task.projectanalysis.step.AbstractComputationSteps; import org.sonar.ce.task.step.ComputationStep; import org.sonar.ce.task.step.ComputationStepExecutor; import org.sonar.ce.task.taskprocessor.CeTaskProcessor; +import org.sonar.ce.task.telemetry.StepsTelemetryUnavailableHolderImpl; import org.sonar.core.platform.Container; import org.sonar.core.platform.ContainerPopulator; import org.sonar.core.platform.SpringComponentContainer; @@ -69,6 +70,7 @@ public class IssueSyncTaskProcessor implements CeTaskProcessor { taskContainer.add(IndexIssuesStep.class); taskContainer.add(new SyncComputationSteps(taskContainer)); taskContainer.add(ComputationStepExecutor.class); + taskContainer.add(StepsTelemetryUnavailableHolderImpl.class); }; } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/taskprocessor/ReportTaskProcessor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/taskprocessor/ReportTaskProcessor.java index ec5db1ac87b..8b21b03e0b8 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/taskprocessor/ReportTaskProcessor.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/taskprocessor/ReportTaskProcessor.java @@ -27,12 +27,12 @@ import org.sonar.ce.task.CeTask; import org.sonar.ce.task.CeTaskResult; import org.sonar.ce.task.container.TaskContainer; import org.sonar.ce.task.projectanalysis.container.ContainerFactory; +import org.sonar.ce.task.projectanalysis.container.ReportAnalysisComponentProvider; import org.sonar.ce.task.step.ComputationStepExecutor; import org.sonar.ce.task.taskprocessor.CeTaskProcessor; import org.sonar.ce.task.taskprocessor.TaskResultHolder; import org.sonar.core.platform.SpringComponentContainer; import org.sonar.db.ce.CeTaskTypes; -import org.sonar.ce.task.projectanalysis.container.ReportAnalysisComponentProvider; import org.springframework.beans.factory.annotation.Autowired; public class ReportTaskProcessor implements CeTaskProcessor { diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/util/cache/ProtobufIssueDiskCache.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/util/cache/ProtobufIssueDiskCache.java index ab722505890..f5aedd11ec5 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/util/cache/ProtobufIssueDiskCache.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/util/cache/ProtobufIssueDiskCache.java @@ -36,7 +36,7 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.api.utils.System2; import org.sonar.core.issue.DefaultImpact; @@ -99,7 +99,7 @@ public class ProtobufIssueDiskCache implements DiskCache<DefaultIssue> { static DefaultIssue toDefaultIssue(IssueCache.Issue next) { DefaultIssue defaultIssue = new DefaultIssue(); defaultIssue.setKey(next.getKey()); - defaultIssue.setType(RuleType.valueOf(next.getRuleType())); + defaultIssue.setType(RuleType.fromDbConstant(next.getRuleType())); defaultIssue.setComponentUuid(next.hasComponentUuid() ? next.getComponentUuid() : null); defaultIssue.setComponentKey(next.getComponentKey()); defaultIssue.setProjectUuid(next.getProjectUuid()); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulatorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulatorTest.java index af035f909cc..6955e475da9 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulatorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulatorTest.java @@ -21,6 +21,7 @@ package org.sonar.ce.task.projectanalysis.container; import com.google.common.collect.ImmutableList; import java.lang.reflect.Modifier; +import java.util.List; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; @@ -28,12 +29,14 @@ import org.junit.Test; import org.reflections.Reflections; import org.sonar.ce.task.CeTask; import org.sonar.ce.task.projectanalysis.step.PersistComponentsStep; +import org.sonar.ce.task.projectanalysis.step.ReportComputationSteps; import org.sonar.ce.task.projectanalysis.task.ListTaskContainer; import org.sonar.ce.task.step.ComputationStep; import static com.google.common.collect.Sets.difference; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockConstruction; import static org.mockito.Mockito.when; public class ProjectAnalysisTaskContainerPopulatorTest { @@ -106,8 +109,48 @@ public class ProjectAnalysisTaskContainerPopulatorTest { assertThat(container.getAddedComponents()).contains(object, clazz); } - private static final class MyClass { + @Test + public void populateContainer_includesReportComputationStepClasses() { + Class<MyClass> clazz = MyClass.class; + ListTaskContainer container = new ListTaskContainer(); + + try (var ignored = mockConstruction(ReportComputationSteps.class, + (mock, context) -> { + when(mock.orderedStepClasses()).thenReturn(List.of(clazz)); + })) { + underTest.populateContainer(container); + assertThat(container.getAddedComponents()).contains(clazz); + } + } + + @Test + public void populateContainer_doesNotIncludeReportComputationStepInterfaces() { + Class<MyInterface> iface = MyInterface.class; + ListTaskContainer container = new ListTaskContainer(); + + try (var ignored = mockConstruction(ReportComputationSteps.class, + (mock, context) -> { + when(mock.orderedStepClasses()).thenReturn(List.of(iface)); + })) { + underTest.populateContainer(container); + + assertThat(container.getAddedComponents()).doesNotContain(iface); + } + } + + private interface MyInterface extends ComputationStep { + } + private static final class MyClass implements ComputationStep { + @Override + public void execute(Context context) { + // do nothing + } + + @Override + public String getDescription() { + return ""; + } } } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/CloseIssuesOnRemovedComponentsVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/CloseIssuesOnRemovedComponentsVisitorTest.java index 76c7c4d45b3..49a4460977c 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/CloseIssuesOnRemovedComponentsVisitorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/CloseIssuesOnRemovedComponentsVisitorTest.java @@ -27,7 +27,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.ce.task.projectanalysis.component.ReportComponent; import org.sonar.ce.task.projectanalysis.component.VisitorsCrawler; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ComputeLocationHashesVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ComputeLocationHashesVisitorTest.java index 04654aafe7b..acd49560c71 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ComputeLocationHashesVisitorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ComputeLocationHashesVisitorTest.java @@ -32,7 +32,7 @@ import org.junit.Test; import org.slf4j.event.Level; import org.sonar.api.config.Configuration; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.testfixtures.log.LogTester; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.ReportComponent; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/DumbRule.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/DumbRule.java index 072ef44aba9..1868fe136df 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/DumbRule.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/DumbRule.java @@ -30,7 +30,7 @@ import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import static java.util.Objects.requireNonNull; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/EffortAggregatorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/EffortAggregatorTest.java index 61a34c46a53..55bd469bd97 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/EffortAggregatorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/EffortAggregatorTest.java @@ -43,9 +43,9 @@ import static org.sonar.api.measures.CoreMetrics.SECURITY_REMEDIATION_EFFORT; import static org.sonar.api.measures.CoreMetrics.SECURITY_REMEDIATION_EFFORT_KEY; import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT; import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT_KEY; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT; import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY; import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java index ab0975defd9..d325f2ab342 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java @@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.ce.common.scanner.ScannerReportReaderRule; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule; @@ -123,9 +123,9 @@ import static org.sonar.api.measures.CoreMetrics.VULNERABILITIES; import static org.sonar.api.measures.CoreMetrics.VULNERABILITIES_KEY; import static org.sonar.api.rule.Severity.CRITICAL; import static org.sonar.api.rule.Severity.MAJOR; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder; import static org.sonar.ce.task.projectanalysis.issue.IssueCounter.IMPACT_TO_JSON_METRIC_KEY; import static org.sonar.ce.task.projectanalysis.issue.IssueCounter.IMPACT_TO_NEW_JSON_METRIC_KEY; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycleTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycleTest.java index 5963b144843..67baa875b97 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycleTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycleTest.java @@ -26,7 +26,7 @@ import org.junit.Test; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule; import org.sonar.ce.task.projectanalysis.analysis.Branch; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/NewAdHocRuleTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/NewAdHocRuleTest.java index 305e43ab4aa..83d58f29980 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/NewAdHocRuleTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/NewAdHocRuleTest.java @@ -23,7 +23,7 @@ import java.util.Map; import org.junit.Test; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.scanner.protocol.Constants; import org.sonar.scanner.protocol.output.ScannerReport; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/NewEffortAggregatorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/NewEffortAggregatorTest.java index 4e6957756a9..72a547a8671 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/NewEffortAggregatorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/NewEffortAggregatorTest.java @@ -26,7 +26,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.ce.task.projectanalysis.analysis.Branch; import org.sonar.ce.task.projectanalysis.component.Component; @@ -55,9 +55,9 @@ import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_REMEDIATION_EFFORT import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_REMEDIATION_EFFORT_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_TECHNICAL_DEBT; import static org.sonar.api.measures.CoreMetrics.NEW_TECHNICAL_DEBT_KEY; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT; import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY; import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryImplTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryImplTest.java index af1cbb8d1d9..3e9301562e2 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryImplTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RuleRepositoryImplTest.java @@ -31,7 +31,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.db.DbClient; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TrackerRawInputFactoryTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TrackerRawInputFactoryTest.java index bd2f05eb6f9..c044e2d0e08 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TrackerRawInputFactoryTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TrackerRawInputFactoryTest.java @@ -36,7 +36,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.ce.common.scanner.ScannerReportReaderRule; import org.sonar.ce.task.projectanalysis.component.Component; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/UpdateConflictResolverTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/UpdateConflictResolverTest.java index e5affec4f15..2b988c6fe49 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/UpdateConflictResolverTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/UpdateConflictResolverTest.java @@ -32,7 +32,7 @@ import org.sonar.db.issue.IssueDto; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.api.issue.Issue.STATUS_OPEN; -import static org.sonar.api.rules.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.CODE_SMELL; public class UpdateConflictResolverTest { private final UpdateConflictResolver underTest = new UpdateConflictResolver(); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/PostMeasuresComputationChecksStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/PostMeasuresComputationChecksStepTest.java index 7f2e8a8a929..eb80fcfb603 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/PostMeasuresComputationChecksStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/PostMeasuresComputationChecksStepTest.java @@ -24,6 +24,7 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.sonar.api.measures.CoreMetrics; +import org.sonar.ce.common.scanner.ScannerReportReader; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule; import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule; import org.sonar.ce.task.projectanalysis.measure.PostMeasuresComputationCheck.Context; @@ -53,6 +54,7 @@ public class PostMeasuresComputationChecksStepTest { public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); @Rule public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule(); + private ScannerReportReader reportReader = mock(ScannerReportReader.class); @Test public void execute_extensions() { @@ -131,9 +133,6 @@ public class PostMeasuresComputationChecksStepTest { } private PostMeasuresComputationChecksStep newStep(PostMeasuresComputationCheck... postMeasuresComputationChecks) { - if (postMeasuresComputationChecks.length == 0) { - return new PostMeasuresComputationChecksStep(treeRootHolder, metricRepository, measureRepository, analysisMetadataHolder); - } - return new PostMeasuresComputationChecksStep(treeRootHolder, metricRepository, measureRepository, analysisMetadataHolder, postMeasuresComputationChecks); + return new PostMeasuresComputationChecksStep(treeRootHolder, metricRepository, measureRepository, analysisMetadataHolder, reportReader, postMeasuresComputationChecks); } } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/PreMeasuresComputationChecksStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/PreMeasuresComputationChecksStepTest.java index c0840838bb2..2a95d90c807 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/PreMeasuresComputationChecksStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/measure/PreMeasuresComputationChecksStepTest.java @@ -19,10 +19,10 @@ */ package org.sonar.ce.task.projectanalysis.measure; -import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; +import org.sonar.ce.common.scanner.ScannerReportReader; import org.sonar.ce.task.log.CeTaskMessages; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule; import org.sonar.ce.task.projectanalysis.analysis.Branch; @@ -40,19 +40,15 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.sonar.ce.task.projectanalysis.measure.PreMeasuresComputationCheck.PreMeasuresComputationCheckException; -import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; +import static org.sonar.db.component.ComponentTesting.newProjectDto; public class PreMeasuresComputationChecksStepTest { public AnalysisMetadataHolderRule analysisMetadataHolder = mock(); public CeTaskMessages ceTaskMessages = mock(); + public ScannerReportReader reportReader = mock(); public ConfigurationRepository configurationRepository = mock(); - @Before - public void setup() { - - } - @Test public void execute_extensions() throws PreMeasuresComputationCheckException { PreMeasuresComputationCheck check1 = mock(PreMeasuresComputationCheck.class); @@ -67,7 +63,7 @@ public class PreMeasuresComputationChecksStepTest { @Test public void context_contains_project_uuid_from_analysis_metadata_holder() throws PreMeasuresComputationCheckException { - Project project = Project.from(newPrivateProjectDto()); + Project project = Project.fromProjectDtoWithTags(newProjectDto().setPrivate(true)); when(analysisMetadataHolder.getProject()).thenReturn(project); PreMeasuresComputationCheck check = mock(PreMeasuresComputationCheck.class); @@ -121,9 +117,6 @@ public class PreMeasuresComputationChecksStepTest { } private PreMeasuresComputationChecksStep newStep(PreMeasuresComputationCheck... preMeasuresComputationChecks) { - if (preMeasuresComputationChecks.length == 0) { - return new PreMeasuresComputationChecksStep(analysisMetadataHolder, ceTaskMessages, configurationRepository); - } return new PreMeasuresComputationChecksStep(analysisMetadataHolder, ceTaskMessages, configurationRepository, preMeasuresComputationChecks); } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/notification/ReportAnalysisFailureNotificationHandlerTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/notification/ReportAnalysisFailureNotificationHandlerTest.java index 02cb59c7981..e53eeb6de94 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/notification/ReportAnalysisFailureNotificationHandlerTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/notification/ReportAnalysisFailureNotificationHandlerTest.java @@ -28,7 +28,7 @@ import java.util.stream.Stream; import javax.annotation.Nullable; import org.junit.Test; import org.mockito.Mockito; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.server.notification.NotificationDispatcherMetadata; import org.sonar.server.notification.NotificationManager; import org.sonar.server.notification.NotificationManager.EmailRecipient; @@ -50,7 +50,7 @@ import static org.sonar.server.notification.NotificationDispatcherMetadata.PER_P public class ReportAnalysisFailureNotificationHandlerTest { private static final String REPORT_FAILURE_DISPATCHER_KEY = "CeReportTaskFailure"; - private static final SubscriberPermissionsOnProject REQUIRED_SUBSCRIBER_PERMISSIONS = new SubscriberPermissionsOnProject(UserRole.ADMIN, UserRole.USER); + private static final SubscriberPermissionsOnProject REQUIRED_SUBSCRIBER_PERMISSIONS = new SubscriberPermissionsOnProject(ProjectPermission.ADMIN, ProjectPermission.USER); private NotificationManager notificationManager = mock(NotificationManager.class); private EmailNotificationChannel emailNotificationChannel = mock(EmailNotificationChannel.class); private ReportAnalysisFailureNotificationHandler underTest = new ReportAnalysisFailureNotificationHandler(notificationManager, emailNotificationChannel); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactoryTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactoryTest.java index 432324185e8..801d7c2c6cb 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactoryTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactoryTest.java @@ -32,7 +32,7 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.DateUtils; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule; import org.sonar.ce.task.projectanalysis.analysis.TestBranch; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java index 39ac16e19f3..8898f645265 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java @@ -26,7 +26,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.FileAttributes; @@ -59,9 +59,9 @@ import static org.sonar.api.rule.Severity.CRITICAL; import static org.sonar.api.rule.Severity.INFO; import static org.sonar.api.rule.Severity.MAJOR; import static org.sonar.api.rule.Severity.MINOR; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY; import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE; import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitorTest.java index 115ba9a347d..9c5526c7ec6 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewSecurityReviewMeasuresVisitorTest.java @@ -26,7 +26,7 @@ import org.assertj.core.data.Offset; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.FileAttributes; import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java index edb0cce4e8b..b5ae767e49d 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java @@ -25,7 +25,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.FileAttributes; @@ -52,9 +52,9 @@ import static org.sonar.api.rule.Severity.CRITICAL; import static org.sonar.api.rule.Severity.INFO; import static org.sonar.api.rule.Severity.MAJOR; import static org.sonar.api.rule.Severity.MINOR; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY; import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE; import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitorTest.java index a039b5ad9e4..68bbdd61fe1 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/qualitymodel/SecurityReviewMeasuresVisitorTest.java @@ -22,7 +22,7 @@ package org.sonar.ce.task.projectanalysis.qualitymodel; import javax.annotation.Nullable; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule; import org.sonar.ce.task.projectanalysis.component.VisitorsCrawler; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scanner/ScannerReportReaderImplTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scanner/ScannerReportReaderImplTest.java index 09d89b3b2d9..6abf97d1ba9 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scanner/ScannerReportReaderImplTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scanner/ScannerReportReaderImplTest.java @@ -21,6 +21,7 @@ package org.sonar.ce.task.projectanalysis.scanner; import com.google.common.collect.ImmutableList; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import org.apache.commons.io.FileUtils; import org.junit.Before; @@ -300,4 +301,20 @@ public class ScannerReportReaderImplTest { assertThat(res).toIterable().containsExactlyElementsOf(warnings); res.close(); } + + @Test + public void verify_readDependencyFilesZip() throws IOException { + File tempDir = tempFolder.newDir(); + File tempFile = new File(tempDir, "dependency-files.zip"); + byte[] expectedBytes = "hello world!".getBytes(); + try (FileOutputStream fos = new FileOutputStream(tempFile)) { + fos.write(expectedBytes); + } + + writer.writeScaFile(tempFile); + + assertThat(underTest.readDependencyFilesZip()).isNotNull(); + var returnBytes = FileUtils.readFileToByteArray(underTest.readDependencyFilesZip()); + assertThat(returnBytes).isEqualTo(expectedBytes); + } } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/DbVersion108Test.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/DefaultPersistScaStepImplTest.java index 5a9fa0b0b82..d5fa971f5c3 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/DbVersion108Test.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/DefaultPersistScaStepImplTest.java @@ -17,24 +17,23 @@ * 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.platform.db.migration.version.v108; +package org.sonar.ce.task.projectanalysis.step; import org.junit.jupiter.api.Test; +import org.sonar.ce.task.step.ComputationStep; -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationNotEmpty; -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.mockito.Mockito.mock; -class DbVersion108Test { - - private final DbVersion108 underTest = new DbVersion108(); +class DefaultPersistScaStepImplTest { @Test - void migrationNumber_starts_at_108_000() { - verifyMinimumMigrationNumber(underTest, 108_000); - } + void shouldNoOpWithoutError() { + var underTest = new DefaultPersistScaStepImpl(); - @Test - void verify_migration_is_not_empty() { - verifyMigrationNotEmpty(underTest); + assertThat(underTest.getDescription()).isEqualTo("Persist software composition analysis unavailable"); + + assertThatNoException().isThrownBy(() -> underTest.execute(mock(ComputationStep.Context.class))); } } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v107/DbVersion107Test.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/DefaultScaStepTest.java index 74c6d6eab13..de46fd6b99c 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v107/DbVersion107Test.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/DefaultScaStepTest.java @@ -17,24 +17,23 @@ * 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.platform.db.migration.version.v107; +package org.sonar.ce.task.projectanalysis.step; import org.junit.jupiter.api.Test; +import org.sonar.ce.task.step.ComputationStep; -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationNotEmpty; -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.mockito.Mockito.mock; -class DbVersion107Test { - - private final DbVersion107 underTest = new DbVersion107(); +class DefaultScaStepTest { @Test - void migrationNumber_starts_at_107_000() { - verifyMinimumMigrationNumber(underTest, 107_000); - } + void shouldNoOpWithoutError() { + var underTest = new DefaultScaStepImpl(); - @Test - void verify_migration_is_not_empty() { - verifyMigrationNotEmpty(underTest); + assertThat(underTest.getDescription()).isEqualTo("Software composition analysis unavailable"); + + assertThatNoException().isThrownBy(() -> underTest.execute(mock(ComputationStep.Context.class))); } } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadChangedIssuesStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadChangedIssuesStepTest.java index 224eeccba67..eae8971c907 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadChangedIssuesStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadChangedIssuesStepTest.java @@ -28,7 +28,7 @@ import org.junit.rules.TemporaryFolder; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.ce.task.projectanalysis.issue.ChangedIssuesRepository; import org.sonar.ce.task.projectanalysis.issue.ProtoIssueCache; diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStepTest.java index bef8826dd4a..0f112131470 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStepTest.java @@ -21,15 +21,18 @@ package org.sonar.ce.task.projectanalysis.step; import java.util.Collections; import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.Optional; import java.util.Set; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.sonar.api.config.Configuration; import org.sonar.api.platform.Server; -import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; import org.sonar.ce.common.scanner.ScannerReportReader; +import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; import org.sonar.ce.task.step.ComputationStep; +import org.sonar.ce.task.telemetry.StepsTelemetryHolder; import org.sonar.core.util.CloseableIterator; import org.sonar.core.util.UuidFactory; import org.sonar.scanner.protocol.output.ScannerReport; @@ -53,14 +56,16 @@ class SendAnalysisTelemetryStepTest { private final ComputationStep.Context context = mock(); private final Configuration configuration = mock(); private final AnalysisMetadataHolder analysisMetadataHolder = mock(); + private final StepsTelemetryHolder stepsTelemetryHolder = mock(); private final SendAnalysisTelemetryStep underTest = new SendAnalysisTelemetryStep(telemetryClient, scannerReportReader, uuidFactory, - server, configuration, analysisMetadataHolder); + server, configuration, analysisMetadataHolder, stepsTelemetryHolder); { when(uuidFactory.create()).thenReturn("uuid"); when(server.getId()).thenReturn("serverId"); when(configuration.getBoolean("sonar.telemetry.enable")).thenReturn(Optional.of(true)); when(analysisMetadataHolder.getProject()).thenReturn(new Project("uuid", "key", "name",null, Collections.emptyList())); + when(stepsTelemetryHolder.getTelemetryMetrics()).thenReturn(Collections.emptyMap()); } @Test @@ -73,7 +78,7 @@ class SendAnalysisTelemetryStepTest { } @Test - void execute_whenTwoMetrics_callTelemetryClientOnce() { + void execute_whenTwoScannerReportMetrics_callTelemetryClientOnce() { Set<ScannerReport.TelemetryEntry> telemetryEntries = Set.of( ScannerReport.TelemetryEntry.newBuilder().setKey("key1").setValue("value1").build(), ScannerReport.TelemetryEntry.newBuilder().setKey("key2").setValue("value2").build()); @@ -92,6 +97,10 @@ class SendAnalysisTelemetryStepTest { ScannerReport.TelemetryEntry.newBuilder().setKey("key2").setValue("value2").build()); when(scannerReportReader.readTelemetryEntries()).thenReturn(CloseableIterator.from(telemetryEntries.iterator())); + Map<String, Object> telemetryMetrics = new LinkedHashMap<>(); + telemetryMetrics.put("step.metric.1", "value1"); + when(stepsTelemetryHolder.getTelemetryMetrics()).thenReturn(telemetryMetrics); + underTest.execute(context); verifyNoInteractions(telemetryClient); @@ -99,11 +108,17 @@ class SendAnalysisTelemetryStepTest { @Test void execute_when2000entries_sendOnly1000entries() { - Set<ScannerReport.TelemetryEntry> telemetryEntries = new HashSet<>(); - for (int i = 0; i < 2000; i++) { - telemetryEntries.add(ScannerReport.TelemetryEntry.newBuilder().setKey(String.valueOf(i)).setValue("value" + i).build()); + Set<ScannerReport.TelemetryEntry> scannerReportTelemetryEntries = new HashSet<>(); + for (int i = 0; i < 700; i++) { + scannerReportTelemetryEntries.add(ScannerReport.TelemetryEntry.newBuilder().setKey(String.valueOf(i)).setValue("value" + i).build()); } - when(scannerReportReader.readTelemetryEntries()).thenReturn(CloseableIterator.from(telemetryEntries.iterator())); + when(scannerReportReader.readTelemetryEntries()).thenReturn(CloseableIterator.from(scannerReportTelemetryEntries.iterator())); + + Map<String, Object> telemetryMetrics = new LinkedHashMap<>(); + for (int i = 0; i < 700; i++) { + telemetryMetrics.put(String.format("step.metric.%s", i), "value" + i); + } + when(stepsTelemetryHolder.getTelemetryMetrics()).thenReturn(telemetryMetrics); underTest.execute(context); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/taskprocessor/IssueSyncTaskProcessorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/taskprocessor/IssueSyncTaskProcessorTest.java index 3bf2024f9d4..40e33e2e5ac 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/taskprocessor/IssueSyncTaskProcessorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/taskprocessor/IssueSyncTaskProcessorTest.java @@ -52,7 +52,7 @@ public class IssueSyncTaskProcessorTest { .build(); IssueSyncTaskProcessor.newContainerPopulator(task).populateContainer(container); - Mockito.verify(container, Mockito.times(5)).add(any()); + Mockito.verify(container, Mockito.times(6)).add(any()); } @Test diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/util/cache/ProtobufIssueDiskCacheTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/util/cache/ProtobufIssueDiskCacheTest.java index 1a3197a94f8..5793dbe9f7d 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/util/cache/ProtobufIssueDiskCacheTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/util/cache/ProtobufIssueDiskCacheTest.java @@ -25,7 +25,7 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultImpact; import org.sonar.core.issue.DefaultIssue; diff --git a/server/sonar-ce-task/src/main/java/org/sonar/ce/task/step/ComputationStep.java b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/step/ComputationStep.java index df382fbeba2..dacce723866 100644 --- a/server/sonar-ce-task/src/main/java/org/sonar/ce/task/step/ComputationStep.java +++ b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/step/ComputationStep.java @@ -19,16 +19,21 @@ */ package org.sonar.ce.task.step; +import javax.annotation.Nullable; + /** * A way of splitting the processing of a task into smaller items which can be executed sequentially * by {@link ComputationStepExecutor}. */ public interface ComputationStep { + void execute(Context context); + + String getDescription(); + /** * Statistics are displayed in the step ending log. They help * understanding the runtime context and potential performance hotspots. - * * <p/> * Example: * <code> @@ -39,12 +44,15 @@ public interface ComputationStep { * <code> * 2018.07.26 10:22:58 DEBUG ce[AWTVrwb-KZf9YbDx-laU][o.s.s.c.t.s.ComputationStepExecutor] Persist issues | inserts=200 | updates=50 | time=30ms * </code> - * * <p/> * Statistics are logged in the order of insertion. */ interface Statistics { /** + * Adds a key-value pair to be logged at the end of the step. + * The keys are in a per-step context so do not need to be namespaced + * to uniquely identify them across steps, just short names are fine. + * * @return this * @throws NullPointerException if key or value is null * @throws IllegalArgumentException if key has already been set @@ -54,10 +62,47 @@ public interface ComputationStep { } interface Context { + /** + * Get a statistics object from the current task context. The object + * is cleared between each step, and used to log statistics at the + * end of the step. + * + * @return the Statistics instance + */ Statistics getStatistics(); - } - void execute(Context context); + /** + * Add a metric to the telemetry data. The given prefix will be prepended to the key + * with a period separating it from the key. Using a prefix is advisable because telemetry + * is in a global namespace, but if needed the prefix may be null to leave it off. + * The naming convention for keys is to use snake_case with underscores. + *<p> + * Typically it will make sense to prefer {@link #addTelemetryWithStatistic(String, String, Object)} + * so the information is visible in the logs as well as the telemetry. But if you know you're + * already logging the information yourself, you might not need it to be a statistic. + *</p> + * @param telemetryPrefix to prepend to the key with a period separating them, or null for none + * @param key key following snake_case convention + * @param value telemetry value + */ + void addTelemetryMetricOnly(@Nullable String telemetryPrefix, String key, Object value); - String getDescription(); + /** + * Adds a metric to the telemetry data and also adds it to the statistics log line at the same + * time. The telemetry metric gets the prefix and the statistic does not. For full control of + * statistic and telemetry separately, use {@link Context#getStatistics()} and + * {@link Context#addTelemetryMetricOnly(String, String, Object)}. The telemetryPrefix is + * not nullable on this method because the key really should be different for the telemetry + * and the statistic (telemetry is globally namespaced, statistics are per-step). + * <p> + * This method is preferred over telemetry only, it can't hurt to show the information in both + * places most of the time. + * </p> + * + * @param telemetryPrefix to prepend to the key for the telemetry, but not for the statistic + * @param key key following snake_case convention + * @param value telemetry/statistic value + */ + void addTelemetryWithStatistic(String telemetryPrefix, String key, Object value); + } } diff --git a/server/sonar-ce-task/src/main/java/org/sonar/ce/task/step/ComputationStepExecutor.java b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/step/ComputationStepExecutor.java index 38242aa4b33..ffde161a8c0 100644 --- a/server/sonar-ce-task/src/main/java/org/sonar/ce/task/step/ComputationStepExecutor.java +++ b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/step/ComputationStepExecutor.java @@ -19,11 +19,14 @@ */ package org.sonar.ce.task.step; +import java.util.Objects; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.ce.task.CeTaskInterrupter; +import org.sonar.ce.task.telemetry.MutableStepsTelemetryHolder; +import org.sonar.ce.task.telemetry.StepsTelemetryUnavailableHolderImpl; import org.sonar.core.util.logs.Profiler; import org.springframework.beans.factory.annotation.Autowired; @@ -36,17 +39,25 @@ public final class ComputationStepExecutor { private final ComputationSteps steps; private final CeTaskInterrupter taskInterrupter; + private final MutableStepsTelemetryHolder stepsTelemetryHolder; @CheckForNull private final Listener listener; + /** + * This constructor is used when running Portfolio Refresh, Project Import or App Refresh tasks. + * @param steps computation steps + * @param taskInterrupter task interrupter + */ public ComputationStepExecutor(ComputationSteps steps, CeTaskInterrupter taskInterrupter) { - this(steps, taskInterrupter, null); + this(steps, taskInterrupter, new StepsTelemetryUnavailableHolderImpl(), null); } @Autowired - public ComputationStepExecutor(ComputationSteps steps, CeTaskInterrupter taskInterrupter, @Nullable Listener listener) { + public ComputationStepExecutor(ComputationSteps steps, CeTaskInterrupter taskInterrupter, + MutableStepsTelemetryHolder stepsTelemetryHolder, @Nullable Listener listener) { this.steps = steps; this.taskInterrupter = taskInterrupter; + this.stepsTelemetryHolder = stepsTelemetryHolder; this.listener = listener; } @@ -65,7 +76,7 @@ public final class ComputationStepExecutor { private void executeSteps(Profiler stepProfiler) { StepStatisticsImpl statistics = new StepStatisticsImpl(stepProfiler); - ComputationStep.Context context = new StepContextImpl(statistics); + ComputationStep.Context context = new StepContextImpl(statistics, stepsTelemetryHolder); for (ComputationStep step : steps.instances()) { executeStep(stepProfiler, context, step); } @@ -119,14 +130,36 @@ public final class ComputationStepExecutor { private static class StepContextImpl implements ComputationStep.Context { private final ComputationStep.Statistics statistics; + private final MutableStepsTelemetryHolder stepsTelemetryHolder; - private StepContextImpl(ComputationStep.Statistics statistics) { + private StepContextImpl(ComputationStep.Statistics statistics, MutableStepsTelemetryHolder stepsTelemetryHolder) { this.statistics = statistics; + this.stepsTelemetryHolder = stepsTelemetryHolder; + } + + private static String prependPrefix(@Nullable String prefix, String key) { + if (prefix == null) { + return key; + } else { + return prefix + "." + key; + } } @Override public ComputationStep.Statistics getStatistics() { return statistics; } + + @Override + public void addTelemetryMetricOnly(@Nullable String telemetryPrefix, String key, Object value) { + stepsTelemetryHolder.add(prependPrefix(telemetryPrefix, key), value); + } + + @Override + public void addTelemetryWithStatistic(String telemetryPrefix, String key, Object value) { + Objects.requireNonNull(telemetryPrefix); + stepsTelemetryHolder.add(prependPrefix(telemetryPrefix, key), value); + statistics.add(key, value); + } } } diff --git a/server/sonar-ce-task/src/main/java/org/sonar/ce/task/telemetry/MutableStepsTelemetryHolder.java b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/telemetry/MutableStepsTelemetryHolder.java new file mode 100644 index 00000000000..83b75d3335c --- /dev/null +++ b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/telemetry/MutableStepsTelemetryHolder.java @@ -0,0 +1,25 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.ce.task.telemetry; + +public interface MutableStepsTelemetryHolder extends StepsTelemetryHolder { + + MutableStepsTelemetryHolder add(String key, Object value); +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/package-info.java b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/telemetry/StepsTelemetryHolder.java index 9d00b4e4061..4d8b1ff6128 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/package-info.java +++ b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/telemetry/StepsTelemetryHolder.java @@ -17,7 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -@ParametersAreNonnullByDefault -package org.sonar.server.platform.db.migration.version.v102; +package org.sonar.ce.task.telemetry; -import javax.annotation.ParametersAreNonnullByDefault; +import java.util.Map; + +public interface StepsTelemetryHolder { + + Map<String, Object> getTelemetryMetrics(); +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexRootComponentUuidInSnapshots.java b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/telemetry/StepsTelemetryHolderImpl.java index 89f2baa5fd8..1f8c1b496a1 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexRootComponentUuidInSnapshots.java +++ b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/telemetry/StepsTelemetryHolderImpl.java @@ -17,17 +17,29 @@ * 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.platform.db.migration.version.v102; +package org.sonar.ce.task.telemetry; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.CreateIndexOnColumn; +import java.util.LinkedHashMap; +import java.util.Map; -public class CreateIndexRootComponentUuidInSnapshots extends CreateIndexOnColumn { +import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; - private static final String TABLE_NAME = "snapshots"; - private static final String COLUMN_NAME = "root_component_uuid"; +public class StepsTelemetryHolderImpl implements MutableStepsTelemetryHolder { - public CreateIndexRootComponentUuidInSnapshots(Database db) { - super(db, TABLE_NAME, COLUMN_NAME, false); + private final Map<String, Object> telemetryMetrics = new LinkedHashMap<>(); + + @Override + public Map<String, Object> getTelemetryMetrics() { + return telemetryMetrics; + } + + @Override + public StepsTelemetryHolderImpl add(String key, Object value) { + requireNonNull(key, "Metric has null key"); + requireNonNull(value, () -> String.format("Metric with key [%s] has null value", key)); + checkArgument(!telemetryMetrics.containsKey(key), "Metric with key [%s] is already present", key); + telemetryMetrics.put(key, value); + return this; } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropScimUserProvisioning.java b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/telemetry/StepsTelemetryUnavailableHolderImpl.java index 49a29886f4d..7a54bfea961 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropScimUserProvisioning.java +++ b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/telemetry/StepsTelemetryUnavailableHolderImpl.java @@ -17,20 +17,19 @@ * 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.platform.db.migration.version.v100; +package org.sonar.ce.task.telemetry; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; +import java.util.Map; -public class DropScimUserProvisioning extends DataChange { +public class StepsTelemetryUnavailableHolderImpl implements MutableStepsTelemetryHolder { - public DropScimUserProvisioning(Database db) { - super(db); + @Override + public Map<String, Object> getTelemetryMetrics() { + throw new UnsupportedOperationException("Telemetry is not available"); } @Override - protected void execute(Context context) throws SQLException { - context.prepareUpsert("delete from scim_users").execute().commit(); + public StepsTelemetryUnavailableHolderImpl add(String key, Object value) { + throw new UnsupportedOperationException("Telemetry is not available"); } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/package-info.java b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/telemetry/package-info.java index 82e1f1e756b..c00b8e386cc 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/package-info.java +++ b/server/sonar-ce-task/src/main/java/org/sonar/ce/task/telemetry/package-info.java @@ -18,6 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @ParametersAreNonnullByDefault -package org.sonar.db.dependency; +package org.sonar.ce.task.telemetry; import javax.annotation.ParametersAreNonnullByDefault; + diff --git a/server/sonar-ce-task/src/test/java/org/sonar/ce/task/step/ComputationStepExecutorTest.java b/server/sonar-ce-task/src/test/java/org/sonar/ce/task/step/ComputationStepExecutorTest.java index 6bc84c4b4e2..5ed7e5bbba0 100644 --- a/server/sonar-ce-task/src/test/java/org/sonar/ce/task/step/ComputationStepExecutorTest.java +++ b/server/sonar-ce-task/src/test/java/org/sonar/ce/task/step/ComputationStepExecutorTest.java @@ -29,6 +29,7 @@ import org.sonar.api.testfixtures.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; import org.sonar.ce.task.CeTaskInterrupter; import org.sonar.ce.task.ChangeLogLevel; +import org.sonar.ce.task.telemetry.MutableStepsTelemetryHolder; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -45,14 +46,26 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; public class ComputationStepExecutorTest { - @Rule - public LogTester logTester = new LogTester(); - private final ComputationStepExecutor.Listener listener = mock(ComputationStepExecutor.Listener.class); + private final MutableStepsTelemetryHolder stepsTelemetryHolder = new TestComputationStepContext.TestTelemetryMetrics(); private final CeTaskInterrupter taskInterrupter = mock(CeTaskInterrupter.class); private final ComputationStep computationStep1 = mockComputationStep("step1"); private final ComputationStep computationStep2 = mockComputationStep("step2"); private final ComputationStep computationStep3 = mockComputationStep("step3"); + @Rule + public LogTester logTester = new LogTester(); + + private static ComputationSteps mockComputationSteps(ComputationStep... computationSteps) { + ComputationSteps steps = mock(ComputationSteps.class); + when(steps.instances()).thenReturn(Arrays.asList(computationSteps)); + return steps; + } + + private static ComputationStep mockComputationStep(String desc) { + ComputationStep mock = mock(ComputationStep.class); + when(mock.getDescription()).thenReturn(desc); + return mock; + } @Test public void execute_call_execute_on_each_ComputationStep_in_order_returned_by_instances_method() { @@ -70,6 +83,32 @@ public class ComputationStepExecutorTest { } @Test + public void execute_call_execute_on_ComputationStepWithTelemetryMetricOnly() { + ComputationStep step = new StepWithTelemetryMetricOnly("Step", "step.foo", "100", "step.bar", "20"); + + new ComputationStepExecutor(mockComputationSteps(step), taskInterrupter, stepsTelemetryHolder, listener) + .execute(); + + assertThat(stepsTelemetryHolder.getTelemetryMetrics()).containsEntry("prefix.step.foo", "100"); + assertThat(stepsTelemetryHolder.getTelemetryMetrics()).containsEntry("prefix.step.bar", "20"); + } + + @Test + public void execute_call_execute_on_ComputationStepWithTelemetryWithStatistic() { + ComputationStep step = new StepWithTelemetrywithStatistic("Step", "step.foo", "100", "step.bar", "20"); + + new ComputationStepExecutor(mockComputationSteps(step), taskInterrupter, stepsTelemetryHolder, listener) + .execute(); + + assertThat(stepsTelemetryHolder.getTelemetryMetrics()).containsEntry("prefix.step.foo", "100"); + assertThat(stepsTelemetryHolder.getTelemetryMetrics()).containsEntry("prefix.step.bar", "20"); + List<String> infoLogs = logTester.logs(Level.INFO); + System.out.println("infoLogs = " + infoLogs); + assertThat(infoLogs).hasSize(1); + assertThat(infoLogs.get(0)).contains("Step | step.foo=100 | step.bar=20 | status=SUCCESS | time="); + } + + @Test public void execute_let_exception_thrown_by_ComputationStep_go_up_as_is() { String message = "Exception should go up"; @@ -182,7 +221,7 @@ public class ComputationStepExecutorTest { @Test public void execute_calls_listener_finished_method_with_all_step_runs() { - new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), taskInterrupter, listener) + new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), taskInterrupter, stepsTelemetryHolder, listener) .execute(); verify(listener).finished(true); @@ -197,7 +236,7 @@ public class ComputationStepExecutorTest { .execute(any()); try { - new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), taskInterrupter, listener) + new ComputationStepExecutor(mockComputationSteps(computationStep1, computationStep2), taskInterrupter, stepsTelemetryHolder, listener) .execute(); fail("exception toBeThrown should have been raised"); } catch (RuntimeException e) { @@ -214,7 +253,7 @@ public class ComputationStepExecutorTest { .when(listener) .finished(anyBoolean()); - new ComputationStepExecutor(mockComputationSteps(computationStep1), taskInterrupter, listener).execute(); + new ComputationStepExecutor(mockComputationSteps(computationStep1), taskInterrupter, stepsTelemetryHolder, listener).execute(); } @Test @@ -286,18 +325,6 @@ public class ComputationStepExecutorTest { } } - private static ComputationSteps mockComputationSteps(ComputationStep... computationSteps) { - ComputationSteps steps = mock(ComputationSteps.class); - when(steps.instances()).thenReturn(Arrays.asList(computationSteps)); - return steps; - } - - private static ComputationStep mockComputationStep(String desc) { - ComputationStep mock = mock(ComputationStep.class); - when(mock.getDescription()).thenReturn(desc); - return mock; - } - private static class StepWithStatistics implements ComputationStep { private final String description; private final String[] statistics; @@ -319,4 +346,48 @@ public class ComputationStepExecutorTest { return description; } } + + private static class StepWithTelemetryMetricOnly implements ComputationStep { + private final String description; + private final String[] metrics; + + private StepWithTelemetryMetricOnly(String description, String... metrics) { + this.description = description; + this.metrics = metrics; + } + + @Override + public void execute(Context context) { + for (int i = 0; i < metrics.length; i += 2) { + context.addTelemetryMetricOnly("prefix", metrics[i], metrics[i + 1]); + } + } + + @Override + public String getDescription() { + return description; + } + } + + private static class StepWithTelemetrywithStatistic implements ComputationStep { + private final String description; + private final String[] metrics; + + private StepWithTelemetrywithStatistic(String description, String... metrics) { + this.description = description; + this.metrics = metrics; + } + + @Override + public void execute(Context context) { + for (int i = 0; i < metrics.length; i += 2) { + context.addTelemetryWithStatistic("prefix", metrics[i], metrics[i + 1]); + } + } + + @Override + public String getDescription() { + return description; + } + } } diff --git a/server/sonar-ce-task/src/test/java/org/sonar/ce/task/telemetry/StepsTelemetryHolderImplTest.java b/server/sonar-ce-task/src/test/java/org/sonar/ce/task/telemetry/StepsTelemetryHolderImplTest.java new file mode 100644 index 00000000000..41883493f64 --- /dev/null +++ b/server/sonar-ce-task/src/test/java/org/sonar/ce/task/telemetry/StepsTelemetryHolderImplTest.java @@ -0,0 +1,63 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.ce.task.telemetry; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class StepsTelemetryHolderImplTest { + + private final StepsTelemetryHolderImpl stepsTelemetryHolderImpl = new StepsTelemetryHolderImpl(); + + @Test + void getTelemetryMetrics_shouldReturnEmptyMap() { + assertThat(stepsTelemetryHolderImpl.getTelemetryMetrics()).isEmpty(); + } + + @Test + void add_shouldAddValue() { + stepsTelemetryHolderImpl.add("key", "value"); + assertThat(stepsTelemetryHolderImpl.getTelemetryMetrics()).containsEntry("key", "value"); + } + + @Test + void add_shouldThrowNPEIfKeyIsNull() { + assertThatThrownBy(() -> stepsTelemetryHolderImpl.add(null, "value")) + .isInstanceOf(NullPointerException.class) + .hasMessage("Metric has null key"); + } + + @Test + void add_shouldThrowNPEIfValueIsNull() { + assertThatThrownBy(() -> stepsTelemetryHolderImpl.add("key", null)) + .isInstanceOf(NullPointerException.class) + .hasMessage("Metric with key [key] has null value"); + } + + @Test + void add_shouldThrowIAEIfKeyIsAlreadyPresent() { + stepsTelemetryHolderImpl.add("key", "value"); + assertThatThrownBy(() -> stepsTelemetryHolderImpl.add("key", "value")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Metric with key [key] is already present"); + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v101/DbVersion101Test.java b/server/sonar-ce-task/src/test/java/org/sonar/ce/task/telemetry/StepsTelemetryUnavailableHolderImplTest.java index 40862058dad..b3f3224d747 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v101/DbVersion101Test.java +++ b/server/sonar-ce-task/src/test/java/org/sonar/ce/task/telemetry/StepsTelemetryUnavailableHolderImplTest.java @@ -17,24 +17,23 @@ * 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.platform.db.migration.version.v101; +package org.sonar.ce.task.telemetry; -import org.junit.Test; +import org.junit.jupiter.api.Test; -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationNotEmpty; -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber; +import static org.junit.jupiter.api.Assertions.assertThrows; -public class DbVersion101Test { - private final DbVersion101 underTest = new DbVersion101(); +class StepsTelemetryUnavailableHolderImplTest { + + private final StepsTelemetryUnavailableHolderImpl stepsTelemetryUnavailableHolderImpl = new StepsTelemetryUnavailableHolderImpl(); @Test - public void migrationNumber_starts_at_10_1_000() { - verifyMinimumMigrationNumber(underTest, 10_1_000); + void getTelemetryMetrics_shouldThrowUnsupportedOperationException() { + assertThrows(UnsupportedOperationException.class, stepsTelemetryUnavailableHolderImpl::getTelemetryMetrics); } @Test - public void verify_migration_is_not_empty() { - verifyMigrationNotEmpty(underTest); + void add_shouldThrowUnsupportedOperationException() { + assertThrows(UnsupportedOperationException.class, () -> stepsTelemetryUnavailableHolderImpl.add("key", "value")); } - } diff --git a/server/sonar-ce-task/src/testFixtures/java/org/sonar/ce/task/step/TestComputationStepContext.java b/server/sonar-ce-task/src/testFixtures/java/org/sonar/ce/task/step/TestComputationStepContext.java index 07bbec22c3d..3781d658035 100644 --- a/server/sonar-ce-task/src/testFixtures/java/org/sonar/ce/task/step/TestComputationStepContext.java +++ b/server/sonar-ce-task/src/testFixtures/java/org/sonar/ce/task/step/TestComputationStepContext.java @@ -20,8 +20,11 @@ package org.sonar.ce.task.step; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; import javax.annotation.Nullable; +import org.sonar.ce.task.telemetry.MutableStepsTelemetryHolder; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; @@ -33,12 +36,37 @@ import static org.assertj.core.api.Assertions.assertThat; public class TestComputationStepContext implements ComputationStep.Context { private final TestStatistics statistics = new TestStatistics(); + private final TestTelemetryMetrics metrics = new TestTelemetryMetrics(); + + private static String prependPrefix(@Nullable String prefix, String key) { + if (prefix == null) { + return key; + } else { + return prefix + "." + key; + } + } @Override public TestStatistics getStatistics() { return statistics; } + @Override + public void addTelemetryMetricOnly(String telemetryPrefix, String key, Object value) { + metrics.add(prependPrefix(telemetryPrefix, key), value); + } + + @Override + public void addTelemetryWithStatistic(String telemetryPrefix, String key, Object value) { + Objects.requireNonNull(telemetryPrefix); + metrics.add(prependPrefix(telemetryPrefix, key), value); + statistics.add(key, value); + } + + public Map<String, Object> getTelemetryMetrics() { + return metrics.getTelemetryMetrics(); + } + public static class TestStatistics implements ComputationStep.Statistics { private final Map<String, Object> map = new HashMap<>(); @@ -69,4 +97,34 @@ public class TestComputationStepContext implements ComputationStep.Context { return this; } } + + public static class TestTelemetryMetrics implements MutableStepsTelemetryHolder { + private final Map<String, Object> map = new LinkedHashMap<>(); + + public TestTelemetryMetrics add(String key, Object value) { + requireNonNull(key, "Metric has null key"); + requireNonNull(value, () -> String.format("Metric with key [%s] has null value", key)); + checkArgument(!map.containsKey(key), "Metric with key [%s] is already present", key); + map.put(key, value); + return this; + } + + @Override + public Map<String, Object> getTelemetryMetrics() { + return map; + } + + public Object get(String key) { + return requireNonNull(map.get(key)); + } + + public TestTelemetryMetrics assertValue(String key, @Nullable Object expectedValue) { + if (expectedValue == null) { + assertThat(map.get(key)).as(key).isNull(); + } else { + assertThat(map.get(key)).as(key).isEqualTo(expectedValue); + } + return this; + } + } } diff --git a/server/sonar-ce/build.gradle b/server/sonar-ce/build.gradle index ac8a5f9ed06..0e0a7269003 100644 --- a/server/sonar-ce/build.gradle +++ b/server/sonar-ce/build.gradle @@ -36,7 +36,7 @@ dependencies { testImplementation 'org.slf4j:slf4j-api' testImplementation 'org.sonarsource.api.plugin:sonar-plugin-api-test-fixtures' - testImplementation testFixtures(project(':server:sonar-db-dao')) + testImplementation testFixtures(project(':server:sonar-server-common')) testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' testRuntimeOnly 'org.junit.vintage:junit-vintage-engine' diff --git a/server/sonar-ce/src/it/java/org/sonar/ce/container/ComputeEngineContainerImplIT.java b/server/sonar-ce/src/it/java/org/sonar/ce/container/ComputeEngineContainerImplIT.java index c65b24fe75c..3259d670792 100644 --- a/server/sonar-ce/src/it/java/org/sonar/ce/container/ComputeEngineContainerImplIT.java +++ b/server/sonar-ce/src/it/java/org/sonar/ce/container/ComputeEngineContainerImplIT.java @@ -19,7 +19,6 @@ */ package org.sonar.ce.container; -import com.google.common.collect.ImmutableSet; import java.io.File; import java.io.IOException; import java.util.Date; @@ -27,10 +26,10 @@ import java.util.Locale; import java.util.Properties; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; import org.sonar.api.CoreProperties; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; @@ -40,13 +39,13 @@ import org.sonar.db.property.PropertyDto; import org.sonar.process.ProcessId; import org.sonar.process.ProcessProperties; import org.sonar.process.Props; +import org.sonar.server.extension.TestCoreExtension; import org.sonar.server.property.InternalProperties; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import static java.lang.String.valueOf; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import static org.sonar.process.ProcessEntryPoint.PROPERTY_PROCESS_INDEX; import static org.sonar.process.ProcessEntryPoint.PROPERTY_SHARED_PATH; import static org.sonar.process.ProcessProperties.Property.JDBC_PASSWORD; @@ -56,31 +55,30 @@ import static org.sonar.process.ProcessProperties.Property.PATH_DATA; import static org.sonar.process.ProcessProperties.Property.PATH_HOME; import static org.sonar.process.ProcessProperties.Property.PATH_TEMP; -public class ComputeEngineContainerImplIT { +class ComputeEngineContainerImplIT { - @Rule - public TemporaryFolder tempFolder = new TemporaryFolder(); - @Rule + @TempDir + private File tempFolder; - public DbTester db = DbTester.create(System2.INSTANCE); + @RegisterExtension + private DbTester db = DbTester.create(System2.INSTANCE); private final ServiceLoaderWrapper serviceLoaderWrapper = mock(ServiceLoaderWrapper.class); private final ProcessProperties processProperties = new ProcessProperties(serviceLoaderWrapper); private final ComputeEngineContainerImpl underTest = new ComputeEngineContainerImpl(); - @Before - public void setUp() { - when(serviceLoaderWrapper.load()).thenReturn(ImmutableSet.of()); + @BeforeEach + void setUp() { underTest.setComputeEngineStatus(mock(ComputeEngineStatus.class)); } @Test - public void constructor_does_not_create_container() { + void constructor_does_not_create_container() { assertThat(underTest.getComponentContainer()).isNull(); } @Test - public void test_real_start() throws IOException { + void whenStartingCeContainer_thenBeansAndExtensionsLoadTogether() throws IOException { Properties properties = getProperties(); // required persisted properties @@ -92,10 +90,19 @@ public class ComputeEngineContainerImplIT { AnnotationConfigApplicationContext context = underTest.getComponentContainer().context(); try { - assertThat(context.getBeanDefinitionNames()).hasSizeGreaterThan(1); - assertThat(context.getParent().getBeanDefinitionNames()).hasSizeGreaterThan(1); - assertThat(context.getParent().getParent().getBeanDefinitionNames()).hasSizeGreaterThan(1); - assertThat(context.getParent().getParent().getParent().getBeanDefinitionNames()).hasSizeGreaterThan(1); + assertThat(context.getBeanDefinitionNames()).hasSizeGreaterThan(1) + .anyMatch(beanName -> beanName.endsWith("TestCoreExtension.TestBean4")); + assertThat(underTest.getComponentContainer().getOptionalComponentByType(TestCoreExtension.TestBean4.class)).isPresent(); + assertThat(context.getParent().getBeanDefinitionNames()).hasSizeGreaterThan(1) + .anyMatch(beanName -> beanName.endsWith("TestCoreExtension.TestBean3")); + assertThat(underTest.getComponentContainer().getOptionalComponentByType(TestCoreExtension.TestBean3.class)).isPresent(); + assertThat(context.getParent().getParent().getBeanDefinitionNames()).hasSizeGreaterThan(1) + .anyMatch(beanName -> beanName.endsWith("TestCoreExtension.TestBean2")); + assertThat(underTest.getComponentContainer().getOptionalComponentByType(TestCoreExtension.TestBean2.class)).isPresent(); + assertThat(context.getParent().getParent().getParent().getBeanDefinitionNames()).hasSizeGreaterThan(1) + .anyMatch(beanName -> beanName.endsWith("TestCoreExtension.TestBean1")); + assertThat(underTest.getComponentContainer().getOptionalComponentByType(TestCoreExtension.TestBean1.class)).isPresent() + .get().matches(tb -> tb.called, "mybatis extension has been called"); assertThat(context.getParent().getParent().getParent().getParent()).isNull(); } finally { underTest.stop(); @@ -113,10 +120,10 @@ public class ComputeEngineContainerImplIT { Props props = new Props(properties); processProperties.completeDefaults(props); properties = props.rawProperties(); - File homeDir = tempFolder.newFolder(); - File dataDir = new File(homeDir, "data"); + File homeDir = tempFolder; + File dataDir = new File(tempFolder, "data"); dataDir.mkdirs(); - File tmpDir = new File(homeDir, "tmp"); + File tmpDir = new File(tempFolder, "tmp"); tmpDir.mkdirs(); properties.setProperty(PATH_HOME.getKey(), homeDir.getAbsolutePath()); properties.setProperty(PATH_DATA.getKey(), dataDir.getAbsolutePath()); diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java index 05c2a8b7045..488102ba2e6 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java @@ -26,6 +26,7 @@ import javax.annotation.CheckForNull; import org.slf4j.LoggerFactory; import org.sonar.api.SonarEdition; import org.sonar.api.SonarQubeSide; +import org.sonar.api.SonarRuntime; import org.sonar.api.internal.MetadataLoader; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.server.profile.BuiltInQualityProfileAnnotationLoader; @@ -64,8 +65,8 @@ import org.sonar.core.extension.CoreExtensionRepositoryImpl; import org.sonar.core.extension.CoreExtensionsLoader; import org.sonar.core.language.LanguagesProvider; import org.sonar.core.metric.SoftwareQualitiesMetrics; -import org.sonar.core.platform.Container; import org.sonar.core.platform.EditionProvider; +import org.sonar.core.platform.ExtensionContainer; import org.sonar.core.platform.PlatformEditionProvider; import org.sonar.core.platform.PluginClassLoader; import org.sonar.core.platform.PluginClassloaderFactory; @@ -198,32 +199,17 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { private static void startLevel1(SpringComponentContainer level1) { level1.startComponents(); - level1.getComponentByType(CoreExtensionsLoader.class) - .load(); - level1.getComponentByType(CECoreExtensionsInstaller.class) - .install(level1, hasPlatformLevel(1), noAdditionalSideFilter()); } private static void startLevel2(SpringComponentContainer level2) { - level2.getParent().getComponentByType(CECoreExtensionsInstaller.class) - .install(level2, hasPlatformLevel(2), noAdditionalSideFilter()); - level2.startComponents(); } private static void startLevel3(SpringComponentContainer level3) { - level3.getParent().getComponentByType(CECoreExtensionsInstaller.class) - .install(level3, hasPlatformLevel(3), noAdditionalSideFilter()); - level3.startComponents(); } private static void startLevel4(SpringComponentContainer level4) { - level4.getParent().getComponentByType(CECoreExtensionsInstaller.class) - .install(level4, hasPlatformLevel4OrNone(), noAdditionalSideFilter()); - level4.getParent().getComponentByType(ServerExtensionInstaller.class) - .installExtensions(level4); - level4.startComponents(); PlatformEditionProvider editionProvider = level4.getComponentByType(PlatformEditionProvider.class); @@ -270,16 +256,18 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { return level4; } - private static void populateLevel1(Container container, Props props, ComputeEngineStatus computeEngineStatus) { + private static void populateLevel1(SpringComponentContainer level1Container, Props props, ComputeEngineStatus computeEngineStatus) { Version apiVersion = MetadataLoader.loadApiVersion(System2.INSTANCE); Version sqVersion = MetadataLoader.loadSQVersion(System2.INSTANCE); SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE); - container.add( + SonarRuntime sonarRuntime = SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.COMPUTE_ENGINE, edition); + + level1Container.add( props.rawProperties(), ThreadLocalSettings.class, new ConfigurationProvider(), new SonarQubeVersion(sqVersion), - SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.COMPUTE_ENGINE, edition), + sonarRuntime, CeProcessLogging.class, UuidFactoryImpl.INSTANCE, NetworkUtilsImpl.INSTANCE, @@ -310,16 +298,25 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { computeEngineStatus, NoOpAuditPersister.class, - DefaultDocumentationLinkGenerator.class, + DefaultDocumentationLinkGenerator.class); + level1Container.add(toArray(CorePropertyDefinitions.all())); - CoreExtensionRepositoryImpl.class, - CoreExtensionsLoader.class, - CECoreExtensionsInstaller.class); - container.add(toArray(CorePropertyDefinitions.all())); + addCoreExtensionMechanism(level1Container, sonarRuntime); } - private static void populateLevel2(Container container) { - container.add( + private static void addCoreExtensionMechanism(SpringComponentContainer level1Container, SonarRuntime sonarRuntime) { + var coreExtensionRepository = new CoreExtensionRepositoryImpl(); + var coreExtensionsLoader = new CoreExtensionsLoader(coreExtensionRepository); + var ceCoreExtensionsInstaller = new CECoreExtensionsInstaller(sonarRuntime, coreExtensionRepository); + + level1Container.add(coreExtensionRepository, coreExtensionsLoader, ceCoreExtensionsInstaller); + + coreExtensionsLoader.load(); + ceCoreExtensionsInstaller.install(level1Container, hasPlatformLevel(1), noAdditionalSideFilter()); + } + + private static void populateLevel2(ExtensionContainer level2Container) { + level2Container.add( new MigrationConfigurationModule(), DatabaseVersion.class, DatabaseCompatibility.class, @@ -340,20 +337,29 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { ServerI18n.class, // used by RuleI18nManager Durations.class // used in Web Services and DebtCalculator ); + + level2Container.getParent().getOptionalComponentByType(CECoreExtensionsInstaller.class) + .orElseThrow(() -> new IllegalStateException("Core extension loading mechanism is not available")) + .install(level2Container, hasPlatformLevel(2), noAdditionalSideFilter()); } - private static void populateLevel3(Container container) { - container.add( + private static void populateLevel3(SpringComponentContainer level3Container) { + level3Container.add( new StartupMetadataProvider(), JdbcUrlSanitizer.class, ServerIdChecksum.class, UriReader.class, ServerImpl.class, SynchronousAsyncExecution.class); + + level3Container.getParent().getOptionalComponentByType(CECoreExtensionsInstaller.class) + .orElseThrow(() -> new IllegalStateException("Core extension loading mechanism is not available")) + .install(level3Container, hasPlatformLevel(3), noAdditionalSideFilter()); + } - private static void populateLevel4(Container container, Props props) { - container.add( + private static void populateLevel4(SpringComponentContainer level4Container, Props props) { + level4Container.add( RuleDescriptionFormatter.class, ComponentTypes.class, DefaultComponentTypes.get(), @@ -454,7 +460,7 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { ); if (props.valueAsBoolean(CLUSTER_ENABLED.getKey())) { - container.add( + level4Container.add( new CeCleaningModule(), // system health @@ -465,11 +471,19 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { DistributedServerLogging.class, ProcessInfoProvider.class); } else { - container.add( + level4Container.add( new CeCleaningModule(), ServerLogging.class, StandaloneCeDistributedInformation.class); } + + level4Container.getParent().getOptionalComponentByType(CECoreExtensionsInstaller.class) + .orElseThrow(() -> new IllegalStateException("Core extension loading mechanism is not available")) + .install(level4Container, hasPlatformLevel4OrNone(), noAdditionalSideFilter()); + + level4Container.getParent().getOptionalComponentByType(ServerExtensionInstaller.class) + .orElseThrow(() -> new IllegalStateException("Core extension loading mechanism is not available")) + .installExtensions(level4Container); } private static Object[] startupComponents() { diff --git a/server/sonar-db-core/build.gradle b/server/sonar-db-core/build.gradle index 9353704a08e..af766e406c0 100644 --- a/server/sonar-db-core/build.gradle +++ b/server/sonar-db-core/build.gradle @@ -15,7 +15,6 @@ dependencies { api 'com.zaxxer:HikariCP' api 'org.mybatis:mybatis' api 'org.slf4j:slf4j-api' - api 'org.sonarsource.api.plugin:sonar-plugin-api' api project(':server:sonar-process') api project(':sonar-plugin-api-impl') diff --git a/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java b/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java index e6eddb97db9..8f54baa76c7 100644 --- a/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java +++ b/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java @@ -36,6 +36,7 @@ public final class SqTables { "analysis_properties", "app_branch_project_branch", "app_projects", + "architecture_graphs", "audits", "ce_activity", "ce_queue", @@ -107,6 +108,11 @@ public final class SqTables { "rules_parameters", "rules_profiles", "rule_repositories", + "sca_dependencies", + "sca_issues", + "sca_issues_releases", + "sca_releases", + "sca_vulnerability_issues", "scanner_analysis_cache", "schema_migrations", "scim_groups", diff --git a/server/sonar-db-core/src/testFixtures/java/org/sonar/db/AbstractDbTester.java b/server/sonar-db-core/src/testFixtures/java/org/sonar/db/AbstractDbTester.java index db50e01a56d..737e076950e 100644 --- a/server/sonar-db-core/src/testFixtures/java/org/sonar/db/AbstractDbTester.java +++ b/server/sonar-db-core/src/testFixtures/java/org/sonar/db/AbstractDbTester.java @@ -78,10 +78,13 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { private static final Pattern INDEX_NAME_PATTERN = Pattern.compile("COALESCE\\(([\\w_]*),"); + private static final Map<Integer, Integer> H2_TYPE_SUBSTITUTION = Map.of( + DECIMAL, DOUBLE); private static final Map<Integer, Integer> POSTGRES_TYPE_SUBSTITUTION = Map.of( BOOLEAN, BIT, DOUBLE, NUMERIC, - CLOB, VARCHAR); + CLOB, VARCHAR, + DECIMAL, NUMERIC); private static final Map<Integer, Integer> MSSQL_TYPE_SUBSTITUTION = Map.of( BOOLEAN, BIT, VARCHAR, NVARCHAR, @@ -91,7 +94,8 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { BOOLEAN, NUMERIC, BIGINT, NUMERIC, INTEGER, NUMERIC, - DOUBLE, NUMERIC); + DOUBLE, NUMERIC, + DECIMAL, NUMERIC); protected final T db; @@ -123,7 +127,7 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { public void executeDdl(String ddl) { try (Connection connection = getConnection(); - Statement stmt = connection.createStatement()) { + Statement stmt = connection.createStatement()) { stmt.execute(ddl); } catch (SQLException e) { throw new IllegalStateException("Failed to execute DDL: " + ddl, e); @@ -162,10 +166,10 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { } String sql = "insert into " + table.toLowerCase(Locale.ENGLISH) + " (" + - COMMA_JOINER.join(valuesByColumn.keySet().stream().map(t -> t.toLowerCase(Locale.ENGLISH)).toArray(String[]::new)) + - ") values (" + - COMMA_JOINER.join(Collections.nCopies(valuesByColumn.size(), '?')) + - ")"; + COMMA_JOINER.join(valuesByColumn.keySet().stream().map(t -> t.toLowerCase(Locale.ENGLISH)).toArray(String[]::new)) + + ") values (" + + COMMA_JOINER.join(Collections.nCopies(valuesByColumn.size(), '?')) + + ")"; executeUpdateSql(sql, valuesByColumn.values().toArray(new Object[valuesByColumn.size()])); } @@ -288,7 +292,7 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { public void assertColumnDefinition(String table, String column, int expectedType, @Nullable Integer expectedSize, @Nullable Boolean isNullable) { try (Connection connection = getConnection(); - ResultSet rs = connection.getMetaData().getColumns(null, null, toVendorCase(table), toVendorCase(column))) { + ResultSet rs = connection.getMetaData().getColumns(null, null, toVendorCase(table), toVendorCase(column))) { boolean exists = false; while (rs.next()) { @@ -314,6 +318,7 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { private int getDBType(int expectedType) { return switch (db.getDatabase().getDialect().getId()) { + case H2.ID -> H2_TYPE_SUBSTITUTION.getOrDefault(expectedType, expectedType); case PostgreSql.ID -> POSTGRES_TYPE_SUBSTITUTION.getOrDefault(expectedType, expectedType); case MsSql.ID -> MSSQL_TYPE_SUBSTITUTION.getOrDefault(expectedType, expectedType); case Oracle.ID -> ORACLE_TYPE_SUBSTITUTION.getOrDefault(expectedType, expectedType); @@ -323,8 +328,8 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { public void assertColumnDoesNotExist(String table, String column) throws SQLException { try (Connection connection = getConnection(); - PreparedStatement stmt = connection.prepareStatement("select * from " + table); - ResultSet res = stmt.executeQuery()) { + PreparedStatement stmt = connection.prepareStatement("select * from " + table); + ResultSet res = stmt.executeQuery()) { assertThat(getColumnNames(res)).doesNotContain(column); } } @@ -362,7 +367,7 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { private void assertIndexImpl(String tableName, String indexName, boolean expectedUnique, String expectedColumn, String... expectedSecondaryColumns) { try (Connection connection = getConnection(); - ResultSet rs = connection.getMetaData().getIndexInfo(null, null, toVendorCase(tableName), false, false)) { + ResultSet rs = connection.getMetaData().getIndexInfo(null, null, toVendorCase(tableName), false, false)) { List<String> onColumns = new ArrayList<>(); while (rs.next()) { @@ -400,7 +405,7 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { */ public void assertIndexDoesNotExist(String tableName, String indexName) { try (Connection connection = getConnection(); - ResultSet rs = connection.getMetaData().getIndexInfo(null, null, tableName.toUpperCase(Locale.ENGLISH), false, false)) { + ResultSet rs = connection.getMetaData().getIndexInfo(null, null, tableName.toUpperCase(Locale.ENGLISH), false, false)) { List<String> indices = new ArrayList<>(); while (rs.next()) { if (rs.getString("INDEX_NAME") != null) { diff --git a/server/sonar-db-dao/build.gradle b/server/sonar-db-dao/build.gradle index 85ef382ae91..1fc05084c9c 100644 --- a/server/sonar-db-dao/build.gradle +++ b/server/sonar-db-dao/build.gradle @@ -60,6 +60,9 @@ test { task dumpSchema(type:JavaExec) { mainClass = 'org.sonar.db.dump.DumpSQSchema' classpath = sourceSets.test.runtimeClasspath + + outputs.file 'src/schema/schema-sq.ddl' + outputs.doNotCacheIf('Caching has not been enabled for the task.') { true } } tasks.check.dependsOn dumpSchema diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/dependency/ProjectDependenciesDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/dependency/ProjectDependenciesDaoIT.java deleted file mode 100644 index 2681decb717..00000000000 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/dependency/ProjectDependenciesDaoIT.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.dependency; - -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.Pagination; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ProjectData; - -import static org.assertj.core.api.Assertions.assertThat; - -class ProjectDependenciesDaoIT { - - private static final String PROJECT_BRANCH_UUID = "branchUuid"; - - @RegisterExtension - private final DbTester db = DbTester.create(System2.INSTANCE); - - private final ProjectDependenciesDao projectDependenciesDao = db.getDbClient().projectDependenciesDao(); - - @Test - void insert_shouldPersistProjectDependencies() { - var projectDependencyDto = new ProjectDependencyDto("projectUuid", "version", "includePaths", "packageManager", 1L, 2L); - - projectDependenciesDao.insert(db.getSession(), projectDependencyDto); - - List<Map<String, Object>> select = db.select(db.getSession(), "select * from project_dependencies"); - assertThat(select).hasSize(1); - Map<String, Object> stringObjectMap = select.get(0); - assertThat(stringObjectMap).containsExactlyInAnyOrderEntriesOf( - Map.of( - "uuid", projectDependencyDto.uuid(), - "version", projectDependencyDto.version(), - "include_paths", projectDependencyDto.includePaths(), - "package_manager", projectDependencyDto.packageManager(), - "created_at", projectDependencyDto.createdAt(), - "updated_at", projectDependencyDto.updatedAt()) - ); - } - - @Test - void deleteByUuid_shoudDeleteProjectDependencies() { - var projectDependencyDto = new ProjectDependencyDto("projectUuid", "version", "includePaths", "packageManager", 1L, 2L); - projectDependenciesDao.insert(db.getSession(), projectDependencyDto); - - projectDependenciesDao.deleteByUuid(db.getSession(), projectDependencyDto.uuid()); - - List<Map<String, Object>> select = db.select(db.getSession(), "select * from project_dependencies"); - assertThat(select).isEmpty(); - } - - @Test - void selectByQuery_shouldReturnProjectDependencies_whenQueryByBranchUuid() { - ProjectData projectData = db.components().insertPublicProject(); - var projectDependencyDto = new ProjectDependencyDto(projectData.getMainBranchComponent().uuid(), "version", "includePaths", "packageManager", 1L, 2L); - projectDependenciesDao.insert(db.getSession(), projectDependencyDto); - - ProjectDependenciesQuery projectDependenciesQuery = new ProjectDependenciesQuery(projectData.mainBranchUuid(), null); - List<ProjectDependencyDto> results = projectDependenciesDao.selectByQuery(db.getSession(), projectDependenciesQuery, Pagination.all()); - - assertThat(results).hasSize(1); - assertThat(results.get(0)).usingRecursiveComparison().isEqualTo(projectDependencyDto); - } - - @Test - void selectByQuery_shouldReturnPaginatedProjectDependencies() { - ProjectDependencyDto projectDependencyDto1 = insertProjectDependency("1"); - ProjectDependencyDto projectDependencyDto2 = insertProjectDependency("2"); - ProjectDependencyDto projectDependencyDto3 = insertProjectDependency("3"); - ProjectDependencyDto projectDependencyDto4 = insertProjectDependency("4"); - - ProjectDependenciesQuery projectDependenciesQuery = new ProjectDependenciesQuery(PROJECT_BRANCH_UUID, null); - List<ProjectDependencyDto> page1Results = projectDependenciesDao.selectByQuery(db.getSession(), projectDependenciesQuery, Pagination.forPage(1).andSize(2)); - List<ProjectDependencyDto> page2Results = projectDependenciesDao.selectByQuery(db.getSession(), projectDependenciesQuery, Pagination.forPage(2).andSize(2)); - - assertThat(page1Results).hasSize(2); - assertThat(page1Results.get(0)).usingRecursiveComparison().isEqualTo(projectDependencyDto1); - assertThat(page1Results.get(1)).usingRecursiveComparison().isEqualTo(projectDependencyDto2); - assertThat(page2Results).hasSize(2); - assertThat(page2Results.get(0)).usingRecursiveComparison().isEqualTo(projectDependencyDto3); - assertThat(page2Results.get(1)).usingRecursiveComparison().isEqualTo(projectDependencyDto4); - } - - @Test - void selectByQuery_shouldPartiallyMatchLongName_whenQueriedByText() { - ProjectDependencyDto projectDepSearched = insertProjectDependency("sEArched"); - insertProjectDependency("notWanted"); - ProjectDependencyDto projectDepSearchAsWell = insertProjectDependency("sEArchedAsWell"); - insertProjectDependency("notwantedeither"); - - ProjectDependenciesQuery projectDependenciesQuery = new ProjectDependenciesQuery(PROJECT_BRANCH_UUID, "long_nameSearCHed"); - List<ProjectDependencyDto> results = projectDependenciesDao.selectByQuery(db.getSession(), projectDependenciesQuery, Pagination.all()); - - assertThat(results).hasSize(2); - assertThat(results.get(0)).usingRecursiveComparison().isEqualTo(projectDepSearched); - assertThat(results.get(1)).usingRecursiveComparison().isEqualTo(projectDepSearchAsWell); - } - - @Test - void selectByQuery_shouldExactlyMatchKee_whenQueriedByText() { - ProjectDependencyDto projectDepSearched = insertProjectDependency("1", dto -> dto.setKey("keySearched")); - insertProjectDependency("2", dto -> dto.setKey("KEySearCHed")); - insertProjectDependency("3", dto -> dto.setKey("some_keySearched")); - - ProjectDependenciesQuery projectDependenciesQuery = new ProjectDependenciesQuery(PROJECT_BRANCH_UUID, "keySearched"); - List<ProjectDependencyDto> results = projectDependenciesDao.selectByQuery(db.getSession(), projectDependenciesQuery, Pagination.all()); - - assertThat(results).hasSize(1); - assertThat(results.get(0)).usingRecursiveComparison().isEqualTo(projectDepSearched); - } - - @Test - void update_shouldUpdateProjectDependency() { - ProjectDependencyDto projectDependencyDto = insertProjectDependency(); - ProjectDependencyDto updatedProjectDependency = - new ProjectDependencyDto(projectDependencyDto.uuid(), "updatedVersion", "updatedIncludePaths", "updatedPackageManager", 2L, 3L); - - projectDependenciesDao.update(db.getSession(), updatedProjectDependency); - - List<Map<String, Object>> select = db.select(db.getSession(), "select * from project_dependencies"); - assertThat(select).hasSize(1); - Map<String, Object> stringObjectMap = select.get(0); - assertThat(stringObjectMap).containsExactlyInAnyOrderEntriesOf( - Map.of( - "uuid", updatedProjectDependency.uuid(), - "version", updatedProjectDependency.version(), - "include_paths", updatedProjectDependency.includePaths(), - "package_manager", updatedProjectDependency.packageManager(), - "created_at", projectDependencyDto.createdAt(), - "updated_at", updatedProjectDependency.updatedAt()) - ); - } - - @Test - void countByQuery_shouldReturnTheTotalOfDependencies() { - insertProjectDependency("sEArched"); - insertProjectDependency("notWanted"); - insertProjectDependency("sEArchedAsWell"); - db.projectDependencies().insertProjectDependency("another_branch_uuid", "searched"); - - ProjectDependenciesQuery projectDependenciesQuery = new ProjectDependenciesQuery(PROJECT_BRANCH_UUID, "long_nameSearCHed"); - - assertThat(projectDependenciesDao.countByQuery(db.getSession(), projectDependenciesQuery)).isEqualTo(2); - assertThat(projectDependenciesDao.countByQuery(db.getSession(), new ProjectDependenciesQuery(PROJECT_BRANCH_UUID, null))).isEqualTo(3); - assertThat(projectDependenciesDao.countByQuery(db.getSession(), new ProjectDependenciesQuery("another_branch_uuid", null))).isEqualTo(1); - } - - private ProjectDependencyDto insertProjectDependency() { - return db.projectDependencies().insertProjectDependency(PROJECT_BRANCH_UUID); - } - - private ProjectDependencyDto insertProjectDependency(String suffix) { - return insertProjectDependency(suffix, null); - } - - private ProjectDependencyDto insertProjectDependency(String suffix, @Nullable Consumer<ComponentDto> dtoPopulator) { - return db.projectDependencies().insertProjectDependency(PROJECT_BRANCH_UUID, suffix, dtoPopulator); - } -} diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java index df3414b2cfc..a7b9260ba8a 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java @@ -42,7 +42,7 @@ import org.sonar.api.issue.Issue; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.db.DbSession; import org.sonar.db.DbTester; diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueMapperIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueMapperIT.java index 31bdb45c3af..2d85056e0c2 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueMapperIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueMapperIT.java @@ -38,7 +38,7 @@ import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.issue.Issue; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; import org.sonar.core.issue.FieldDiffs; diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/AuthorizationDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/AuthorizationDaoIT.java index e7816a9c29f..1e322841762 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/AuthorizationDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/AuthorizationDaoIT.java @@ -31,7 +31,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.util.Uuids; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -218,13 +217,13 @@ class AuthorizationDaoIT { @Test void keepAuthorizedEntityUuids_returns_empty_for_group_AnyOne_if_project_set_is_empty_on__project() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), null, ProjectPermission.USER)) .isEmpty(); } @Test void keepAuthorizedEntityUuids_returns_empty_for_user_if_project_set_is_empty_on__project() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), user.getUuid(), ProjectPermission.USER)) .isEmpty(); } @@ -234,7 +233,7 @@ class AuthorizationDaoIT { .mapToObj(i -> Integer.toString(3_562 + i)) .collect(Collectors.toSet()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomNonProjectsSet, null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomNonProjectsSet, null, ProjectPermission.USER)) .isEmpty(); } @@ -244,31 +243,31 @@ class AuthorizationDaoIT { .mapToObj(i -> Integer.toString(9_666 + i)) .collect(Collectors.toSet()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomNonProjectsSet, user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomNonProjectsSet, user.getUuid(), ProjectPermission.USER)) .isEmpty(); } @Test void keepAuthorizedEntityUuids_returns_any__project_for_group_AnyOne_without_any_permission_in_DB_and_permission_USER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, null, ProjectPermission.USER)) .containsAll(randomPublicEntityUuids); } @Test void keepAuthorizedEntityUuids_returns_any__project_for_user_without_any_permission_in_DB_and_permission_USER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, user.getUuid(), ProjectPermission.USER)) .containsAll(randomPublicEntityUuids); } @Test void keepAuthorizedEntityUuids_returns_any__project_for_group_AnyOne_without_any_permission_in_DB_and_permission_CODEVIEWER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, null, UserRole.CODEVIEWER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, null, ProjectPermission.CODEVIEWER)) .containsAll(randomPublicEntityUuids); } @Test void keepAuthorizedEntityUuids_returns_any__project_for_user_without_any_permission_in_DB_and_permission_CODEVIEWER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, user.getUuid(), UserRole.CODEVIEWER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, user.getUuid(), ProjectPermission.CODEVIEWER)) .containsAll(randomPublicEntityUuids); } @@ -335,25 +334,25 @@ class AuthorizationDaoIT { @Test void keepAuthorizedEntityUuids_returns_empty_for_user_on_private_project_without_any_permission_in_DB_and_permission_USER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, user.getUuid(), ProjectPermission.USER)) .isEmpty(); } @Test void keepAuthorizedEntityUuids_returns_empty_for_group_AnyOne_on_private_project_without_any_permission_in_DB_and_permission_USER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, null, ProjectPermission.USER)) .isEmpty(); } @Test void keepAuthorizedEntityUuids_returns_empty_for_user_on_private_project_without_any_permission_in_DB_and_permission_CODEVIEWER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, user.getUuid(), UserRole.CODEVIEWER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, user.getUuid(), ProjectPermission.CODEVIEWER)) .isEmpty(); } @Test void keepAuthorizedEntityUuids_returns_empty_for_group_AnyOne_on_private_project_without_any_permission_in_DB_and_permission_CODEVIEWER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, null, UserRole.CODEVIEWER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, null, ProjectPermission.CODEVIEWER)) .isEmpty(); } @@ -421,20 +420,20 @@ class AuthorizationDaoIT { ProjectDto project3 = db.components().insertPrivateProject().getProjectDto(); UserDto user = db.users().insertUser("u1"); GroupDto group = db.users().insertGroup(); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project2); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project3); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project2); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project3); db.users().insertMember(group, user); - db.users().insertEntityPermissionOnGroup(group, UserRole.USER, project1); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.USER, project1); assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project2.getUuid(), project3.getUuid()), user.getUuid(), - UserRole.USER)) + ProjectPermission.USER)) .containsOnly(project2.getUuid(), project3.getUuid()); // user does not have the role "admin" - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project2.getUuid()), user.getUuid(), UserRole.ADMIN)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project2.getUuid()), user.getUuid(), ProjectPermission.ADMIN)) .isEmpty(); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), user.getUuid(), UserRole.ADMIN)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), user.getUuid(), ProjectPermission.ADMIN)) .isEmpty(); } @@ -446,17 +445,17 @@ class AuthorizationDaoIT { UserDto user1 = db.users().insertUser("u1"); GroupDto group = db.users().insertGroup(); db.users().insertMembers(group, user1); - db.users().insertProjectPermissionOnUser(user1, UserRole.USER, project1); - db.users().insertEntityPermissionOnGroup(group, UserRole.USER, project2); - db.users().insertEntityPermissionOnGroup(group, UserRole.USER, project3); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.USER, project1); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.USER, project2); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.USER, project3); assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project2.getUuid(), project3.getUuid()), user1.getUuid(), - UserRole.USER)) + ProjectPermission.USER)) .containsOnly(project2.getUuid(), project3.getUuid()); // group does not have the role "admin" assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project2.getUuid(), project3.getUuid()), user1.getUuid(), - UserRole.ADMIN)) + ProjectPermission.ADMIN)) .isEmpty(); } @@ -468,7 +467,7 @@ class AuthorizationDaoIT { GroupDto group = db.users().insertGroup(); db.users().insertMembers(group, user1); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project1.getUuid(), project2.getUuid()), null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project1.getUuid(), project2.getUuid()), null, ProjectPermission.USER)) .containsOnly(project1.getUuid(), project2.getUuid()); // group does not have the role "admin" @@ -481,7 +480,7 @@ class AuthorizationDaoIT { List<ProjectDto> projects = IntStream.range(0, 2000).mapToObj(i -> db.components().insertPublicProject().getProjectDto()).toList(); Collection<String> uuids = projects.stream().map(ProjectDto::getUuid).collect(Collectors.toSet()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, uuids, null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, uuids, null, ProjectPermission.USER)) .containsOnly(uuids.toArray(new String[0])); } @@ -489,7 +488,7 @@ class AuthorizationDaoIT { void keepAuthorizedUsersForRoleAndEntity_returns_empty_if_user_set_is_empty_on__project() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, Collections.emptySet(), UserRole.USER, project.getUuid())) + assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, Collections.emptySet(), ProjectPermission.USER, project.getUuid())) .isEmpty(); } @@ -501,7 +500,7 @@ class AuthorizationDaoIT { .mapToObj(i -> Uuids.createFast()) .collect(Collectors.toSet()); - assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomNonExistingUserUuidsSet, UserRole.USER, project.getUuid())) + assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomNonExistingUserUuidsSet, ProjectPermission.USER, project.getUuid())) .isEmpty(); } @@ -509,7 +508,7 @@ class AuthorizationDaoIT { void keepAuthorizedUsersForRoleAndEntity_returns_any_users_for__project_without_any_permission_in_DB_and_permission_USER() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, UserRole.USER, project.getUuid())) + assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, ProjectPermission.USER, project.getUuid())) .containsAll(randomExistingUserUuids); } @@ -517,7 +516,7 @@ class AuthorizationDaoIT { void keepAuthorizedUsersForRoleAndEntity_returns_any_users_for__project_without_any_permission_in_DB_and_permission_CODEVIEWER() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, UserRole.CODEVIEWER, project.getUuid())) + assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, ProjectPermission.CODEVIEWER, project.getUuid())) .containsAll(randomExistingUserUuids); } @@ -591,7 +590,7 @@ class AuthorizationDaoIT { void keepAuthorizedUsersForRoleAndEntity_returns_empty_for_any_user_on_private_project_without_any_permission_in_DB_and_permission_USER() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, UserRole.USER, project.getUuid())) + assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, ProjectPermission.USER, project.getUuid())) .isEmpty(); } @@ -599,7 +598,7 @@ class AuthorizationDaoIT { void keepAuthorizedUsersForRoleAndEntity_returns_empty_for_any_user_on_private_project_without_any_permission_in_DB_and_permission_CODEVIEWER() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, UserRole.CODEVIEWER, project.getUuid())) + assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, ProjectPermission.CODEVIEWER, project.getUuid())) .isEmpty(); } @@ -667,10 +666,10 @@ class AuthorizationDaoIT { GroupDto group2 = db.users().insertGroup(); db.users().insertMembers(group1, user1, user2); db.users().insertMembers(group2, user3); - db.users().insertProjectPermissionOnUser(user1, UserRole.USER, project1); - db.users().insertProjectPermissionOnUser(user2, UserRole.USER, project1); - db.users().insertProjectPermissionOnUser(user3, UserRole.USER, project1); - db.users().insertEntityPermissionOnGroup(group2, UserRole.USER, project3); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.USER, project1); + db.users().insertProjectPermissionOnUser(user2, ProjectPermission.USER, project1); + db.users().insertProjectPermissionOnUser(user3, ProjectPermission.USER, project1); + db.users().insertEntityPermissionOnGroup(group2, ProjectPermission.USER, project3); assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, // Only 100 and 101 has 'user' role on project @@ -769,31 +768,31 @@ class AuthorizationDaoIT { @Test void selectEntityPermissions_returns_permissions_of_logged_in_user_on_specified_project() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, project); - db.users().insertProjectPermissionOnUser(db.users().insertUser(), UserRole.ISSUE_ADMIN, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, project); + db.users().insertProjectPermissionOnUser(db.users().insertUser(), ProjectPermission.ISSUE_ADMIN, project); - assertThat(underTest.selectEntityPermissions(dbSession, project.getUuid(), user.getUuid())).containsOnly(UserRole.CODEVIEWER); + assertThat(underTest.selectEntityPermissions(dbSession, project.getUuid(), user.getUuid())).containsOnly(ProjectPermission.CODEVIEWER.getKey()); } @Test void selectEntityPermissions_returns_permissions_of_logged_in_user_on_specified_project_through_group_membership() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertEntityPermissionOnGroup(group1, UserRole.CODEVIEWER, project); - db.users().insertEntityPermissionOnGroup(group2, UserRole.ISSUE_ADMIN, project); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.CODEVIEWER, project); + db.users().insertEntityPermissionOnGroup(group2, ProjectPermission.ISSUE_ADMIN, project); db.users().insertMember(group1, user); - assertThat(underTest.selectEntityPermissions(dbSession, project.getUuid(), user.getUuid())).containsOnly(UserRole.CODEVIEWER); + assertThat(underTest.selectEntityPermissions(dbSession, project.getUuid(), user.getUuid())).containsOnly(ProjectPermission.CODEVIEWER.getKey()); } @Test void selectEntityPermissions_returns_permissions_of_logged_in_user_on_specified_private_project_through_all_possible_configurations() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, project); - db.users().insertEntityPermissionOnGroup(group1, UserRole.USER, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, project); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.USER, project); db.users().insertMember(group1, user); - assertThat(underTest.selectEntityPermissions(dbSession, project.getUuid(), user.getUuid())).containsOnly(UserRole.CODEVIEWER, - UserRole.USER); + assertThat(underTest.selectEntityPermissions(dbSession, project.getUuid(), user.getUuid())).containsOnly(ProjectPermission.CODEVIEWER.getKey(), + ProjectPermission.USER.getKey()); } @Test @@ -918,14 +917,14 @@ class AuthorizationDaoIT { ProjectDto privateProject = db.components().insertPrivateProject().getProjectDto(); ProjectDto Project = db.components().insertPublicProject().getProjectDto(); UserDto user = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, privateProject); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, privateProject); assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(privateProject.getUuid(), Project.getUuid()), user.getUuid(), - UserRole.ADMIN)) + ProjectPermission.ADMIN)) .containsOnly(privateProject.getUuid()); // user does not have the permission "issueadmin" assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(privateProject.getUuid(), Project.getUuid()), user.getUuid(), - UserRole.ISSUE_ADMIN)) + ProjectPermission.ISSUE_ADMIN)) .isEmpty(); } @@ -936,14 +935,14 @@ class AuthorizationDaoIT { UserDto user = db.users().insertUser(); GroupDto group = db.users().insertGroup(); db.users().insertMember(group, user); - db.users().insertEntityPermissionOnGroup(group, UserRole.ADMIN, privateProject); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.ADMIN, privateProject); assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(privateProject.getUuid(), Project.getUuid()), user.getUuid(), - UserRole.ADMIN)) + ProjectPermission.ADMIN)) .containsOnly(privateProject.getUuid()); // user does not have the permission "issueadmin" assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(privateProject.getUuid(), Project.getUuid()), user.getUuid(), - UserRole.ISSUE_ADMIN)) + ProjectPermission.ISSUE_ADMIN)) .isEmpty(); } @@ -952,11 +951,11 @@ class AuthorizationDaoIT { ProjectDto Project = db.components().insertPublicProject().getProjectDto(); UserDto user = db.users().insertUser(); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), user.getUuid(), ProjectPermission.USER)) .isEmpty(); // projects do not exist - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet("does_not_exist"), user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet("does_not_exist"), user.getUuid(), ProjectPermission.USER)) .isEmpty(); } @@ -965,7 +964,7 @@ class AuthorizationDaoIT { ProjectDto Project = db.components().insertPublicProject().getProjectDto(); UserDto user = db.users().insertUser(); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet("does_not_exist"), user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet("does_not_exist"), user.getUuid(), ProjectPermission.USER)) .isEmpty(); } @@ -975,19 +974,19 @@ class AuthorizationDaoIT { UserDto user = db.users().insertUser(); // logged-in user - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), user.getUuid(), UserRole.CODEVIEWER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), user.getUuid(), ProjectPermission.CODEVIEWER)) .containsOnly(Project.getUuid()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), user.getUuid(), ProjectPermission.USER)) .containsOnly(Project.getUuid()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), user.getUuid(), UserRole.ADMIN)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), user.getUuid(), ProjectPermission.ADMIN)) .isEmpty(); // anonymous - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), null, UserRole.CODEVIEWER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), null, ProjectPermission.CODEVIEWER)) .containsOnly(Project.getUuid()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), null, ProjectPermission.USER)) .containsOnly(Project.getUuid()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), null, UserRole.ADMIN)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), null, ProjectPermission.ADMIN)) .isEmpty(); } @@ -1148,21 +1147,21 @@ class AuthorizationDaoIT { // admin with "direct" ADMIN role UserDto admin1 = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(admin1, UserRole.ADMIN, project); + db.users().insertProjectPermissionOnUser(admin1, ProjectPermission.ADMIN, project); // admin2 with ADMIN role through group UserDto admin2 = db.users().insertUser(); GroupDto adminGroup = db.users().insertGroup("ADMIN"); db.users().insertMember(adminGroup, admin2); - db.users().insertEntityPermissionOnGroup(adminGroup, UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(adminGroup, ProjectPermission.ADMIN, project); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin()), project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin()), project.getKey(), ProjectPermission.USER)) .containsOnly(user1.getLogin()); assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin(), admin1.getLogin(), admin2.getLogin()), - project.getKey(), UserRole.USER)) + project.getKey(), ProjectPermission.USER)) .containsOnly(user1.getLogin(), admin1.getLogin(), admin2.getLogin()); assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin(), admin1.getLogin(), admin2.getLogin()), - project.getKey(), UserRole.ADMIN)) + project.getKey(), ProjectPermission.ADMIN)) .containsOnly(admin1.getLogin(), admin2.getLogin()); } @@ -1172,12 +1171,12 @@ class AuthorizationDaoIT { GroupDto userGroup = db.users().insertGroup("USERS"); GroupDto adminGroup = db.users().insertGroup("ADMIN"); - db.users().insertEntityPermissionOnGroup(userGroup, UserRole.USER, project); - db.users().insertEntityPermissionOnGroup(adminGroup, UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(userGroup, ProjectPermission.USER, project); + db.users().insertEntityPermissionOnGroup(adminGroup, ProjectPermission.ADMIN, project); // admin with "direct" ADMIN role UserDto admin1 = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(admin1, UserRole.ADMIN, project); + db.users().insertProjectPermissionOnUser(admin1, ProjectPermission.ADMIN, project); // admin2 with ADMIN role through group UserDto admin2 = db.users().insertUser(); @@ -1185,7 +1184,7 @@ class AuthorizationDaoIT { // user1 with "direct" USER role UserDto user1 = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(user1, UserRole.USER, project); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.USER, project); // user2 with USER role through group UserDto user2 = db.users().insertUser(); @@ -1194,17 +1193,17 @@ class AuthorizationDaoIT { // user without role UserDto userWithNoRole = db.users().insertUser(); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(userWithNoRole.getLogin()), project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(userWithNoRole.getLogin()), project.getKey(), ProjectPermission.USER)) .isEmpty(); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin()), project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin()), project.getKey(), ProjectPermission.USER)) .containsOnly(user1.getLogin()); Set<String> allLogins = newHashSet(admin1.getLogin(), admin2.getLogin(), user1.getLogin(), user2.getLogin(), userWithNoRole.getLogin()); // Admin does not have the USER permission set - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), ProjectPermission.USER)) .containsOnly(user1.getLogin(), user2.getLogin()); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), UserRole.ADMIN)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), ProjectPermission.ADMIN)) .containsOnly(admin1.getLogin(), admin2.getLogin()); } @@ -1215,12 +1214,12 @@ class AuthorizationDaoIT { GroupDto userGroup = db.users().insertGroup("USERS"); GroupDto adminGroup = db.users().insertGroup("ADMIN"); - db.users().insertEntityPermissionOnGroup(userGroup, UserRole.USER, project); - db.users().insertEntityPermissionOnGroup(adminGroup, UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(userGroup, ProjectPermission.USER, project); + db.users().insertEntityPermissionOnGroup(adminGroup, ProjectPermission.ADMIN, project); // admin with "direct" ADMIN role UserDto admin1 = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(admin1, UserRole.ADMIN, project); + db.users().insertProjectPermissionOnUser(admin1, ProjectPermission.ADMIN, project); // admin2 with ADMIN role through group UserDto admin2 = db.users().insertUser(); @@ -1228,7 +1227,7 @@ class AuthorizationDaoIT { // user1 with "direct" USER role UserDto user1 = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(user1, UserRole.USER, project); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.USER, project); // user2 with USER role through group UserDto user2 = db.users().insertUser(); @@ -1237,17 +1236,17 @@ class AuthorizationDaoIT { // user without role UserDto userWithNoRole = db.users().insertUser(); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(userWithNoRole.getLogin()), project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(userWithNoRole.getLogin()), project.getKey(), ProjectPermission.USER)) .isEmpty(); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin()), project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin()), project.getKey(), ProjectPermission.USER)) .containsOnly(user1.getLogin()); Set<String> allLogins = newHashSet(admin1.getLogin(), admin2.getLogin(), user1.getLogin(), user2.getLogin(), userWithNoRole.getLogin()); // Admin does not have the USER permission set - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), ProjectPermission.USER)) .containsOnly(user1.getLogin(), user2.getLogin()); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), UserRole.ADMIN)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), ProjectPermission.ADMIN)) .containsOnly(admin1.getLogin(), admin2.getLogin()); } diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoIT.java index 9f640b326a0..04563dc062a 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoIT.java @@ -31,7 +31,6 @@ import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.audit.NoOpAuditPersister; @@ -70,19 +69,19 @@ class GroupPermissionDaoIT { ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project3 = db.components().insertPrivateProject().getProjectDto(); - db.users().insertEntityPermissionOnGroup(group1, UserRole.ISSUE_ADMIN, project1); - db.users().insertEntityPermissionOnGroup(group1, UserRole.ADMIN, project2); - db.users().insertEntityPermissionOnGroup(group2, UserRole.ADMIN, project2); - db.users().insertEntityPermissionOnGroup(group3, UserRole.ADMIN, project2); - db.users().insertEntityPermissionOnGroup(group1, UserRole.USER, project2); - db.users().insertEntityPermissionOnGroup(group1, UserRole.USER, project3); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.ISSUE_ADMIN, project1); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.ADMIN, project2); + db.users().insertEntityPermissionOnGroup(group2, ProjectPermission.ADMIN, project2); + db.users().insertEntityPermissionOnGroup(group3, ProjectPermission.ADMIN, project2); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.USER, project2); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.USER, project3); final List<CountPerEntityPermission> result = new ArrayList<>(); underTest.groupsCountByComponentUuidAndPermission(dbSession, asList(project2.getUuid(), project3.getUuid(), "789"), context -> result.add(context.getResultObject())); assertThat(result).hasSize(3); - assertThat(result).extracting("permission").containsOnly(UserRole.ADMIN, UserRole.USER); + assertThat(result).extracting("permission").containsOnly(ProjectPermission.ADMIN.getKey(), ProjectPermission.USER.getKey()); assertThat(result).extracting("entityUuid").containsOnly(project2.getUuid(), project3.getUuid()); assertThat(result).extracting("count").containsOnly(3, 1); } @@ -195,7 +194,7 @@ class GroupPermissionDaoIT { db.users().insertPermissionOnAnyone(GlobalPermission.PROVISION_PROJECTS); db.users().insertPermissionOnGroup(group1, GlobalPermission.SCAN); db.users().insertPermissionOnGroup(group3, GlobalPermission.ADMINISTER); - db.users().insertEntityPermissionOnGroup(group2, UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(group2, ProjectPermission.ADMIN, project); assertThat(underTest.selectGroupNamesByQuery(dbSession, newQuery().setPermission(GlobalPermission.SCAN.getKey()).build())).containsExactly(ANYONE, group1.getName()); @@ -247,8 +246,8 @@ class GroupPermissionDaoIT { db.users().insertEntityPermissionOnGroup(group1, GlobalPermission.SCAN.getKey(), project); db.users().insertEntityPermissionOnGroup(group1, GlobalPermission.PROVISION_PROJECTS.getKey(), project); - db.users().insertEntityPermissionOnGroup(group1, UserRole.ADMIN, anotherProject); - db.users().insertEntityPermissionOnGroup(group3, UserRole.SCAN, anotherProject); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.ADMIN, anotherProject); + db.users().insertEntityPermissionOnGroup(group3, ProjectPermission.SCAN, anotherProject); db.users().insertPermissionOnGroup(group2, GlobalPermission.SCAN); PermissionQuery.Builder builderOnComponent = newQuery() @@ -258,7 +257,7 @@ class GroupPermissionDaoIT { assertThat(underTest.selectGroupNamesByQuery(dbSession, builderOnComponent.setPermission(GlobalPermission.SCAN.getKey()).build())).containsOnlyOnce(group1.getName()); assertThat(underTest.selectGroupNamesByQuery(dbSession, - builderOnComponent.setPermission(UserRole.USER).build())).isEmpty(); + builderOnComponent.setPermission(ProjectPermission.USER).build())).isEmpty(); } @Test @@ -297,7 +296,7 @@ class GroupPermissionDaoIT { GroupDto group2 = db.users().insertGroup("Group-2"); ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertEntityPermissionOnGroup(group2, UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(group2, ProjectPermission.ADMIN, project); GroupDto group3 = db.users().insertGroup("Group-3"); db.users().insertPermissionOnGroup(group3, GlobalPermission.ADMINISTER); @@ -370,10 +369,10 @@ class GroupPermissionDaoIT { GroupDto group2 = db.users().insertGroup("Group-2"); ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - db.users().insertProjectPermissionOnGroup(group2, UserRole.USER, project); + db.users().insertProjectPermissionOnGroup(group2, ProjectPermission.USER, project); GroupDto group3 = db.users().insertGroup("Group-3"); - db.users().insertProjectPermissionOnGroup(group3, UserRole.USER, project); + db.users().insertProjectPermissionOnGroup(group3, ProjectPermission.USER, project); // Anyone group db.users().insertPermissionOnAnyone(GlobalPermission.SCAN); @@ -382,11 +381,11 @@ class GroupPermissionDaoIT { assertThat(underTest.selectByGroupUuids(dbSession, singletonList(group2.getUuid()), project.uuid())) .extracting(GroupPermissionDto::getGroupUuid, GroupPermissionDto::getRole, GroupPermissionDto::getEntityUuid) - .containsOnly(tuple(group2.getUuid(), UserRole.USER, project.uuid())); + .containsOnly(tuple(group2.getUuid(), ProjectPermission.USER.getKey(), project.uuid())); assertThat(underTest.selectByGroupUuids(dbSession, singletonList(group3.getUuid()), project.uuid())) .extracting(GroupPermissionDto::getGroupUuid, GroupPermissionDto::getRole, GroupPermissionDto::getEntityUuid) - .containsOnly(tuple(group3.getUuid(), UserRole.USER, project.uuid())); + .containsOnly(tuple(group3.getUuid(), ProjectPermission.USER.getKey(), project.uuid())); assertThat(underTest.selectByGroupUuids(dbSession, singletonList(ANYONE_UUID), project.uuid())) .isEmpty(); @@ -527,7 +526,7 @@ class GroupPermissionDaoIT { GroupDto group = db.users().insertGroup(); db.users().insertProjectPermissionOnGroup(group, "foo", project.getMainBranchComponent()); - assertThat(underTest.selectGroupUuidsWithPermissionOnEntityBut(dbSession, "1234", UserRole.USER)) + assertThat(underTest.selectGroupUuidsWithPermissionOnEntityBut(dbSession, "1234", ProjectPermission.USER)) .isEmpty(); } diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoWithPersisterIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoWithPersisterIT.java index e81f33a54de..51c7d24aa3d 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoWithPersisterIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoWithPersisterIT.java @@ -38,8 +38,8 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; -import static org.sonar.api.web.UserRole.ADMIN; import static org.sonar.core.util.SequenceUuidFactory.UUID_1; +import static org.sonar.db.permission.ProjectPermission.ADMIN; class GroupPermissionDaoWithPersisterIT { private final AuditPersister auditPersister = mock(AuditPersister.class); @@ -100,7 +100,7 @@ class GroupPermissionDaoWithPersisterIT { verify(auditPersister).deleteGroupPermission(eq(dbSession), newValueCaptor.capture()); newValue = newValueCaptor.getValue(); - assertNewValue(newValue, null, null, null, project.projectUuid(), null, project.projectKey(), project.getProjectDto().getName(), "TRK"); + assertNewValue(newValue, null, null, null, project.projectUuid(), (String) null, project.projectKey(), project.getProjectDto().getName(), "TRK"); assertThat(newValue).hasToString("{\"componentUuid\": \"projectUuid\", \"componentKey\": \"cKey\", \"componentName\": \"cname\", " + "\"qualifier\": \"project\" }"); } @@ -132,7 +132,7 @@ class GroupPermissionDaoWithPersisterIT { verify(auditPersister).deleteGroupPermission(eq(dbSession), newValueCaptor.capture()); newValue = newValueCaptor.getValue(); - assertNewValue(newValue, null, null, null, project.projectUuid(), null, project.projectKey(), project.getProjectDto().getName(), "TRK"); + assertNewValue(newValue, null, null, null, project.projectUuid(), (String) null, project.projectKey(), project.getProjectDto().getName(), "TRK"); assertThat(newValue).hasToString("{\"componentUuid\": \"projectUuid\", \"componentKey\": \"cKey\", " + "\"componentName\": \"cname\", \"qualifier\": \"project\" }"); } @@ -181,6 +181,12 @@ class GroupPermissionDaoWithPersisterIT { } private void assertNewValue(GroupPermissionNewValue newValue, String uuid, String groupUuid, String groupName, String cUuid, + ProjectPermission permission, + String componentKey, String cName, String qualifier) { + assertNewValue(newValue, uuid, groupUuid, groupName, cUuid, permission.getKey(), componentKey, cName, qualifier); + } + + private void assertNewValue(GroupPermissionNewValue newValue, String uuid, String groupUuid, String groupName, String cUuid, String permission, String componentKey, String cName, String qualifier) { assertThat(newValue) diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/UserPermissionDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/UserPermissionDaoIT.java index 1162a9e3778..34a7122ab06 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/UserPermissionDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/UserPermissionDaoIT.java @@ -30,7 +30,6 @@ import org.assertj.core.groups.Tuple; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.util.Uuids; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -68,7 +67,7 @@ class UserPermissionDaoIT { UserPermissionDto global1 = addGlobalPermission(GlobalPermission.ADMINISTER.getKey(), user1); UserPermissionDto global2 = addGlobalPermission(GlobalPermission.ADMINISTER.getKey(), user2); UserPermissionDto global3 = addGlobalPermission(GlobalPermission.PROVISION_PROJECTS.getKey(), user2); - UserPermissionDto project1Perm = addProjectPermission(UserRole.USER, user3, project); + UserPermissionDto project1Perm = addProjectPermission(ProjectPermission.USER, user3, project); // global permissions of users who has at least one global permission, ordered by user name then permission PermissionQuery query = PermissionQuery.builder().withAtLeastOnePermission().build(); @@ -117,10 +116,10 @@ class UserPermissionDaoIT { addGlobalPermission(GlobalPermission.ADMINISTER.getKey(), user1); ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); - UserPermissionDto perm1 = addProjectPermission(UserRole.USER, user1, project1); - UserPermissionDto perm2 = addProjectPermission(UserRole.ISSUE_ADMIN, user1, project1); - UserPermissionDto perm3 = addProjectPermission(UserRole.ISSUE_ADMIN, user2, project1); - addProjectPermission(UserRole.ISSUE_ADMIN, user3, project2); + UserPermissionDto perm1 = addProjectPermission(ProjectPermission.USER, user1, project1); + UserPermissionDto perm2 = addProjectPermission(ProjectPermission.ISSUE_ADMIN, user1, project1); + UserPermissionDto perm3 = addProjectPermission(ProjectPermission.ISSUE_ADMIN, user2, project1); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user3, project2); // project permissions of users who has at least one permission on this project PermissionQuery query = PermissionQuery.builder().withAtLeastOnePermission().setEntity(project1).build(); @@ -135,7 +134,7 @@ class UserPermissionDaoIT { expectPermissions(query, asList(user2.getUuid(), user1.getUuid()), perm3, perm2, perm1); // search by user name (matches 2 users) and project permission - query = PermissionQuery.builder().setSearchQuery("Mari").setPermission(UserRole.ISSUE_ADMIN).setEntity(project1).build(); + query = PermissionQuery.builder().setSearchQuery("Mari").setPermission(ProjectPermission.ISSUE_ADMIN).setEntity(project1).build(); expectPermissions(query, asList(user2.getUuid(), user1.getUuid()), perm3, perm2); // search by user name (no match) @@ -208,9 +207,9 @@ class UserPermissionDaoIT { UserDto user2 = insertUser(u -> u.setLogin("login2").setName("A").setEmail("email2@email.com")); addGlobalPermission(GlobalPermission.ADMINISTER.getKey(), user1); ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); - addProjectPermission(UserRole.USER, user2, project1); - addProjectPermission(UserRole.USER, user1, project1); - addProjectPermission(UserRole.ADMIN, user1, project1); + addProjectPermission(ProjectPermission.USER, user2, project1); + addProjectPermission(ProjectPermission.USER, user1, project1); + addProjectPermission(ProjectPermission.ADMIN, user1, project1); PermissionQuery query = PermissionQuery.builder().build(); @@ -226,24 +225,24 @@ class UserPermissionDaoIT { ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); addGlobalPermission(GlobalPermission.ADMINISTER.getKey(), user1); - addProjectPermission(UserRole.USER, user1, project1); - addProjectPermission(UserRole.ISSUE_ADMIN, user1, project1); - addProjectPermission(UserRole.ISSUE_ADMIN, user2, project1); - addProjectPermission(UserRole.ISSUE_ADMIN, user2, project2); + addProjectPermission(ProjectPermission.USER, user1, project1); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user1, project1); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user2, project1); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user2, project2); // no projects -> return empty list assertThat(underTest.countUsersByEntityPermission(dbSession, emptyList())).isEmpty(); // one project expectCount(singletonList(project1.getUuid()), - new CountPerEntityPermission(project1.getUuid(), UserRole.USER, 1), - new CountPerEntityPermission(project1.getUuid(), UserRole.ISSUE_ADMIN, 2)); + new CountPerEntityPermission(project1.getUuid(), ProjectPermission.USER, 1), + new CountPerEntityPermission(project1.getUuid(), ProjectPermission.ISSUE_ADMIN, 2)); // multiple projects expectCount(asList(project1.getUuid(), project2.getUuid(), "invalid"), - new CountPerEntityPermission(project1.getUuid(), UserRole.USER, 1), - new CountPerEntityPermission(project1.getUuid(), UserRole.ISSUE_ADMIN, 2), - new CountPerEntityPermission(project2.getUuid(), UserRole.ISSUE_ADMIN, 1)); + new CountPerEntityPermission(project1.getUuid(), ProjectPermission.USER, 1), + new CountPerEntityPermission(project1.getUuid(), ProjectPermission.ISSUE_ADMIN, 2), + new CountPerEntityPermission(project2.getUuid(), ProjectPermission.ISSUE_ADMIN, 1)); } @Test @@ -252,9 +251,9 @@ class UserPermissionDaoIT { UserDto user2 = insertUser(u -> u.setLogin("login2").setName("Marie").setEmail("email2@email.com")); ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); - addProjectPermission(UserRole.USER, user1, project1); - addProjectPermission(UserRole.USER, user2, project1); - addProjectPermission(UserRole.ISSUE_ADMIN, user2, project1); + addProjectPermission(ProjectPermission.USER, user1, project1); + addProjectPermission(ProjectPermission.USER, user2, project1); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user2, project1); // logins are ordered by user name: user2 ("Marie") then user1 ("Marius") PermissionQuery query = PermissionQuery.builder().setEntity(project1).withAtLeastOnePermission().build(); @@ -285,9 +284,9 @@ class UserPermissionDaoIT { UserDto user2 = insertUser(u -> u.setLogin("login2").setName("Marie").setEmail("email2@email.com")); ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); - addProjectPermission(UserRole.USER, user1, project1); + addProjectPermission(ProjectPermission.USER, user1, project1); addGlobalPermission(GlobalPermission.PROVISION_PROJECTS.getKey(), user1); - addProjectPermission(UserRole.ISSUE_ADMIN, user2, project2); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user2, project2); PermissionQuery query = PermissionQuery.builder().build(); List<String> result = underTest.selectUserUuidsByQueryAndScope(dbSession, query); @@ -302,9 +301,9 @@ class UserPermissionDaoIT { UserDto user2 = insertUser(u -> u.setLogin("login2").setName("Marie").setEmail("email2@email.com")); ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); - addProjectPermission(UserRole.USER, user1, project1); + addProjectPermission(ProjectPermission.USER, user1, project1); addGlobalPermission(GlobalPermission.PROVISION_PROJECTS.getKey(), user1); - addProjectPermission(UserRole.ISSUE_ADMIN, user2, project2); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user2, project2); PermissionQuery query = PermissionQuery.builder() .setEntity(project1) .build(); @@ -459,7 +458,7 @@ class UserPermissionDaoIT { UserDto user = insertUser(); db.users().insertProjectPermissionOnUser(user, "foo", project.getMainBranchComponent()); - assertThat(underTest.selectUserIdsWithPermissionOnEntityBut(dbSession, "1234", UserRole.USER)) + assertThat(underTest.selectUserIdsWithPermissionOnEntityBut(dbSession, "1234", ProjectPermission.USER.getKey())) .isEmpty(); } @@ -579,7 +578,8 @@ class UserPermissionDaoIT { assertThat(underTest.selectEntityPermissionsOfUser(dbSession, user1.getUuid(), project1.projectUuid())).isEmpty(); assertThat(underTest.selectEntityPermissionsOfUser(dbSession, user2.getUuid(), project1.projectUuid())).isEmpty(); assertThat(underTest.selectEntityPermissionsOfUser(dbSession, user1.getUuid(), project2.projectUuid())).containsOnly(GlobalPermission.SCAN.getKey()); - assertThat(underTest.selectEntityPermissionsOfUser(dbSession, user2.getUuid(), project2.projectUuid())).containsOnly(GlobalPermission.SCAN.getKey(), GlobalPermission.PROVISION_PROJECTS.getKey()); + assertThat(underTest.selectEntityPermissionsOfUser(dbSession, user2.getUuid(), project2.projectUuid())).containsOnly(GlobalPermission.SCAN.getKey(), + GlobalPermission.PROVISION_PROJECTS.getKey()); deletedCount = underTest.deleteEntityPermissionOfAnyUser(dbSession, GlobalPermission.SCAN.getKey(), project2.getProjectDto()); @@ -639,6 +639,10 @@ class UserPermissionDaoIT { return dto; } + private UserPermissionDto addProjectPermission(ProjectPermission permission, UserDto user, EntityDto project) { + return addProjectPermission(permission.getKey(), user, project); + } + private UserPermissionDto addProjectPermission(String permission, UserDto user, EntityDto project) { UserPermissionDto dto = new UserPermissionDto(Uuids.create(), permission, user.getUuid(), project.getUuid()); underTest.insert(dbSession, dto, project, user, null); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/GroupWithPermissionTemplateDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/GroupWithPermissionTemplateDaoIT.java index 382fbc885b6..4367f147b0c 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/GroupWithPermissionTemplateDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/GroupWithPermissionTemplateDaoIT.java @@ -25,7 +25,7 @@ import java.util.stream.IntStream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.permission.PermissionQuery; @@ -34,8 +34,8 @@ import org.sonar.db.user.GroupDto; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE; import static org.sonar.db.permission.PermissionQuery.builder; @@ -95,7 +95,7 @@ class GroupWithPermissionTemplateDaoIT { GroupDto group2 = db.users().insertGroup("B"); GroupDto group3 = db.users().insertGroup("C"); - permissionTemplateDbTester.addGroupToTemplate(template, group3, UserRole.USER); + permissionTemplateDbTester.addGroupToTemplate(template, group3, ProjectPermission.USER); PermissionQuery query = PermissionQuery.builder().build(); assertThat(underTest.selectGroupNamesByQueryAndTemplate(db.getSession(), query, template.getUuid())) @@ -108,7 +108,7 @@ class GroupWithPermissionTemplateDaoIT { IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> db.users().insertGroup("Group-" + i)); String lastGroupName = "Group-" + (DEFAULT_PAGE_SIZE + 1); - permissionTemplateDbTester.addGroupToTemplate(template, db.users().selectGroup(lastGroupName).get(), UserRole.USER); + permissionTemplateDbTester.addGroupToTemplate(template, db.users().selectGroup(lastGroupName).get(), ProjectPermission.USER); PermissionQuery query = PermissionQuery.builder().build(); assertThat(underTest.selectGroupNamesByQueryAndTemplate(db.getSession(), query, template.getUuid())) @@ -122,11 +122,11 @@ class GroupWithPermissionTemplateDaoIT { PermissionTemplateDto otherTemplate = permissionTemplateDbTester.insertTemplate(); IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> { GroupDto group = db.users().insertGroup("Group-" + i); - permissionTemplateDbTester.addGroupToTemplate(otherTemplate, group, UserRole.USER); + permissionTemplateDbTester.addGroupToTemplate(otherTemplate, group, ProjectPermission.USER); }); String lastGroupName = "Group-" + (DEFAULT_PAGE_SIZE + 1); - permissionTemplateDbTester.addGroupToTemplate(template, db.users().selectGroup(lastGroupName).get(), UserRole.USER); + permissionTemplateDbTester.addGroupToTemplate(template, db.users().selectGroup(lastGroupName).get(), ProjectPermission.USER); PermissionQuery query = PermissionQuery.builder().build(); assertThat(underTest.selectGroupNamesByQueryAndTemplate(db.getSession(), query, template.getUuid())) @@ -216,8 +216,8 @@ class GroupWithPermissionTemplateDaoIT { .extracting(PermissionTemplateGroupDto::getGroupUuid, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission) .containsOnly( - tuple(group1.getUuid(), "Group-1", USER), - tuple(group1.getUuid(), "Group-1", ADMIN)); + tuple(group1.getUuid(), "Group-1", USER.getKey()), + tuple(group1.getUuid(), "Group-1", ADMIN.getKey())); assertThat(underTest.selectGroupPermissionsByTemplateIdAndGroupNames(session, anotherTemplate.getUuid(), asList("Group-1"))) .extracting(PermissionTemplateGroupDto::getGroupUuid, PermissionTemplateGroupDto::getGroupName, @@ -229,7 +229,7 @@ class GroupWithPermissionTemplateDaoIT { .extracting(PermissionTemplateGroupDto::getGroupUuid, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission) .containsOnly( - tuple("Anyone", "Anyone", USER)); + tuple("Anyone", "Anyone", USER.getKey())); assertThat(underTest.selectGroupPermissionsByTemplateIdAndGroupNames(session, template.getUuid(), asList("Group-1", "Group-2", "Anyone"))).hasSize(3); @@ -258,15 +258,15 @@ class GroupWithPermissionTemplateDaoIT { .extracting(PermissionTemplateGroupDto::getGroupUuid, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission) .containsOnly( - tuple(group1.getUuid(), "Group-1", USER), - tuple(group1.getUuid(), "Group-1", ADMIN), + tuple(group1.getUuid(), "Group-1", USER.getKey()), + tuple(group1.getUuid(), "Group-1", ADMIN.getKey()), tuple(group2.getUuid(), "Group-2", PROVISION_PROJECTS.getKey())); assertThat(underTest.selectGroupPermissionsByTemplateUuid(session, anotherTemplate.getUuid())) .extracting(PermissionTemplateGroupDto::getGroupUuid, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission) .containsOnly( tuple(group1.getUuid(), "Group-1", PROVISION_PROJECTS.getKey()), - tuple("Anyone", "Anyone", USER)); + tuple("Anyone", "Anyone", USER.getKey())); assertThat(underTest.selectGroupPermissionsByTemplateUuid(session, "321")).isEmpty(); } diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoIT.java index ed49ce3fd1c..d275eb56563 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoIT.java @@ -24,7 +24,7 @@ import java.util.Optional; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.audit.NoOpAuditPersister; @@ -46,7 +46,7 @@ class PermissionTemplateCharacteristicDaoIT { void selectByTemplateId_filter_by_template_uuid() { PermissionTemplateCharacteristicDto templatePermission1 = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid1") - .setPermission(UserRole.ADMIN) + .setPermission(ProjectPermission.ADMIN) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(1_000_000_000L) @@ -54,7 +54,7 @@ class PermissionTemplateCharacteristicDaoIT { "template"); PermissionTemplateCharacteristicDto templatePermission2 = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid2") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("2") .setWithProjectCreator(false) .setCreatedAt(1_000_000_000L) @@ -62,7 +62,7 @@ class PermissionTemplateCharacteristicDaoIT { "template"); PermissionTemplateCharacteristicDto templatePermission3 = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid3") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("3") .setWithProjectCreator(false) .setCreatedAt(1_000_000_001L) @@ -71,7 +71,7 @@ class PermissionTemplateCharacteristicDaoIT { PermissionTemplateCharacteristicDto templatePermissionForAnotherTemplate = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid4") - .setPermission(UserRole.ADMIN) + .setPermission(ProjectPermission.ADMIN) .setTemplateUuid("42") .setWithProjectCreator(true) .setCreatedAt(1_000_000_000L) @@ -99,7 +99,7 @@ class PermissionTemplateCharacteristicDaoIT { void selectByPermissionAndTemplateId() { PermissionTemplateCharacteristicDto templatePermission1 = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid1") - .setPermission(UserRole.ADMIN) + .setPermission(ProjectPermission.ADMIN) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(1_000_000_000L) @@ -107,7 +107,7 @@ class PermissionTemplateCharacteristicDaoIT { "template"); underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid2") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(false) .setCreatedAt(1_000_000_000L) @@ -115,14 +115,14 @@ class PermissionTemplateCharacteristicDaoIT { "template"); underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid3") - .setPermission(UserRole.ADMIN) + .setPermission(ProjectPermission.ADMIN) .setTemplateUuid("42") .setWithProjectCreator(true) .setCreatedAt(1_000_000_000L) .setUpdatedAt(2_000_000_000L), "template"); - Optional<PermissionTemplateCharacteristicDto> result = underTest.selectByPermissionAndTemplateId(dbSession, UserRole.ADMIN, "1"); + Optional<PermissionTemplateCharacteristicDto> result = underTest.selectByPermissionAndTemplateId(dbSession, ProjectPermission.ADMIN, "1"); assertThat(result).isPresent(); assertThat(result.get()).isEqualToComparingFieldByField(templatePermission1); @@ -132,7 +132,7 @@ class PermissionTemplateCharacteristicDaoIT { void insert() { PermissionTemplateCharacteristicDto expectedResult = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(123_456_789L) @@ -149,7 +149,7 @@ class PermissionTemplateCharacteristicDaoIT { void update_only_change_with_project_creator_and_updated_at() { PermissionTemplateCharacteristicDto insertedDto = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(123_456_789L) @@ -177,7 +177,7 @@ class PermissionTemplateCharacteristicDaoIT { void fail_insert_if_created_at_is_equal_to_0() { PermissionTemplateCharacteristicDto characteristicDto = new PermissionTemplateCharacteristicDto() .setUuid("uuid") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(true) .setUpdatedAt(2_000_000_000L); @@ -189,7 +189,7 @@ class PermissionTemplateCharacteristicDaoIT { void fail_insert_if_updated_at_is_equal_to_0() { PermissionTemplateCharacteristicDto characteristicDto = new PermissionTemplateCharacteristicDto() .setUuid("uuid") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(2_000_000_000L); @@ -201,7 +201,7 @@ class PermissionTemplateCharacteristicDaoIT { @Test void fail_update_if_uuid_is_null() { PermissionTemplateCharacteristicDto characteristicDto = new PermissionTemplateCharacteristicDto() - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(123_456_789L) @@ -214,7 +214,7 @@ class PermissionTemplateCharacteristicDaoIT { void delete_by_permission_template_uuid() { underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid1") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(123_456_789L) @@ -222,7 +222,7 @@ class PermissionTemplateCharacteristicDaoIT { "template"); underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid2") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("2") .setWithProjectCreator(true) .setCreatedAt(123_456_789L) diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoWithPersisterIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoWithPersisterIT.java index 0d35817630b..e7890b25e6c 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoWithPersisterIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoWithPersisterIT.java @@ -23,7 +23,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.ArgumentCaptor; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.audit.AuditPersister; @@ -45,7 +45,7 @@ class PermissionTemplateCharacteristicDaoWithPersisterIT { @Test void insertPermissionTemplateCharacteristicIsPersisted() { - PermissionTemplateCharacteristicDto dto = getPermissionTemplateCharacteristic(UserRole.USER); + PermissionTemplateCharacteristicDto dto = getPermissionTemplateCharacteristic(ProjectPermission.USER); underTest.insert(session, dto, "template"); verify(auditPersister).addCharacteristicToPermissionTemplate(eq(session), newValueCaptor.capture()); @@ -59,9 +59,9 @@ class PermissionTemplateCharacteristicDaoWithPersisterIT { @Test void updatePermissionTemplateCharacteristicIsPersisted() { - underTest.insert(session, getPermissionTemplateCharacteristic(UserRole.USER), + underTest.insert(session, getPermissionTemplateCharacteristic(ProjectPermission.USER), "template"); - PermissionTemplateCharacteristicDto updated = getPermissionTemplateCharacteristic(UserRole.ADMIN); + PermissionTemplateCharacteristicDto updated = getPermissionTemplateCharacteristic(ProjectPermission.ADMIN); underTest.update(session, updated, "template"); verify(auditPersister).updateCharacteristicInPermissionTemplate(eq(session), newValueCaptor.capture()); @@ -73,10 +73,10 @@ class PermissionTemplateCharacteristicDaoWithPersisterIT { assertThat(newValue.toString()).contains("withProjectCreator"); } - private PermissionTemplateCharacteristicDto getPermissionTemplateCharacteristic(String role) { + private PermissionTemplateCharacteristicDto getPermissionTemplateCharacteristic(ProjectPermission role) { return new PermissionTemplateCharacteristicDto() .setUuid("uuid") - .setPermission(role) + .setPermission(role.getKey()) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(123_456_789L) diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoIT.java index 4e5edc3d579..24dcf253be2 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoIT.java @@ -26,13 +26,13 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.util.UuidFactory; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.audit.NoOpAuditPersister; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; @@ -284,22 +284,22 @@ class PermissionTemplateDaoIT { GroupDto group1 = db.users().insertGroup(newGroupDto()); GroupDto group2 = db.users().insertGroup(newGroupDto()); GroupDto group3 = db.users().insertGroup(newGroupDto()); - templateDb.addGroupToTemplate(template1.getUuid(), group1.getUuid(), UserRole.CODEVIEWER, template1.getName(), group1.getName()); - templateDb.addGroupToTemplate(template1.getUuid(), group2.getUuid(), UserRole.CODEVIEWER, template1.getName(), group2.getName()); - templateDb.addGroupToTemplate(template1.getUuid(), group3.getUuid(), UserRole.CODEVIEWER, template1.getName(), group3.getName()); - templateDb.addGroupToTemplate(template1.getUuid(), null, UserRole.CODEVIEWER, template1.getName(), null); - templateDb.addGroupToTemplate(template1.getUuid(), group1.getUuid(), UserRole.ADMIN, template1.getName(), group1.getName()); - templateDb.addGroupToTemplate(template2.getUuid(), group1.getUuid(), UserRole.ADMIN, template2.getName(), group1.getName()); - templateDb.addGroupToTemplate(template4.getUuid(), group1.getUuid(), UserRole.ISSUE_ADMIN, template4.getName(), group1.getName()); + templateDb.addGroupToTemplate(template1.getUuid(), group1.getUuid(), ProjectPermission.CODEVIEWER, template1.getName(), group1.getName()); + templateDb.addGroupToTemplate(template1.getUuid(), group2.getUuid(), ProjectPermission.CODEVIEWER, template1.getName(), group2.getName()); + templateDb.addGroupToTemplate(template1.getUuid(), group3.getUuid(), ProjectPermission.CODEVIEWER, template1.getName(), group3.getName()); + templateDb.addGroupToTemplate(template1.getUuid(), null, ProjectPermission.CODEVIEWER, template1.getName(), null); + templateDb.addGroupToTemplate(template1.getUuid(), group1.getUuid(), ProjectPermission.ADMIN, template1.getName(), group1.getName()); + templateDb.addGroupToTemplate(template2.getUuid(), group1.getUuid(), ProjectPermission.ADMIN, template2.getName(), group1.getName()); + templateDb.addGroupToTemplate(template4.getUuid(), group1.getUuid(), ProjectPermission.ISSUE_ADMIN, template4.getName(), group1.getName()); final List<CountByTemplateAndPermissionDto> result = new ArrayList<>(); underTest.groupsCountByTemplateUuidAndPermission(dbSession, asList(template1.getUuid(), template2.getUuid(), template3.getUuid()), context -> result.add(context.getResultObject())); assertThat(result).extracting(CountByTemplateAndPermissionDto::getPermission, CountByTemplateAndPermissionDto::getTemplateUuid, - CountByTemplateAndPermissionDto::getCount) - .containsOnly(tuple(UserRole.ADMIN, template1.getUuid(), 1), tuple(UserRole.CODEVIEWER, template1.getUuid(), 4), - tuple(UserRole.ADMIN, template2.getUuid(), 1)); + CountByTemplateAndPermissionDto::getCount) + .containsOnly(tuple(ProjectPermission.ADMIN.getKey(), template1.getUuid(), 1), tuple(ProjectPermission.CODEVIEWER.getKey(), template1.getUuid(), 4), + tuple(ProjectPermission.ADMIN.getKey(), template2.getUuid(), 1)); } @Test @@ -313,12 +313,12 @@ class PermissionTemplateDaoIT { UserDto user2 = db.users().insertUser(); UserDto user3 = db.users().insertUser(); - templateDb.addUserToTemplate(template1.getUuid(), user1.getUuid(), UserRole.ADMIN, template1.getName(), user1.getLogin()); - templateDb.addUserToTemplate(template1.getUuid(), user2.getUuid(), UserRole.ADMIN, template1.getName(), user2.getLogin()); - templateDb.addUserToTemplate(template1.getUuid(), user3.getUuid(), UserRole.ADMIN, template1.getName(), user3.getLogin()); - templateDb.addUserToTemplate(template1.getUuid(), user1.getUuid(), UserRole.USER, template1.getName(), user1.getLogin()); - templateDb.addUserToTemplate(template2.getUuid(), user1.getUuid(), UserRole.USER, template2.getName(), user1.getLogin()); - templateDb.addUserToTemplate(anotherTemplate.getUuid(), user1.getUuid(), UserRole.ISSUE_ADMIN, anotherTemplate.getName(), + templateDb.addUserToTemplate(template1.getUuid(), user1.getUuid(), ProjectPermission.ADMIN, template1.getName(), user1.getLogin()); + templateDb.addUserToTemplate(template1.getUuid(), user2.getUuid(), ProjectPermission.ADMIN, template1.getName(), user2.getLogin()); + templateDb.addUserToTemplate(template1.getUuid(), user3.getUuid(), ProjectPermission.ADMIN, template1.getName(), user3.getLogin()); + templateDb.addUserToTemplate(template1.getUuid(), user1.getUuid(), ProjectPermission.USER, template1.getName(), user1.getLogin()); + templateDb.addUserToTemplate(template2.getUuid(), user1.getUuid(), ProjectPermission.USER, template2.getName(), user1.getLogin()); + templateDb.addUserToTemplate(anotherTemplate.getUuid(), user1.getUuid(), ProjectPermission.ISSUE_ADMIN, anotherTemplate.getName(), user1.getLogin()); final List<CountByTemplateAndPermissionDto> result = new ArrayList<>(); @@ -328,9 +328,9 @@ class PermissionTemplateDaoIT { .extracting(CountByTemplateAndPermissionDto::getPermission, CountByTemplateAndPermissionDto::getTemplateUuid, CountByTemplateAndPermissionDto::getCount) .containsExactlyInAnyOrder( - tuple(UserRole.ADMIN, template1.getUuid(), 3), - tuple(UserRole.USER, template1.getUuid(), 1), - tuple(UserRole.USER, template2.getUuid(), 1)); + tuple(ProjectPermission.ADMIN.getKey(), template1.getUuid(), 3), + tuple(ProjectPermission.USER.getKey(), template1.getUuid(), 1), + tuple(ProjectPermission.USER.getKey(), template2.getUuid(), 1)); } @Test @@ -357,21 +357,22 @@ class PermissionTemplateDaoIT { db.users().insertMember(group, user); PermissionTemplateDto template = templateDb.insertTemplate(); templateDb.addProjectCreatorToTemplate(template.getUuid(), GlobalPermission.SCAN.getKey(), template.getName()); - templateDb.addProjectCreatorToTemplate(template.getUuid(), UserRole.ADMIN, template.getName()); - templateDb.addUserToTemplate(template.getUuid(), user.getUuid(), UserRole.USER, template.getName(), user.getLogin()); - templateDb.addUserToTemplate(template.getUuid(), user.getUuid(), UserRole.ADMIN, template.getName(), user.getLogin()); - templateDb.addGroupToTemplate(template.getUuid(), group.getUuid(), UserRole.CODEVIEWER, template.getName(), group.getName()); - templateDb.addGroupToTemplate(template.getUuid(), group.getUuid(), UserRole.ADMIN, template.getName(), group.getName()); - templateDb.addGroupToTemplate(template.getUuid(), null, UserRole.ISSUE_ADMIN, template.getName(), null); + templateDb.addProjectCreatorToTemplate(template.getUuid(), ProjectPermission.ADMIN, template.getName()); + templateDb.addUserToTemplate(template.getUuid(), user.getUuid(), ProjectPermission.USER, template.getName(), user.getLogin()); + templateDb.addUserToTemplate(template.getUuid(), user.getUuid(), ProjectPermission.ADMIN, template.getName(), user.getLogin()); + templateDb.addGroupToTemplate(template.getUuid(), group.getUuid(), ProjectPermission.CODEVIEWER, template.getName(), group.getName()); + templateDb.addGroupToTemplate(template.getUuid(), group.getUuid(), ProjectPermission.ADMIN, template.getName(), group.getName()); + templateDb.addGroupToTemplate(template.getUuid(), null, ProjectPermission.ISSUE_ADMIN, template.getName(), null); List<String> resultWithUser = underTest.selectPotentialPermissionsByUserUuidAndTemplateUuid(dbSession, user.getUuid(), template.getUuid()); List<String> resultWithoutUser = underTest.selectPotentialPermissionsByUserUuidAndTemplateUuid(dbSession, null, template.getUuid()); - assertThat(resultWithUser).containsOnlyOnce(GlobalPermission.SCAN.getKey(), UserRole.ADMIN, UserRole.USER, UserRole.CODEVIEWER, - UserRole.ISSUE_ADMIN); + assertThat(resultWithUser).containsOnlyOnce(ProjectPermission.SCAN.getKey(), ProjectPermission.ADMIN.getKey(), ProjectPermission.USER.getKey(), + ProjectPermission.CODEVIEWER.getKey(), + ProjectPermission.ISSUE_ADMIN.getKey()); // only permission from anyone group - assertThat(resultWithoutUser).containsOnly(UserRole.ISSUE_ADMIN); + assertThat(resultWithoutUser).containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); } @Test diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoWithPersisterIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoWithPersisterIT.java index b9126a5953f..6a12c5222b9 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoWithPersisterIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoWithPersisterIT.java @@ -36,7 +36,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; -import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.db.permission.ProjectPermission.ADMIN; import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateDto; import static org.sonar.db.user.GroupTesting.newGroupDto; @@ -110,7 +110,7 @@ class PermissionTemplateDaoWithPersisterIT { assertThat(newValue) .extracting(PermissionTemplateNewValue::getTemplateUuid, PermissionTemplateNewValue::getName, PermissionTemplateNewValue::getPermission, PermissionTemplateNewValue::getUserUuid, PermissionTemplateNewValue::getUserLogin) - .containsExactly(dto.getUuid(), dto.getName(), ADMIN, user.getUuid(), user.getLogin()); + .containsExactly(dto.getUuid(), dto.getName(), ADMIN.getKey(), user.getUuid(), user.getLogin()); assertThat(newValue.toString()).doesNotContain("groupUuid"); underTest.deleteUserPermission(session, dto.getUuid(), user.getUuid(), ADMIN, dto.getName(), user.getLogin()); @@ -120,7 +120,7 @@ class PermissionTemplateDaoWithPersisterIT { assertThat(newValue) .extracting(PermissionTemplateNewValue::getTemplateUuid, PermissionTemplateNewValue::getName, PermissionTemplateNewValue::getPermission, PermissionTemplateNewValue::getUserUuid, PermissionTemplateNewValue::getUserLogin) - .containsExactly(dto.getUuid(), dto.getName(), ADMIN, user.getUuid(), user.getLogin()); + .containsExactly(dto.getUuid(), dto.getName(), ADMIN.getKey(), user.getUuid(), user.getLogin()); assertThat(newValue.toString()).doesNotContain("groupUuid"); } @@ -166,7 +166,7 @@ class PermissionTemplateDaoWithPersisterIT { assertThat(newValue) .extracting(PermissionTemplateNewValue::getTemplateUuid, PermissionTemplateNewValue::getName, PermissionTemplateNewValue::getPermission, PermissionTemplateNewValue::getGroupUuid, PermissionTemplateNewValue::getGroupName) - .containsExactly(dto.getUuid(), dto.getName(), ADMIN, group.getUuid(), group.getName()); + .containsExactly(dto.getUuid(), dto.getName(), ADMIN.getKey(), group.getUuid(), group.getName()); assertThat(newValue.toString()).contains("groupUuid"); underTest.deleteGroupPermission(session, dto.getUuid(), group.getUuid(), ADMIN, dto.getName(), group.getName()); @@ -176,7 +176,7 @@ class PermissionTemplateDaoWithPersisterIT { assertThat(newValue) .extracting(PermissionTemplateNewValue::getTemplateUuid, PermissionTemplateNewValue::getName, PermissionTemplateNewValue::getPermission, PermissionTemplateNewValue::getGroupUuid, PermissionTemplateNewValue::getGroupName) - .containsExactly(dto.getUuid(), dto.getName(), ADMIN, group.getUuid(), group.getName()); + .containsExactly(dto.getUuid(), dto.getName(), ADMIN.getKey(), group.getUuid(), group.getName()); assertThat(newValue.toString()).contains("groupUuid"); } @@ -206,7 +206,7 @@ class PermissionTemplateDaoWithPersisterIT { assertThat(newValue) .extracting(PermissionTemplateNewValue::getTemplateUuid, PermissionTemplateNewValue::getName, PermissionTemplateNewValue::getPermission, PermissionTemplateNewValue::getGroupUuid, PermissionTemplateNewValue::getGroupName) - .containsExactly(templateDto.getUuid(), templateDto.getName(), ADMIN, templateGroupDto.getGroupUuid(), + .containsExactly(templateDto.getUuid(), templateDto.getName(), ADMIN.getKey(), templateGroupDto.getGroupUuid(), templateGroupDto.getGroupName()); assertThat(newValue.toString()).doesNotContain("userUuid"); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/UserWithPermissionTemplateDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/UserWithPermissionTemplateDaoIT.java index 3916abc3e51..e85669305e0 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/UserWithPermissionTemplateDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/UserWithPermissionTemplateDaoIT.java @@ -24,7 +24,7 @@ import java.util.stream.IntStream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.permission.PermissionQuery; @@ -34,9 +34,9 @@ import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE; import static org.sonar.db.permission.PermissionQuery.builder; @@ -140,7 +140,7 @@ class UserWithPermissionTemplateDaoIT { UserDto user1 = db.users().insertUser(u -> u.setName("A")); UserDto user2 = db.users().insertUser(u -> u.setName("B")); UserDto user3 = db.users().insertUser(u -> u.setName("C")); - db.permissionTemplates().addUserToTemplate(template.getUuid(), user3.getUuid(), UserRole.USER, template.getName(), user3.getLogin()); + db.permissionTemplates().addUserToTemplate(template.getUuid(), user3.getUuid(), ProjectPermission.USER, template.getName(), user3.getLogin()); PermissionQuery query = PermissionQuery.builder().build(); assertThat(underTest.selectUserLoginsByQueryAndTemplate(db.getSession(), query, template.getUuid())) @@ -154,10 +154,10 @@ class UserWithPermissionTemplateDaoIT { PermissionTemplateDto otherTemplate = db.permissionTemplates().insertTemplate(); IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> { UserDto user = db.users().insertUser("User-" + i); - db.permissionTemplates().addUserToTemplate(otherTemplate, user, UserRole.USER); + db.permissionTemplates().addUserToTemplate(otherTemplate, user, ProjectPermission.USER); }); String lastLogin = "User-" + (DEFAULT_PAGE_SIZE + 1); - db.permissionTemplates().addUserToTemplate(template, db.users().selectUserByLogin(lastLogin).get(), UserRole.USER); + db.permissionTemplates().addUserToTemplate(template, db.users().selectUserByLogin(lastLogin).get(), ProjectPermission.USER); PermissionQuery query = PermissionQuery.builder().build(); assertThat(underTest.selectUserLoginsByQueryAndTemplate(db.getSession(), query, template.getUuid())) @@ -219,18 +219,18 @@ class UserWithPermissionTemplateDaoIT { singletonList(user1.getLogin()))) .extracting(PermissionTemplateUserDto::getUserLogin, PermissionTemplateUserDto::getPermission) .containsExactlyInAnyOrder( - tuple(user1.getLogin(), USER), - tuple(user1.getLogin(), ADMIN), - tuple(user1.getLogin(), CODEVIEWER)); + tuple(user1.getLogin(), USER.getKey()), + tuple(user1.getLogin(), ADMIN.getKey()), + tuple(user1.getLogin(), CODEVIEWER.getKey())); assertThat(underTest.selectUserPermissionsByTemplateIdAndUserLogins(dbSession, permissionTemplate.getUuid(), asList(user1.getLogin(), user2.getLogin(), user2.getLogin()))) .extracting(PermissionTemplateUserDto::getUserLogin, PermissionTemplateUserDto::getPermission) .containsExactlyInAnyOrder( - tuple(user1.getLogin(), USER), - tuple(user1.getLogin(), ADMIN), - tuple(user1.getLogin(), CODEVIEWER), - tuple(user2.getLogin(), USER)); + tuple(user1.getLogin(), USER.getKey()), + tuple(user1.getLogin(), ADMIN.getKey()), + tuple(user1.getLogin(), CODEVIEWER.getKey()), + tuple(user2.getLogin(), USER.getKey())); assertThat(underTest.selectUserPermissionsByTemplateIdAndUserLogins(dbSession, permissionTemplate.getUuid(), singletonList("unknown"))).isEmpty(); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectExportDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectExportDaoIT.java index f6b00f3c515..4bf4c263fef 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectExportDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectExportDaoIT.java @@ -34,7 +34,7 @@ import org.sonar.api.issue.Issue; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; import org.sonar.db.component.BranchDto; diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/property/PropertiesDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/property/PropertiesDaoIT.java index 8cc5c95e032..05283591dbe 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/property/PropertiesDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/property/PropertiesDaoIT.java @@ -30,6 +30,7 @@ import java.util.Set; import java.util.function.Consumer; import javax.annotation.CheckForNull; import javax.annotation.Nullable; +import org.assertj.core.groups.Tuple; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -125,10 +126,10 @@ class PropertiesDaoIT { // Global + Project subscribers assertThat(underTest.hasProjectNotificationSubscribersForDispatchers(projectUuid, singletonList( "DispatcherWithGlobalAndProjectSubscribers"))) - .isTrue(); + .isTrue(); assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_B", singletonList( "DispatcherWithGlobalAndProjectSubscribers"))) - .isTrue(); + .isTrue(); } @Test @@ -536,7 +537,7 @@ class PropertiesDaoIT { } private static Object[][] allValuesForSelect() { - return new Object[][] { + return new Object[][]{ {null, ""}, {"", ""}, {"some value", "some value"}, @@ -561,6 +562,26 @@ class PropertiesDaoIT { } @Test + void selectUserProperty() { + final String propertyKey = "user.property.one"; + + UserDto userDto1 = db.users().insertUser(); + UserDto userDto2 = db.users().insertUser(); + + insertProperty(propertyKey, "one", null, userDto1.getUuid(), null, null, null); + insertProperty(propertyKey, "two", null, userDto2.getUuid(), null, null, null); + + List<PropertyDto> property = underTest.selectUserPropertiesByKey(db.getSession(), propertyKey); + + assertThat(property) + .extracting(PropertyDto::getKey, PropertyDto::getEntityUuid, PropertyDto::getUserUuid, PropertyDto::getValue) + .containsExactlyInAnyOrderElementsOf(Set.of( + Tuple.tuple(propertyKey, null, userDto1.getUuid(), "one"), + Tuple.tuple(propertyKey, null, userDto2.getUuid(), "two") + )); + } + + @Test void select_by_query() { // global insertProperty("global.one", "one", null, null, null, null, null); @@ -641,10 +662,10 @@ class PropertiesDaoIT { tuple(key, project2.getUuid())); assertThat(underTest.selectPropertiesByKeysAndEntityUuids(session, newHashSet(key, anotherKey), newHashSet(project.getUuid(), project2.getUuid()))) - .extracting(PropertyDto::getKey, PropertyDto::getEntityUuid).containsOnly( - tuple(key, project.getUuid()), - tuple(key, project2.getUuid()), - tuple(anotherKey, project2.getUuid())); + .extracting(PropertyDto::getKey, PropertyDto::getEntityUuid).containsOnly( + tuple(key, project.getUuid()), + tuple(key, project2.getUuid()), + tuple(anotherKey, project2.getUuid())); assertThat(underTest.selectPropertiesByKeysAndEntityUuids(session, newHashSet("unknown"), newHashSet(project.getUuid()))).isEmpty(); assertThat(underTest.selectPropertiesByKeysAndEntityUuids(session, newHashSet("key"), newHashSet("uuid123456789"))).isEmpty(); @@ -849,7 +870,7 @@ class PropertiesDaoIT { } static Object[][] valueUpdatesDataProvider() { - return new Object[][] { + return new Object[][]{ {null, null}, {null, ""}, {null, "some value"}, @@ -934,8 +955,8 @@ class PropertiesDaoIT { assertThat(db.select("select prop_key as \"key\", text_value as \"value\", entity_uuid as \"projectUuid\", user_uuid as \"userUuid\" " + "from properties")) - .extracting((row) -> row.get("key"), (row) -> row.get("value"), (row) -> row.get("projectUuid"), (row) -> row.get("userUuid")) - .containsOnly(tuple("KEY", "ANOTHER_VALUE", null, null), tuple("ANOTHER_KEY", "VALUE", project.uuid(), "100")); + .extracting((row) -> row.get("key"), (row) -> row.get("value"), (row) -> row.get("projectUuid"), (row) -> row.get("userUuid")) + .containsOnly(tuple("KEY", "ANOTHER_VALUE", null, null), tuple("ANOTHER_KEY", "VALUE", project.uuid(), "100")); } private static Map<String, String> mapOf(String... values) { diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java index f93eaafd3aa..589145c220f 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java @@ -29,7 +29,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Random; import java.util.Set; @@ -136,6 +138,7 @@ class PurgeDaoIT { private final LogTesterJUnit5 logTester = new LogTesterJUnit5(); private final DbClient dbClient = db.getDbClient(); private final DbSession dbSession = db.getSession(); + private final PurgeDao underTest = db.getDbClient().purgeDao(); @Test @@ -1960,6 +1963,59 @@ oldCreationDate)); } + private <K, V> Map<K, V> merge(Map<? extends K, ? extends V> map1, Map<? extends K, ? extends V> map2) { + Map<K, V> result = new HashMap<>(map1); + result.putAll(map2); + return result; + } + + // the SCA mappers are in an extension, so we have to use direct sql here. + // A cleaner approach would be to allow extensions to add purge logic on branch + // deletion and remove SCA knowledge from the core PurgeMapper. + private void insertScaData(String branch1Uuid, String branch2Uuid) { + var releaseBase = Map.of("package_url", "purl1", + "package_manager", "MAVEN", + "package_name", "whatever", + "version", "1.0", + "license_expression", "MIT", + "known", true, + "created_at", 0L, "updated_at", 0L); + db.executeInsert("sca_releases", merge(releaseBase, Map.of("uuid", "release-uuid1", "component_uuid", branch1Uuid))); + db.executeInsert("sca_releases", merge(releaseBase, Map.of("uuid", "release-uuid2", "component_uuid", branch2Uuid))); + assertThat(db.countRowsOfTable(dbSession, "sca_releases")).isEqualTo(2); + + var dependencyBase = Map.of("created_at", 0L, "updated_at", 0L, + "direct", true, "scope", "compile", "new_in_pull_request", true); + db.executeInsert("sca_dependencies", merge(dependencyBase, Map.of("uuid", "dependency-uuid1", "sca_release_uuid", "release-uuid1"))); + db.executeInsert("sca_dependencies", merge(dependencyBase, Map.of("uuid", "dependency-uuid2", "sca_release_uuid", "release-uuid2"))); + assertThat(db.countRowsOfTable(dbSession, "sca_dependencies")).isEqualTo(2); + + // the issue uuids here don't even exist but doesn't matter, we don't delete issues so not testing that + var issueReleaseBase = Map.of("created_at", 0L, "updated_at", 0L, + "severity", "INFO", "severity_sort_key", 42); + db.executeInsert("sca_issues_releases", merge(issueReleaseBase, Map.of("uuid", "issue-release-uuid1", + "sca_issue_uuid", "issue-uuid1", "sca_release_uuid", "release-uuid1"))); + db.executeInsert("sca_issues_releases", merge(issueReleaseBase, Map.of("uuid", "issue-release-uuid2", + "sca_issue_uuid", "issue-uuid2", "sca_release_uuid", "release-uuid2"))); + + assertThat(db.countRowsOfTable(dbSession, "sca_issues_releases")).isEqualTo(2); + } + + @Test + void deleteBranch_purgesScaActivity() { + ProjectDto project = db.components().insertPublicProject().getProjectDto(); + BranchDto branch1 = db.components().insertProjectBranch(project); + BranchDto branch2 = db.components().insertProjectBranch(project); + + insertScaData(branch1.getUuid(), branch2.getUuid()); + + underTest.deleteBranch(dbSession, branch1.getUuid()); + + assertThat(db.countRowsOfTable(dbSession, "sca_releases")).isEqualTo(1); + assertThat(db.countRowsOfTable(dbSession, "sca_dependencies")).isEqualTo(1); + assertThat(db.countRowsOfTable(dbSession, "sca_issues_releases")).isEqualTo(1); + } + private AnticipatedTransitionDto getAnticipatedTransitionsDto(String uuid, String projectUuid, Date creationDate) { return new AnticipatedTransitionDto(uuid, projectUuid, "userUuid", "transition", null, null, null, null, "rule:key", "filepath", creationDate.getTime()); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/ActiveRuleDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/ActiveRuleDaoIT.java index 033ba5daa9f..f15bbf5cc1c 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/ActiveRuleDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/ActiveRuleDaoIT.java @@ -33,7 +33,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.impl.utils.TestSystem2; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RuleParamType; import org.sonar.api.utils.System2; import org.sonar.db.DbSession; diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/QualityProfileExportDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/QualityProfileExportDaoIT.java index 3b7f50942fa..be6d177fb98 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/QualityProfileExportDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/QualityProfileExportDaoIT.java @@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.rule.RuleDto; @@ -97,7 +97,7 @@ class QualityProfileExportDaoIT { assertThat(exportCustomRuleDto.getExtendedDescription()).isEqualTo(customRule.getNoteData()); assertThat(exportCustomRuleDto.getName()).isEqualTo(customRule.getName()); assertThat(exportCustomRuleDto.getRuleKey()).isEqualTo(customRule.getKey()); - assertThat(exportCustomRuleDto.getRuleType()).isEqualTo(RuleType.valueOf(customRule.getType())); + assertThat(exportCustomRuleDto.getRuleType()).isEqualTo(RuleType.fromDbConstant(customRule.getType())); assertThat(exportCustomRuleDto.getTags()).isEqualTo(customRule.getTags()); assertThat(exportCustomRuleDto.getTemplateRuleKey()).isEqualTo(ruleTemplate.getKey()); @@ -115,7 +115,7 @@ class QualityProfileExportDaoIT { assertThat(exportRuleDto.getExtendedDescription()).isEqualTo(rule.getNoteData()); assertThat(exportRuleDto.getName()).isEqualTo(rule.getName()); assertThat(exportRuleDto.getRuleKey()).isEqualTo(rule.getKey()); - assertThat(exportRuleDto.getRuleType()).isEqualTo(RuleType.valueOf(rule.getType())); + assertThat(exportRuleDto.getRuleType()).isEqualTo(RuleType.fromDbConstant(rule.getType())); ActiveRuleDto activeRule = activeRules.stream().filter(activeRuleDto -> activeRuleDto.getRuleKey().equals(rule.getKey())).findFirst().get(); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/report/RegulatoryReportDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/report/RegulatoryReportDaoIT.java index 7eb2bc34250..3b3d9ca49cc 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/report/RegulatoryReportDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/report/RegulatoryReportDaoIT.java @@ -26,7 +26,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/rule/RuleDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/rule/RuleDaoIT.java index 26f799fa610..cb66d99fc6b 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/rule/RuleDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/rule/RuleDaoIT.java @@ -41,7 +41,7 @@ import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttribute; import org.sonar.api.rules.RuleQuery; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; @@ -1157,7 +1157,7 @@ class RuleDaoIT { assertThat(ruleForIndexing.getInternalKey()).isEqualTo(r1.getConfigKey()); assertThat(ruleForIndexing.getLanguage()).isEqualTo(r1.getLanguage()); assertThat(ruleForIndexing.getType()).isEqualTo(r1.getType()); - assertThat(ruleForIndexing.getTypeAsRuleType()).isEqualTo(RuleType.valueOf(r1.getType())); + assertThat(ruleForIndexing.getTypeAsRuleType()).isEqualTo(RuleType.fromDbConstant(r1.getType())); assertThat(ruleForIndexing.getCreatedAt()).isEqualTo(r1.getCreatedAt()); assertThat(ruleForIndexing.getUpdatedAt()).isEqualTo(r1.getUpdatedAt()); } diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/user/RoleDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/user/RoleDaoIT.java index 51740d120f0..a2ad19232a7 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/user/RoleDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/user/RoleDaoIT.java @@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.component.ComponentQualifiers; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -64,13 +64,13 @@ class RoleDaoIT { @Test void selectComponentUuidsByPermissionAndUserId_throws_IAR_if_permission_USER_is_specified() { expectUnsupportedUserAndCodeViewerPermission(() -> underTest.selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, - UserRole.USER, Uuids.createFast(), PROJECT_QUALIFIER)); + ProjectPermission.USER, Uuids.createFast(), PROJECT_QUALIFIER)); } @Test void selectComponentUuidsByPermissionAndUserId_throws_IAR_if_permission_CODEVIEWER_is_specified() { expectUnsupportedUserAndCodeViewerPermission(() -> underTest.selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, - UserRole.CODEVIEWER, Uuids.createFast(), PROJECT_QUALIFIER)); + ProjectPermission.CODEVIEWER, Uuids.createFast(), PROJECT_QUALIFIER)); } private void expectUnsupportedUserAndCodeViewerPermission(ThrowingCallable callback) { @@ -81,16 +81,16 @@ class RoleDaoIT { @Test void selectEntityIdsByPermissionAndUserUuid() { - db.users().insertProjectPermissionOnUser(user1, UserRole.ADMIN, project1); - db.users().insertProjectPermissionOnUser(user1, UserRole.ADMIN, project2); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.ADMIN, project1); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.ADMIN, project2); // global permission - not returned db.users().insertGlobalPermissionOnUser(user1, ADMINISTER); // project permission on another user id - not returned - db.users().insertProjectPermissionOnUser(user2, UserRole.ADMIN, project1); + db.users().insertProjectPermissionOnUser(user2, ProjectPermission.ADMIN, project1); // project permission on another permission - not returned - db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, project1); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.ISSUE_ADMIN, project1); - List<String> entityUuids = underTest.selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, UserRole.ADMIN, user1.getUuid(), + List<String> entityUuids = underTest.selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, ProjectPermission.ADMIN, user1.getUuid(), PROJECT_QUALIFIER); assertThat(entityUuids).containsExactly(project1.getUuid(), project2.getUuid()); @@ -100,9 +100,9 @@ class RoleDaoIT { void selectComponentIdsByPermissionAndUserUuid_group_permissions() { GroupDto group1 = db.users().insertGroup(); GroupDto group2 = db.users().insertGroup(); - db.users().insertEntityPermissionOnGroup(group1, UserRole.ADMIN, project1); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.ADMIN, project1); db.users().insertMember(group1, user1); - db.users().insertProjectPermissionOnUser(user1, UserRole.ADMIN, project2); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.ADMIN, project2); // global permission - not returned db.users().insertGlobalPermissionOnUser(user1, ADMINISTER); db.users().insertPermissionOnGroup(group1, ADMINISTER); @@ -110,9 +110,9 @@ class RoleDaoIT { db.users().insertPermissionOnGroup(group2, ADMINISTER); db.users().insertMember(group2, user2); // project permission on another permission - not returned - db.users().insertEntityPermissionOnGroup(group1, UserRole.ISSUE_ADMIN, project1); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.ISSUE_ADMIN, project1); - List<String> result = underTest.selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, UserRole.ADMIN, user1.getUuid(), + List<String> result = underTest.selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, ProjectPermission.ADMIN, user1.getUuid(), PROJECT_QUALIFIER); assertThat(result).containsExactlyInAnyOrder(project1.getUuid(), project2.getUuid()); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java index db5edec1bf1..02986d9c4c6 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java @@ -38,7 +38,6 @@ import org.sonar.db.component.ComponentDao; import org.sonar.db.component.ComponentKeyUpdaterDao; import org.sonar.db.component.ProjectLinkDao; import org.sonar.db.component.SnapshotDao; -import org.sonar.db.dependency.ProjectDependenciesDao; import org.sonar.db.duplication.DuplicationDao; import org.sonar.db.entity.EntityDao; import org.sonar.db.es.EsQueueDao; @@ -161,7 +160,6 @@ public class DaoModule extends Module { PluginDao.class, ProjectDao.class, ProjectBadgeTokenDao.class, - ProjectDependenciesDao.class, ProjectExportDao.class, PortfolioDao.class, ProjectLinkDao.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java index 4ddbe135d14..ec1fc6884b1 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java @@ -38,7 +38,6 @@ import org.sonar.db.component.ComponentDao; import org.sonar.db.component.ComponentKeyUpdaterDao; import org.sonar.db.component.ProjectLinkDao; import org.sonar.db.component.SnapshotDao; -import org.sonar.db.dependency.ProjectDependenciesDao; import org.sonar.db.duplication.DuplicationDao; import org.sonar.db.entity.EntityDao; import org.sonar.db.es.EsQueueDao; @@ -201,7 +200,6 @@ public class DbClient { private final ProjectExportDao projectExportDao; private final IssueFixedDao issueFixedDao; private final TelemetryMetricsSentDao telemetryMetricsSentDao; - private final ProjectDependenciesDao projectDependenciesDao; public DbClient(Database database, MyBatis myBatis, DBSessions dbSessions, Dao... daos) { this.database = database; @@ -298,7 +296,6 @@ public class DbClient { projectExportDao = getDao(map, ProjectExportDao.class); issueFixedDao = getDao(map, IssueFixedDao.class); telemetryMetricsSentDao = getDao(map, TelemetryMetricsSentDao.class); - projectDependenciesDao = getDao(map, ProjectDependenciesDao.class); } public DbSession openSession(boolean batch) { @@ -662,8 +659,4 @@ public class DbClient { public ProjectExportDao projectExportDao() { return projectExportDao; } - - public ProjectDependenciesDao projectDependenciesDao() { - return projectDependenciesDao; - } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java index 250f51d9729..334ad5a5cdf 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java @@ -63,8 +63,6 @@ import org.sonar.db.component.SnapshotDto; import org.sonar.db.component.SnapshotMapper; import org.sonar.db.component.UuidWithBranchUuidDto; import org.sonar.db.component.ViewsSnapshotDto; -import org.sonar.db.dependency.ProjectDependenciesMapper; -import org.sonar.db.dependency.ProjectDependencyDto; import org.sonar.db.duplication.DuplicationMapper; import org.sonar.db.duplication.DuplicationUnitDto; import org.sonar.db.entity.EntityDto; @@ -244,7 +242,6 @@ public class MyBatis { confBuilder.loadAlias("ProjectQgateAssociation", ProjectQgateAssociationDto.class); confBuilder.loadAlias("Project", ProjectDto.class); confBuilder.loadAlias("ProjectBadgeToken", ProjectBadgeTokenDto.class); - confBuilder.loadAlias("ProjectDependency", ProjectDependencyDto.class); confBuilder.loadAlias("AnalysisPropertyValuePerProject", AnalysisPropertyValuePerProject.class); confBuilder.loadAlias("ProjectAlmKeyAndProject", ProjectAlmKeyAndProject.class); confBuilder.loadAlias("PrAndBranchCountByProjectDto", PrBranchAnalyzedLanguageCountByProjectDto.class); @@ -317,7 +314,6 @@ public class MyBatis { PluginMapper.class, PortfolioMapper.class, ProjectAlmSettingMapper.class, - ProjectDependenciesMapper.class, ProjectLinkMapper.class, ProjectMapper.class, ProjectBadgeTokenMapper.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatisConfBuilder.java b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatisConfBuilder.java index a9efb454c14..928e5982c42 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatisConfBuilder.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatisConfBuilder.java @@ -51,11 +51,15 @@ class MyBatisConfBuilder { this.conf.setLocalCacheScope(LocalCacheScope.STATEMENT); } - void loadAlias(String alias, Class dtoClass) { + void loadTypeHandler(Class<?> typeHandlerClass) { + this.conf.getTypeHandlerRegistry().register(typeHandlerClass); + } + + void loadAlias(String alias, Class<?> dtoClass) { conf.getTypeAliasRegistry().registerAlias(alias, dtoClass); } - void loadMapper(Class mapperClass) { + void loadMapper(Class<?> mapperClass) { String configFile = configFilePath(mapperClass); InputStream input = null; try { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/ProjectDependenciesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/ProjectDependenciesDao.java deleted file mode 100644 index dd2429d7ba2..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/ProjectDependenciesDao.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.dependency; - -import java.util.List; -import java.util.Optional; -import org.sonar.db.Dao; -import org.sonar.db.DbSession; -import org.sonar.db.Pagination; - -public class ProjectDependenciesDao implements Dao { - - private static ProjectDependenciesMapper mapper(DbSession session) { - return session.getMapper(ProjectDependenciesMapper.class); - } - - public void insert(DbSession session, ProjectDependencyDto projectDependencyDto) { - mapper(session).insert(projectDependencyDto); - } - - public void deleteByUuid(DbSession session, String uuid) { - mapper(session).deleteByUuid(uuid); - } - - public Optional<ProjectDependencyDto> selectByUuid(DbSession dbSession, String uuid) { - return Optional.ofNullable(mapper(dbSession).selectByUuid(uuid)); - } - - /** - * Retrieves all dependencies with a specific branch UUID, no other filtering is done by this method. - */ - public List<ProjectDependencyDto> selectByBranchUuid(DbSession dbSession, String branchUuid) { - return mapper(dbSession).selectByBranchUuid(branchUuid); - } - - public List<ProjectDependencyDto> selectByQuery(DbSession session, ProjectDependenciesQuery projectDependenciesQuery, Pagination pagination) { - return mapper(session).selectByQuery(projectDependenciesQuery, pagination); - } - - public int countByQuery(DbSession session, ProjectDependenciesQuery projectDependenciesQuery) { - return mapper(session).countByQuery(projectDependenciesQuery); - } - - public void update(DbSession session, ProjectDependencyDto projectDependencyDto) { - mapper(session).update(projectDependencyDto); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/ProjectDependenciesQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/ProjectDependenciesQuery.java deleted file mode 100644 index b4b2805e1da..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/ProjectDependenciesQuery.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.dependency; - -import java.util.Locale; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; - -import static org.sonar.db.DaoUtils.buildLikeValue; -import static org.sonar.db.WildcardPosition.BEFORE_AND_AFTER; - -public final class ProjectDependenciesQuery { - private final String branchUuid; - @Nullable - private final String query; - - public ProjectDependenciesQuery(String branchUuid, @Nullable String query) { - this.branchUuid = branchUuid; - this.query = query; - } - - /** - * Used by MyBatis mapper - */ - @CheckForNull - public String getLikeQuery() { - return query == null ? null : buildLikeValue(query, BEFORE_AND_AFTER).toLowerCase(Locale.ENGLISH); - } - - public String branchUuid() { - return branchUuid; - } - - @Nullable - public String query() { - return query; - } - - -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/ProjectDependencyDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/ProjectDependencyDto.java deleted file mode 100644 index 11eb2f297db..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/ProjectDependencyDto.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.dependency; - -import javax.annotation.Nullable; - -public record ProjectDependencyDto( - String uuid, - @Nullable String version, - @Nullable String includePaths, - @Nullable String packageManager, - Long createdAt, - Long updatedAt - ) { -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java index 61f2b6d96c6..1e58c75dc36 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java @@ -42,7 +42,7 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.core.issue.DefaultIssue; import org.sonar.db.component.ComponentDto; @@ -877,7 +877,7 @@ public final class IssueDto implements Serializable { public DefaultIssue toDefaultIssue() { DefaultIssue issue = new DefaultIssue(); issue.setKey(kee); - issue.setType(RuleType.valueOf(type)); + issue.setType(RuleType.fromDbConstant(type)); issue.setStatus(status); issue.setResolution(resolution); issue.setMessage(message); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java index 1402b8cadd0..85dd8c651e9 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java @@ -126,6 +126,10 @@ public class AuthorizationDao implements Dao { return mapper(dbSession).countUsersWithGlobalPermissionExcludingUserPermission(permission, userUuid); } + public Set<String> keepAuthorizedEntityUuids(DbSession dbSession, Collection<String> entityUuids, @Nullable String userUuid, ProjectPermission permission) { + return keepAuthorizedEntityUuids(dbSession, entityUuids, userUuid, permission.getKey()); + } + public Set<String> keepAuthorizedEntityUuids(DbSession dbSession, Collection<String> entityUuids, @Nullable String userUuid, String permission) { return executeLargeInputsIntoSet( entityUuids, @@ -142,10 +146,15 @@ public class AuthorizationDao implements Dao { * Keep only authorized user that have the given permission on a given entity. * Please Note that if the permission is 'Anyone' is NOT taking into account by this method. */ - public Collection<String> keepAuthorizedUsersForRoleAndEntity(DbSession dbSession, Collection<String> userUuids, String role, String entityUuid) { + public Collection<String> keepAuthorizedUsersForRoleAndEntity(DbSession dbSession, Collection<String> userUuids, ProjectPermission permission, String entityUuid) { + return keepAuthorizedUsersForRoleAndEntity(dbSession, userUuids, permission.getKey(), entityUuid); + } + + + public Collection<String> keepAuthorizedUsersForRoleAndEntity(DbSession dbSession, Collection<String> userUuids, String permission, String entityUuid) { return executeLargeInputs( userUuids, - partitionOfIds -> mapper(dbSession).keepAuthorizedUsersForRoleAndEntity(role, entityUuid, partitionOfIds), + partitionOfIds -> mapper(dbSession).keepAuthorizedUsersForRoleAndEntity(permission, entityUuid, partitionOfIds), partitionSize -> partitionSize / 3); } @@ -161,6 +170,10 @@ public class AuthorizationDao implements Dao { return mapper(dbSession).selectEmailSubscribersWithGlobalPermission(ADMINISTER.getKey()); } + public Set<String> keepAuthorizedLoginsOnEntity(DbSession dbSession, Set<String> logins, String entityKey, ProjectPermission permission) { + return keepAuthorizedLoginsOnEntity(dbSession, logins, entityKey, permission.getKey()); + } + public Set<String> keepAuthorizedLoginsOnEntity(DbSession dbSession, Set<String> logins, String entityKey, String permission) { return executeLargeInputsIntoSet( logins, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/CountPerEntityPermission.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/CountPerEntityPermission.java index 9d6c2c207ac..e3870a20127 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/CountPerEntityPermission.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/CountPerEntityPermission.java @@ -34,9 +34,9 @@ public class CountPerEntityPermission { } @VisibleForTesting - CountPerEntityPermission(String entityUuid, String permission, int count) { + CountPerEntityPermission(String entityUuid, ProjectPermission permission, int count) { this.entityUuid = entityUuid; - this.permission = permission; + this.permission = permission.getKey(); this.count = count; } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GlobalPermission.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GlobalPermission.java index 395d31a7ff9..f7998a70808 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GlobalPermission.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GlobalPermission.java @@ -59,7 +59,7 @@ public enum GlobalPermission { return p; } } - throw new IllegalArgumentException("Unsupported permission: " + key); + throw new IllegalArgumentException("Unsupported global permission: " + key); } public static boolean contains(String key) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDao.java index 3306033e1d3..bcdfaee08db 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDao.java @@ -117,6 +117,10 @@ public class GroupPermissionDao implements Dao { * permission, <strong>excluding group "AnyOne"</strong> (which implies the returned {@code Sett} can't contain * {@code null}). */ + public Set<String> selectGroupUuidsWithPermissionOnEntityBut(DbSession session, String entityUuid, ProjectPermission permission) { + return selectGroupUuidsWithPermissionOnEntityBut(session, entityUuid, permission.getKey()); + } + public Set<String> selectGroupUuidsWithPermissionOnEntityBut(DbSession session, String entityUuid, String permission) { return mapper(session).selectGroupUuidsWithPermissionOnEntityBut(entityUuid, permission); } @@ -205,6 +209,11 @@ public class GroupPermissionDao implements Dao { * @param groupUuid if null, then anyone, else uuid of group * @param entityDto if null, then global permission, otherwise the uuid of entity */ + public void delete(DbSession dbSession, ProjectPermission permission, @Nullable String groupUuid, + @Nullable String groupName, @Nullable EntityDto entityDto) { + delete(dbSession, permission.getKey(), groupUuid, groupName, entityDto); + } + public void delete(DbSession dbSession, String permission, @Nullable String groupUuid, @Nullable String groupName, @Nullable EntityDto entityDto) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDto.java index e0507f7bb26..d6fcd6a3646 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDto.java @@ -64,6 +64,10 @@ public class GroupPermissionDto { return role; } + public GroupPermissionDto setRole(ProjectPermission permission) { + return setRole(permission.getKey()); + } + public GroupPermissionDto setRole(String role) { this.role = role; return this; diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/PermissionQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/PermissionQuery.java index 95dd6226eea..5bb0acd62f1 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/PermissionQuery.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/PermissionQuery.java @@ -137,6 +137,10 @@ public class PermissionQuery { return this; } + public Builder setPermission(@Nullable ProjectPermission permission) { + return setPermission(permission == null ? null : permission.getKey()); + } + public Builder setEntity(ComponentDto component) { return setEntityUuid(component.uuid()); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/ProjectPermission.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/ProjectPermission.java new file mode 100644 index 00000000000..230594b58b5 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/ProjectPermission.java @@ -0,0 +1,77 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.permission; + +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; + +public enum ProjectPermission { + + USER("user"), + ADMIN("admin"), + CODEVIEWER("codeviewer"), + ISSUE_ADMIN("issueadmin"), + SECURITYHOTSPOT_ADMIN("securityhotspotadmin"), + SCAN("scan"); + + /** + * Permissions which are implicitly available for any user, any group on public projects. + */ + public static final Set<ProjectPermission> PUBLIC_PERMISSIONS = Collections.unmodifiableSet(EnumSet.of(ProjectPermission.USER, ProjectPermission.CODEVIEWER)); + + private final String key; + + ProjectPermission(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + + @Override + public String toString() { + return key; + } + + public static ProjectPermission fromKey(String key) { + for (ProjectPermission p : values()) { + if (p.getKey().equals(key)) { + return p; + } + } + throw new IllegalArgumentException("Unsupported project permission: " + key); + } + + public static boolean contains(String key) { + return Arrays.stream(values()).anyMatch(v -> v.getKey().equals(key)); + } + + public static boolean isPublic(ProjectPermission permission) { + return PUBLIC_PERMISSIONS.contains(permission); + } + + public static boolean isPublic(String permissionKey) { + return PUBLIC_PERMISSIONS.stream().anyMatch(p -> p.getKey().equals(permissionKey)); + } + +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDao.java index 7014a0aed29..b6cc79c9f85 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDao.java @@ -25,6 +25,7 @@ import org.sonar.db.Dao; import org.sonar.db.DbSession; import org.sonar.db.audit.AuditPersister; import org.sonar.db.audit.model.PermissionTemplateNewValue; +import org.sonar.db.permission.ProjectPermission; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; @@ -41,6 +42,10 @@ public class PermissionTemplateCharacteristicDao implements Dao { return executeLargeInputs(templateUuids, partitionOfTemplateUuids -> mapper(dbSession).selectByTemplateUuids(partitionOfTemplateUuids)); } + public Optional<PermissionTemplateCharacteristicDto> selectByPermissionAndTemplateId(DbSession dbSession, ProjectPermission permission, String templateUuid) { + return selectByPermissionAndTemplateId(dbSession, permission.getKey(), templateUuid); + } + public Optional<PermissionTemplateCharacteristicDto> selectByPermissionAndTemplateId(DbSession dbSession, String permission, String templateUuid) { PermissionTemplateCharacteristicDto dto = mapper(dbSession).selectByPermissionAndTemplateUuid(permission, templateUuid); return Optional.ofNullable(dto); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDto.java index 89aebabc55d..fc3224c9ec6 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDto.java @@ -19,6 +19,8 @@ */ package org.sonar.db.permission.template; +import org.sonar.db.permission.ProjectPermission; + import static com.google.common.base.Preconditions.checkArgument; public class PermissionTemplateCharacteristicDto { @@ -54,6 +56,10 @@ public class PermissionTemplateCharacteristicDto { return permission; } + public PermissionTemplateCharacteristicDto setPermission(ProjectPermission permission) { + return setPermission(permission.getKey()); + } + public PermissionTemplateCharacteristicDto setPermission(String permission) { checkArgument(permission.length() <= MAX_PERMISSION_KEY_LENGTH, "Permission key length (%s) is longer than the maximum authorized (%s). '%s' was provided.", permission.length(), MAX_PERMISSION_KEY_LENGTH, permission); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java index 5ef2e73adef..46a6633133e 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java @@ -37,6 +37,7 @@ import org.sonar.db.audit.AuditPersister; import org.sonar.db.audit.model.PermissionTemplateNewValue; import org.sonar.db.permission.CountPerEntityPermission; import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.ProjectPermission; import static java.lang.String.format; import static org.sonar.api.security.DefaultGroups.ANYONE; @@ -175,6 +176,11 @@ public class PermissionTemplateDao implements Dao { return permissionTemplate; } + public void insertUserPermission(DbSession session, String templateUuid, String userUuid, ProjectPermission permission, + String templateName, String userLogin) { + insertUserPermission(session, templateUuid, userUuid, permission.getKey(), templateName, userLogin); + } + public void insertUserPermission(DbSession session, String templateUuid, String userUuid, String permission, String templateName, String userLogin) { PermissionTemplateUserDto permissionTemplateUser = new PermissionTemplateUserDto() @@ -192,6 +198,11 @@ public class PermissionTemplateDao implements Dao { session.commit(); } + public void deleteUserPermission(DbSession session, String templateUuid, String userUuid, ProjectPermission permission, + String templateName, String userLogin) { + deleteUserPermission(session, templateUuid, userUuid, permission.getKey(), templateName, userLogin); + } + public void deleteUserPermission(DbSession session, String templateUuid, String userUuid, String permission, String templateName, String userLogin) { PermissionTemplateUserDto permissionTemplateUser = new PermissionTemplateUserDto() @@ -215,6 +226,11 @@ public class PermissionTemplateDao implements Dao { } } + public void insertGroupPermission(DbSession session, String templateUuid, @Nullable String groupUuid, ProjectPermission permission, + String templateName, @Nullable String groupName) { + insertGroupPermission(session, templateUuid, groupUuid, permission.getKey(), templateName, groupName); + } + public void insertGroupPermission(DbSession session, String templateUuid, @Nullable String groupUuid, String permission, String templateName, @Nullable String groupName) { PermissionTemplateGroupDto permissionTemplateGroup = new PermissionTemplateGroupDto() @@ -236,6 +252,11 @@ public class PermissionTemplateDao implements Dao { permissionTemplateGroup.getPermission(), null, null, permissionTemplateGroup.getGroupUuid(), permissionTemplateGroup.getGroupName())); } + public void deleteGroupPermission(DbSession session, String templateUuid, @Nullable String groupUuid, ProjectPermission permission, String templateName, + @Nullable String groupName) { + deleteGroupPermission(session, templateUuid, groupUuid, permission.getKey(), templateName, groupName); + } + public void deleteGroupPermission(DbSession session, String templateUuid, @Nullable String groupUuid, String permission, String templateName, @Nullable String groupName) { PermissionTemplateGroupDto permissionTemplateGroup = new PermissionTemplateGroupDto() diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateGroupDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateGroupDto.java index 1bd6fc26ef1..94155be3d5c 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateGroupDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateGroupDto.java @@ -21,6 +21,7 @@ package org.sonar.db.permission.template; import java.util.Date; import javax.annotation.Nullable; +import org.sonar.db.permission.ProjectPermission; public class PermissionTemplateGroupDto { private String uuid; @@ -67,6 +68,10 @@ public class PermissionTemplateGroupDto { return this; } + public PermissionTemplateGroupDto setPermission(ProjectPermission permission) { + return setPermission(permission.getKey()); + } + public String getGroupName() { return groupName; } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java index 04b91bf0883..fcf9e17e0bb 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java @@ -74,7 +74,7 @@ public class ProjectDao implements Dao { if (keys.isEmpty()) { return emptyList(); } - return mapper(session).selectProjectsByKeys(keys); + return executeLargeInputs(keys, partition -> mapper(session).selectProjectsByKeys(partition)); } public List<ProjectDto> selectApplicationsByKeys(DbSession session, Set<String> keys) { @@ -175,4 +175,8 @@ public class ProjectDao implements Dao { public int countAiCodeFixDisabledProjects(DbSession session) { return mapper(session).countProjectsByAiCodeFixEnablement(false); } + + public Set<String> selectAiCodeFixEnabledProjectKeys(DbSession session) { + return mapper(session).selectProjectKeysByAiCodeFixEnablement(true); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java index 59c6850ad99..b92e7280879 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java @@ -21,6 +21,7 @@ package org.sonar.db.project; import java.util.Collection; import java.util.List; +import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.apache.ibatis.annotations.Param; @@ -83,4 +84,6 @@ public interface ProjectMapper { int countApplications(); int countProjectsByAiCodeFixEnablement(@Param("aiCodeFixEnabled") boolean aiCodeFixEnabled); + + Set<String> selectProjectKeysByAiCodeFixEnablement(@Param("aiCodeFixEnabled") boolean aiCodeFixEnabled); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java index 97d5ee872e4..824ea54b14e 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java @@ -179,6 +179,10 @@ public class PropertiesDao implements Dao { return getMapper(session).selectProjectPropertyByKey(key); } + public List<PropertyDto> selectUserPropertiesByKey(DbSession session, String key) { + return getMapper(session).selectUserPropertiesByKey(key); + } + /** * Saves the specified property and its value. * <p> diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java index c1685ad9a59..8fb96f382a2 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesMapper.java @@ -42,6 +42,8 @@ public interface PropertiesMapper { List<PropertyDto> selectProjectPropertyByKey(@Param("key") String key); + List<PropertyDto> selectUserPropertiesByKey(@Param("key") String key); + List<PropertyDto> selectByEntityUuids(@Param("entityUuids") List<String> entityUuids); List<PropertyDto> selectByQuery(@Param("query") PropertyQuery query); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/provisioning/DevOpsPermissionsMappingDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/provisioning/DevOpsPermissionsMappingDto.java index d1e8a396407..d1e6085d072 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/provisioning/DevOpsPermissionsMappingDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/provisioning/DevOpsPermissionsMappingDto.java @@ -19,5 +19,20 @@ */ package org.sonar.db.provisioning; +import org.apache.ibatis.annotations.AutomapConstructor; +import org.sonar.db.permission.ProjectPermission; + public record DevOpsPermissionsMappingDto(String uuid, String devOpsPlatform, String role, String sonarqubePermission) { + + @AutomapConstructor + public DevOpsPermissionsMappingDto { + } + + public DevOpsPermissionsMappingDto(String uuid, String devOpsPlatform, String role, ProjectPermission sonarqubePermission) { + this(uuid, devOpsPlatform, role, sonarqubePermission.getKey()); + } + + public ProjectPermission projectPermission() { + return ProjectPermission.fromKey(sonarqubePermission); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java index 9847cbc75a3..230d9aff010 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java @@ -523,4 +523,23 @@ class PurgeCommands { session.commit(); profiler.stop(); } + + public void deleteScaActivity(String componentUuid) { + profiler.start("deleteScaDependencies (sca_dependencies)"); + purgeMapper.deleteScaDependenciesByComponentUuid(componentUuid); + session.commit(); + profiler.stop(); + + profiler.start("deleteScaIssuesReleases (sca_issues_releases)"); + purgeMapper.deleteScaIssuesReleasesByComponentUuid(componentUuid); + session.commit(); + profiler.stop(); + + // sca_releases MUST be deleted last because dependencies and + // issues_releases only join to the component through sca_releases + profiler.start("deleteScaReleases (sca_releases)"); + purgeMapper.deleteScaReleasesByComponentUuid(componentUuid); + session.commit(); + profiler.stop(); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java index 0d0e13b89ab..ce5e0cf5e70 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java @@ -280,6 +280,7 @@ public class PurgeDao implements Dao { commands.deleteReportSchedules(branchUuid); commands.deleteReportSubscriptions(branchUuid); commands.deleteIssuesFixed(branchUuid); + commands.deleteScaActivity(branchUuid); } private static void deleteProject(String projectUuid, PurgeMapper mapper, PurgeCommands commands) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java index c7a312c905a..5ca08a12d7a 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java @@ -194,4 +194,10 @@ public interface PurgeMapper { void deleteAnticipatedTransitionsByProjectUuidAndCreationDate(@Param("projectUuid") String projectUuid, @Param("createdAtBefore") Long createdAtBefore); void deleteIssuesFixedByBranchUuid(@Param("branchUuid") String branchUuid); + + void deleteScaDependenciesByComponentUuid(@Param("componentUuid") String componentUuid); + + void deleteScaIssuesReleasesByComponentUuid(@Param("componentUuid") String componentUuid); + + void deleteScaReleasesByComponentUuid(@Param("componentUuid") String componentUuid); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDto.java index 7187f8d4c2c..0c4b7798934 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDto.java @@ -31,7 +31,6 @@ import org.apache.commons.lang3.builder.ToStringStyle; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.ActiveRule; import org.sonar.db.rule.RuleDto; import org.sonar.db.rule.SeverityUtil; @@ -39,8 +38,8 @@ import static java.util.Objects.requireNonNull; public class ActiveRuleDto { - public static final String INHERITED = ActiveRule.INHERITED; - public static final String OVERRIDES = ActiveRule.OVERRIDES; + public static final String INHERITED = "INHERITED"; + public static final String OVERRIDES = "OVERRIDES"; private static final Gson GSON = new Gson(); private static final Type TYPE = new TypeToken<Map<SoftwareQuality, Severity>>() { }.getType(); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ExportRuleDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ExportRuleDto.java index 8b847759942..ec68a1f28cb 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ExportRuleDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ExportRuleDto.java @@ -26,7 +26,7 @@ import java.util.Objects; import java.util.Set; import javax.annotation.CheckForNull; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.rule.SeverityUtil; public class ExportRuleDto { @@ -71,7 +71,7 @@ public class ExportRuleDto { } public RuleType getRuleType() { - return RuleType.valueOf(type); + return RuleType.fromDbConstant(type); } @CheckForNull diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/report/IssueFindingDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/report/IssueFindingDto.java index 43eeda81427..b3e75db1658 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/report/IssueFindingDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/report/IssueFindingDto.java @@ -22,7 +22,7 @@ package org.sonar.db.report; import java.util.List; import java.util.Set; import javax.annotation.CheckForNull; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.issue.ImpactDto; import org.sonar.db.rule.RuleDto; @@ -77,7 +77,7 @@ public class IssueFindingDto { } public RuleType getType() { - return RuleType.valueOf(type); + return RuleType.fromDbConstant(type); } public String getSeverity() { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java index 684cf6eca4a..c9dd18df7ba 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java @@ -36,7 +36,7 @@ import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.issue.ImpactDto; import static com.google.common.base.Preconditions.checkArgument; @@ -421,7 +421,7 @@ public class RuleDto { } public RuleType getEnumType() { - return RuleType.valueOf(type); + return RuleType.fromDbConstant(type); } public RuleDto setType(int type) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleForIndexingDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleForIndexingDto.java index f1041e97702..c03eb7c04f0 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleForIndexingDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleForIndexingDto.java @@ -28,7 +28,7 @@ import javax.annotation.CheckForNull; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.issue.ImpactDto; public class RuleForIndexingDto { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/user/RoleDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/user/RoleDao.java index 6c725d60262..bc823cc79a6 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/user/RoleDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/user/RoleDao.java @@ -19,33 +19,33 @@ */ package org.sonar.db.user; -import com.google.common.collect.ImmutableSet; import java.util.Collection; +import java.util.EnumSet; import java.util.List; import java.util.Set; -import org.sonar.api.web.UserRole; import org.sonar.db.Dao; import org.sonar.db.DbSession; +import org.sonar.db.permission.ProjectPermission; import static com.google.common.base.Preconditions.checkArgument; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; public class RoleDao implements Dao { - private static final Set<String> UNSUPPORTED_PROJECT_PERMISSIONS = ImmutableSet.of(USER, CODEVIEWER); + private static final Set<ProjectPermission> UNSUPPORTED_PROJECT_PERMISSIONS = EnumSet.of(USER, CODEVIEWER); /** * All the entities on which the user has {@code permission}, directly or through * groups. * - * @throws IllegalArgumentException this method does not support permissions {@link UserRole#USER user} nor - * {@link UserRole#CODEVIEWER codeviewer} because it does not support public root components. + * @throws IllegalArgumentException this method does not support permissions {@link ProjectPermission#USER user} nor + * {@link ProjectPermission#CODEVIEWER codeviewer} because it does not support public root components. */ - public List<String> selectEntityUuidsByPermissionAndUserUuidAndQualifier(DbSession dbSession, String permission, String userUuid, Collection<String> qualifiers) { + public List<String> selectEntityUuidsByPermissionAndUserUuidAndQualifier(DbSession dbSession, ProjectPermission permission, String userUuid, Collection<String> qualifiers) { checkArgument( !UNSUPPORTED_PROJECT_PERMISSIONS.contains(permission), "Permissions %s are not supported by selectEntityUuidsByPermissionAndUserUuidAndQualifier", UNSUPPORTED_PROJECT_PERMISSIONS); - return mapper(dbSession).selectEntityUuidsByPermissionAndUserUuidAndQualifier(permission, userUuid, qualifiers); + return mapper(dbSession).selectEntityUuidsByPermissionAndUserUuidAndQualifier(permission.getKey(), userUuid, qualifiers); } public void deleteGroupRolesByGroupUuid(DbSession session, String groupUuid) { diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml index 108d01369cc..64cae83c679 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml @@ -249,4 +249,12 @@ and ai_code_fix_enabled = #{aiCodeFixEnabled,jdbcType=BOOLEAN} </select> + <select id="selectProjectKeysByAiCodeFixEnablement" resultType="String"> + select p.kee + from projects p + where + p.qualifier = 'TRK' + and ai_code_fix_enabled = #{aiCodeFixEnabled,jdbcType=BOOLEAN} + </select> + </mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml index b186e885986..a6c5ca9e2e0 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml @@ -163,6 +163,16 @@ and p.user_uuid is null </select> + <select id="selectUserPropertiesByKey" parameterType="map" resultType="ScrapProperty"> + select + <include refid="columnsToScrapPropertyDto"/> + from properties p + inner join users u on u.uuid=p.user_uuid + where + p.prop_key = #{key, jdbcType=VARCHAR} + and p.entity_uuid is null + </select> + <select id="selectByQuery" parameterType="map" resultType="ScrapProperty"> select <include refid="columnsToScrapPropertyDto"/> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml index 3700a8df647..4a64f3cdeab 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml @@ -669,4 +669,15 @@ <delete id="deleteIssuesFixedByBranchUuid"> delete from issues_fixed where pull_request_uuid = #{branchUuid,jdbcType=VARCHAR} </delete> + + + <delete id="deleteScaDependenciesByComponentUuid"> + delete from sca_dependencies where sca_release_uuid in (select uuid from sca_releases where component_uuid = #{componentUuid,jdbcType=VARCHAR}) + </delete> + <delete id="deleteScaIssuesReleasesByComponentUuid"> + delete from sca_issues_releases where sca_release_uuid in (select uuid from sca_releases where component_uuid = #{componentUuid,jdbcType=VARCHAR}) + </delete> + <delete id="deleteScaReleasesByComponentUuid"> + delete from sca_releases where component_uuid = #{componentUuid,jdbcType=VARCHAR} + </delete> </mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml index f9310f514fb..a68739906c0 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml @@ -153,7 +153,7 @@ INNER JOIN org_qprofiles oqp ON oqp.rules_profile_uuid = rp.uuid INNER JOIN rules r ON r.uuid = a.rule_uuid AND r.status != 'REMOVED' WHERE - (a.impacts LIKE CONCAT('%', #{softwareQuality, jdbcType=VARCHAR}, '%') OR r.rule_type = 4) + (a.impacts LIKE CONCAT(CONCAT('%', #{softwareQuality, jdbcType=VARCHAR}), '%') OR r.rule_type = 4) AND oqp.uuid IN <foreach collection="profileUuids" item="uuid" separator="," open="(" close=")">#{uuid, jdbcType=VARCHAR}</foreach> </select> diff --git a/server/sonar-db-dao/src/schema/schema-sq.ddl b/server/sonar-db-dao/src/schema/schema-sq.ddl index 5e13a691d7a..33f9b380ce5 100644 --- a/server/sonar-db-dao/src/schema/schema-sq.ddl +++ b/server/sonar-db-dao/src/schema/schema-sq.ddl @@ -118,6 +118,16 @@ CREATE UNIQUE NULLS NOT DISTINCT INDEX "UNIQ_APP_PROJECTS" ON "APP_PROJECTS"("AP CREATE INDEX "IDX_APP_PROJ_APPLICATION_UUID" ON "APP_PROJECTS"("APPLICATION_UUID" NULLS FIRST); CREATE INDEX "IDX_APP_PROJ_PROJECT_UUID" ON "APP_PROJECTS"("PROJECT_UUID" NULLS FIRST); +CREATE TABLE "ARCHITECTURE_GRAPHS"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "BRANCH_UUID" CHARACTER VARYING(40) NOT NULL, + "SOURCE" CHARACTER VARYING(255) NOT NULL, + "TYPE" CHARACTER VARYING(255) NOT NULL, + "GRAPH_DATA" CHARACTER LARGE OBJECT NOT NULL +); +ALTER TABLE "ARCHITECTURE_GRAPHS" ADD CONSTRAINT "PK_ARCHITECTURE_GRAPHS" PRIMARY KEY("UUID"); +CREATE UNIQUE NULLS NOT DISTINCT INDEX "UQ_IDX_AG_BRANCH_TYPE_SOURCE" ON "ARCHITECTURE_GRAPHS"("BRANCH_UUID" NULLS FIRST, "TYPE" NULLS FIRST, "SOURCE" NULLS FIRST); + CREATE TABLE "AUDITS"( "UUID" CHARACTER VARYING(40) NOT NULL, "USER_UUID" CHARACTER VARYING(255) NOT NULL, @@ -389,9 +399,9 @@ ALTER TABLE "GROUPS" ADD CONSTRAINT "PK_GROUPS" PRIMARY KEY("UUID"); CREATE UNIQUE NULLS NOT DISTINCT INDEX "UNIQ_GROUPS_NAME" ON "GROUPS"("NAME" NULLS FIRST); CREATE TABLE "GROUPS_USERS"( + "UUID" CHARACTER VARYING(40) NOT NULL, "GROUP_UUID" CHARACTER VARYING(40) NOT NULL, - "USER_UUID" CHARACTER VARYING(255) NOT NULL, - "UUID" CHARACTER VARYING(40) NOT NULL + "USER_UUID" CHARACTER VARYING(255) NOT NULL ); ALTER TABLE "GROUPS_USERS" ADD CONSTRAINT "PK_GROUPS_USERS" PRIMARY KEY("UUID"); CREATE INDEX "INDEX_GROUPS_USERS_GROUP_UUID" ON "GROUPS_USERS"("GROUP_UUID" NULLS FIRST); @@ -1032,6 +1042,75 @@ CREATE TABLE "SAML_MESSAGE_IDS"( ALTER TABLE "SAML_MESSAGE_IDS" ADD CONSTRAINT "PK_SAML_MESSAGE_IDS" PRIMARY KEY("UUID"); CREATE UNIQUE NULLS NOT DISTINCT INDEX "SAML_MESSAGE_IDS_UNIQUE" ON "SAML_MESSAGE_IDS"("MESSAGE_ID" NULLS FIRST); +CREATE TABLE "SCA_DEPENDENCIES"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "SCA_RELEASE_UUID" CHARACTER VARYING(40) NOT NULL, + "DIRECT" BOOLEAN NOT NULL, + "SCOPE" CHARACTER VARYING(100) NOT NULL, + "USER_DEPENDENCY_FILE_PATH" CHARACTER VARYING(1000), + "LOCKFILE_DEPENDENCY_FILE_PATH" CHARACTER VARYING(1000), + "CHAINS" CHARACTER LARGE OBJECT, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL, + "NEW_IN_PULL_REQUEST" BOOLEAN DEFAULT FALSE NOT NULL, + "PRODUCTION_SCOPE" BOOLEAN DEFAULT TRUE NOT NULL +); +ALTER TABLE "SCA_DEPENDENCIES" ADD CONSTRAINT "PK_SCA_DEPENDENCIES" PRIMARY KEY("UUID"); +CREATE INDEX "SCA_DEPENDENCIES_RELEASE_UUID" ON "SCA_DEPENDENCIES"("SCA_RELEASE_UUID" NULLS FIRST); + +CREATE TABLE "SCA_ISSUES"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "SCA_ISSUE_TYPE" CHARACTER VARYING(40) NOT NULL, + "PACKAGE_URL" CHARACTER VARYING(400) NOT NULL, + "VULNERABILITY_ID" CHARACTER VARYING(63) NOT NULL, + "SPDX_LICENSE_ID" CHARACTER VARYING(127) NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL +); +ALTER TABLE "SCA_ISSUES" ADD CONSTRAINT "PK_SCA_ISSUES" PRIMARY KEY("UUID"); +CREATE UNIQUE NULLS NOT DISTINCT INDEX "SCA_ISSUES_UNIQUE" ON "SCA_ISSUES"("SCA_ISSUE_TYPE" NULLS FIRST, "VULNERABILITY_ID" NULLS FIRST, "PACKAGE_URL" NULLS FIRST, "SPDX_LICENSE_ID" NULLS FIRST); + +CREATE TABLE "SCA_ISSUES_RELEASES"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "SCA_ISSUE_UUID" CHARACTER VARYING(40) NOT NULL, + "SCA_RELEASE_UUID" CHARACTER VARYING(40) NOT NULL, + "SEVERITY" CHARACTER VARYING(15) NOT NULL, + "SEVERITY_SORT_KEY" INTEGER NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL +); +ALTER TABLE "SCA_ISSUES_RELEASES" ADD CONSTRAINT "PK_SCA_ISSUES_RELEASES" PRIMARY KEY("UUID"); +CREATE INDEX "SCA_ISSUES_RELEASES_SCA_ISSUE" ON "SCA_ISSUES_RELEASES"("SCA_ISSUE_UUID" NULLS FIRST); +CREATE INDEX "SCA_ISSUES_RELEASES_SCA_RELEAS" ON "SCA_ISSUES_RELEASES"("SCA_RELEASE_UUID" NULLS FIRST); +CREATE UNIQUE NULLS NOT DISTINCT INDEX "SCA_ISSUES_RELEASES_UNIQUE" ON "SCA_ISSUES_RELEASES"("SCA_ISSUE_UUID" NULLS FIRST, "SCA_RELEASE_UUID" NULLS FIRST); + +CREATE TABLE "SCA_RELEASES"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "COMPONENT_UUID" CHARACTER VARYING(40) NOT NULL, + "PACKAGE_URL" CHARACTER VARYING(400) NOT NULL, + "PACKAGE_MANAGER" CHARACTER VARYING(20) NOT NULL, + "PACKAGE_NAME" CHARACTER VARYING(400) NOT NULL, + "VERSION" CHARACTER VARYING(400) NOT NULL, + "LICENSE_EXPRESSION" CHARACTER VARYING(400) NOT NULL, + "KNOWN" BOOLEAN NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL, + "NEW_IN_PULL_REQUEST" BOOLEAN DEFAULT FALSE NOT NULL, + "DECLARED_LICENSE_EXPRESSION" CHARACTER VARYING(400) DEFAULT 'NOASSERTION' NOT NULL +); +ALTER TABLE "SCA_RELEASES" ADD CONSTRAINT "PK_SCA_RELEASES" PRIMARY KEY("UUID"); +CREATE INDEX "SCA_RELEASES_COMP_UUID_UUID" ON "SCA_RELEASES"("COMPONENT_UUID" NULLS FIRST, "UUID" NULLS FIRST); + +CREATE TABLE "SCA_VULNERABILITY_ISSUES"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "BASE_SEVERITY" CHARACTER VARYING(15) NOT NULL, + "CWE_IDS" CHARACTER VARYING(255) NOT NULL, + "CVSS_SCORE" DOUBLE PRECISION, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL +); +ALTER TABLE "SCA_VULNERABILITY_ISSUES" ADD CONSTRAINT "PK_SCA_VULNERABILITY_ISSUES" PRIMARY KEY("UUID"); + CREATE TABLE "SCANNER_ANALYSIS_CACHE"( "BRANCH_UUID" CHARACTER VARYING(40) NOT NULL, "DATA" BINARY LARGE OBJECT NOT NULL diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/createdb/PopulateDb.java b/server/sonar-db-dao/src/test/java/org/sonar/db/createdb/PopulateDb.java index c7821cf24d3..57d80bc8fc1 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/createdb/PopulateDb.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/createdb/PopulateDb.java @@ -39,7 +39,7 @@ import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.core.metric.SoftwareQualitiesMetrics; import org.sonar.core.util.UuidFactoryImpl; diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDtoTest.java index 790a9dd48b5..00e1d78fb3e 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDtoTest.java @@ -34,7 +34,7 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.core.issue.DefaultIssue; import org.sonar.db.protobuf.DbIssues; diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java index 6ccc07e07d6..e043370f381 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java @@ -28,7 +28,7 @@ import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.util.Uuids; import org.sonar.db.issue.ImpactDto; diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleForIndexingDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleForIndexingDtoTest.java index a9886bd355c..8a72fbe785e 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleForIndexingDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleForIndexingDtoTest.java @@ -25,7 +25,7 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rules.CleanCodeAttribute; import org.sonar.api.rules.CleanCodeAttributeCategory; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.issue.ImpactDto; import static org.assertj.core.api.Assertions.assertThat; diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java index e8915f097dd..866b89dfadb 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java @@ -42,7 +42,6 @@ import org.sonar.db.audit.AuditPersister; import org.sonar.db.audit.NoOpAuditPersister; import org.sonar.db.component.ComponentDbTester; import org.sonar.db.component.ProjectLinkDbTester; -import org.sonar.db.dependency.ProjectDependenciesDbTester; import org.sonar.db.event.EventDbTester; import org.sonar.db.favorite.FavoriteDbTester; import org.sonar.db.issue.IssueDbTester; @@ -97,7 +96,6 @@ public class DbTester extends AbstractDbTester<TestDbImpl> implements BeforeEach private final AlmPatsDbTester almPatsDbtester; private final AuditDbTester auditDbTester; private final AnticipatedTransitionDbTester anticipatedTransitionDbTester; - private final ProjectDependenciesDbTester projectDependenciesDbTester; private DbTester(UuidFactory uuidFactory, System2 system2, @Nullable String schemaPath, AuditPersister auditPersister, MyBatisConfExtension... confExtensions) { super(TestDbImpl.create(schemaPath, confExtensions)); @@ -130,7 +128,6 @@ public class DbTester extends AbstractDbTester<TestDbImpl> implements BeforeEach this.almPatsDbtester = new AlmPatsDbTester(this); this.auditDbTester = new AuditDbTester(this); this.anticipatedTransitionDbTester = new AnticipatedTransitionDbTester(this); - this.projectDependenciesDbTester = new ProjectDependenciesDbTester(this); } public static DbTester create() { @@ -153,6 +150,10 @@ public class DbTester extends AbstractDbTester<TestDbImpl> implements BeforeEach return new DbTester(new SequenceUuidFactory(), system2, null, new NoOpAuditPersister(), new DbTesterMyBatisConfExtension(firstMapperClass, otherMapperClasses)); } + public static DbTester createWithConfExtension(System2 system2, MyBatisConfExtension myBatisConfExtension) { + return new DbTester(new SequenceUuidFactory(), system2, null, new NoOpAuditPersister(), myBatisConfExtension); + } + public static DbTester createWithDifferentUuidFactory(UuidFactory uuidFactory) { return new DbTester(uuidFactory, System2.INSTANCE, null, new NoOpAuditPersister()); } @@ -278,10 +279,6 @@ public class DbTester extends AbstractDbTester<TestDbImpl> implements BeforeEach return anticipatedTransitionDbTester; } - public ProjectDependenciesDbTester projectDependencies() { - return projectDependenciesDbTester; - } - @Override public void afterEach(ExtensionContext context) throws Exception { after(); diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/dependency/ProjectDependenciesDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/dependency/ProjectDependenciesDbTester.java deleted file mode 100644 index e3c9b8d1430..00000000000 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/dependency/ProjectDependenciesDbTester.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.dependency; - -import java.util.function.Consumer; -import javax.annotation.Nullable; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; - -import static org.apache.commons.lang3.StringUtils.EMPTY; - -public class ProjectDependenciesDbTester { - private final DbTester db; - private final DbClient dbClient; - - public ProjectDependenciesDbTester(DbTester db) { - this.db = db; - this.dbClient = db.getDbClient(); - } - - public ProjectDependencyDto insertProjectDependency(String branchUuid) { - return insertProjectDependency(branchUuid, EMPTY, null); - } - - public ProjectDependencyDto insertProjectDependency(String branchUuid, String suffix) { - return insertProjectDependency(branchUuid, suffix, null); - } - - public ProjectDependencyDto insertProjectDependency(String branchUuid, String suffix, @Nullable Consumer<ComponentDto> dtoPopulator) { - ComponentDto componentDto = new ComponentDto().setUuid("uuid" + suffix) - .setKey("key" + suffix) - .setUuidPath("uuidPath" + suffix) - .setName("name" + suffix) - .setLongName("long_name" + suffix) - .setBranchUuid(branchUuid); - - if (dtoPopulator != null) { - dtoPopulator.accept(componentDto); - } - - db.components().insertComponent(componentDto); - var projectDependencyDto = new ProjectDependencyDto(componentDto.uuid(), "version" + suffix, "includePaths" + suffix, "packageManager" + suffix, 1L, 2L); - dbClient.projectDependenciesDao().insert(db.getSession(), projectDependencyDto); - return projectDependencyDto; - } -} diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java index 82112928b32..171ac2ea2de 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java @@ -24,7 +24,7 @@ import java.util.Random; import java.util.function.Consumer; import javax.annotation.Nullable; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssueComment; import org.sonar.core.issue.FieldDiffs; import org.sonar.core.util.Uuids; @@ -38,7 +38,7 @@ import org.sonar.db.user.UserDto; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Arrays.stream; import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.issue.IssueTesting.newIssue; diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/PermissionsTestHelper.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/PermissionsTestHelper.java index 740c25e5ccb..4f644ffe6e0 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/PermissionsTestHelper.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/PermissionsTestHelper.java @@ -20,7 +20,6 @@ package org.sonar.db.permission; import java.util.Set; -import org.sonar.api.web.UserRole; import static org.sonar.db.permission.GlobalPermission.APPLICATION_CREATOR; import static org.sonar.db.permission.GlobalPermission.PORTFOLIO_CREATOR; @@ -28,8 +27,9 @@ import static org.sonar.db.permission.GlobalPermission.SCAN; public class PermissionsTestHelper { - public static final Set<String> ALL_PERMISSIONS = Set.of(UserRole.ADMIN, UserRole.CODEVIEWER, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, - SCAN.getKey(), UserRole.USER, APPLICATION_CREATOR.getKey(), PORTFOLIO_CREATOR.getKey()); + public static final Set<String> ALL_PERMISSIONS = Set.of(ProjectPermission.ADMIN.getKey(), ProjectPermission.CODEVIEWER.getKey(), + ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), + SCAN.getKey(), ProjectPermission.USER.getKey(), APPLICATION_CREATOR.getKey(), PORTFOLIO_CREATOR.getKey()); private PermissionsTestHelper() { } diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/template/PermissionTemplateDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/template/PermissionTemplateDbTester.java index 981ffa9664c..4eb8168524e 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/template/PermissionTemplateDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/template/PermissionTemplateDbTester.java @@ -23,6 +23,7 @@ import java.util.function.Consumer; import javax.annotation.Nullable; import org.sonar.db.DbClient; import org.sonar.db.DbTester; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; @@ -68,32 +69,60 @@ public class PermissionTemplateDbTester { return templateInDb; } + public void addGroupToTemplate(PermissionTemplateDto permissionTemplate, GroupDto group, ProjectPermission permission) { + addGroupToTemplate(permissionTemplate, group, permission.getKey()); + } + public void addGroupToTemplate(PermissionTemplateDto permissionTemplate, GroupDto group, String permission) { addGroupToTemplate(permissionTemplate.getUuid(), group.getUuid(), permission, permissionTemplate.getName(), group.getName()); } + public void addGroupToTemplate(String templateUuid, @Nullable String groupUuid, ProjectPermission permission, String templateName, @Nullable String groupName) { + addGroupToTemplate(templateUuid, groupUuid, permission.getKey(), templateName, groupName); + } + public void addGroupToTemplate(String templateUuid, @Nullable String groupUuid, String permission, String templateName, @Nullable String groupName) { dbClient.permissionTemplateDao().insertGroupPermission(db.getSession(), templateUuid, groupUuid, permission, templateName, groupName); db.commit(); } + public void addAnyoneToTemplate(PermissionTemplateDto permissionTemplate, ProjectPermission permission) { + addAnyoneToTemplate(permissionTemplate, permission.getKey()); + } + public void addAnyoneToTemplate(PermissionTemplateDto permissionTemplate, String permission) { addGroupToTemplate(permissionTemplate.getUuid(), null, permission, permissionTemplate.getName(), null); } + public void addUserToTemplate(PermissionTemplateDto permissionTemplate, UserDto user, ProjectPermission permission) { + addUserToTemplate(permissionTemplate, user, permission.getKey()); + } + public void addUserToTemplate(PermissionTemplateDto permissionTemplate, UserDto user, String permission) { addUserToTemplate(permissionTemplate.getUuid(), user.getUuid(), permission, permissionTemplate.getName(), user.getName()); } + public void addUserToTemplate(String templateUuid, String userUuid, ProjectPermission permission, String templateName, String userLogin) { + addUserToTemplate(templateUuid, userUuid, permission.getKey(), templateName, userLogin); + } + public void addUserToTemplate(String templateUuid, String userUuid, String permission, String templateName, String userLogin) { dbClient.permissionTemplateDao().insertUserPermission(db.getSession(), templateUuid, userUuid, permission, templateName, userLogin); db.commit(); } + public void addProjectCreatorToTemplate(PermissionTemplateDto permissionTemplate, ProjectPermission permission) { + addProjectCreatorToTemplate(permissionTemplate, permission.getKey()); + } + public void addProjectCreatorToTemplate(PermissionTemplateDto permissionTemplate, String permission) { addProjectCreatorToTemplate(permissionTemplate.getUuid(), permission, permissionTemplate.getName()); } + public void addProjectCreatorToTemplate(String templateUuid, ProjectPermission permission, String templateName) { + addProjectCreatorToTemplate(templateUuid, permission.getKey(), templateName); + } + public void addProjectCreatorToTemplate(String templateUuid, String permission, String templateName) { dbClient.permissionTemplateCharacteristicDao().insert(db.getSession(), newPermissionTemplateCharacteristicDto() .setWithProjectCreator(true) diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleDbTester.java index 18bbfe1e700..a984b01cf27 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleDbTester.java @@ -23,12 +23,12 @@ import java.util.Arrays; import java.util.Random; import java.util.function.Consumer; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.util.Uuids; import org.sonar.db.DbTester; import static java.util.Arrays.asList; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.db.rule.RuleTesting.newDeprecatedRuleKey; import static org.sonar.db.rule.RuleTesting.newRule; diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java index 73a0b5a0993..cdb250e515d 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java @@ -31,7 +31,7 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RuleParamType; import org.sonar.core.util.UuidFactory; import org.sonar.core.util.UuidFactoryFast; @@ -44,7 +44,7 @@ import static com.google.common.collect.Sets.newHashSet; import static java.util.Arrays.stream; import static org.apache.commons.lang3.RandomStringUtils.secure; import static org.sonar.api.rule.RuleKey.EXTERNAL_RULE_REPO_PREFIX; -import static org.sonar.api.rules.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.CODE_SMELL; import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection; /** diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java index 0335b8fe354..26dcfbab451 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java @@ -28,18 +28,18 @@ import java.util.Set; import java.util.function.Consumer; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.sonar.db.component.ComponentQualifiers; import org.sonar.api.security.DefaultGroups; -import org.sonar.api.web.UserRole; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.BranchDto; import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.dismissmessage.MessageType; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; import org.sonar.db.permission.GroupPermissionDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.UserPermissionDto; import org.sonar.db.project.ProjectDto; import org.sonar.db.provisioning.GithubOrganizationGroupDto; @@ -51,10 +51,10 @@ import static java.util.Arrays.stream; import static java.util.stream.Collectors.toSet; import static org.apache.commons.lang3.RandomStringUtils.secure; import static org.sonar.db.permission.GlobalPermission.ADMINISTER; +import static org.sonar.db.permission.ProjectPermission.PUBLIC_PERMISSIONS; import static org.sonar.db.user.GroupTesting.newGroupDto; public class UserDbTester { - private static final Set<String> PUBLIC_PERMISSIONS = Set.of(UserRole.USER, UserRole.CODEVIEWER); public static final String PERMISSIONS_CANT_BE_GRANTED_ON_BRANCHES = "Permissions can't be granted on branches"; private final Random random = new SecureRandom(); @@ -253,10 +253,18 @@ public class UserDbTester { return dto; } + public GroupPermissionDto insertPermissionOnAnyone(ProjectPermission permission) { + return insertPermissionOnAnyone(permission.getKey()); + } + public GroupPermissionDto insertPermissionOnAnyone(GlobalPermission permission) { return insertPermissionOnAnyone(permission.getKey()); } + public Set<GroupPermissionDto> insertPermissionsOnGroup(GroupDto group, ProjectPermission... permissions) { + return insertPermissionsOnGroup(group, stream(permissions).map(ProjectPermission::getKey).toArray(String[]::new)); + } + public Set<GroupPermissionDto> insertPermissionsOnGroup(GroupDto group, String... permissions) { return stream(permissions) .map(p -> insertPermissionOnGroup(group, p)) @@ -277,9 +285,13 @@ public class UserDbTester { return insertPermissionOnGroup(group, permission.getKey()); } + public GroupPermissionDto insertPermissionOnGroup(GroupDto group, ProjectPermission permission) { + return insertPermissionOnGroup(group, permission.getKey()); + } + public GroupPermissionDto insertProjectPermissionOnAnyone(String permission, ComponentDto project) { checkArgument(!project.isPrivate(), "No permission to group AnyOne can be granted on a private project"); - checkArgument(!PUBLIC_PERMISSIONS.contains(permission), + checkArgument(!PUBLIC_PERMISSIONS.stream().map(ProjectPermission::getKey).collect(toSet()).contains(permission), "permission %s can't be granted on a public project", permission); Optional<BranchDto> branchDto = db.getDbClient().branchDao().selectByUuid(db.getSession(), project.branchUuid()); // I don't know if this check is worth it @@ -300,9 +312,13 @@ public class UserDbTester { return dto; } + public GroupPermissionDto insertEntityPermissionOnAnyone(ProjectPermission permission, EntityDto entity) { + return insertEntityPermissionOnAnyone(permission.getKey(), entity); + } + public GroupPermissionDto insertEntityPermissionOnAnyone(String permission, EntityDto entity) { checkArgument(!entity.isPrivate(), "No permission to group AnyOne can be granted on a private entity"); - checkArgument(!PUBLIC_PERMISSIONS.contains(permission), + checkArgument(!PUBLIC_PERMISSIONS.stream().map(ProjectPermission::getKey).collect(toSet()).contains(permission), "permission %s can't be granted on a public entity", permission); GroupPermissionDto dto = new GroupPermissionDto() .setUuid(Uuids.createFast()) @@ -315,13 +331,17 @@ public class UserDbTester { return dto; } - public void deleteProjectPermissionFromAnyone(EntityDto entity, String permission) { - db.getDbClient().groupPermissionDao().delete(db.getSession(), permission, null, null, entity); + public void deleteProjectPermissionFromAnyone(EntityDto entity, ProjectPermission permission) { + db.getDbClient().groupPermissionDao().delete(db.getSession(), permission.getKey(), null, null, entity); db.commit(); } + public GroupPermissionDto insertProjectPermissionOnGroup(GroupDto group, ProjectPermission permission, ComponentDto project) { + return insertProjectPermissionOnGroup(group, permission.getKey(), project); + } + public GroupPermissionDto insertProjectPermissionOnGroup(GroupDto group, String permission, ComponentDto project) { - checkArgument(project.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission), + checkArgument(project.isPrivate() || !PUBLIC_PERMISSIONS.stream().map(ProjectPermission::getKey).collect(toSet()).contains(permission), "%s can't be granted on a public project", permission); Optional<BranchDto> branchDto = db.getDbClient().branchDao().selectByUuid(db.getSession(), project.branchUuid()); // I don't know if this check is worth it @@ -343,12 +363,20 @@ public class UserDbTester { return dto; } + public Set<GroupPermissionDto> insertEntityPermissionsOnGroup(GroupDto group, EntityDto entity, ProjectPermission... permissions) { + return insertEntityPermissionsOnGroup(group, entity, stream(permissions).map(ProjectPermission::getKey).toArray(String[]::new)); + } + public Set<GroupPermissionDto> insertEntityPermissionsOnGroup(GroupDto group, EntityDto entity, String... permissions) { return stream(permissions) .map(permission -> insertEntityPermissionOnGroup(group, permission, entity)) .collect(toSet()); } + public GroupPermissionDto insertEntityPermissionOnGroup(GroupDto group, ProjectPermission permission, EntityDto entity) { + return insertEntityPermissionOnGroup(group, permission.getKey(), entity); + } + public GroupPermissionDto insertEntityPermissionOnGroup(GroupDto group, String permission, EntityDto entity) { checkArgument(entity.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission), "%s can't be granted on a public entity (project or portfolio)", permission); @@ -405,16 +433,20 @@ public class UserDbTester { db.commit(); } - public void deletePermissionFromUser(EntityDto project, UserDto user, String permission) { - db.getDbClient().userPermissionDao().deleteEntityPermission(db.getSession(), user, permission, project); + public void deletePermissionFromUser(EntityDto project, UserDto user, ProjectPermission permission) { + db.getDbClient().userPermissionDao().deleteEntityPermission(db.getSession(), user, permission.getKey(), project); db.commit(); } /** * Grant permission on given project */ + public UserPermissionDto insertProjectPermissionOnUser(UserDto user, ProjectPermission permission, ComponentDto project) { + return insertProjectPermissionOnUser(user, permission.getKey(), project); + } + public UserPermissionDto insertProjectPermissionOnUser(UserDto user, String permission, ComponentDto project) { - checkArgument(project.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission), + checkArgument(project.isPrivate() || !PUBLIC_PERMISSIONS.stream().map(ProjectPermission::getKey).collect(toSet()).contains(permission), "%s can't be granted on a public project", permission); EntityDto entityDto; if (project.qualifier().equals(ComponentQualifiers.VIEW) || project.qualifier().equals(ComponentQualifiers.SUBVIEW)) { @@ -436,8 +468,12 @@ public class UserDbTester { return dto; } + public UserPermissionDto insertProjectPermissionOnUser(UserDto user, ProjectPermission permission, EntityDto project) { + return insertProjectPermissionOnUser(user, permission.getKey(), project); + } + public UserPermissionDto insertProjectPermissionOnUser(UserDto user, String permission, EntityDto project) { - checkArgument(project.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission), + checkArgument(project.isPrivate() || !ProjectPermission.isPublic(permission), "%s can't be granted on a public project", permission); UserPermissionDto dto = new UserPermissionDto(Uuids.create(), permission, user.getUuid(), project.getUuid()); db.getDbClient().userPermissionDao().insert(db.getSession(), dto, project, user, null); diff --git a/server/sonar-db-migration/src/docs/table_ownership.md b/server/sonar-db-migration/src/docs/table_ownership.md index f988a75eb27..416545f4cbf 100644 --- a/server/sonar-db-migration/src/docs/table_ownership.md +++ b/server/sonar-db-migration/src/docs/table_ownership.md @@ -94,6 +94,11 @@ Important read: [Data Ownership Principles](https://xtranet-sonarsource.atlassia | rules_parameters | | | rules_profiles | Dev and Team Workflow Squad | | saml_message_ids | | +| sca_dependencies | SCA Squad | +| sca_issues | SCA Squad | +| sca_issues_releases | SCA Squad | +| sca_releases | SCA Squad | +| sca_vulnerability_issues | SCA Squad | | scanner_analysis_cache | | | schema_migrations | | | scim_groups | | diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v00/CreateInitialSchemaIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v00/CreateInitialSchemaIT.java index ac9362850c5..9c965a93899 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v00/CreateInitialSchemaIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v00/CreateInitialSchemaIT.java @@ -60,6 +60,7 @@ class CreateInitialSchemaIT { .containsOnly( "active_rules", "active_rule_parameters", + "anticipated_transitions", "app_branch_project_branch", "alm_pats", "app_projects", @@ -73,23 +74,31 @@ class CreateInitialSchemaIT { "ce_task_characteristics", "ce_task_input", "ce_task_message", + "cves", + "cve_cwe", "components", "default_qprofiles", "deprecated_rule_keys", + "devops_perms_mapping", "duplications_index", "es_queue", "events", "event_component_changes", + "external_groups", "file_sources", + "github_orgs_groups", "groups", "groups_users", "group_roles", "internal_component_props", "internal_properties", "issues", + "issues_dependency", + "issues_fixed", + "issues_impacts", "issue_changes", - "live_measures", "metrics", + "measures", "new_code_periods", "new_code_reference_issues", "notifications", @@ -106,8 +115,8 @@ class CreateInitialSchemaIT { "projects", "project_badge_token", "project_branches", + "project_dependencies", "project_links", - "project_mappings", "project_measures", "project_qprofiles", "project_qgates", @@ -120,6 +129,12 @@ class CreateInitialSchemaIT { "qprofile_edit_users", "quality_gates", "quality_gate_conditions", + "report_schedules", + "report_subscriptions", + "rule_changes", + "rule_impact_changes", + "rule_tags", + "rules_default_impacts", "rules", "rules_parameters", "rules_profiles", @@ -128,9 +143,12 @@ class CreateInitialSchemaIT { "saml_message_ids", "scanner_analysis_cache", "schema_migrations", + "scim_groups", "scim_users", + "scm_accounts", "session_tokens", "snapshots", + "telemetry_metrics_sent", "users", "user_dismissed_messages", "user_roles", diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v00/PopulateInitialSchemaIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v00/PopulateInitialSchemaIT.java index 8cd32fb3219..1a4052d78fd 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v00/PopulateInitialSchemaIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v00/PopulateInitialSchemaIT.java @@ -36,6 +36,7 @@ import org.sonar.core.platform.SonarQubeVersion; import org.sonar.core.util.UuidFactory; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.MigrationDbTester; +import org.sonar.server.platform.db.migration.history.MigrationHistory; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -50,15 +51,18 @@ class PopulateInitialSchemaIT { private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); private final System2 system2 = mock(System2.class); private final SonarQubeVersion sonarQubeVersion = mock(SonarQubeVersion.class); + private final MigrationHistory migrationHistory = mock(MigrationHistory.class); @RegisterExtension public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulateInitialSchema.class); - private final PopulateInitialSchema underTest = new PopulateInitialSchema(db.database(), system2, uuidFactory, sonarQubeVersion); + private final PopulateInitialSchema underTest = new PopulateInitialSchema(db.database(), system2, uuidFactory, sonarQubeVersion, + migrationHistory); @BeforeEach public void setUp() { when(sonarQubeVersion.get()).thenReturn(version); + when(migrationHistory.getInitialDbVersion()).thenReturn(-1L); } @Test @@ -179,7 +183,7 @@ class PopulateInitialSchemaIT { "text_value as \"VAL\"," + "created_at as \"CREATED_AT\" " + " from properties"); - assertThat(rows).hasSize(4); + assertThat(rows).hasSize(5); Map<String, Map<String, Object>> rowsByKey = rows.stream().collect(Collectors.toMap(t -> (String) t.get("PROP_KEY"), Function.identity())); verifyProperty(rowsByKey, "sonar.forceAuthentication", "true"); diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/AddNclocToProjectsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/AddNclocToProjectsIT.java deleted file mode 100644 index 545df59e5aa..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/AddNclocToProjectsIT.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class AddNclocToProjectsIT { - - private static final String TABLE_NAME = "projects"; - private static final String COLUMN_NAME = "ncloc"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddNclocToProjects.class); - private final DdlChange underTest = new AddNclocToProjects(db.database()); - - @Test - void add_column() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.BIGINT, null, true); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.BIGINT, null, true); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/CreateScimGroupsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/CreateScimGroupsTableIT.java deleted file mode 100644 index eda88d6eeb8..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/CreateScimGroupsTableIT.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.version.v100.CreateScimGroupsTable.TABLE_NAME; - -class CreateScimGroupsTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateScimGroupsTable.class); - - private final DdlChange underTest = new CreateScimGroupsTable(db.database()); - - @Test - void migration_should_create_a_table() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - underTest.execute(); - - db.assertTableExists(TABLE_NAME); - db.assertColumnDefinition(TABLE_NAME, "scim_uuid", Types.VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, "group_uuid", Types.VARCHAR, UUID_SIZE, false); - db.assertPrimaryKey(TABLE_NAME, "pk_scim_groups", "scim_uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - underTest.execute(); - // re-entrant - underTest.execute(); - - db.assertTableExists(TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropBModuleUuidInComponentsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropBModuleUuidInComponentsIT.java deleted file mode 100644 index afe49078337..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropBModuleUuidInComponentsIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropBModuleUuidInComponentsIT { - private static final String TABLE_NAME = "components"; - private static final String COLUMN_NAME = "b_module_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropBModuleUuidInComponents.class); - private final DdlChange underTest = new DropBModuleUuidInComponents(db.database()); - - @Test - void drops_column() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 50, true); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 50, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropBModuleUuidPathInComponentsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropBModuleUuidPathInComponentsIT.java deleted file mode 100644 index f5004803d9b..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropBModuleUuidPathInComponentsIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropBModuleUuidPathInComponentsIT { - private static final String TABLE_NAME = "components"; - private static final String COLUMN_NAME = "b_module_uuid_path"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropBModuleUuidPathInComponents.class); - private final DdlChange underTest = new DropBModuleUuidPathInComponents(db.database()); - - @Test - void drops_column() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 1500, true); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 1500, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropIndexProjectsModuleUuidInComponentsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropIndexProjectsModuleUuidInComponentsIT.java deleted file mode 100644 index c91d3c11905..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropIndexProjectsModuleUuidInComponentsIT.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropIndexProjectsModuleUuidInComponentsIT { - private static final String TABLE_NAME = "components"; - private static final String COLUMN_NAME = "module_uuid"; - private static final String INDEX_NAME = "projects_module_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropIndexProjectsModuleUuidInComponents.class); - private final DdlChange underTest = new DropIndexProjectsModuleUuidInComponents(db.database()); - - @Test - void drops_index() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - underTest.execute(); - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - } - - @Test - void execute_whenIndexNameWithPrefix_shouldStillDelete() throws SQLException { - String alteredIndexName = "idx_1234567891345678916456789_" + INDEX_NAME; - db.renameIndex(TABLE_NAME, INDEX_NAME, alteredIndexName); - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - db.assertIndex(TABLE_NAME, alteredIndexName, COLUMN_NAME); - underTest.execute(); - db.assertIndexDoesNotExist(TABLE_NAME, alteredIndexName); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropModuleUuidInComponentsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropModuleUuidInComponentsIT.java deleted file mode 100644 index 9252b3b90ee..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropModuleUuidInComponentsIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropModuleUuidInComponentsIT { - private static final String TABLE_NAME = "components"; - private static final String COLUMN_NAME = "module_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropModuleUuidInComponents.class); - private final DdlChange underTest = new DropModuleUuidInComponents(db.database()); - - @Test - void drops_column() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 50, true); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 50, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropModuleUuidPathInComponentsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropModuleUuidPathInComponentsIT.java deleted file mode 100644 index 1dd6526905b..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropModuleUuidPathInComponentsIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropModuleUuidPathInComponentsIT { - private static final String TABLE_NAME = "components"; - private static final String COLUMN_NAME = "module_uuid_path"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropModuleUuidPathInComponents.class); - private final DdlChange underTest = new DropModuleUuidPathInComponents(db.database()); - - @Test - void drops_column() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 1500, true); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 1500, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropRootUuidInComponentsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropRootUuidInComponentsIT.java deleted file mode 100644 index 652ac5b330c..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropRootUuidInComponentsIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropRootUuidInComponentsIT { - private static final String TABLE_NAME = "components"; - private static final String COLUMN_NAME = "root_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropRootUuidInComponents.class); - private final DdlChange underTest = new DropRootUuidInComponents(db.database()); - - @Test - void drops_column() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 50, false); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 50, false); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropScimUserProvisioningIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropScimUserProvisioningIT.java deleted file mode 100644 index 46df6158f77..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropScimUserProvisioningIT.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; - -class DropScimUserProvisioningIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropScimUserProvisioning.class); - private final DataChange underTest = new DropScimUserProvisioning(db.database()); - - @Test - void migration_should_truncate_scim_users_table() throws SQLException { - insertScimUser(1); - insertScimUser(2); - - underTest.execute(); - - assertThat(db.select("select * from scim_users")).isEmpty(); - } - - private void insertScimUser(long id) { - db.executeInsert("scim_users", - "scim_uuid", "any-scim-uuid-" + id, - "user_uuid", "any-user-uuid-" + id - ); - } - - @Test - void migration_is_reentrant() throws SQLException { - insertScimUser(1); - insertScimUser(2); - - underTest.execute(); - underTest.execute(); - assertThat(db.select("select * from scim_users")).isEmpty(); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropSonarScimEnabledPropertyIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropSonarScimEnabledPropertyIT.java deleted file mode 100644 index 2f98f95049e..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropSonarScimEnabledPropertyIT.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -class DropSonarScimEnabledPropertyIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropSonarScimEnabledProperty.class); - private final DataChange underTest = new DropSonarScimEnabledProperty(db.database()); - - @Test - void migration_should_remove_scim_property() throws SQLException { - insertScimProperty(db); - - underTest.execute(); - - Assertions.assertThat(db.select("select * from properties")).isEmpty(); - } - - @Test - void migration_is_reentrant() throws SQLException { - insertScimProperty(db); - - underTest.execute(); - underTest.execute(); - - Assertions.assertThat(db.select("select * from properties")).isEmpty(); - } - - private void insertScimProperty(MigrationDbTester db) { - db.executeInsert("properties ", - "prop_key", "sonar.scim.enabled", - "is_empty", false, - "text_value", "true", - "created_at", 100_000L, - "uuid", "some-random-uuid" - ); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/LogMessageIfSonarScimEnabledPresentPropertyIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/LogMessageIfSonarScimEnabledPresentPropertyIT.java deleted file mode 100644 index adaa135d410..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/LogMessageIfSonarScimEnabledPresentPropertyIT.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.slf4j.event.Level; -import org.sonar.api.testfixtures.log.LogTesterJUnit5; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.platform.db.migration.version.v100.LogMessageIfSonarScimEnabledPresentProperty.SONAR_SCIM_ENABLED; - -class LogMessageIfSonarScimEnabledPresentPropertyIT { - - @RegisterExtension - public final LogTesterJUnit5 logger = new LogTesterJUnit5(); - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(LogMessageIfSonarScimEnabledPresentProperty.class); - private final DataChange underTest = new LogMessageIfSonarScimEnabledPresentProperty(db.database()); - - @BeforeEach - public void before() { - logger.clear(); - } - - @Test - void migration_should_log_message_when_scim_property() throws SQLException { - db.executeInsert("properties ", - "prop_key", "sonar.scim.enabled", - "is_empty", false, - "text_value", "true", - "created_at", 100_000L, - "uuid", "some-random-uuid" - ); - - underTest.execute(); - - assertThat(logger.logs(Level.WARN)) - .hasSize(1) - .containsExactly("'" + SONAR_SCIM_ENABLED + "' property is defined but not read anymore. Please read the upgrade notes" + - " for the instruction to upgrade. User provisioning is deactivated until reactivated from the SonarQube" + - " Administration Interface (\"General->Authentication\"). " - + "See documentation: https://docs.sonarsource.com/sonarqube/10.1/instance-administration/authentication/saml/scim/overview/"); - } - - @Test - void migration_should_not_log_if_no_scim_property() throws SQLException { - - underTest.execute(); - - assertThat(logger.logs(Level.WARN)).isEmpty(); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.executeInsert("properties ", - "prop_key", "sonar.scim.enabled", - "is_empty", false, - "text_value", "true", - "created_at", 100_000L, - "uuid", "some-random-uuid" - ); - - underTest.execute(); - underTest.execute(); - - assertThat(logger.logs(Level.WARN)).hasSize(2); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/PopulateNclocForForProjectsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/PopulateNclocForForProjectsIT.java deleted file mode 100644 index 5c47eafbdc0..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/PopulateNclocForForProjectsIT.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.UuidFactory; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.apache.commons.lang3.RandomStringUtils.secure; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; - -class PopulateNclocForForProjectsIT { - - private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulateNclocForForProjects.class); - - private final DataChange underTest = new PopulateNclocForForProjects(db.database()); - - @Test - void migration_populates_ncloc_for_projects() throws SQLException { - Map<String, Long> expectedNclocByProjectUuid = populateData(); - underTest.execute(); - verifyNclocCorrectlyPopulatedForProjects(expectedNclocByProjectUuid); - } - - @Test - void migration_does_nothing_if_live_measures_table_is_missing() { - db.executeDdl("drop table live_measures"); - db.assertTableDoesNotExist("live_measures"); - - assertThatCode(underTest::execute) - .doesNotThrowAnyException(); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - Map<String, Long> expectedNclocByProjectUuid = populateData(); - underTest.execute(); - // re-entrant - underTest.execute(); - verifyNclocCorrectlyPopulatedForProjects(expectedNclocByProjectUuid); - } - - private Map<String, Long> populateData() { - String nclocMetricUuid = insertMetric("ncloc"); - - String projectUuid1 = insertProject(); - String project1Branch1 = insertProjectBranch(projectUuid1); - String project1Branch2 = insertProjectBranch(projectUuid1); - - long project1maxNcloc = 100; - insertLiveMeasure(nclocMetricUuid, projectUuid1, project1Branch1, 80L); - insertLiveMeasure(nclocMetricUuid, projectUuid1, project1Branch2, project1maxNcloc); - - String otherMetricUuid = insertMetric("other"); - insertLiveMeasure(otherMetricUuid, projectUuid1, project1Branch1, 5000L); - insertLiveMeasure(otherMetricUuid, projectUuid1, project1Branch2, 6000L); - - String projectUuid2 = insertProject(); - String project2Branch1 = insertProjectBranch(projectUuid2); - String project2Branch2 = insertProjectBranch(projectUuid2); - String project2Branch3 = insertProjectBranch(projectUuid2); - - long project2maxNcloc = 60; - insertLiveMeasure(nclocMetricUuid, projectUuid2, project2Branch1, 20L); - insertLiveMeasure(nclocMetricUuid, projectUuid2, project2Branch2, 50L); - insertLiveMeasure(nclocMetricUuid, projectUuid2, project2Branch3, project2maxNcloc); - - return Map.of(projectUuid1, project1maxNcloc, projectUuid2, project2maxNcloc); - } - - private void verifyNclocCorrectlyPopulatedForProjects(Map<String, Long> expectedNclocByProjectUuid) { - for (Map.Entry<String, Long> entry : expectedNclocByProjectUuid.entrySet()) { - String query = String.format("select ncloc from projects where uuid='%s'", entry.getKey()); - Long nclocFromProject = (Long) db.selectFirst(query).get("NCLOC"); - assertThat(nclocFromProject).isEqualTo(entry.getValue()); - } - } - - private String insertMetric(String name) { - Map<String, Object> map = new HashMap<>(); - String uuid = uuidFactory.create(); - map.put("UUID", uuid); - map.put("NAME", name); - db.executeInsert("metrics", map); - return uuid; - } - - private String insertProject() { - Map<String, Object> map = new HashMap<>(); - String uuid = uuidFactory.create(); - map.put("UUID", uuid); - map.put("KEE", secure().nextAlphabetic(20)); - map.put("QUALIFIER", "TRK"); - map.put("PRIVATE", true); - map.put("UPDATED_AT", System.currentTimeMillis()); - db.executeInsert("projects", map); - return uuid; - } - - private String insertProjectBranch(String projectUuid) { - Map<String, Object> map = new HashMap<>(); - String uuid = uuidFactory.create(); - map.put("UUID", uuid); - map.put("PROJECT_UUID", projectUuid); - map.put("KEE", secure().nextAlphabetic(20)); - map.put("BRANCH_TYPE", "PULL_REQUEST"); - map.put("UPDATED_AT", System.currentTimeMillis()); - map.put("CREATED_AT", System.currentTimeMillis()); - map.put("NEED_ISSUE_SYNC", false); - db.executeInsert("project_branches", map); - return uuid; - } - - private void insertLiveMeasure(String metricUuid, String projectUuid, String componentUuid, Long value) { - Map<String, Object> map = new HashMap<>(); - String uuid = uuidFactory.create(); - map.put("UUID", uuid); - map.put("PROJECT_UUID", projectUuid); - map.put("COMPONENT_UUID", componentUuid); - map.put("METRIC_UUID", metricUuid); - map.put("VALUE", value); - map.put("UPDATED_AT", System.currentTimeMillis()); - map.put("CREATED_AT", System.currentTimeMillis()); - db.executeInsert("live_measures", map); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/RemoveOrphanRulesFromQualityProfilesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/RemoveOrphanRulesFromQualityProfilesIT.java deleted file mode 100644 index 226fd4d6619..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/RemoveOrphanRulesFromQualityProfilesIT.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.utils.System2; -import org.sonar.core.util.SequenceUuidFactory; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.core.util.SequenceUuidFactory.UUID_1; - -class RemoveOrphanRulesFromQualityProfilesIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RemoveOrphanRulesFromQualityProfiles.class); - private final System2 system2 = mock(System2.class); - private final UuidFactory instance = new SequenceUuidFactory(); - private final DataChange underTest = new RemoveOrphanRulesFromQualityProfiles(db.database(), instance, system2); - - @BeforeEach - public void before() { - when(system2.now()).thenReturn(1L); - } - - @Test - void migration_should_remove_orphans() throws SQLException { - insertData(); - - underTest.execute(); - - assertOrphanRuleRemoved(); - assertQualityProfileChanges(); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - insertData(); - - // re-entrant - underTest.execute(); - underTest.execute(); - - assertOrphanRuleRemoved(); - assertQualityProfileChanges(); - } - - private void insertData() { - insertRule("uuid-rule-1", "language-1", "rule1"); - insertRule("uuid-rule-2", "language-2", "rule2"); - insertProfile("uuid-profile-1", "language-1"); - insertProfile("uuid-profile-2", "language-2"); - activateRule("uuid-active-rule-1", "uuid-profile-1", "uuid-rule-1"); - activateRule("uuid-active-rule-2", "uuid-profile-1", "uuid-rule-2"); - activateRule("uuid-active-rule-3", "uuid-profile-2", "uuid-rule-2"); - } - - private void insertRule(String uuid, String language, String ruleKey) { - Map<String, Object> rule = new HashMap<>(); - rule.put("uuid", uuid); - rule.put("plugin_rule_key", language + ":" + ruleKey); - rule.put("plugin_name", "plugin-name-1"); - rule.put("scope", "MAIN"); - rule.put("language", language); - rule.put("is_template", false); - rule.put("is_ad_hoc", false); - rule.put("is_external", false); - db.executeInsert("rules", rule); - } - - private void insertProfile(String uuid, String language) { - Map<String, Object> profile = new HashMap<>(); - profile.put("uuid", uuid); - profile.put("name", "profile-name-1"); - profile.put("language", language); - profile.put("is_built_in", false); - db.executeInsert("rules_profiles", profile); - } - - private void activateRule(String activeRuleUuid, String profileUuid, String ruleUuid) { - Map<String, Object> active_rule = new HashMap<>(); - active_rule.put("uuid", activeRuleUuid); - active_rule.put("failure_level", 3); - active_rule.put("profile_uuid", profileUuid); - active_rule.put("rule_uuid", ruleUuid); - db.executeInsert("active_rules", active_rule); - } - - private void assertOrphanRuleRemoved() { - assertThat(db.select("SELECT * from active_rules")) - .extracting(r -> r.get("UUID")) - .containsExactly("uuid-active-rule-1", "uuid-active-rule-3"); - } - - private void assertQualityProfileChanges() { - assertThat(db.select("SELECT * from qprofile_changes")) - .extracting(r -> r.get("KEE"), r -> r.get("RULES_PROFILE_UUID"), r -> r.get("CHANGE_TYPE"), r -> r.get("USER_UUID"), r -> r.get("CHANGE_DATA"), r -> r.get("CREATED_AT")) - .containsExactly(tuple(UUID_1, "uuid-profile-1", "DEACTIVATED", null, "ruleUuid=uuid-rule-2", 1L)); - } - - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/UpdateUserLocalValueInUsersIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/UpdateUserLocalValueInUsersIT.java deleted file mode 100644 index 294a8963e5a..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/UpdateUserLocalValueInUsersIT.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.UuidFactory; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.apache.commons.lang3.RandomStringUtils.secure; -import static org.assertj.core.api.Assertions.assertThat; - -class UpdateUserLocalValueInUsersIT { - - private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(UpdateUserLocalValueInUsers.class); - - private final DataChange underTest = new UpdateUserLocalValueInUsers(db.database()); - - @Test - void migration_updates_user_local_if_null() throws SQLException { - String userUuid1 = insertUser(true); - String userUuid2 = insertUser(false); - String userUuid3 = insertUser(null); - - underTest.execute(); - - assertUserLocalIsUpdatedCorrectly(userUuid1, true); - assertUserLocalIsUpdatedCorrectly(userUuid2, false); - assertUserLocalIsUpdatedCorrectly(userUuid3, true); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - String userUuid1 = insertUser(true); - String userUuid2 = insertUser(false); - String userUuid3 = insertUser(null); - - underTest.execute(); - // re-entrant - underTest.execute(); - - assertUserLocalIsUpdatedCorrectly(userUuid1, true); - assertUserLocalIsUpdatedCorrectly(userUuid2, false); - assertUserLocalIsUpdatedCorrectly(userUuid3, true); - } - - private void assertUserLocalIsUpdatedCorrectly(String userUuid, boolean expected) { - String selectSql = String.format("select user_local from users where uuid='%s'", userUuid); - assertThat(db.select(selectSql).stream() - .map(row -> row.get("USER_LOCAL")) - .toList()) - .containsExactlyInAnyOrder(expected); - } - - private String insertUser(Boolean userLocal) { - Map<String, Object> map = new HashMap<>(); - String uuid = uuidFactory.create(); - map.put("UUID", uuid); - map.put("LOGIN", secure().nextAlphabetic(20)); - map.put("EXTERNAL_LOGIN", secure().nextAlphabetic(20)); - map.put("EXTERNAL_IDENTITY_PROVIDER", "sonarqube"); - map.put("EXTERNAL_ID", secure().nextNumeric(5)); - map.put("CREATED_AT", System.currentTimeMillis()); - map.put("USER_LOCAL", userLocal); - map.put("RESET_PASSWORD", false); - db.executeInsert("users", map); - return uuid; - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AddCodeVariantsColumnInIssuesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AddCodeVariantsColumnInIssuesTableIT.java deleted file mode 100644 index e5bad3ef96b..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AddCodeVariantsColumnInIssuesTableIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; - -class AddCodeVariantsColumnInIssuesTableIT { - - private static final String TABLE_NAME = "issues"; - private static final String COLUMN_NAME = "code_variants"; - private static final int COLUMN_SIZE = 4000; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddCodeVariantsColumnInIssuesTable.class); - private final AddCodeVariantsColumnInIssuesTable underTest = new AddCodeVariantsColumnInIssuesTable(db.database()); - - @Test - void migration_should_add_column() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, COLUMN_SIZE, true); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, COLUMN_SIZE, true); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AddReportSubscriptionsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AddReportSubscriptionsTableIT.java deleted file mode 100644 index 0eb52dbc866..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AddReportSubscriptionsTableIT.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.version.v101.AddReportSubscriptionsTable.TABLE_NAME; - -class AddReportSubscriptionsTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddReportSubscriptionsTable.class); - - private final DdlChange underTest = new AddReportSubscriptionsTable(db.database()); - - @Test - void migration_should_create_a_table() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - underTest.execute(); - - db.assertTableExists(TABLE_NAME); - db.assertColumnDefinition(TABLE_NAME, "uuid", Types.VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, "portfolio_uuid", Types.VARCHAR, UUID_SIZE, true); - db.assertColumnDefinition(TABLE_NAME, "branch_uuid", Types.VARCHAR, UUID_SIZE, true); - db.assertColumnDefinition(TABLE_NAME, "user_uuid", Types.VARCHAR, UUID_SIZE, false); - db.assertPrimaryKey(TABLE_NAME, "pk_report_subscriptions", "uuid"); - - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - underTest.execute(); - // re-entrant - underTest.execute(); - - db.assertTableExists(TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AlterIsMainColumnInProjectBranchesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AlterIsMainColumnInProjectBranchesIT.java deleted file mode 100644 index f62e1edbd23..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AlterIsMainColumnInProjectBranchesIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.BOOLEAN; - -class AlterIsMainColumnInProjectBranchesIT { - - private static final String TABLE_NAME = "project_branches"; - private static final String COLUMN_NAME = "is_main"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AlterIsMainColumnInProjectBranches.class); - private final AlterIsMainColumnInProjectBranches underTest = new AlterIsMainColumnInProjectBranches(db.database()); - - @Test - void execute_shouldNotBeNullable() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, true); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, false); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, false); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateExternalGroupsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateExternalGroupsTableIT.java deleted file mode 100644 index ac82425e781..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateExternalGroupsTableIT.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.version.v101.CreateExternalGroupsTable.EXTERNAL_GROUP_ID_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateExternalGroupsTable.EXTERNAL_IDENTITY_PROVIDER_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateExternalGroupsTable.GROUP_UUID_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateExternalGroupsTable.TABLE_NAME; - -class CreateExternalGroupsTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateExternalGroupsTable.class); - - private final DdlChange createExternalGroupsTable = new CreateExternalGroupsTable(db.database()); - - @Test - void migration_should_create_a_table() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - createExternalGroupsTable.execute(); - - db.assertTableExists(TABLE_NAME); - db.assertColumnDefinition(TABLE_NAME, GROUP_UUID_COLUMN_NAME, Types.VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, EXTERNAL_GROUP_ID_COLUMN_NAME, Types.VARCHAR, 255, false); - db.assertColumnDefinition(TABLE_NAME, EXTERNAL_IDENTITY_PROVIDER_COLUMN_NAME, Types.VARCHAR, 100, false); - db.assertPrimaryKey(TABLE_NAME, "pk_external_groups", GROUP_UUID_COLUMN_NAME); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - createExternalGroupsTable.execute(); - // re-entrant - createExternalGroupsTable.execute(); - - db.assertTableExists(TABLE_NAME); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexForEmailOnUsersTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexForEmailOnUsersTableIT.java deleted file mode 100644 index 77a057b360e..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexForEmailOnUsersTableIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v101.CreateIndexForEmailOnUsersTable.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateIndexForEmailOnUsersTable.INDEX_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateIndexForEmailOnUsersTable.TABLE_NAME; - -class CreateIndexForEmailOnUsersTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexForEmailOnUsersTable.class); - private final CreateIndexForEmailOnUsersTable createIndexForEmailOnUsersTable = new CreateIndexForEmailOnUsersTable(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - - createIndexForEmailOnUsersTable.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndexForEmailOnUsersTable.execute(); - createIndexForEmailOnUsersTable.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexForScmAccountOnScmAccountsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexForScmAccountOnScmAccountsTableIT.java deleted file mode 100644 index 6c66fb25e30..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexForScmAccountOnScmAccountsTableIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v101.CreateIndexForScmAccountOnScmAccountsTable.INDEX_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateScmAccountsTable.SCM_ACCOUNTS_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateScmAccountsTable.SCM_ACCOUNT_COLUMN_NAME; - -class CreateIndexForScmAccountOnScmAccountsTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexForScmAccountOnScmAccountsTable.class); - private final CreateIndexForScmAccountOnScmAccountsTable createIndexForScmAccountOnScmAccountsTable = new CreateIndexForScmAccountOnScmAccountsTable(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(SCM_ACCOUNTS_TABLE_NAME, INDEX_NAME); - - createIndexForScmAccountOnScmAccountsTable.execute(); - - db.assertIndex(SCM_ACCOUNTS_TABLE_NAME, INDEX_NAME, SCM_ACCOUNT_COLUMN_NAME); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndexForScmAccountOnScmAccountsTable.execute(); - createIndexForScmAccountOnScmAccountsTable.execute(); - - db.assertIndex(SCM_ACCOUNTS_TABLE_NAME, INDEX_NAME, SCM_ACCOUNT_COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexOnExternalIdAndIdentityOnExternalGroupsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexOnExternalIdAndIdentityOnExternalGroupsTableIT.java deleted file mode 100644 index 508e22e955d..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexOnExternalIdAndIdentityOnExternalGroupsTableIT.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v101.CreateExternalGroupsTable.EXTERNAL_GROUP_ID_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateExternalGroupsTable.EXTERNAL_IDENTITY_PROVIDER_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateExternalGroupsTable.TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateIndexOnExternalIdAndIdentityOnExternalGroupsTable.INDEX_NAME; - -class CreateIndexOnExternalIdAndIdentityOnExternalGroupsTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexOnExternalIdAndIdentityOnExternalGroupsTable.class); - private final CreateIndexOnExternalIdAndIdentityOnExternalGroupsTable createIndexOnExternalIdAndIdentityOnExternalGroupsTable = new CreateIndexOnExternalIdAndIdentityOnExternalGroupsTable( - db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - - createIndexOnExternalIdAndIdentityOnExternalGroupsTable.execute(); - - db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, EXTERNAL_IDENTITY_PROVIDER_COLUMN_NAME, EXTERNAL_GROUP_ID_COLUMN_NAME); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndexOnExternalIdAndIdentityOnExternalGroupsTable.execute(); - createIndexOnExternalIdAndIdentityOnExternalGroupsTable.execute(); - - db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, EXTERNAL_IDENTITY_PROVIDER_COLUMN_NAME, EXTERNAL_GROUP_ID_COLUMN_NAME); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateProjectUuidInUserTokensIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateProjectUuidInUserTokensIT.java deleted file mode 100644 index 7a5f57c5bde..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateProjectUuidInUserTokensIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; - -class CreateProjectUuidInUserTokensIT { - private static final String TABLE_NAME = "user_tokens"; - private static final String COLUMN_NAME = "project_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateProjectUuidInUserTokens.class); - private final CreateProjectUuidInUserTokens underTest = new CreateProjectUuidInUserTokens(db.database()); - - @Test - void migration_creates_new_column() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 40, null); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 40, null); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateScmAccountsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateScmAccountsTableIT.java deleted file mode 100644 index 1e5f562baed..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateScmAccountsTableIT.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.USER_UUID_SIZE; -import static org.sonar.server.platform.db.migration.version.v101.CreateScmAccountsTable.SCM_ACCOUNTS_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateScmAccountsTable.SCM_ACCOUNT_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateScmAccountsTable.SCM_ACCOUNT_SIZE; -import static org.sonar.server.platform.db.migration.version.v101.CreateScmAccountsTable.USER_UUID_COLUMN_NAME; - -class CreateScmAccountsTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateScmAccountsTable.class); - - private final DdlChange createScmAccountsTable = new CreateScmAccountsTable(db.database()); - - @Test - void migration_should_create_a_table() throws SQLException { - db.assertTableDoesNotExist(SCM_ACCOUNTS_TABLE_NAME); - - createScmAccountsTable.execute(); - - db.assertTableExists(SCM_ACCOUNTS_TABLE_NAME); - db.assertColumnDefinition(SCM_ACCOUNTS_TABLE_NAME, USER_UUID_COLUMN_NAME, Types.VARCHAR, USER_UUID_SIZE, false); - db.assertColumnDefinition(SCM_ACCOUNTS_TABLE_NAME, SCM_ACCOUNT_COLUMN_NAME, Types.VARCHAR, SCM_ACCOUNT_SIZE, false); - db.assertPrimaryKey(SCM_ACCOUNTS_TABLE_NAME, "pk_scm_accounts", USER_UUID_COLUMN_NAME, SCM_ACCOUNT_COLUMN_NAME); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertTableDoesNotExist(SCM_ACCOUNTS_TABLE_NAME); - - createScmAccountsTable.execute(); - // re-entrant - createScmAccountsTable.execute(); - - db.assertTableExists(SCM_ACCOUNTS_TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateUniqueIndexForReportSchedulesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateUniqueIndexForReportSchedulesTableIT.java deleted file mode 100644 index 2a7a470d5a8..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateUniqueIndexForReportSchedulesTableIT.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v101.AddReportSchedulesTable.TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateUniqueIndexForReportSchedulesTable.COLUMN_NAME_BRANCH; -import static org.sonar.server.platform.db.migration.version.v101.CreateUniqueIndexForReportSchedulesTable.COLUMN_NAME_PORTFOLIO; -import static org.sonar.server.platform.db.migration.version.v101.CreateUniqueIndexForReportSchedulesTable.INDEX_NAME; - - -class CreateUniqueIndexForReportSchedulesTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateUniqueIndexForReportSchedulesTable.class); - private final CreateUniqueIndexForReportSchedulesTable createUniqueIndexForReportSchedulesTable = new CreateUniqueIndexForReportSchedulesTable(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - - createUniqueIndexForReportSchedulesTable.execute(); - - db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_PORTFOLIO, COLUMN_NAME_BRANCH); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createUniqueIndexForReportSchedulesTable.execute(); - createUniqueIndexForReportSchedulesTable.execute(); - - db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_PORTFOLIO, COLUMN_NAME_BRANCH); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateUniqueIndexForReportSubscriptionsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateUniqueIndexForReportSubscriptionsTableIT.java deleted file mode 100644 index 22584426e20..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/CreateUniqueIndexForReportSubscriptionsTableIT.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v101.AddReportSubscriptionsTable.TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateUniqueIndexForReportSubscriptionsTable.COLUMN_NAME_BRANCH; -import static org.sonar.server.platform.db.migration.version.v101.CreateUniqueIndexForReportSubscriptionsTable.COLUMN_NAME_PORTFOLIO; -import static org.sonar.server.platform.db.migration.version.v101.CreateUniqueIndexForReportSubscriptionsTable.COLUMN_NAME_USER; -import static org.sonar.server.platform.db.migration.version.v101.CreateUniqueIndexForReportSubscriptionsTable.INDEX_NAME; - - -class CreateUniqueIndexForReportSubscriptionsTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateUniqueIndexForReportSubscriptionsTable.class); - private final CreateUniqueIndexForReportSubscriptionsTable createUniqueIndexForReportSubscriptionsTable = new CreateUniqueIndexForReportSubscriptionsTable(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - - createUniqueIndexForReportSubscriptionsTable.execute(); - - db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_PORTFOLIO, COLUMN_NAME_BRANCH, COLUMN_NAME_USER); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createUniqueIndexForReportSubscriptionsTable.execute(); - createUniqueIndexForReportSubscriptionsTable.execute(); - - db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_PORTFOLIO, COLUMN_NAME_BRANCH, COLUMN_NAME_USER); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/DropProjectKeyInUserTokensIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/DropProjectKeyInUserTokensIT.java deleted file mode 100644 index c62580f7941..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/DropProjectKeyInUserTokensIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v101.DropProjectKeyInUserTokens.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.DropProjectKeyInUserTokens.TABLE_NAME; - -class DropProjectKeyInUserTokensIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropProjectKeyInUserTokens.class); - private final DdlChange underTest = new DropProjectKeyInUserTokens(db.database()); - - @Test - void drops_column() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 255, true); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 255, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/DropScmAccountsInUsersIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/DropScmAccountsInUsersIT.java deleted file mode 100644 index 9aa14860131..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/DropScmAccountsInUsersIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v101.DropScmAccountsInUsers.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.DropScmAccountsInUsers.TABLE_NAME; - -class DropScmAccountsInUsersIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropScmAccountsInUsers.class); - private final DdlChange dropScmAccountsInUsers = new DropScmAccountsInUsers(db.database()); - - @Test - void drops_column() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 4000, true); - dropScmAccountsInUsers.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 4000, true); - dropScmAccountsInUsers.execute(); - dropScmAccountsInUsers.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/FixDifferentUuidsForSubportfoliosIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/FixDifferentUuidsForSubportfoliosIT.java deleted file mode 100644 index 1c39c8133cb..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/FixDifferentUuidsForSubportfoliosIT.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import javax.annotation.Nullable; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.util.stream.Collectors.toSet; - -class FixDifferentUuidsForSubportfoliosIT { - private static final String OLD_UUID = "differentSubPfUuid"; - private static final String SUB_PF_KEY = "subPfKey"; - private static final String NEW_SUBPF_UUID = "subPfUuid"; - private static final String PF_UUID = "pfUuid"; - private static final String NEW_CHILD_SUBPF_UUID = "childsubpfUuid"; - private static final String OLD_CHILD_SUBPF_UUID = "old_child_subpf_uuid"; - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(FixDifferentUuidsForSubportfolios.class); - private final FixDifferentUuidsForSubportfolios underTest = new FixDifferentUuidsForSubportfolios(db.database()); - - @Test - void execute_shouldUpdatePortfoliosAndPortfolioProjectsAndPortfolioReferenceTable() throws SQLException { - insertPortfolio("pfKey", PF_UUID); - insertComponent(SUB_PF_KEY, NEW_SUBPF_UUID, PF_UUID, "SVW"); - insertSubPortfolio(SUB_PF_KEY, PF_UUID, PF_UUID, OLD_UUID); - insertPortfolioProject("projUuid", OLD_UUID); - insertPortfolioReference("refUuid", OLD_UUID); - - underTest.execute(); - - Assertions.assertThat(findValueIn("portfolios", "uuid")).containsExactlyInAnyOrder(PF_UUID, NEW_SUBPF_UUID); - Assertions.assertThat(findValueIn("portfolio_projects", "portfolio_uuid")).containsExactlyInAnyOrder(NEW_SUBPF_UUID); - Assertions.assertThat(findValueIn("portfolio_references", "portfolio_uuid")).containsExactlyInAnyOrder(NEW_SUBPF_UUID); - } - - @Test - void execute_shouldBeRentrant() throws SQLException { - insertPortfolio("pfKey", PF_UUID); - insertComponent(SUB_PF_KEY, NEW_SUBPF_UUID, PF_UUID, "SVW"); - insertSubPortfolio(SUB_PF_KEY, PF_UUID, PF_UUID, OLD_UUID); - insertPortfolioProject("projUuid", OLD_UUID); - insertPortfolioReference("refUuid", OLD_UUID); - - underTest.execute(); - underTest.execute(); - - Assertions.assertThat(findValueIn("portfolios", "uuid")).containsExactlyInAnyOrder(PF_UUID, NEW_SUBPF_UUID); - Assertions.assertThat(findValueIn("portfolio_projects", "portfolio_uuid")).containsExactlyInAnyOrder(NEW_SUBPF_UUID); - Assertions.assertThat(findValueIn("portfolio_references", "portfolio_uuid")).containsExactlyInAnyOrder(NEW_SUBPF_UUID); - } - - @Test - void execute_shouldFixUuidForSubPortfolioAtDifferentLevels() throws SQLException { - insertPortfolio("pfKey", PF_UUID); - - insertComponent(SUB_PF_KEY, NEW_SUBPF_UUID, PF_UUID, "SVW"); - insertComponent("child_subpfkey", NEW_CHILD_SUBPF_UUID, PF_UUID, "SVW"); - - insertSubPortfolio(SUB_PF_KEY, PF_UUID, PF_UUID, OLD_UUID); - insertSubPortfolio("child_subpfkey", OLD_UUID, PF_UUID, OLD_CHILD_SUBPF_UUID); - insertPortfolioProject("projUuid", OLD_CHILD_SUBPF_UUID); - insertPortfolioReference("refUuid", OLD_CHILD_SUBPF_UUID); - - underTest.execute(); - - Assertions.assertThat(findValueIn("portfolios", "uuid")).containsExactlyInAnyOrder(PF_UUID, NEW_SUBPF_UUID, NEW_CHILD_SUBPF_UUID); - Assertions.assertThat(findValueIn("portfolios", "parent_uuid")).containsExactlyInAnyOrder(null, PF_UUID, NEW_SUBPF_UUID); - Assertions.assertThat(findValueIn("portfolio_projects", "portfolio_uuid")).containsExactlyInAnyOrder(NEW_CHILD_SUBPF_UUID); - Assertions.assertThat(findValueIn("portfolio_references", "portfolio_uuid")).containsExactlyInAnyOrder(NEW_CHILD_SUBPF_UUID); - } - - private Set<String> findValueIn(String table, String field) { - return db.select(String.format("select %s FROM %s", field, table)) - .stream() - .map(row -> (String) row.get(field)) - .collect(toSet()); - } - - private String insertComponent(String key, String uuid, String branchUuid, String qualifier) { - Map<String, Object> map = new HashMap<>(); - map.put("UUID", uuid); - map.put("KEE", key); - map.put("BRANCH_UUID", branchUuid); - map.put("UUID_PATH", "." + uuid + "."); - map.put("QUALIFIER", qualifier); - map.put("ENABLED", true); - map.put("PRIVATE", true); - - db.executeInsert("components", map); - return uuid; - } - - private String insertPortfolio(String kee, String uuid) { - return insertSubPortfolio(kee, uuid, uuid); - } - - private String insertSubPortfolio(String kee, String rootUuid, String uuid) { - return insertSubPortfolio(kee, null, rootUuid, uuid); - } - - private String insertSubPortfolio(String kee, @Nullable String parentUuid, String rootUuid, String uuid) { - Map<String, Object> map = new HashMap<>(); - map.put("UUID", uuid); - map.put("KEE", kee); - map.put("NAME", uuid); - map.put("ROOT_UUID", rootUuid); - map.put("PRIVATE", false); - map.put("SELECTION_MODE", "MANUAL"); - map.put("PARENT_UUID", parentUuid); - map.put("CREATED_AT", System.currentTimeMillis()); - map.put("UPDATED_AT", System.currentTimeMillis()); - - db.executeInsert("portfolios", map); - return uuid; - } - - private String insertPortfolioReference(String uuid, String portfolioUuid) { - Map<String, Object> map = new HashMap<>(); - map.put("UUID", uuid); - map.put("PORTFOLIO_UUID", portfolioUuid); - map.put("REFERENCE_UUID", "reference"); - map.put("CREATED_AT", System.currentTimeMillis()); - - db.executeInsert("portfolio_references", map); - return uuid; - } - - private String insertPortfolioProject(String uuid, String portfolioUuid) { - Map<String, Object> map = new HashMap<>(); - map.put("UUID", uuid); - map.put("PORTFOLIO_UUID", portfolioUuid); - map.put("PROJECT_UUID", portfolioUuid); - map.put("CREATED_AT", System.currentTimeMillis()); - - db.executeInsert("portfolio_projects", map); - return uuid; - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/IncreaseKeeColumnSizeInInternalPropertiesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/IncreaseKeeColumnSizeInInternalPropertiesIT.java deleted file mode 100644 index 103c066b0dd..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/IncreaseKeeColumnSizeInInternalPropertiesIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; -import static org.sonar.server.platform.db.migration.version.v101.IncreaseKeeColumnSizeInInternalProperties.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.IncreaseKeeColumnSizeInInternalProperties.NEW_COLUMN_SIZE; -import static org.sonar.server.platform.db.migration.version.v101.IncreaseKeeColumnSizeInInternalProperties.TABLE_NAME; - -class IncreaseKeeColumnSizeInInternalPropertiesIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(IncreaseKeeColumnSizeInInternalProperties.class); - private final IncreaseKeeColumnSizeInInternalProperties underTest = new IncreaseKeeColumnSizeInInternalProperties(db.database()); - - @Test - void execute_increaseColumnSize() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 20, false); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, NEW_COLUMN_SIZE, false); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 20, false); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, NEW_COLUMN_SIZE, false); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/IncreaseTaskTypeColumnSizeInCeActivityIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/IncreaseTaskTypeColumnSizeInCeActivityIT.java deleted file mode 100644 index dcfe635e1aa..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/IncreaseTaskTypeColumnSizeInCeActivityIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; -import static org.sonar.server.platform.db.migration.version.v101.IncreaseTaskTypeColumnSizeInCeActivity.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.IncreaseTaskTypeColumnSizeInCeActivity.NEW_COLUMN_SIZE; -import static org.sonar.server.platform.db.migration.version.v101.IncreaseTaskTypeColumnSizeInCeActivity.TABLE_NAME; - -class IncreaseTaskTypeColumnSizeInCeActivityIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(IncreaseTaskTypeColumnSizeInCeActivity.class); - private final IncreaseTaskTypeColumnSizeInCeActivity underTest = new IncreaseTaskTypeColumnSizeInCeActivity(db.database()); - - @Test - void execute_increaseColumnSize() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 15, false); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, NEW_COLUMN_SIZE, false); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 15, false); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, NEW_COLUMN_SIZE, false); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/IncreaseTaskTypeColumnSizeInCeQueueIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/IncreaseTaskTypeColumnSizeInCeQueueIT.java deleted file mode 100644 index 4ec0f8e8241..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/IncreaseTaskTypeColumnSizeInCeQueueIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; -import static org.sonar.server.platform.db.migration.version.v101.IncreaseTaskTypeColumnSizeInCeQueue.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.IncreaseTaskTypeColumnSizeInCeQueue.NEW_COLUMN_SIZE; -import static org.sonar.server.platform.db.migration.version.v101.IncreaseTaskTypeColumnSizeInCeQueue.TABLE_NAME; - -class IncreaseTaskTypeColumnSizeInCeQueueIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(IncreaseTaskTypeColumnSizeInCeQueue.class); - private final IncreaseTaskTypeColumnSizeInCeQueue underTest = new IncreaseTaskTypeColumnSizeInCeQueue(db.database()); - - @Test - void execute_increaseColumnSize() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 15, false); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, NEW_COLUMN_SIZE, false); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 15, false); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, NEW_COLUMN_SIZE, false); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/MigrateScmAccountsFromUsersToScmAccountsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/MigrateScmAccountsFromUsersToScmAccountsIT.java deleted file mode 100644 index 5826466b48e..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/MigrateScmAccountsFromUsersToScmAccountsIT.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.UuidFactory; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.version.v101.MigrateScmAccountsFromUsersToScmAccounts.ScmAccountRow; - -import static java.lang.String.format; -import static java.util.stream.Collectors.toSet; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatNoException; -import static org.sonar.server.platform.db.migration.version.v101.MigrateScmAccountsFromUsersToScmAccounts.SCM_ACCOUNTS_SEPARATOR_CHAR; - -class MigrateScmAccountsFromUsersToScmAccountsIT { - - private static final UuidFactory UUID_FACTORY = UuidFactoryFast.getInstance(); - private static final String SCM_ACCOUNT1 = "scmaccount"; - private static final String SCM_ACCOUNT2 = "scmaccount2"; - private static final String SCM_ACCOUNT_CAMELCASE = "scmAccount3"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(MigrateScmAccountsFromUsersToScmAccounts.class); - private final DataChange migrateScmAccountsFromUsersToScmAccounts = new MigrateScmAccountsFromUsersToScmAccounts(db.database()); - - @Test - void execute_whenUserHasNullScmAccounts_doNotInsertInScmAccounts() throws SQLException { - insertUserAndGetUuid(null); - - migrateScmAccountsFromUsersToScmAccounts.execute(); - - Set<ScmAccountRow> scmAccounts = findAllScmAccounts(); - assertThat(scmAccounts).isEmpty(); - } - - @Test - void execute_whenUserHasEmptyScmAccounts_doNotInsertInScmAccounts() throws SQLException { - insertUserAndGetUuid(""); - - migrateScmAccountsFromUsersToScmAccounts.execute(); - - Set<ScmAccountRow> scmAccounts = findAllScmAccounts(); - assertThat(scmAccounts).isEmpty(); - } - - @Test - void execute_whenUserHasEmptyScmAccountsWithOneSeparator_doNotInsertInScmAccounts() throws SQLException { - insertUserAndGetUuid(String.valueOf(SCM_ACCOUNTS_SEPARATOR_CHAR)); - - migrateScmAccountsFromUsersToScmAccounts.execute(); - - Set<ScmAccountRow> scmAccounts = findAllScmAccounts(); - assertThat(scmAccounts).isEmpty(); - } - - @Test - void execute_whenUserHasEmptyScmAccountsWithTwoSeparators_doNotInsertInScmAccounts() throws SQLException { - insertUserAndGetUuid(SCM_ACCOUNTS_SEPARATOR_CHAR + String.valueOf(SCM_ACCOUNTS_SEPARATOR_CHAR)); - - migrateScmAccountsFromUsersToScmAccounts.execute(); - - Set<ScmAccountRow> scmAccounts = findAllScmAccounts(); - assertThat(scmAccounts).isEmpty(); - } - - @Test - void execute_whenUserHasOneScmAccountWithoutSeparator_insertsInScmAccounts() throws SQLException { - String userUuid = insertUserAndGetUuid(SCM_ACCOUNT1); - - migrateScmAccountsFromUsersToScmAccounts.execute(); - - Set<ScmAccountRow> scmAccounts = findAllScmAccounts(); - assertThat(scmAccounts).containsExactly(new ScmAccountRow(userUuid, SCM_ACCOUNT1)); - } - - @Test - void execute_whenUserHasOneScmAccountWithSeparators_insertsInScmAccounts() throws SQLException { - String userUuid = insertUserAndGetUuid(format("%s%s%s", SCM_ACCOUNTS_SEPARATOR_CHAR, SCM_ACCOUNT1, SCM_ACCOUNTS_SEPARATOR_CHAR)); - - migrateScmAccountsFromUsersToScmAccounts.execute(); - - Set<ScmAccountRow> scmAccounts = findAllScmAccounts(); - assertThat(scmAccounts).containsExactly(new ScmAccountRow(userUuid, SCM_ACCOUNT1)); - } - - @Test - void execute_whenUserHasOneScmAccountWithMixedCase_insertsInScmAccountsInLowerCase() throws SQLException { - String userUuid = insertUserAndGetUuid(format("%s%s%s", SCM_ACCOUNTS_SEPARATOR_CHAR, SCM_ACCOUNT_CAMELCASE, SCM_ACCOUNTS_SEPARATOR_CHAR)); - - migrateScmAccountsFromUsersToScmAccounts.execute(); - - Set<ScmAccountRow> scmAccounts = findAllScmAccounts(); - assertThat(scmAccounts).containsExactly(new ScmAccountRow(userUuid, SCM_ACCOUNT_CAMELCASE.toLowerCase(Locale.ENGLISH))); - } - - @Test - void execute_whenUserHasTwoScmAccount_insertsInScmAccounts() throws SQLException { - String userUuid = insertUserAndGetUuid(format("%s%s%s%s%s", - SCM_ACCOUNTS_SEPARATOR_CHAR, SCM_ACCOUNT1, SCM_ACCOUNTS_SEPARATOR_CHAR, SCM_ACCOUNT2, SCM_ACCOUNTS_SEPARATOR_CHAR)); - - migrateScmAccountsFromUsersToScmAccounts.execute(); - - Set<ScmAccountRow> scmAccounts = findAllScmAccounts(); - assertThat(scmAccounts).containsExactlyInAnyOrder( - new ScmAccountRow(userUuid, SCM_ACCOUNT1), - new ScmAccountRow(userUuid, SCM_ACCOUNT2) - ); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - String userUuid = insertUserAndGetUuid(SCM_ACCOUNT1); - - migrateScmAccountsFromUsersToScmAccounts.execute(); - migrateScmAccountsFromUsersToScmAccounts.execute(); - - Set<ScmAccountRow> scmAccounts = findAllScmAccounts(); - assertThat(scmAccounts).containsExactly(new ScmAccountRow(userUuid, SCM_ACCOUNT1)); - } - - @Test - void migration_should_be_reentrant_if_scm_account_column_dropped() { - db.executeDdl("alter table users drop column scm_accounts"); - - assertThatNoException().isThrownBy(migrateScmAccountsFromUsersToScmAccounts::execute); - } - - - private Set<ScmAccountRow> findAllScmAccounts() { - Set<ScmAccountRow> scmAccounts = db.select("select user_uuid, scm_account from scm_accounts") - .stream() - .map(row -> new ScmAccountRow((String) row.get("user_uuid"), (String) row.get("scm_account"))) - .collect(toSet()); - return scmAccounts; - } - - private String insertUserAndGetUuid(@Nullable String scmAccounts) { - - Map<String, Object> map = new HashMap<>(); - String uuid = UUID_FACTORY.create(); - String login = "login_" + uuid; - map.put("UUID", uuid); - map.put("LOGIN", login); - map.put("HASH_METHOD", "tagada"); - map.put("EXTERNAL_LOGIN", login); - map.put("EXTERNAL_IDENTITY_PROVIDER", "sonarqube"); - map.put("EXTERNAL_ID", login); - map.put("CREATED_AT", System.currentTimeMillis()); - map.put("RESET_PASSWORD", false); - map.put("USER_LOCAL", true); - map.put("SCM_ACCOUNTS", scmAccounts); - db.executeInsert("users", map); - return uuid; - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/PopulateProjectUuidInUserTokensIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/PopulateProjectUuidInUserTokensIT.java deleted file mode 100644 index e91b3319b73..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/PopulateProjectUuidInUserTokensIT.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.UuidFactory; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.groups.Tuple.tuple; - -class PopulateProjectUuidInUserTokensIT { - private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulateProjectUuidInUserTokens.class); - - private final DataChange underTest = new PopulateProjectUuidInUserTokens(db.database()); - - @Test - void migration_populates_project_uuid_for_tokens() throws SQLException { - String project1Uuid = insertProject("project1"); - String project2Uuid = insertProject("project2"); - - String token1Uuid = insertUserToken("project1"); - String token2Uuid = insertUserToken("project1"); - String token3Uuid = insertUserToken("project2"); - String token4Uuid = insertUserToken(null); - - underTest.execute(); - assertThat(db.select("select * from user_tokens")) - .extracting(r -> r.get("UUID"), r -> r.get("PROJECT_UUID")) - .containsOnly( - tuple(token1Uuid, project1Uuid), - tuple(token2Uuid, project1Uuid), - tuple(token3Uuid, project2Uuid), - tuple(token4Uuid, null)); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - String project1Uuid = insertProject("project1"); - String project2Uuid = insertProject("project2"); - - String token1Uuid = insertUserToken("project1"); - String token2Uuid = insertUserToken("project1"); - String token3Uuid = insertUserToken("project2"); - String token4Uuid = insertUserToken(null); - - underTest.execute(); - underTest.execute(); - - assertThat(db.select("select * from user_tokens")) - .extracting(r -> r.get("UUID"), r -> r.get("PROJECT_UUID")) - .containsOnly( - tuple(token1Uuid, project1Uuid), - tuple(token2Uuid, project1Uuid), - tuple(token3Uuid, project2Uuid), - tuple(token4Uuid, null)); - } - - private String insertUserToken(@Nullable String projectKey) { - Map<String, Object> map = new HashMap<>(); - String uuid = uuidFactory.create(); - map.put("UUID", uuid); - map.put("USER_UUID", "user" + uuid); - map.put("NAME", "name" + uuid); - map.put("TOKEN_HASH", "token" + uuid); - map.put("CREATED_AT", 1); - map.put("PROJECT_KEY", projectKey); - map.put("TYPE", "PROJECT_ANALYSIS_TOKEN"); - - db.executeInsert("user_tokens", map); - return uuid; - } - - private String insertProject(String projectKey) { - Map<String, Object> map = new HashMap<>(); - String uuid = uuidFactory.create(); - map.put("UUID", uuid); - map.put("KEE", projectKey); - map.put("QUALIFIER", "TRK"); - map.put("PRIVATE", true); - map.put("UPDATED_AT", System.currentTimeMillis()); - db.executeInsert("projects", map); - return uuid; - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/PopulateReportSchedulesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/PopulateReportSchedulesIT.java deleted file mode 100644 index 148bb2211e2..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/PopulateReportSchedulesIT.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.UuidFactory; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; - -class PopulateReportSchedulesIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulateReportSchedules.class); - - private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); - private final DataChange underTest = new PopulateReportSchedules(db.database()); - - @Test - void execute_shouldPopulateFromPortfolioProperties() throws SQLException { - insertPortfolio("uuid1"); - insertPortfolioProperty("uuid1", "1234"); - - underTest.execute(); - - assertThat(db.select("select * from report_schedules")) - .extracting(m -> m.get("PORTFOLIO_UUID"), m -> m.get("BRANCH_UUID"), m -> m.get("LAST_SEND_TIME_IN_MS")) - .containsOnly(tuple("uuid1", null, 1234L)); - } - - @Test - void execute_shouldPopulateFromBranchProperties() throws SQLException { - insertBranch("uuid1"); - insertProjectBranchProperty("uuid1", "1234"); - - underTest.execute(); - - assertThat(db.select("select * from report_schedules")) - .extracting(m -> m.get("PORTFOLIO_UUID"), m -> m.get("BRANCH_UUID"), m -> m.get("LAST_SEND_TIME_IN_MS")) - .containsOnly(tuple(null, "uuid1", 1234L)); - } - - @Test - void execute_whenPropertyMatchesBothBranchAndPortfolio_shouldNotPopulate() throws SQLException { - insertBranch("uuid1"); - insertPortfolio("uuid1"); - insertProjectBranchProperty("uuid1", "1234"); - - underTest.execute(); - underTest.execute(); - - assertThat(db.select("select * from report_schedules")).isEmpty(); - } - - private void insertPortfolio(String uuid) { - db.executeInsert("portfolios", - "uuid", uuid, - "kee", "kee_" + uuid, - "name", "name_" + uuid, - "root_uuid", uuid, - "private", true, - "selection_mode", "manual", - "created_at", 1000, - "updated_at", 1000 - ); - } - - private void insertProjectBranchProperty(String portfolioUuid, String value) { - db.executeInsert("properties", - "uuid", uuidFactory.create(), - "prop_key", "sonar.governance.report.project.branch.lastSendTimeInMs", - "is_empty", false, - "text_value", value, - "created_at", 1000, - "entity_uuid", portfolioUuid - ); - } - - private void insertPortfolioProperty(String portfolioUuid, String value) { - db.executeInsert("properties", - "uuid", uuidFactory.create(), - "prop_key", "sonar.governance.report.lastSendTimeInMs", - "is_empty", false, - "text_value", value, - "created_at", 1000, - "entity_uuid", portfolioUuid - ); - } - - private void insertBranch(String uuid) { - db.executeInsert("project_branches", - "uuid", uuid, - "project_uuid", "project_" + uuid, - "kee", "kee_" + uuid, - "branch_type", "BRANCH", - "created_at", 1000, - "updated_at", 1000, - "need_issue_sync", false, - "is_main", true - ); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/PopulateReportSubscriptionsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/PopulateReportSubscriptionsIT.java deleted file mode 100644 index 673c8e06b41..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/PopulateReportSubscriptionsIT.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.UuidFactory; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; - -class PopulateReportSubscriptionsIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulateReportSubscriptions.class); - - private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); - private final DataChange underTest = new PopulateReportSubscriptions(db.database()); - - @Test - void execute_shouldPopulateFromPortfolioProperties() throws SQLException { - insertPortfolio("uuid1"); - insertPortfolioProperty("uuid1", "1234"); - - underTest.execute(); - - assertThat(db.select("select * from report_subscriptions")) - .extracting(m -> m.get("PORTFOLIO_UUID"), m -> m.get("BRANCH_UUID"), m -> m.get("USER_UUID")) - .containsOnly(tuple("uuid1", null, "1234")); - } - - @Test - void execute_shouldPopulateFromBranchProperties() throws SQLException { - insertBranch("uuid1"); - insertBranchProperty("uuid1", "1234"); - - underTest.execute(); - - assertThat(db.select("select * from report_subscriptions")) - .extracting(m -> m.get("PORTFOLIO_UUID"), m -> m.get("BRANCH_UUID"), m -> m.get("USER_UUID")) - .containsOnly(tuple(null, "uuid1", "1234")); - } - - @Test - void execute_whenPropertyMatchesBothBranchAndPortfolio_shouldNotPopulate() throws SQLException { - insertBranch("uuid1"); - insertPortfolio("uuid1"); - insertBranchProperty("uuid1", "1234"); - - underTest.execute(); - underTest.execute(); - - assertThat(db.select("select * from report_subscriptions")).isEmpty(); - } - - private void insertPortfolio(String uuid) { - db.executeInsert("portfolios", - "uuid", uuid, - "kee", "kee_" + uuid, - "name", "name_" + uuid, - "root_uuid", uuid, - "private", true, - "selection_mode", "manual", - "created_at", 1000, - "updated_at", 1000 - ); - } - - private void insertBranchProperty(String branchUuid, String userUuid){ - insertProperty( branchUuid, userUuid, "sonar.governance.report.userNotification"); - } - - private void insertPortfolioProperty(String branchUuid, String userUuid){ - insertProperty( branchUuid, userUuid, "sonar.governance.report.project.branch.userNotification"); - } - - private void insertProperty(String componentUuid, String userUuid, String propertyKey) { - db.executeInsert("properties", - "uuid", uuidFactory.create(), - "prop_key", propertyKey, - "is_empty", false, - "text_value", "true", - "created_at", 1000, - "entity_uuid", componentUuid, - "user_uuid", userUuid - ); - } - - private void insertBranch(String uuid) { - db.executeInsert("project_branches", - "uuid", uuid, - "project_uuid", "project_" + uuid, - "kee", "kee_" + uuid, - "branch_type", "BRANCH", - "created_at", 1000, - "updated_at", 1000, - "need_issue_sync", false, - "is_main", true - ); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/RemoveOrphanUserTokensIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/RemoveOrphanUserTokensIT.java deleted file mode 100644 index 24946bfa8fa..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/RemoveOrphanUserTokensIT.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.UuidFactory; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; - -class RemoveOrphanUserTokensIT { - private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RemoveOrphanUserTokens.class); - - private final DataChange underTest = new RemoveOrphanUserTokens(db.database()); - - @Test - void migration_deletes_orphan_tokens() throws SQLException { - String project1Uuid = insertProject("project1"); - - String token1Uuid = insertUserToken("project1"); - String token2Uuid = insertUserToken("orphan"); - String token3Uuid = insertUserToken(null); - - underTest.execute(); - assertThat(db.select("select * from user_tokens")) - .extracting(r -> r.get("UUID")) - .containsOnly(token1Uuid, token3Uuid); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - String project1Uuid = insertProject("project1"); - - String token1Uuid = insertUserToken("project1"); - String token2Uuid = insertUserToken("orphan"); - - underTest.execute(); - underTest.execute(); - - assertThat(db.select("select * from user_tokens")) - .extracting(r -> r.get("UUID")) - .containsOnly(token1Uuid); - } - - private String insertUserToken( @Nullable String projectKey) { - Map<String, Object> map = new HashMap<>(); - String uuid = uuidFactory.create(); - map.put("UUID", uuid); - map.put("USER_UUID", "user" + uuid); - map.put("NAME", "name" + uuid); - map.put("TOKEN_HASH", "token" + uuid); - map.put("CREATED_AT", 1); - map.put("PROJECT_KEY", projectKey); - map.put("TYPE", "PROJECT_ANALYSIS_TOKEN"); - - db.executeInsert("user_tokens", map); - return uuid; - } - - private String insertProject(String projectKey) { - Map<String, Object> map = new HashMap<>(); - String uuid = uuidFactory.create(); - map.put("UUID", uuid); - map.put("KEE", projectKey); - map.put("QUALIFIER", "TRK"); - map.put("PRIVATE", true); - map.put("UPDATED_AT", System.currentTimeMillis()); - db.executeInsert("projects", map); - return uuid; - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/RemoveReportPropertiesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/RemoveReportPropertiesIT.java deleted file mode 100644 index 2ad919913d9..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/RemoveReportPropertiesIT.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.UuidFactory; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; - -class RemoveReportPropertiesIT { - - private static final String SONAR_GOVERNANCE_REPORT_USER_NOTIFICATION = "sonar.governance.report.userNotification"; - private static final String SONAR_GOVERNANCE_REPORT_PROJECT_BRANCH_USER_NOTIFICATION = "sonar.governance.report.project.branch.userNotification"; - private static final String SONAR_GOVERNANCE_REPORT_LAST_SEND_TIME_IN_MS = "sonar.governance.report.lastSendTimeInMs"; - private static final String SONAR_GOVERNANCE_REPORT_PROJECT_BRANCH_LAST_SEND_TIME_IN_MS = "sonar.governance.report.project.branch.lastSendTimeInMs"; - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RemoveReportProperties.class); - - private final DataChange underTest = new RemoveReportProperties(db.database()); - - private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); - - @Test - void execute_shouldRemoveRelevantPropertiesFromTable() throws SQLException { - insertProperty( "branch_uuid", "user_uuid", SONAR_GOVERNANCE_REPORT_USER_NOTIFICATION, "true"); - insertProperty( "portfolio_uuid", "user_uuid", SONAR_GOVERNANCE_REPORT_PROJECT_BRANCH_USER_NOTIFICATION, "true"); - insertProperty( "branch_uuid", "user_uuid", SONAR_GOVERNANCE_REPORT_LAST_SEND_TIME_IN_MS, "12"); - insertProperty( "portfolio_uuid", "user_uuid", SONAR_GOVERNANCE_REPORT_PROJECT_BRANCH_LAST_SEND_TIME_IN_MS, "123"); - insertProperty( "portfolio_uuid", "user_uuid", "sonar.other.property", "123"); - - underTest.execute(); - - assertThat(db.select("select * from properties")).hasSize(1) - .extracting(r->r.get("PROP_KEY")).containsExactly("sonar.other.property"); - } - - @Test - void execute_shouldBeIdempotent() throws SQLException { - insertProperty( "branch_uuid", "user_uuid", SONAR_GOVERNANCE_REPORT_USER_NOTIFICATION, "true"); - insertProperty( "portfolio_uuid", "user_uuid", SONAR_GOVERNANCE_REPORT_PROJECT_BRANCH_USER_NOTIFICATION, "true"); - - underTest.execute(); - underTest.execute(); - - assertThat(db.select("select * from properties")).isEmpty(); - } - - private void insertProperty(String componentUuid, String userUuid, String propertyKey, String value) { - db.executeInsert("properties", - "uuid", uuidFactory.create(), - "prop_key", propertyKey, - "is_empty", false, - "text_value", value, - "created_at", 1000, - "entity_uuid", componentUuid, - "user_uuid", userUuid - ); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/RenameColumnComponentUuidInPropertiesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/RenameColumnComponentUuidInPropertiesIT.java deleted file mode 100644 index 126bb6100bd..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/RenameColumnComponentUuidInPropertiesIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; - -class RenameColumnComponentUuidInPropertiesIT { - - public static final String TABLE_NAME = "properties"; - public static final String NEW_COLUMN_NAME = "entity_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameColumnComponentUuidInProperties.class); - private final RenameColumnComponentUuidInProperties underTest = new RenameColumnComponentUuidInProperties(db.database()); - - @Test - void columnIsRenamed() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 40, true); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 40, true); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/UpdateIsMainColumnInProjectBranchesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/UpdateIsMainColumnInProjectBranchesIT.java deleted file mode 100644 index 9ee17933868..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/UpdateIsMainColumnInProjectBranchesIT.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.UuidFactory; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; - -class UpdateIsMainColumnInProjectBranchesIT { - - private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(UpdateIsMainColumnInProjectBranches.class); - - private final DataChange underTest = new UpdateIsMainColumnInProjectBranches(db.database()); - - private static int not_random_value_always_incremented = 0; - - @Test - void migration_updates_is_main_if_row_has_the_same_uuids() throws SQLException { - String branchUuid1 = insertProjectBranch(true); - String branchUuid2 = insertProjectBranch(false); - - underTest.execute(); - - assertBranchIsMain(branchUuid1); - assertBranchIsNotMain(branchUuid2); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - String branchUuid1 = insertProjectBranch(true); - String branchUuid2 = insertProjectBranch(false); - - underTest.execute(); - // re-entrant - underTest.execute(); - - assertBranchIsMain(branchUuid1); - assertBranchIsNotMain(branchUuid2); - } - - private void assertBranchIsMain(String branchUuid) { - assertBranchIs(branchUuid, true); - } - - private void assertBranchIsNotMain(String branchUuid) { - assertBranchIs(branchUuid, false); - } - - private void assertBranchIs(String branchUuid, boolean isMain) { - String selectSql = String.format("select is_main from project_branches where uuid='%s'", branchUuid); - assertThat(db.select(selectSql).stream() - .map(row -> row.get("IS_MAIN")) - .toList()) - .containsExactlyInAnyOrder(isMain); - } - - private String insertProjectBranch(boolean sameUuids) { - Map<String, Object> map = new HashMap<>(); - String uuid = uuidFactory.create(); - map.put("UUID", uuid); - if(sameUuids) { - map.put("PROJECT_UUID", uuid); - } else { - map.put("PROJECT_UUID", "uuid" + not_random_value_always_incremented++); - } - map.put("KEE", "randomKey"); - map.put("BRANCH_TYPE", "BRANCH"); - map.put("MERGE_BRANCH_UUID", null); - map.put("CREATED_AT", System.currentTimeMillis()); - map.put("UPDATED_AT", System.currentTimeMillis()); - map.put("PULL_REQUEST_BINARY", null); - map.put("EXCLUDE_FROM_PURGE", true); - map.put("NEED_ISSUE_SYNC", false); - db.executeInsert("project_branches", map); - return uuid; - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/AddCleanCodeAttributeInRulesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/AddCleanCodeAttributeInRulesIT.java deleted file mode 100644 index 2fd67d44eae..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/AddCleanCodeAttributeInRulesIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -class AddCleanCodeAttributeInRulesIT { - private static final String TABLE_NAME = "rules"; - private static final String COLUMN_NAME = "clean_code_attribute"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddCleanCodeAttributeInRules.class); - - private final AddCleanCodeAttributeInRules underTest = new AddCleanCodeAttributeInRules(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 40, true); - } - - @Test - void execute_whenExecutedTwice_shouldNotFail() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 40, true); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/AddUserConsentRequiredIfGithubAutoProvisioningEnabledIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/AddUserConsentRequiredIfGithubAutoProvisioningEnabledIT.java deleted file mode 100644 index 280d63dfddb..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/AddUserConsentRequiredIfGithubAutoProvisioningEnabledIT.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.slf4j.event.Level; -import org.sonar.api.testfixtures.log.LogTesterJUnit5; -import org.sonar.api.utils.System2; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.platform.db.migration.version.v102.AddUserConsentRequiredIfGithubAutoProvisioningEnabled.PROP_KEY; -import static org.sonar.server.platform.db.migration.version.v102.AddUserConsentRequiredIfGithubAutoProvisioningEnabled.PROVISIONING_GITHUB_ENABLED_PROP_KEY; - -class AddUserConsentRequiredIfGithubAutoProvisioningEnabledIT { - - @RegisterExtension - public final LogTesterJUnit5 logger = new LogTesterJUnit5(); - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddUserConsentRequiredIfGithubAutoProvisioningEnabled.class); - private final DataChange underTest = new AddUserConsentRequiredIfGithubAutoProvisioningEnabled(db.database(), new System2(), UuidFactoryFast.getInstance()); - - @BeforeEach - public void before() { - logger.clear(); - } - - @Test - void migration_whenGitHubAutoProvisioningPropertyNotPresent_shouldNotRequireConsent() throws SQLException { - underTest.execute(); - - assertThat(logger.logs(Level.WARN)).isEmpty(); - assertThat(isConsentRequired()).isFalse(); - } - - @Test - void migration_whenGitHubAutoProvisioningDisabled_shouldNotRequireConsent() throws SQLException { - disableGithubProvisioning(); - underTest.execute(); - - assertThat(logger.logs(Level.WARN)).isEmpty(); - assertThat(isConsentRequired()).isFalse(); - } - - @Test - void migration_whenGitHubAutoProvisioningEnabled_shouldRequireConsent() throws SQLException { - enableGithubProvisioning(); - - underTest.execute(); - - assertThat(logger.logs(Level.WARN)).containsExactly("Automatic synchronization was previously activated for GitHub. It requires user consent to continue working as new" - + " features were added with the synchronization. Please read the upgrade notes."); - assertThat(isConsentRequired()).isTrue(); - } - - @Test - void migration_is_reentrant() throws SQLException { - enableGithubProvisioning(); - - underTest.execute(); - underTest.execute(); - - assertThat(logger.logs(Level.WARN)).containsExactly("Automatic synchronization was previously activated for GitHub. It requires user consent to continue working as new" - + " features were added with the synchronization. Please read the upgrade notes."); - assertThat(isConsentRequired()).isTrue(); - } - - private void disableGithubProvisioning() { - toggleGithubProvisioning(false); - } - private void enableGithubProvisioning() { - toggleGithubProvisioning(true); - } - - private boolean isConsentRequired() { - return db.countSql("select count(*) from properties where prop_key = '" + PROP_KEY + "'") >= 1; - } - - private void toggleGithubProvisioning(boolean enabled) { - db.executeInsert("internal_properties", "kee", PROVISIONING_GITHUB_ENABLED_PROP_KEY, "text_value", String.valueOf(enabled), "is_empty", true, "created_at", 0); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateAnticipatedTransitionsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateAnticipatedTransitionsTableIT.java deleted file mode 100644 index c870442dd97..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateAnticipatedTransitionsTableIT.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.MAX_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.USER_UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.version.v102.CreateAnticipatedTransitionsTable.ANTICIPATED_TRANSITIONS_TABLE_NAME; - -class CreateAnticipatedTransitionsTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateAnticipatedTransitionsTable.class); - - private final DdlChange createAnticipatedTransitionsTable = new CreateAnticipatedTransitionsTable(db.database()); - - @Test - void migration_should_create_a_table() throws SQLException { - db.assertTableDoesNotExist(ANTICIPATED_TRANSITIONS_TABLE_NAME); - - createAnticipatedTransitionsTable.execute(); - - db.assertTableExists(ANTICIPATED_TRANSITIONS_TABLE_NAME); - db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "uuid", Types.VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "project_uuid", Types.VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "user_uuid", Types.VARCHAR, USER_UUID_SIZE, false); - db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "transition", Types.VARCHAR, 20, false); - db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "transition_comment", Types.VARCHAR, MAX_SIZE, true); - db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "line", Types.INTEGER, null, true); - db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "message", Types.VARCHAR, MAX_SIZE, true); - db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "line_hash", Types.VARCHAR, 255, true); - db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "rule_key", Types.VARCHAR, 200, false); - db.assertColumnDefinition(ANTICIPATED_TRANSITIONS_TABLE_NAME, "file_path", Types.VARCHAR, 1500, false); - db.assertPrimaryKey(ANTICIPATED_TRANSITIONS_TABLE_NAME, "pk_anticipated_transitions", "uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertTableDoesNotExist(ANTICIPATED_TRANSITIONS_TABLE_NAME); - - createAnticipatedTransitionsTable.execute(); - // re-entrant - createAnticipatedTransitionsTable.execute(); - - db.assertTableExists(ANTICIPATED_TRANSITIONS_TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateGithubOrganizationsGroupsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateGithubOrganizationsGroupsTableIT.java deleted file mode 100644 index 0ec928e608b..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateGithubOrganizationsGroupsTableIT.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.version.v102.CreateGithubOrganizationsGroupsTable.GROUP_UUID_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v102.CreateGithubOrganizationsGroupsTable.ORGANIZATION_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v102.CreateGithubOrganizationsGroupsTable.TABLE_NAME; - -class CreateGithubOrganizationsGroupsTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateGithubOrganizationsGroupsTable.class); - private final DdlChange createGithubOrganizationsGroupsTable = new CreateGithubOrganizationsGroupsTable(db.database()); - - @Test - void migration_should_create_a_table() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - createGithubOrganizationsGroupsTable.execute(); - - db.assertTableExists(TABLE_NAME); - db.assertColumnDefinition(TABLE_NAME, GROUP_UUID_COLUMN_NAME, Types.VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, ORGANIZATION_COLUMN_NAME, Types.VARCHAR, 100, false); - db.assertPrimaryKey(TABLE_NAME, "pk_github_orgs_groups", GROUP_UUID_COLUMN_NAME); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - createGithubOrganizationsGroupsTable.execute(); - // re-entrant - createGithubOrganizationsGroupsTable.execute(); - - db.assertTableExists(TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexCreatedAtInWebhookDeliveriesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexCreatedAtInWebhookDeliveriesIT.java deleted file mode 100644 index 83df756e86c..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexCreatedAtInWebhookDeliveriesIT.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class CreateIndexCreatedAtInWebhookDeliveriesIT { - - public static final String TABLE_NAME = "webhook_deliveries"; - public static final String INDEX_NAME = "wd_created_at"; - public static final String EXPECTED_COLUMN = "created_at"; - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexCreatedAtInWebhookDeliveries.class); - private final DdlChange createIndex = new CreateIndexCreatedAtInWebhookDeliveries(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - - createIndex.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, EXPECTED_COLUMN); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, EXPECTED_COLUMN); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInCeActivityIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInCeActivityIT.java deleted file mode 100644 index 45b7981f962..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInCeActivityIT.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -class CreateIndexEntityUuidInCeActivityIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexEntityUuidInCeActivity.class); - private final CreateIndexEntityUuidInCeActivity createIndex = new CreateIndexEntityUuidInCeActivity(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist("ce_activity", "ce_activity_entity_uuid"); - - createIndex.execute(); - - db.assertIndex("ce_activity", "ce_activity_entity_uuid", "entity_uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertIndex("ce_activity", "ce_activity_entity_uuid", "entity_uuid"); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInCeQueueIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInCeQueueIT.java deleted file mode 100644 index d80604d9415..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInCeQueueIT.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -class CreateIndexEntityUuidInCeQueueIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexEntityUuidInCeQueue.class); - private final CreateIndexEntityUuidInCeQueue createIndex = new CreateIndexEntityUuidInCeQueue(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist("ce_queue", "ce_queue_entity_uuid"); - - createIndex.execute(); - - db.assertIndex("ce_queue", "ce_queue_entity_uuid", "entity_uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertIndex("ce_queue", "ce_queue_entity_uuid", "entity_uuid"); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInGroupRolesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInGroupRolesIT.java deleted file mode 100644 index cd3a604afd6..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInGroupRolesIT.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -class CreateIndexEntityUuidInGroupRolesIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexEntityUuidInGroupRoles.class); - private final CreateIndexEntityUuidInGroupRoles createIndex = new CreateIndexEntityUuidInGroupRoles(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist("group_roles", "group_roles_entity_uuid"); - - createIndex.execute(); - - db.assertIndex("group_roles", "group_roles_entity_uuid", "entity_uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertIndex("group_roles", "group_roles_entity_uuid", "entity_uuid"); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInUserRolesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInUserRolesIT.java deleted file mode 100644 index b98c6802061..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInUserRolesIT.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -class CreateIndexEntityUuidInUserRolesIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexEntityUuidInUserRoles.class); - private final CreateIndexEntityUuidInUserRoles createIndex = new CreateIndexEntityUuidInUserRoles(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist("user_roles", "user_roles_entity_uuid"); - - createIndex.execute(); - - db.assertIndex("user_roles", "user_roles_entity_uuid", "entity_uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertIndex("user_roles", "user_roles_entity_uuid", "entity_uuid"); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexProjectUuidCreatedAtInWebhookDeliveriesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexProjectUuidCreatedAtInWebhookDeliveriesIT.java deleted file mode 100644 index a77dca305b4..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexProjectUuidCreatedAtInWebhookDeliveriesIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class CreateIndexProjectUuidCreatedAtInWebhookDeliveriesIT { - - public static final String TABLE_NAME = "webhook_deliveries"; - public static final String INDEX_NAME = "wd_project_uuid_created_at"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexProjectUuidCreatedAtInWebhookDeliveries.class); - private final DdlChange createIndex = new CreateIndexProjectUuidCreatedAtInWebhookDeliveries(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - - createIndex.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, "project_uuid", "created_at"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, "project_uuid", "created_at"); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexProjectUuidInProjectBranchesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexProjectUuidInProjectBranchesIT.java deleted file mode 100644 index 927bbf09730..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexProjectUuidInProjectBranchesIT.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - - - -class CreateIndexProjectUuidInProjectBranchesIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexProjectUuidInProjectBranches.class); - private final CreateIndexProjectUuidInProjectBranches createIndex = new CreateIndexProjectUuidInProjectBranches(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist("project_branches", "project_branches_project_uuid"); - - createIndex.execute(); - - db.assertIndex("project_branches", "project_branches_project_uuid", "project_uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertIndex("project_branches", "project_branches_project_uuid", "project_uuid"); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexRootComponentUuidInSnapshotsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexRootComponentUuidInSnapshotsIT.java deleted file mode 100644 index bfb20829a37..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexRootComponentUuidInSnapshotsIT.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - - - -class CreateIndexRootComponentUuidInSnapshotsIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexRootComponentUuidInSnapshots.class); - private final CreateIndexRootComponentUuidInSnapshots createIndex = new CreateIndexRootComponentUuidInSnapshots(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist("snapshots", "snapshots_root_component_uuid"); - - createIndex.execute(); - - db.assertIndex("snapshots", "snapshots_root_component_uuid", "root_component_uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertIndex("snapshots", "snapshots_root_component_uuid", "root_component_uuid"); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexTaskUuidCreatedAtInWebhookDeliveriesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexTaskUuidCreatedAtInWebhookDeliveriesIT.java deleted file mode 100644 index fef3462f9b3..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexTaskUuidCreatedAtInWebhookDeliveriesIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class CreateIndexTaskUuidCreatedAtInWebhookDeliveriesIT { - - public static final String TABLE_NAME = "webhook_deliveries"; - public static final String INDEX_NAME = "wd_ce_task_uuid_created_at"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexTaskUuidCreatedAtInWebhookDeliveries.class); - private final DdlChange createIndex = new CreateIndexTaskUuidCreatedAtInWebhookDeliveries(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - - createIndex.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, "ce_task_uuid", "created_at"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, "ce_task_uuid", "created_at"); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexWebhookUuidCreatedAtInWebhookDeliveriesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexWebhookUuidCreatedAtInWebhookDeliveriesIT.java deleted file mode 100644 index e2b6e872f23..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexWebhookUuidCreatedAtInWebhookDeliveriesIT.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class CreateIndexWebhookUuidCreatedAtInWebhookDeliveriesIT { - - public static final String TABLE_NAME = "webhook_deliveries"; - public static final String INDEX_NAME = "wd_webhook_uuid_created_at"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexWebhookUuidCreatedAtInWebhookDeliveries.class); - private final DdlChange createIndex = new CreateIndexWebhookUuidCreatedAtInWebhookDeliveries(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - - createIndex.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, "webhook_uuid", "created_at"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, "webhook_uuid", "created_at"); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIssueImpactsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIssueImpactsTableIT.java deleted file mode 100644 index f23e55704a9..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateIssueImpactsTableIT.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class CreateIssueImpactsTableIT { - private static final String EXPECTED_TABLE_NAME = "issues_impacts"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIssueImpactsTable.class); - - private final DdlChange underTest = new CreateIssueImpactsTable(db.database()); - - @Test - void migration_should_create_a_table() throws SQLException { - db.assertTableDoesNotExist(EXPECTED_TABLE_NAME); - - underTest.execute(); - - db.assertTableExists(EXPECTED_TABLE_NAME); - db.assertColumnDefinition(EXPECTED_TABLE_NAME, "issue_key", Types.VARCHAR, 40, false); - db.assertColumnDefinition(EXPECTED_TABLE_NAME, "software_quality", Types.VARCHAR, 40, false); - db.assertColumnDefinition(EXPECTED_TABLE_NAME, "severity", Types.VARCHAR, 40, false); - db.assertPrimaryKey(EXPECTED_TABLE_NAME, null, "uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertTableDoesNotExist(EXPECTED_TABLE_NAME); - - underTest.execute(); - // re-entrant - underTest.execute(); - - db.assertTableExists(EXPECTED_TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreatePreviousNonCompliantValueInNewCodePeriodsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreatePreviousNonCompliantValueInNewCodePeriodsIT.java deleted file mode 100644 index 80601d4abd6..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreatePreviousNonCompliantValueInNewCodePeriodsIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; - -class CreatePreviousNonCompliantValueInNewCodePeriodsIT { - - private static final String COLUMN_NAME= "previous_non_compliant_value"; - - private static final String TABLE_NAME = "new_code_periods"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreatePreviousNonCompliantValueInNewCodePeriods.class); - private final CreatePreviousNonCompliantValueInNewCodePeriods underTest = new CreatePreviousNonCompliantValueInNewCodePeriods(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreatePurgedColumn() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 255, null); - } - - @Test - void execute_whenExecutedTwice_shouldNotFail() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 255, null); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateRulesDefaultImpactsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateRulesDefaultImpactsTableIT.java deleted file mode 100644 index 5990ac995eb..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateRulesDefaultImpactsTableIT.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - - -class CreateRulesDefaultImpactsTableIT { - private static final String EXPECTED_TABLE_NAME = "rules_default_impacts"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateRulesDefaultImpactsTable.class); - - private final DdlChange underTest = new CreateRulesDefaultImpactsTable(db.database()); - - @Test - void migration_should_create_a_table() throws SQLException { - db.assertTableDoesNotExist(EXPECTED_TABLE_NAME); - - underTest.execute(); - - db.assertTableExists(EXPECTED_TABLE_NAME); - db.assertColumnDefinition(EXPECTED_TABLE_NAME, "rule_uuid", Types.VARCHAR, 40, false); - db.assertColumnDefinition(EXPECTED_TABLE_NAME, "software_quality", Types.VARCHAR, 40, false); - db.assertColumnDefinition(EXPECTED_TABLE_NAME, "severity", Types.VARCHAR, 40, false); - db.assertPrimaryKey(EXPECTED_TABLE_NAME, null, "uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertTableDoesNotExist(EXPECTED_TABLE_NAME); - - underTest.execute(); - // re-entrant - underTest.execute(); - - db.assertTableExists(EXPECTED_TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateUniqueConstraintOnIssuesImpactsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateUniqueConstraintOnIssuesImpactsIT.java deleted file mode 100644 index bd5551d801e..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateUniqueConstraintOnIssuesImpactsIT.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - - - -class CreateUniqueConstraintOnIssuesImpactsIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateUniqueConstraintOnIssuesImpacts.class); - private final CreateUniqueConstraintOnIssuesImpacts underTest = new CreateUniqueConstraintOnIssuesImpacts(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist("issues_impacts", "uniq_iss_key_sof_qual"); - - underTest.execute(); - - db.assertUniqueIndex("issues_impacts", "uniq_iss_key_sof_qual", "issue_key", "software_quality"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - underTest.execute(); - underTest.execute(); - - db.assertUniqueIndex("issues_impacts", "uniq_iss_key_sof_qual", "issue_key", "software_quality"); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateUniqueConstraintOnRulesDefaultImpactsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateUniqueConstraintOnRulesDefaultImpactsIT.java deleted file mode 100644 index 06736e508fa..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateUniqueConstraintOnRulesDefaultImpactsIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - - - - -class CreateUniqueConstraintOnRulesDefaultImpactsIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateUniqueConstraintOnRulesDefaultImpacts.class); - private final CreateUniqueConstraintOnRulesDefaultImpacts underTest = new CreateUniqueConstraintOnRulesDefaultImpacts(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist("rules_default_impacts", "uniq_rul_uuid_sof_qual"); - - underTest.execute(); - - db.assertUniqueIndex("rules_default_impacts", "uniq_rul_uuid_sof_qual", "rule_uuid", "software_quality"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - underTest.execute(); - underTest.execute(); - - db.assertUniqueIndex("rules_default_impacts", "uniq_rul_uuid_sof_qual", "rule_uuid", "software_quality"); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInGroupRolesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInGroupRolesIT.java deleted file mode 100644 index 0b9fb69b560..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInGroupRolesIT.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.CoreDbTester; -import org.sonar.db.MigrationDbTester; - - - -class DropIndexComponentUuidInGroupRolesIT { - - private static final String TABLE_NAME = "group_roles"; - private static final String COLUMN_NAME = "component_uuid"; - private static final String INDEX_NAME = "group_roles_component_uuid"; - - /** - * {@link MigrationDbTester} is not used because we are expecting index with component_uuid to exist. However, renaming the column component_uuid to entity_uuid - * also updated the index - */ - @RegisterExtension - public final CoreDbTester db = CoreDbTester.createForSchema(DropIndexComponentUuidInGroupRolesIT.class, "schema.sql"); - private final DropIndexComponentUuidInGroupRoles underTest = new DropIndexComponentUuidInGroupRoles(db.database()); - - @Test - void index_is_dropped() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInUserRolesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInUserRolesIT.java deleted file mode 100644 index fa0ff9f3df2..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInUserRolesIT.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.CoreDbTester; -import org.sonar.db.MigrationDbTester; - - - -class DropIndexComponentUuidInUserRolesIT { - - private static final String TABLE_NAME = "user_roles"; - private static final String COLUMN_NAME = "component_uuid"; - private static final String INDEX_NAME = "user_roles_component_uuid"; - - /** - * {@link MigrationDbTester} is not used because we are expecting index with component_uuid to exist. However, renaming the column component_uuid to entity_uuid - * also updated the index - */ - @RegisterExtension - public final CoreDbTester db = CoreDbTester.createForSchema(DropIndexComponentUuidInUserRolesIT.class, "schema.sql"); - private final DropIndexComponentUuidInUserRoles underTest = new DropIndexComponentUuidInUserRoles(db.database()); - - @Test - void index_is_dropped() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInWebhookDeliveriesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInWebhookDeliveriesIT.java deleted file mode 100644 index 9ca24e7f36b..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInWebhookDeliveriesIT.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - - - -class DropIndexComponentUuidInWebhookDeliveriesIT { - - private static final String TABLE_NAME = "webhook_deliveries"; - private static final String COLUMN_NAME = "component_uuid"; - private static final String INDEX_NAME = "component_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropIndexComponentUuidInWebhookDeliveries.class); - private final DropIndexComponentUuidInWebhookDeliveries underTest = new DropIndexComponentUuidInWebhookDeliveries(db.database()); - - @Test - void index_is_dropped() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexMainComponentUuidInCeActivityIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexMainComponentUuidInCeActivityIT.java deleted file mode 100644 index 0e45b0398c4..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexMainComponentUuidInCeActivityIT.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - - - -class DropIndexMainComponentUuidInCeActivityIT { - - private static final String TABLE_NAME = "ce_activity"; - private static final String COLUMN_NAME = "main_component_uuid"; - private static final String INDEX_NAME = "ce_activity_main_component"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropIndexMainComponentUuidInCeActivity.class); - private final DropIndexMainComponentUuidInCeActivity underTest = new DropIndexMainComponentUuidInCeActivity(db.database()); - - @Test - void index_is_dropped() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexMainComponentUuidInCeQueueIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexMainComponentUuidInCeQueueIT.java deleted file mode 100644 index 1a8442b9547..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexMainComponentUuidInCeQueueIT.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - - - -class DropIndexMainComponentUuidInCeQueueIT { - - private static final String TABLE_NAME = "ce_queue"; - private static final String COLUMN_NAME = "main_component_uuid"; - private static final String INDEX_NAME = "ce_queue_main_component"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropIndexMainComponentUuidInCeQueue.class); - private final DropIndexMainComponentUuidInCeQueue underTest = new DropIndexMainComponentUuidInCeQueue(db.database()); - - @Test - void index_is_dropped() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexProjectUuidInWebhookDeliveriesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexProjectUuidInWebhookDeliveriesIT.java deleted file mode 100644 index 55da8cc41ab..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexProjectUuidInWebhookDeliveriesIT.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.CoreDbTester; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropIndexProjectUuidInWebhookDeliveriesIT { - - private static final String TABLE_NAME = "webhook_deliveries"; - private static final String COLUMN_NAME = "project_uuid"; - private static final String INDEX_NAME = "wd_project_uuid"; - - /** - * {@link MigrationDbTester} is not used because we are expecting index with component_uuid to exist. However, renaming the column component_uuid to entity_uuid - * also updated the index - */ - @RegisterExtension - public final CoreDbTester db = CoreDbTester.createForSchema(DropIndexProjectUuidInWebhookDeliveriesIT.class, "schema.sql"); - private final DdlChange underTest = new DropIndexProjectUuidInWebhookDeliveries(db.database()); - - @Test - void index_is_dropped() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexTaskUuidInWebhookDeliveriesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexTaskUuidInWebhookDeliveriesIT.java deleted file mode 100644 index 11c3cefbd6e..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexTaskUuidInWebhookDeliveriesIT.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropIndexTaskUuidInWebhookDeliveriesIT { - - private static final String TABLE_NAME = "webhook_deliveries"; - private static final String COLUMN_NAME = "ce_task_uuid"; - private static final String INDEX_NAME = "ce_task_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropIndexTaskUuidInWebhookDeliveries.class); - private final DdlChange underTest = new DropIndexTaskUuidInWebhookDeliveries(db.database()); - - @Test - void index_is_dropped() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexWebhookUuidInWebhookDeliveriesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexWebhookUuidInWebhookDeliveriesIT.java deleted file mode 100644 index 45d56e1c942..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexWebhookUuidInWebhookDeliveriesIT.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropIndexWebhookUuidInWebhookDeliveriesIT { - - private static final String TABLE_NAME = "webhook_deliveries"; - private static final String COLUMN_NAME = "webhook_uuid"; - private static final String INDEX_NAME = "idx_wbhk_dlvrs_wbhk_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropIndexWebhookUuidInWebhookDeliveries.class); - private final DdlChange underTest = new DropIndexWebhookUuidInWebhookDeliveries(db.database()); - - @Test - void index_is_dropped() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - - underTest.execute(); - underTest.execute(); - - db.assertIndexDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropMainBranchProjectUuidInComponentsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropMainBranchProjectUuidInComponentsIT.java deleted file mode 100644 index 329bb1ebc37..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropMainBranchProjectUuidInComponentsIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v102.DropMainBranchProjectUuidInComponents.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v102.DropMainBranchProjectUuidInComponents.TABLE_NAME; - -class DropMainBranchProjectUuidInComponentsIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropMainBranchProjectUuidInComponents.class); - private final DdlChange underTest = new DropMainBranchProjectUuidInComponents(db.database()); - - @Test - void drops_column() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 50, true); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 50, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropPurgeStatusColumnInSnapshotsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropPurgeStatusColumnInSnapshotsIT.java deleted file mode 100644 index bce5e938251..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropPurgeStatusColumnInSnapshotsIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - - - -class DropPurgeStatusColumnInSnapshotsIT { - - private static final String TABLE_NAME = "snapshots"; - private static final String COLUMN_NAME = "purge_status"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropPurgeStatusColumnInSnapshots.class); - private final DropPurgeStatusColumnInSnapshots underTest = new DropPurgeStatusColumnInSnapshots(db.database()); - - @Test - void drops_column() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.INTEGER, null, null); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.INTEGER, null, null); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropTableProjectMappingsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropTableProjectMappingsIT.java deleted file mode 100644 index 2f99322000b..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropTableProjectMappingsIT.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - - - -class DropTableProjectMappingsIT { - public static final String TABLE_NAME = "project_mappings"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropTableProjectMappings.class); - private final DropTableProjectMappings underTest = new DropTableProjectMappings(db.database()); - - @Test - void execute_shouldDropTable() throws SQLException { - db.assertTableExists(TABLE_NAME); - underTest.execute(); - db.assertTableDoesNotExist(TABLE_NAME); - } - - @Test - void execute_shouldSupportReentrantMigrationExecution() throws SQLException { - db.assertTableExists(TABLE_NAME); - underTest.execute(); - underTest.execute(); - db.assertTableDoesNotExist(TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/FixSqaleIndexMetricDescriptionIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/FixSqaleIndexMetricDescriptionIT.java deleted file mode 100644 index 4928d10eac4..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/FixSqaleIndexMetricDescriptionIT.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; - -class FixSqaleIndexMetricDescriptionIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(FixSqaleIndexMetricDescription.class); - private final FixSqaleIndexMetricDescription underTest = new FixSqaleIndexMetricDescription(db.database()); - private final String OLD_DESCRIPTION = "Total effort (in hours) to fix all the issues on the component and therefore to comply to all the requirements."; - private final String NEW_DESCRIPTION = "Total effort (in minutes) to fix all the issues on the component and therefore to comply to all the requirements."; - - @BeforeEach - public void setUp() { - db.executeInsert("metrics", - "uuid", "uuid", - "name", "sqale_index", - "description", OLD_DESCRIPTION); - } - - @Test - void execute_whenExecuted_shouldUpdateSqaleIndexDescription() throws SQLException { - assertThat(select()).isEqualTo(OLD_DESCRIPTION); - underTest.execute(); - assertThat(select()).isEqualTo(NEW_DESCRIPTION); - } - - @Test - void execute_WhenExecutedTwice_shouldBeReentrant() throws SQLException { - assertThat(select()).isEqualTo(OLD_DESCRIPTION); - underTest.execute(); - underTest.execute(); - assertThat(select()).isEqualTo(NEW_DESCRIPTION); - } - - private String select() { - return (String) db.selectFirst("SELECT description FROM metrics WHERE name = 'sqale_index'").get("description"); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/IncreaseIsLastKeyInCeActivityIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/IncreaseIsLastKeyInCeActivityIT.java deleted file mode 100644 index d96ad15c169..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/IncreaseIsLastKeyInCeActivityIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; -import static org.sonar.server.platform.db.migration.version.v102.IncreaseIsLastKeyInCeActivity.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v102.IncreaseIsLastKeyInCeActivity.NEW_COLUMN_SIZE; -import static org.sonar.server.platform.db.migration.version.v102.IncreaseIsLastKeyInCeActivity.TABLE_NAME; - -class IncreaseIsLastKeyInCeActivityIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(IncreaseIsLastKeyInCeActivity.class); - private final IncreaseIsLastKeyInCeActivity underTest = new IncreaseIsLastKeyInCeActivity(db.database()); - - @Test - void execute_increaseColumnSize() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 55, false); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, NEW_COLUMN_SIZE, false); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 55, false); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, NEW_COLUMN_SIZE, false); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/IncreaseMainIsLastKeyInCeActivityIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/IncreaseMainIsLastKeyInCeActivityIT.java deleted file mode 100644 index 28d00a4c131..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/IncreaseMainIsLastKeyInCeActivityIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; -import static org.sonar.server.platform.db.migration.version.v102.IncreaseMainIsLastKeyInCeActivity.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v102.IncreaseMainIsLastKeyInCeActivity.NEW_COLUMN_SIZE; -import static org.sonar.server.platform.db.migration.version.v102.IncreaseMainIsLastKeyInCeActivity.TABLE_NAME; - -class IncreaseMainIsLastKeyInCeActivityIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(IncreaseMainIsLastKeyInCeActivity.class); - private final IncreaseMainIsLastKeyInCeActivity underTest = new IncreaseMainIsLastKeyInCeActivity(db.database()); - - @Test - void execute_increaseColumnSize() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 55, false); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, NEW_COLUMN_SIZE, false); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 55, false); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, NEW_COLUMN_SIZE, false); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/MakeProjectUuidNullableInUserDismissedMessagesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/MakeProjectUuidNullableInUserDismissedMessagesIT.java deleted file mode 100644 index 05c4e121439..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/MakeProjectUuidNullableInUserDismissedMessagesIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; - -class MakeProjectUuidNullableInUserDismissedMessagesIT { - - private static final String TABLE_NAME = "user_dismissed_messages"; - private static final String COLUMN_NAME = "project_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(MakeProjectUuidNullableInUserDismissedMessages.class); - private final MakeProjectUuidNullableInUserDismissedMessages underTest = new MakeProjectUuidNullableInUserDismissedMessages(db.database()); - - @Test - void execute_shouldBeNullable() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 40, false); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 40, true); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 40, false); - underTest.execute(); - underTest.execute(); - - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, 40, true); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/MakePurgedColumnNotNullableInSnapshotsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/MakePurgedColumnNotNullableInSnapshotsIT.java deleted file mode 100644 index e8faf66f43a..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/MakePurgedColumnNotNullableInSnapshotsIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.BOOLEAN; - -class MakePurgedColumnNotNullableInSnapshotsIT { - private static final String TABLE_NAME = "snapshots"; - private static final String COLUMN_NAME = "purged"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(MakePurgedColumnNotNullableInSnapshots.class); - private final MakePurgedColumnNotNullableInSnapshots underTest = new MakePurgedColumnNotNullableInSnapshots(db.database()); - - @Test - void execute_whenColumnIsNullable_shouldMakeColumnNullable() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, true); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, false); - } - - @Test - void execute_whenExecutedTwice_shouldMakeColumnNullable() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, false); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/PopulateCleanCodeAttributeColumnInRulesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/PopulateCleanCodeAttributeColumnInRulesIT.java deleted file mode 100644 index 8074c39e777..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/PopulateCleanCodeAttributeColumnInRulesIT.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; - -class PopulateCleanCodeAttributeColumnInRulesIT { - - private static final String TABLE_NAME = "rules"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulateCleanCodeAttributeColumnInRules.class); - private final PopulateCleanCodeAttributeColumnInRules underTest = new PopulateCleanCodeAttributeColumnInRules(db.database()); - - @Test - void execute_whenRulesDoNotExist_shouldNotFail() { - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } - - @Test - void execute_whenRuleWithUndefinedCleanCodeAttribute_shouldUpdate() throws SQLException { - insertRule("1", null); - underTest.execute(); - assertThat(db.select("select uuid, clean_code_attribute from rules")) - .extracting(stringObjectMap -> stringObjectMap.get("clean_code_attribute")) - .containsExactly(CleanCodeAttribute.CONVENTIONAL.name()); - } - - @Test - void execute_whenRuleWithUndefinedCleanCodeAttribute_shouldBeReentrant() throws SQLException { - insertRule("1", null); - underTest.execute(); - underTest.execute(); - assertThat(db.select("select uuid, clean_code_attribute from rules")) - .extracting(stringObjectMap -> stringObjectMap.get("clean_code_attribute")) - .containsExactly(CleanCodeAttribute.CONVENTIONAL.name()); - } - - @Test - void execute_whenRuleWithDefinedCleanCodeAttribute_shouldNotUpdate() throws SQLException { - insertRule("1", CleanCodeAttribute.FOCUSED); - underTest.execute(); - assertThat(db.select("select uuid, clean_code_attribute from rules")) - .extracting(stringObjectMap -> stringObjectMap.get("clean_code_attribute")) - .containsExactly(CleanCodeAttribute.FOCUSED.name()); - } - - @Test - void execute_whenRuleIsHotspot_shouldNotUpdate() throws SQLException { - insertRule("1", RuleType.SECURITY_HOTSPOT, null, null); - underTest.execute(); - assertThat(db.select("select uuid, clean_code_attribute from rules")) - .extracting(stringObjectMap -> stringObjectMap.get("clean_code_attribute")) - .containsOnlyNulls(); - } - - @Test - void execute_whenAdhocRuleIsHotspot_shouldNotUpdate() throws SQLException { - insertRule("1", null, RuleType.SECURITY_HOTSPOT, null); - underTest.execute(); - assertThat(db.select("select uuid, clean_code_attribute from rules")) - .extracting(stringObjectMap -> stringObjectMap.get("clean_code_attribute")) - .containsOnlyNulls(); - } - - - private void insertRule(String uuid, @Nullable RuleType ruleType, @Nullable RuleType adhocRuleType, @Nullable CleanCodeAttribute cleanCodeAttribute) { - db.executeInsert(TABLE_NAME, - "UUID", uuid, - "PLUGIN_RULE_KEY", "key", - "PLUGIN_NAME", "name", - "SCOPE", "1", - "CLEAN_CODE_ATTRIBUTE", cleanCodeAttribute != null ? cleanCodeAttribute.name() : null, - "IS_TEMPLATE", false, - "RULE_TYPE", ruleType != null ? ruleType.getDbConstant() : null, - "AD_HOC_TYPE", adhocRuleType != null ? adhocRuleType.getDbConstant() : null, - "IS_AD_HOC", false, - "IS_EXTERNAL", false); - } - - private void insertRule(String uuid, @Nullable CleanCodeAttribute cleanCodeAttribute) { - insertRule(uuid, RuleType.CODE_SMELL, null, cleanCodeAttribute); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/PopulateDefaultImpactsInRulesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/PopulateDefaultImpactsInRulesIT.java deleted file mode 100644 index ee6ac81abb8..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/PopulateDefaultImpactsInRulesIT.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.batch.rule.Severity; -import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; -import org.sonar.api.testfixtures.log.LogTesterJUnit5; -import org.sonar.core.util.Uuids; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.tuple; - -class PopulateDefaultImpactsInRulesIT { - private static final String TABLE_NAME = "rules"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulateDefaultImpactsInRules.class); - @RegisterExtension - public final LogTesterJUnit5 logTester = new LogTesterJUnit5(); - - private final PopulateDefaultImpactsInRules underTest = new PopulateDefaultImpactsInRules(db.database()); - - @Test - void execute_whenRulesDoNotExist_shouldNotFail() { - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } - - @Test - void execute_whenRulesHasTypeAndSeverity_shouldCreateImpact() throws SQLException { - insertRuleWithType("uuid", RuleType.CODE_SMELL, Severity.MAJOR); - underTest.execute(); - - assertThat(db.select("select software_quality, severity from rules_default_impacts")) - .extracting(stringObjectMap -> stringObjectMap.get("software_quality"), - stringObjectMap -> stringObjectMap.get("severity")) - .containsExactly(tuple(SoftwareQuality.MAINTAINABILITY.name(), org.sonar.api.issue.impact.Severity.MEDIUM.name())); - } - - @Test - void execute_shouldBeReentrant() throws SQLException { - insertRuleWithType("uuid", RuleType.CODE_SMELL, Severity.MAJOR); - underTest.execute(); - underTest.execute(); - - assertThat(db.select("select software_quality, severity from rules_default_impacts")) - .hasSize(1) - .extracting(stringObjectMap -> stringObjectMap.get("software_quality"), - stringObjectMap -> stringObjectMap.get("severity")) - .containsExactly(tuple(SoftwareQuality.MAINTAINABILITY.name(), org.sonar.api.issue.impact.Severity.MEDIUM.name())); - - } - - @Test - void execute_shouldNotBeExecuted_whenImpactsTableHasAlreadyRecords() throws SQLException { - insertRuleWithType("uuid", RuleType.CODE_SMELL, Severity.MAJOR); - insertRuleWithType("uuid2", RuleType.CODE_SMELL, Severity.MAJOR); - insertImpact("uuid", SoftwareQuality.SECURITY, org.sonar.api.issue.impact.Severity.HIGH); - - underTest.execute(); - - assertThat(db.select("select software_quality, severity from rules_default_impacts")) - .hasSize(1) - .extracting(stringObjectMap -> stringObjectMap.get("software_quality"), - stringObjectMap -> stringObjectMap.get("severity")) - .containsExactly(tuple(SoftwareQuality.SECURITY.name(), org.sonar.api.issue.impact.Severity.HIGH.name())); - } - - @Test - void execute_whenAdhocRulesHasTypeAndSeverity_shouldCreateImpact() throws SQLException { - insertRuleWithAdHocType("uuid", RuleType.CODE_SMELL, Severity.MAJOR); - underTest.execute(); - - assertThat(db.select("select software_quality, severity from rules_default_impacts")) - .hasSize(1) - .extracting(stringObjectMap -> stringObjectMap.get("software_quality"), - stringObjectMap -> stringObjectMap.get("severity")) - .containsExactly(tuple(SoftwareQuality.MAINTAINABILITY.name(), org.sonar.api.issue.impact.Severity.MEDIUM.name())); - - } - - @Test - void execute_whenAdhocRulesHasImpactAlready_shouldNotCreateImpact() throws SQLException { - insertRuleWithAdHocType("uuid", RuleType.CODE_SMELL, Severity.MAJOR); - insertImpact("uuid", SoftwareQuality.SECURITY, org.sonar.api.issue.impact.Severity.HIGH); - underTest.execute(); - - assertThat(db.select("select software_quality, severity from rules_default_impacts")) - .hasSize(1) - .extracting(stringObjectMap -> stringObjectMap.get("software_quality"), - stringObjectMap -> stringObjectMap.get("severity")) - .containsExactly(tuple(SoftwareQuality.SECURITY.name(), org.sonar.api.issue.impact.Severity.HIGH.name())); - - } - - @Test - void execute_whenNoTypeAndSeverityDefined_shouldNotCreateImpact() throws SQLException { - insertRuleWithType("uuid", null, null); - underTest.execute(); - - assertThat(db.select("select software_quality, severity from rules_default_impacts")) - .isEmpty(); - - } - - @Test - void execute_whenInvalidValueDefined_shouldNotCreateImpactAndLog() throws SQLException { - insertInvalidRule("uuid"); - underTest.execute(); - - assertThat(db.select("select software_quality, severity from rules_default_impacts")) - .isEmpty(); - assertThat(logTester.logs()).contains("Error while mapping type to impact for rule 'uuid'"); - - } - - @Test - void execute_whenTypeIsHotspot_shouldNotCreateImpactAndLog() throws SQLException { - insertRuleWithType("uuid", RuleType.SECURITY_HOTSPOT, Severity.MAJOR); - underTest.execute(); - - assertThat(db.select("select software_quality, severity from rules_default_impacts")) - .isEmpty(); - assertThat(logTester.logs()).doesNotContain("Error while mapping type to impact for rule 'uuid'"); - } - - @Test - void execute_whenRuleHasEmptyFields_shouldCreateADefaultImpact() throws SQLException { - insertPlaceholderAdhocRule("uuid"); - underTest.execute(); - - assertThat(db.select("select software_quality, severity from rules_default_impacts")) - .hasSize(1) - .extracting(stringObjectMap -> stringObjectMap.get("software_quality"), - stringObjectMap -> stringObjectMap.get("severity")) - .containsExactly(tuple(SoftwareQuality.MAINTAINABILITY.name(), org.sonar.api.issue.impact.Severity.MEDIUM.name())); - } - - @Test - void execute_whenStandardRuleHasBothAdhocAndStandardTypeAndSeverity_shouldCreateADefaultImpactWithAdhocTypes() throws SQLException { - insertRule("uuid", RuleType.CODE_SMELL, Severity.CRITICAL, RuleType.VULNERABILITY, Severity.MINOR, true); - underTest.execute(); - - assertThat(db.select("select software_quality, severity from rules_default_impacts")) - .hasSize(1) - .extracting(stringObjectMap -> stringObjectMap.get("software_quality"), - stringObjectMap -> stringObjectMap.get("severity")) - .containsExactly(tuple(SoftwareQuality.SECURITY.name(), org.sonar.api.issue.impact.Severity.LOW.name())); - } - - private void insertRuleWithType(String uuid, @Nullable RuleType ruleType, @Nullable Severity severity) { - insertRule(uuid, ruleType, severity, null, null); - } - - private void insertRuleWithAdHocType(String uuid, @Nullable RuleType adHocType, @Nullable Severity adHocseverity) { - insertRule(uuid, null, null, adHocType, adHocseverity); - } - - - private void insertRule(String uuid, @Nullable RuleType ruleType, @Nullable Severity severity, @Nullable RuleType adHocType, @Nullable Severity adHocseverity) { - insertRule(uuid, ruleType, severity, adHocType, adHocseverity, adHocType != null); - } - - private void insertRule(String uuid, @Nullable RuleType ruleType, @Nullable Severity severity, @Nullable RuleType adHocType, @Nullable Severity adHocseverity, boolean isAdhoc) { - db.executeInsert(TABLE_NAME, - "UUID", uuid, - "PLUGIN_RULE_KEY", "key" + uuid, - "PLUGIN_NAME", "name", - "SCOPE", "1", - "RULE_TYPE", ruleType != null ? ruleType.getDbConstant() : null, - "PRIORITY", severity != null ? org.sonar.api.rule.Severity.ALL.indexOf(severity.name()) : null, - "AD_HOC_TYPE", adHocType != null ? adHocType.getDbConstant() : null, - "AD_HOC_SEVERITY", adHocseverity != null ? adHocseverity.name() : null, - "IS_TEMPLATE", false, - "IS_AD_HOC", isAdhoc, - "IS_EXTERNAL", isAdhoc); - } - - private void insertInvalidRule(String uuid) { - db.executeInsert(TABLE_NAME, - "UUID", uuid, - "PLUGIN_RULE_KEY", "key" + uuid, - "PLUGIN_NAME", "name", - "SCOPE", "1", - "RULE_TYPE", 100, - "PRIORITY", -1, - "AD_HOC_TYPE", 100, - "AD_HOC_SEVERITY", "-1", - "IS_TEMPLATE", false, - "IS_AD_HOC", false, - "IS_EXTERNAL", false); - } - - private void insertPlaceholderAdhocRule(String uuid) { - db.executeInsert(TABLE_NAME, - "UUID", uuid, - "PLUGIN_RULE_KEY", "key" + uuid, - "PLUGIN_NAME", "name", - "SCOPE", "1", - "IS_TEMPLATE", false, - "IS_AD_HOC", true, - "IS_EXTERNAL", false); - } - - private void insertImpact(String ruleUuid, SoftwareQuality softwareQuality, org.sonar.api.issue.impact.Severity severity) { - db.executeInsert("RULES_DEFAULT_IMPACTS", - "UUID", Uuids.create(), - "RULE_UUID", ruleUuid, - "SOFTWARE_QUALITY", softwareQuality.name(), - "SEVERITY", severity.name()); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/PopulatePurgedColumnInSnapshotsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/PopulatePurgedColumnInSnapshotsIT.java deleted file mode 100644 index 51134683836..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/PopulatePurgedColumnInSnapshotsIT.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.tuple; - -class PopulatePurgedColumnInSnapshotsIT { - private static final String TABLE_NAME = "snapshots"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulatePurgedColumnInSnapshots.class); - private final PopulatePurgedColumnInSnapshots underTest = new PopulatePurgedColumnInSnapshots(db.database()); - - @Test - void execute_whenSnapshotsDoesNotExist_shouldNotFail() { - assertThatCode(underTest::execute) - .doesNotThrowAnyException(); - } - - @Test - void execute_whenSnapshotsExist_shouldPopulatePurgedColumn() throws SQLException { - insertSnapshot("uuid-1", null); - insertSnapshot("uuid-2", 1); - insertSnapshot("uuid-3", 0); - insertSnapshot("uuid-4", null); - - underTest.execute(); - - assertThat(db.select("select uuid, purged from snapshots")) - .extracting(stringObjectMap -> stringObjectMap.get("uuid"), stringObjectMap -> stringObjectMap.get("purged")) - .containsExactlyInAnyOrder( - tuple("uuid-1", false), - tuple("uuid-2", true), - tuple("uuid-3", false), - tuple("uuid-4", false)); - } - - private void insertSnapshot(String uuid, @Nullable Integer status) { - db.executeInsert(TABLE_NAME, - "UUID", uuid, - "ROOT_COMPONENT_UUID", "r_c_uuid", - "STATUS", "s", - "ISLAST", true, - "PURGE_STATUS", status, - "PURGED", null); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameBuildDateInSnapshotsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameBuildDateInSnapshotsIT.java deleted file mode 100644 index debe98cc276..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameBuildDateInSnapshotsIT.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - - - -class RenameBuildDateInSnapshotsIT { - private static final String TABLE_NAME = "snapshots"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameBuildDateInSnapshots.class); - private final RenameBuildDateInSnapshots underTest = new RenameBuildDateInSnapshots(db.database()); - - @Test - void execute_whenExecuted_shouldRenameColumn() throws SQLException { - assertColumnExists("build_date"); - underTest.execute(); - assertColumnExists("analysis_date"); - } - - @Test - void execute_whenExecutedTwice_shouldNotFail() throws SQLException { - assertColumnExists("build_date"); - underTest.execute(); - underTest.execute(); - assertColumnExists("analysis_date"); - } - - private void assertColumnExists(String columnName) { - db.assertColumnDefinition(TABLE_NAME, columnName, Types.BIGINT, null, true); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInGroupRolesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInGroupRolesIT.java deleted file mode 100644 index d148a65eeb3..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInGroupRolesIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; - -class RenameComponentUuidInGroupRolesIT { - public static final String TABLE_NAME = "group_roles"; - public static final String NEW_COLUMN_NAME = "entity_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameComponentUuidInGroupRoles.class); - private final RenameComponentUuidInGroupRoles underTest = new RenameComponentUuidInGroupRoles(db.database()); - - @Test - void columnIsRenamed() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 40, true); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 40, true); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInSnapshotsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInSnapshotsIT.java deleted file mode 100644 index 4e4ce2ef6ce..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInSnapshotsIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; - -class RenameComponentUuidInSnapshotsIT { - public static final String TABLE_NAME = "snapshots"; - public static final String NEW_COLUMN_NAME = "root_component_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameComponentUuidInSnapshots.class); - private final RenameComponentUuidInSnapshots underTest = new RenameComponentUuidInSnapshots(db.database()); - - @Test - void columnIsRenamed() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 50, false); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 50, false); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInUserRolesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInUserRolesIT.java deleted file mode 100644 index 747cce992b0..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInUserRolesIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; - -class RenameComponentUuidInUserRolesIT { - public static final String TABLE_NAME = "user_roles"; - public static final String NEW_COLUMN_NAME = "entity_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameComponentUuidInUserRoles.class); - private final RenameComponentUuidInUserRoles underTest = new RenameComponentUuidInUserRoles(db.database()); - - @Test - void columnIsRenamed() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 40, true); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 40, true); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInWebhookDeliveriesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInWebhookDeliveriesIT.java deleted file mode 100644 index 719486076fc..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInWebhookDeliveriesIT.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.AbstractDbTester; -import org.sonar.db.MigrationDbTester; -import org.sonar.db.TestDb; -import org.sonar.server.platform.db.migration.step.RenameVarcharColumnChange; -import org.sonar.server.platform.db.migration.version.RenameVarcharColumnAbstractTest; - -class RenameComponentUuidInWebhookDeliveriesIT extends RenameVarcharColumnAbstractTest { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameComponentUuidInWebhookDeliveries.class); - - public RenameComponentUuidInWebhookDeliveriesIT() { - super("webhook_deliveries", "project_uuid", false); - } - - @Test - void migration_is_reentrant() throws SQLException { - super.verifyMigrationIsReentrant(); - } - - @Test - void column_is_renamed() throws SQLException { - super.verifyColumnIsRenamed(); - } - - @Override - protected RenameVarcharColumnChange getClassUnderTest() { - return new RenameComponentUuidInWebhookDeliveries(db.database()); - } - - @Override - protected AbstractDbTester<? extends TestDb> getDatabase() { - return db; - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameMainComponentUuidInCeActivityIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameMainComponentUuidInCeActivityIT.java deleted file mode 100644 index b51f0442020..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameMainComponentUuidInCeActivityIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; - -class RenameMainComponentUuidInCeActivityIT { - public static final String TABLE_NAME = "ce_activity"; - public static final String NEW_COLUMN_NAME = "entity_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameMainComponentUuidInCeActivity.class); - private final RenameMainComponentUuidInCeActivity underTest = new RenameMainComponentUuidInCeActivity(db.database()); - - @Test - void column_is_renamed() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 40, true); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 40, true); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameMainComponentUuidInCeQueueIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameMainComponentUuidInCeQueueIT.java deleted file mode 100644 index c4d54188283..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/RenameMainComponentUuidInCeQueueIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; - -class RenameMainComponentUuidInCeQueueIT { - public static final String TABLE_NAME = "ce_queue"; - public static final String NEW_COLUMN_NAME = "entity_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameMainComponentUuidInCeQueue.class); - private final RenameMainComponentUuidInCeQueue underTest = new RenameMainComponentUuidInCeQueue(db.database()); - - @Test - void column_is_renamed() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 40, true); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 40, true); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriodsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriodsIT.java deleted file mode 100644 index 9697905bd2d..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriodsIT.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; - -class UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriodsIT { - - private static final String TABLE_NAME = "new_code_periods"; - private static final String PROJECT_UUID = "project-uuid"; - private static final String BRANCH_UUID = "branch-uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriods.class); - public final UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriods underTest = new UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriods(db.database()); - - @Test - void execute_whenSnapshotsExist_shouldPopulatePurgedColumn() throws SQLException { - insertNewCodePeriods("uuid-1", PROJECT_UUID, BRANCH_UUID, "PREVIOUS_VERSION", null); - insertNewCodePeriods("uuid-2", PROJECT_UUID, null, "NUMBER_OF_DAYS", "90"); - insertNewCodePeriods("uuid-3", null, null, "NUMBER_OF_DAYS", "97"); - - underTest.execute(); - - assertThat(db.select("select uuid, value, previous_non_compliant_value from new_code_periods")) - .extracting(stringObjectMap -> stringObjectMap.get("uuid"), stringObjectMap -> stringObjectMap.get("value"), - stringObjectMap -> stringObjectMap.get("previous_non_compliant_value")) - .containsExactlyInAnyOrder( - tuple("uuid-1", null, null), - tuple("uuid-2", "90", null), - tuple("uuid-3", "90", "97")); - } - - private void insertNewCodePeriods(String uuid, @Nullable String projectUuid, @Nullable String branchUuid, String type, String value) { - db.executeInsert(TABLE_NAME, - "UUID", uuid, - "PROJECT_UUID", projectUuid, - "BRANCH_UUID", branchUuid, - "TYPE", type, - "VALUE", value, - "UPDATED_AT", System.currentTimeMillis(), - "CREATED_AT", System.currentTimeMillis()); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/AddCleanCodeAttributeColumnInIssuesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/AddCleanCodeAttributeColumnInIssuesTableIT.java deleted file mode 100644 index ec959be0df7..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/AddCleanCodeAttributeColumnInIssuesTableIT.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThatCode; - -class AddCleanCodeAttributeColumnInIssuesTableIT { - private static final String TABLE_NAME = "issues"; - private static final String COLUMN_NAME = "clean_code_attribute"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddCleanCodeAttributeColumnInIssuesTable.class); - private final AddCleanCodeAttributeColumnInIssuesTable underTest = new AddCleanCodeAttributeColumnInIssuesTable(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 40, true); - } - - @Test - void execute_whenColumnsAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/AddCreationMethodColumnInProjectsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/AddCreationMethodColumnInProjectsTableIT.java deleted file mode 100644 index 34593e87572..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/AddCreationMethodColumnInProjectsTableIT.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.sonar.server.platform.db.migration.version.v103.AddCreationMethodColumnInProjectsTable.PROJECTS_CREATION_METHOD_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v103.AddCreationMethodColumnInProjectsTable.PROJECTS_CREATION_METHOD_COLUMN_SIZE; -import static org.sonar.server.platform.db.migration.version.v103.AddCreationMethodColumnInProjectsTable.PROJECTS_TABLE_NAME; - -class AddCreationMethodColumnInProjectsTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddCreationMethodColumnInProjectsTable.class); - private final AddCreationMethodColumnInProjectsTable underTest = new AddCreationMethodColumnInProjectsTable(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(PROJECTS_TABLE_NAME, PROJECTS_CREATION_METHOD_COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(PROJECTS_TABLE_NAME, PROJECTS_CREATION_METHOD_COLUMN_NAME, VARCHAR, PROJECTS_CREATION_METHOD_COLUMN_SIZE, true); - } - - @Test - void execute_whenColumnsAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/AddRuleChangesUuidColumnInQProfileChangesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/AddRuleChangesUuidColumnInQProfileChangesIT.java deleted file mode 100644 index 7f35b30b308..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/AddRuleChangesUuidColumnInQProfileChangesIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThatCode; - -class AddRuleChangesUuidColumnInQProfileChangesIT { - - private static final String TABLE_NAME = "qprofile_changes"; - private static final String COLUMN_NAME = "rule_change_uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddRuleChangesUuidColumnInQProfileChanges.class); - private final AddRuleChangesUuidColumnInQProfileChanges underTest = new AddRuleChangesUuidColumnInQProfileChanges(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 40, true); - } - - @Test - void execute_whenColumnsAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/AddSqVersionColumnInQprofileChangesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/AddSqVersionColumnInQprofileChangesTableIT.java deleted file mode 100644 index 68735826365..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/AddSqVersionColumnInQprofileChangesTableIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThatCode; - -class AddSqVersionColumnInQprofileChangesTableIT { - - private static final String TABLE_NAME = "qprofile_changes"; - private static final String COLUMN_NAME = "sq_version"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddSqVersionColumnInQprofileChangesTable.class); - private final AddSqVersionColumnInQprofileChangesTable underTest = new AddSqVersionColumnInQprofileChangesTable(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 40, true); - } - - @Test - void execute_whenColumnsAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateGithubPermissionsMappingTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateGithubPermissionsMappingTableIT.java deleted file mode 100644 index 2f33aeb0495..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateGithubPermissionsMappingTableIT.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.GITHUB_PERMISSIONS_MAPPING_TABLE_NAME; - -class CreateGithubPermissionsMappingTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateGithubPermissionsMappingTable.class); - - private final DdlChange createGithubPermissionsMappingTable = new CreateGithubPermissionsMappingTable(db.database()); - - @Test - void migration_should_create_a_table() throws SQLException { - db.assertTableDoesNotExist(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME); - - createGithubPermissionsMappingTable.execute(); - - db.assertTableExists(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME); - db.assertColumnDefinition(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, "uuid", Types.VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, "github_role", Types.VARCHAR, 100, false); - db.assertColumnDefinition(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, "sonarqube_permission", Types.VARCHAR, 64, false); - db.assertPrimaryKey(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, "pk_github_perms_mapping", "uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertTableDoesNotExist(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME); - - createGithubPermissionsMappingTable.execute(); - // re-entrant - createGithubPermissionsMappingTable.execute(); - - db.assertTableExists(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateIndexForRuleImpactChangesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateIndexForRuleImpactChangesTableIT.java deleted file mode 100644 index dc851d12d69..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateIndexForRuleImpactChangesTableIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - - - -class CreateIndexForRuleImpactChangesTableIT { - - static final String INDEX_NAME = "rule_impact_changes_r_c_uuid"; - static final String TABLE_NAME = "rule_impact_changes"; - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexForRuleImpactChangesTable.class); - private final CreateIndexForRuleImpactChangesTable underTest = new CreateIndexForRuleImpactChangesTable(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - - underTest.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, "rule_change_uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - underTest.execute(); - underTest.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, "rule_change_uuid"); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateRuleChangesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateRuleChangesTableIT.java deleted file mode 100644 index 3e61048fa77..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateRuleChangesTableIT.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; - -class CreateRuleChangesTableIT { - - private final static String TABLE_NAME = "rule_changes"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateRuleChangesTable.class); - - private final DdlChange underTest = new CreateRuleChangesTable(db.database()); - - @Test - void migration_should_create_a_table() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - underTest.execute(); - - db.assertTableExists(TABLE_NAME); - db.assertColumnDefinition(TABLE_NAME, "uuid", Types.VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, "new_clean_code_attribute", Types.VARCHAR, 40, true); - db.assertColumnDefinition(TABLE_NAME, "old_clean_code_attribute", Types.VARCHAR, 40, true); - db.assertColumnDefinition(TABLE_NAME, "rule_uuid", Types.VARCHAR, UUID_SIZE, false); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - underTest.execute(); - // re-entrant - underTest.execute(); - - db.assertTableExists(TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateRuleImpactChangesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateRuleImpactChangesTableIT.java deleted file mode 100644 index 42891eedcb6..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateRuleImpactChangesTableIT.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; - -class CreateRuleImpactChangesTableIT { - - - private final static String TABLE_NAME = "rule_impact_changes"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateRuleImpactChangesTable.class); - - private final DdlChange underTest = new CreateRuleImpactChangesTable(db.database()); - - @Test - void migration_should_create_a_table() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - underTest.execute(); - - db.assertTableExists(TABLE_NAME); - db.assertColumnDefinition(TABLE_NAME, "new_software_quality", Types.VARCHAR, 40, true); - db.assertColumnDefinition(TABLE_NAME, "old_software_quality", Types.VARCHAR, 40, true); - db.assertColumnDefinition(TABLE_NAME, "new_severity", Types.VARCHAR, 40, true); - db.assertColumnDefinition(TABLE_NAME, "old_severity", Types.VARCHAR, 40, true); - db.assertColumnDefinition(TABLE_NAME, "rule_change_uuid", Types.VARCHAR, UUID_SIZE, false); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - underTest.execute(); - // re-entrant - underTest.execute(); - - db.assertTableExists(TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForGithubPermissionsMappingTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForGithubPermissionsMappingTableIT.java deleted file mode 100644 index 055132471d5..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForGithubPermissionsMappingTableIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.GITHUB_PERMISSIONS_MAPPING_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.GITHUB_ROLE_COLUMN; -import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.SONARQUBE_PERMISSION_COLUMN; -import static org.sonar.server.platform.db.migration.version.v103.CreateUniqueIndexForGithubPermissionsMappingTable.INDEX_NAME; - -class CreateUniqueIndexForGithubPermissionsMappingTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateUniqueIndexForGithubPermissionsMappingTable.class); - private final CreateUniqueIndexForGithubPermissionsMappingTable createIndex = new CreateUniqueIndexForGithubPermissionsMappingTable(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, INDEX_NAME); - - createIndex.execute(); - - db.assertUniqueIndex(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, INDEX_NAME, GITHUB_ROLE_COLUMN, SONARQUBE_PERMISSION_COLUMN); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertUniqueIndex(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, INDEX_NAME, GITHUB_ROLE_COLUMN, SONARQUBE_PERMISSION_COLUMN); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForPropertiesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForPropertiesTableIT.java deleted file mode 100644 index 73141c898be..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForPropertiesTableIT.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v103.CreateUniqueIndexForPropertiesTable.INDEX_NAME; -import static org.sonar.server.platform.db.migration.version.v103.CreateUniqueIndexForPropertiesTable.PROPERTIES_TABLE_NAME; - - -class CreateUniqueIndexForPropertiesTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateUniqueIndexForPropertiesTable.class); - private final CreateUniqueIndexForPropertiesTable createIndex = new CreateUniqueIndexForPropertiesTable(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(PROPERTIES_TABLE_NAME, INDEX_NAME); - - createIndex.execute(); - - db.assertUniqueIndex(PROPERTIES_TABLE_NAME, INDEX_NAME, "prop_key", "entity_uuid", "user_uuid"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertUniqueIndex(PROPERTIES_TABLE_NAME, INDEX_NAME, "prop_key", "entity_uuid", "user_uuid"); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/DeduplicatePropertiesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/DeduplicatePropertiesTableIT.java deleted file mode 100644 index 126474d6bd7..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/DeduplicatePropertiesTableIT.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import java.util.Date; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.Uuids; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; - -class DeduplicatePropertiesTableIT { - public static final String KEY = "key"; - public static final String ENTITY = "entity"; - public static final String USER = "user"; - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DeduplicatePropertiesTable.class); - private final DeduplicatePropertiesTable underTest = new DeduplicatePropertiesTable(db.database()); - - - public void createBaseProperties() { - createProperty(KEY, null, null); - createProperty(KEY, USER, null); - createProperty(KEY, USER, ENTITY); - } - - private void createProperty(String key, @Nullable String user, @Nullable String entity) { - db.executeInsert("PROPERTIES", - "UUID", Uuids.createFast(), - "PROP_KEY", key, - "TEXT_VALUE", "value", - "ENTITY_UUID", entity, - "USER_UUID", user, - "IS_EMPTY", false, - "CREATED_AT", new Date().getTime()); - } - - @Test - void execute_shouldDeduplicateRows_WhenOnlyKeyIsSpecified() throws SQLException { - createBaseProperties(); - createProperty(KEY, null, null); - createProperty(KEY, null, null); - underTest.execute(); - assertThat(db.select("select * from properties")) - .hasSize(3) - .extracting(str -> str.get("PROP_KEY"), str -> str.get("USER_UUID"), str -> str.get("ENTITY_UUID")) - .containsExactlyInAnyOrder(tuple(KEY, null, null), tuple(KEY, USER, null), tuple(KEY, USER, ENTITY)); - } - - @Test - void execute_shouldDeduplicateRows_WhenOnlyKeyAndUserAreSpecified() throws SQLException { - createBaseProperties(); - createProperty(KEY, USER, null); - createProperty(KEY, USER, null); - underTest.execute(); - assertThat(db.select("select * from properties")) - .hasSize(3) - .extracting(str -> str.get("PROP_KEY"), str -> str.get("USER_UUID"), str -> str.get("ENTITY_UUID")) - .containsExactlyInAnyOrder(tuple(KEY, null, null), tuple(KEY, USER, null), tuple(KEY, USER, ENTITY)); - } - - @Test - void execute_shouldDeduplicateRows_WhenKeyUserAndEntityAreSpecified() throws SQLException { - createBaseProperties(); - createProperty(KEY, USER, ENTITY); - createProperty(KEY, USER, ENTITY); - underTest.execute(); - assertThat(db.select("select * from properties")) - .hasSize(3) - .extracting(str -> str.get("PROP_KEY"), str -> str.get("USER_UUID"), str -> str.get("ENTITY_UUID")) - .containsExactlyInAnyOrder(tuple(KEY, null, null), tuple(KEY, USER, null), tuple(KEY, USER, ENTITY)); - } - - @Test - void execute_shouldBeReentrant() throws SQLException { - createBaseProperties(); - createProperty(KEY, USER, ENTITY); - - underTest.execute(); - underTest.execute(); - - assertThat(db.select("select * from properties")) - .hasSize(3) - .extracting(str -> str.get("PROP_KEY"), str -> str.get("USER_UUID"), str -> str.get("ENTITY_UUID")) - .containsExactlyInAnyOrder(tuple(KEY, null, null), tuple(KEY, USER, null), tuple(KEY, USER, ENTITY)); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/MakeCreationMethodColumnInProjectsNotNullableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/MakeCreationMethodColumnInProjectsNotNullableIT.java deleted file mode 100644 index eab88021c1e..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/MakeCreationMethodColumnInProjectsNotNullableIT.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; -import static org.sonar.server.platform.db.migration.version.v103.AddCreationMethodColumnInProjectsTable.PROJECTS_CREATION_METHOD_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v103.AddCreationMethodColumnInProjectsTable.PROJECTS_TABLE_NAME; - -class MakeCreationMethodColumnInProjectsNotNullableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(MakeCreationMethodColumnInProjectsNotNullable.class); - private final MakeCreationMethodColumnInProjectsNotNullable underTest = new MakeCreationMethodColumnInProjectsNotNullable(db.database()); - - @Test - void user_local_column_is_not_null() throws SQLException { - db.assertColumnDefinition(PROJECTS_TABLE_NAME, PROJECTS_CREATION_METHOD_COLUMN_NAME, VARCHAR, null, true); - underTest.execute(); - db.assertColumnDefinition(PROJECTS_TABLE_NAME, PROJECTS_CREATION_METHOD_COLUMN_NAME, VARCHAR, null, false); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(PROJECTS_TABLE_NAME, PROJECTS_CREATION_METHOD_COLUMN_NAME, VARCHAR, null, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(PROJECTS_TABLE_NAME, PROJECTS_CREATION_METHOD_COLUMN_NAME, VARCHAR, null, false); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/PopulateCreationMethodColumnInProjectsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/PopulateCreationMethodColumnInProjectsTableIT.java deleted file mode 100644 index 685e8c88147..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/PopulateCreationMethodColumnInProjectsTableIT.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.platform.db.migration.version.v103.AddCreationMethodColumnInProjectsTable.PROJECTS_TABLE_NAME; - -class PopulateCreationMethodColumnInProjectsTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulateCreationMethodColumnInProjectsTable.class); - private final PopulateCreationMethodColumnInProjectsTable underTest = new PopulateCreationMethodColumnInProjectsTable(db.database()); - - @Test - void execute_whenProjectsTableIsEmpty_shouldDoNothing() throws SQLException { - underTest.execute(); - - assertThat(db.select("select creation_method from projects")).isEmpty(); - } - - @Test - void execute_whenProjectsExist_shouldPopulateCreationMethodColumn() throws SQLException { - insertProject("uuid-1"); - insertProject("uuid-2"); - - underTest.execute(); - - assertThat(db.select("select creation_method from projects")) - .extracting(stringObjectMap -> stringObjectMap.get("CREATION_METHOD")) - .containsExactlyInAnyOrder("UNKNOWN", "UNKNOWN"); - } - - @Test - void execute_isReentrant() throws SQLException { - insertProject("uuid-1"); - - underTest.execute(); - underTest.execute(); - - assertThat(db.select("select creation_method from projects")) - .extracting(stringObjectMap -> stringObjectMap.get("CREATION_METHOD")) - .containsExactlyInAnyOrder("UNKNOWN"); - } - - private void insertProject(String uuid) { - db.executeInsert(PROJECTS_TABLE_NAME, - "UUID", uuid, - "KEE", uuid, - "QUALIFIER", "TRK", - "PRIVATE", true, - "UPDATED_AT", 1); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMappingIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMappingIT.java deleted file mode 100644 index cbfc828e88c..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMappingIT.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.testfixtures.log.LogTesterJUnit5; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.GITHUB_PERMISSIONS_MAPPING_TABLE_NAME; - -class PopulateGithubPermissionsMappingIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulateGithubPermissionsMapping.class); - @RegisterExtension - public final LogTesterJUnit5 logTester = new LogTesterJUnit5(); - - private final PopulateGithubPermissionsMapping migration = new PopulateGithubPermissionsMapping(db.database(), UuidFactoryFast.getInstance()); - - @Test - void execute_whenTableAlreadyPopulated_doesNothing() throws SQLException { - db.executeInsert(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, - "UUID", UuidFactoryFast.getInstance().create(), - "github_role", "gh_role", - "sonarqube_permission", "sq_perm"); - - migration.execute(); - - assertThat(db.select("select github_role, sonarqube_permission from github_perms_mapping")) - .extracting(stringObjectMap -> stringObjectMap.get("GITHUB_ROLE"), stringObjectMap -> stringObjectMap.get("SONARQUBE_PERMISSION")) - .containsExactly(tuple("gh_role", "sq_perm")); - } - - @Test - void execute_whenTableIsEmpty_shouldPopulate() throws SQLException { - migration.execute(); - - verifyMapping(); - } - - @Test - void execute_isReentrant() throws SQLException { - migration.execute(); - migration.execute(); - migration.execute(); - - verifyMapping(); - } - - private void verifyMapping() { - assertThat(db.select("select github_role, sonarqube_permission from github_perms_mapping")) - .extracting(stringObjectMap -> stringObjectMap.get("GITHUB_ROLE"), stringObjectMap -> stringObjectMap.get("SONARQUBE_PERMISSION")) - .containsExactlyInAnyOrder( - tuple("read", "codeviewer"), - tuple("read", "user"), - tuple("triage", "codeviewer"), - tuple("triage", "user"), - tuple("write", "codeviewer"), - tuple("write", "user"), - tuple("write", "issueadmin"), - tuple("write", "securityhotspotadmin"), - tuple("write", "scan"), - tuple("maintain", "codeviewer"), - tuple("maintain", "user"), - tuple("maintain", "issueadmin"), - tuple("maintain", "securityhotspotadmin"), - tuple("maintain", "scan"), - tuple("admin", "codeviewer"), - tuple("admin", "user"), - tuple("admin", "issueadmin"), - tuple("admin", "securityhotspotadmin"), - tuple("admin", "scan"), - tuple("admin", "admin") - ); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/SetAllowQualityProfileDisableInheritedRulesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/SetAllowQualityProfileDisableInheritedRulesIT.java deleted file mode 100644 index 8c8a9b24cc1..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v103/SetAllowQualityProfileDisableInheritedRulesIT.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.impl.utils.TestSystem2; -import org.sonar.api.utils.System2; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; - -class SetAllowQualityProfileDisableInheritedRulesIT { - - private static final long NOW = 1; - - @RegisterExtension - public final MigrationDbTester dbTester = MigrationDbTester.createForMigrationStep(SetAllowQualityProfileDisableInheritedRules.class); - private final System2 system2 = new TestSystem2().setNow(NOW); - - private final SetAllowQualityProfileDisableInheritedRules script = new SetAllowQualityProfileDisableInheritedRules(dbTester.database(), system2, UuidFactoryFast.getInstance()); - - @Test - void execute_shouldInsertPropertyWithFalseValue() throws SQLException { - script.execute(); - - assertThatForceAuthenticationEquals("false"); - } - - @Test - void execute_shouldBeReentrant() throws SQLException { - script.execute(); - // re-entrant - script.execute(); - - assertThatForceAuthenticationEquals("false"); - } - - @Test - void execute_shouldNotUpdateTheValueThatAlreadyExistsInTheDatabase() throws SQLException { - insertPropertyWithValueAsTrue(); - script.execute(); - - assertThatForceAuthenticationEquals("true"); - } - - private void assertThatForceAuthenticationEquals(String s) { - assertThat(dbTester.selectFirst("select p.text_value from properties p where p.prop_key = 'sonar.qualityProfiles.allowDisableInheritedRules'")) - .containsEntry("TEXT_VALUE", s); - } - - private void insertPropertyWithValueAsTrue() { - dbTester.executeInsert("properties", - "uuid", "uuid-1", - "prop_key", "sonar.qualityProfiles.allowDisableInheritedRules", - "is_empty", false, - "text_value", "true", - "created_at", NOW); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/AddUuidColumnToGroupsUsersIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/AddUuidColumnToGroupsUsersIT.java deleted file mode 100644 index 3167af80300..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/AddUuidColumnToGroupsUsersIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThatCode; - -class AddUuidColumnToGroupsUsersIT { - - private static final String TABLE_NAME = "groups_users"; - private static final String COLUMN_NAME = "uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddUuidColumnToGroupsUsers.class); - private final AddUuidColumnToGroupsUsers underTest = new AddUuidColumnToGroupsUsers(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 40, true); - } - - @Test - void execute_whenColumnsAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/CreateIssuesFixedTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/CreateIssuesFixedTableIT.java deleted file mode 100644 index 0b8a956adef..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/CreateIssuesFixedTableIT.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.version.v104.CreateIssuesFixedTable.COLUMN_ISSUE_KEY; -import static org.sonar.server.platform.db.migration.version.v104.CreateIssuesFixedTable.COLUMN_PULL_REQUEST_UUID; -import static org.sonar.server.platform.db.migration.version.v104.CreateIssuesFixedTable.TABLE_NAME; - -class CreateIssuesFixedTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIssuesFixedTable.class); - - private final DdlChange underTest = new CreateIssuesFixedTable(db.database()); - - @Test - void execute_shouldCreateTable() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - underTest.execute(); - - db.assertTableExists(TABLE_NAME); - db.assertColumnDefinition(TABLE_NAME, COLUMN_PULL_REQUEST_UUID, Types.VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, COLUMN_ISSUE_KEY, Types.VARCHAR, 50, false); - db.assertPrimaryKey(TABLE_NAME, "pk_issues_fixed", COLUMN_PULL_REQUEST_UUID, COLUMN_ISSUE_KEY); - } - - @Test - void execute_shouldBeReentrant() throws SQLException { - db.assertTableDoesNotExist(TABLE_NAME); - - underTest.execute(); - underTest.execute(); - - db.assertTableExists(TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/CreatePrimaryKeyOnGroupsUsersTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/CreatePrimaryKeyOnGroupsUsersTableIT.java deleted file mode 100644 index 4f17ee5579c..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/CreatePrimaryKeyOnGroupsUsersTableIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v104.AddUuidColumnToGroupsUsers.GROUPS_USERS_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v104.AddUuidColumnToGroupsUsers.GROUPS_USERS_UUID_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v104.CreatePrimaryKeyOnGroupsUsersTable.PK_NAME; - -class CreatePrimaryKeyOnGroupsUsersTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreatePrimaryKeyOnGroupsUsersTable.class); - private final CreatePrimaryKeyOnGroupsUsersTable createIndex = new CreatePrimaryKeyOnGroupsUsersTable(db.database()); - - @Test - void execute_whenPrimaryKeyDoesntExist_shouldCreatePrimaryKey() throws SQLException { - db.assertNoPrimaryKey(GROUPS_USERS_TABLE_NAME); - - createIndex.execute(); - db.assertPrimaryKey(GROUPS_USERS_TABLE_NAME, PK_NAME, GROUPS_USERS_UUID_COLUMN_NAME); - } - - @Test - void execute_whenPrimaryKeyAlreadyExist_shouldKeepThePrimaryKeyAndNotFail() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertPrimaryKey(GROUPS_USERS_TABLE_NAME, PK_NAME, GROUPS_USERS_UUID_COLUMN_NAME); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/CreateRuleTagsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/CreateRuleTagsTableIT.java deleted file mode 100644 index 9085440e27a..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/CreateRuleTagsTableIT.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.version.v104.CreateRuleTagsTable.IS_SYSTEM_TAG_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v104.CreateRuleTagsTable.RULE_TAGS_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v104.CreateRuleTagsTable.RULE_UUID_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v104.CreateRuleTagsTable.VALUE_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v104.CreateRuleTagsTable.VALUE_COLUMN_SIZE; - -class CreateRuleTagsTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateRuleTagsTable.class); - - private final DdlChange createScmAccountsTable = new CreateRuleTagsTable(db.database()); - - @Test - void execute_whenRun_shouldCreateRuleTagsTable() throws SQLException { - db.assertTableDoesNotExist(RULE_TAGS_TABLE_NAME); - - createScmAccountsTable.execute(); - - db.assertTableExists(RULE_TAGS_TABLE_NAME); - db.assertColumnDefinition(RULE_TAGS_TABLE_NAME, VALUE_COLUMN_NAME, Types.VARCHAR, VALUE_COLUMN_SIZE, false); - db.assertColumnDefinition(RULE_TAGS_TABLE_NAME, IS_SYSTEM_TAG_COLUMN_NAME, Types.BOOLEAN, null, false); - db.assertColumnDefinition(RULE_TAGS_TABLE_NAME, RULE_UUID_COLUMN_NAME, Types.VARCHAR, UUID_SIZE, false); - db.assertPrimaryKey(RULE_TAGS_TABLE_NAME, "pk_rule_tags", VALUE_COLUMN_NAME, RULE_UUID_COLUMN_NAME); - } - - @Test - void execute_whenRunMoreThanOnce_shouldBeReentrant() throws SQLException { - db.assertTableDoesNotExist(RULE_TAGS_TABLE_NAME); - - createScmAccountsTable.execute(); - // re-entrant - createScmAccountsTable.execute(); - - db.assertTableExists(RULE_TAGS_TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/DeleteRedundantFailedAlertsForApplicationsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/DeleteRedundantFailedAlertsForApplicationsIT.java deleted file mode 100644 index 8e141309373..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/DeleteRedundantFailedAlertsForApplicationsIT.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import java.util.Map; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; - -class DeleteRedundantFailedAlertsForApplicationsIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DeleteRedundantFailedAlertsForApplications.class); - private final DataChange underTest = new DeleteRedundantFailedAlertsForApplications(db.database()); - - @BeforeEach - public void setUp() { - // cleanup db - db.executeUpdateSql("truncate table events"); - db.executeUpdateSql("truncate table event_component_changes"); - db.executeUpdateSql("truncate table components"); - } - - @Test - void givenFailedAlertsForApplication_whenExecuted_thenFailedAlertsAreDeleted() throws SQLException { - // given - insertComponent("app1", "appUuid1", "appUuid1", "APP"); - - // event that should be deleted - insertEvent("eventUuid1", "appUuid1", "Failed", "Alert", "{ stillFailing: false, status: \"ERROR\" }"); - insertEventChanges("eventChangeUuid1", "eventUuid1", "appUuid1"); - insertEventChanges("eventChangeUuid2", "eventUuid1", "appUuid1"); - - // events that should not be deleted - insertEvent("eventUuid2", "appUuid1", "Passed", "Alert", "{ stillFailing: false, status: \"ERROR\" }"); - insertEventChanges("eventChangeUuid3", "eventUuid2", "appUuid1"); - insertEvent("eventUuid3", "appUuid1", "Failed", "Alert", "{ stillFailing: false, status: \"PASSED\" }"); - insertEventChanges("eventChangeUuid4", "eventUuid3", "appUuid1"); - - // when - underTest.execute(); - - // then - assertThat(db.countRowsOfTable("events")).isEqualTo(2); - assertThat(db.countSql("select count(1) from events where uuid = 'eventUuid1'")).isZero(); - - assertThat(db.countRowsOfTable("event_component_changes")).isEqualTo(2); - assertThat(db.countSql("select count(1) from event_component_changes where uuid = 'eventUuid1'")).isZero(); - } - - @Test - void givenFailedAlertsForProject_whenExecute_thenTheEventsAreNotDeleted() throws SQLException { - // given - insertComponent("project1", "projectUuid1", "projectUuid1", "TRK"); - - // event that should not be deleted - insertEvent("eventUuid1", "projectUuid1", "Failed", "Alert", "{ stillFailing: false, status: \"ERROR\" }"); - insertEventChanges("eventChangeUuid1", "eventUuid1", "projectUuid1"); - insertEventChanges("eventChangeUuid2", "eventUuid1", "projectUuid1"); - - // when - underTest.execute(); - - // then - assertThat(db.countSql("select count(1) from events where uuid = 'eventUuid1'")).isEqualTo(1); - assertThat(db.countSql("select count(1) from event_component_changes where event_uuid = 'eventUuid1'")).isEqualTo(2); - } - - @Test - void givenMigration_whenExecutedMoreThanOnce_thenNoError() throws SQLException { - // given - insertComponent("app1", "appUuid1", "appUuid1", "APP"); - - // event that should be deleted - insertEvent("eventUuid1", "appUuid1", "Failed", "Alert", "{ stillFailing: false, status: \"ERROR\" }"); - insertEventChanges("eventChangeUuid1", "eventUuid1", "appUuid1"); - insertEventChanges("eventChangeUuid2", "eventUuid1", "appUuid1"); - - // when - underTest.execute(); - underTest.execute(); - - // then - assertThat(db.countSql("select count(1) from events where uuid = 'eventUuid1'")).isZero(); - assertThat(db.countSql("select count(1) from event_component_changes where uuid = 'eventUuid1'")).isZero(); - } - - private void insertComponent(String key, String uuid, String branchUuid, String qualifier) { - Map<String, Object> map = Map.ofEntries( - Map.entry("UUID", uuid), - Map.entry("KEE", key), - Map.entry("BRANCH_UUID", branchUuid), - Map.entry("UUID_PATH", "." + uuid + "."), - Map.entry("QUALIFIER", qualifier), - Map.entry("ENABLED", true), - Map.entry("PRIVATE", true) - ); - - db.executeInsert("components", map); - } - - private void insertEvent(String uuid, String componentUuid, String name, String category, String eventData) { - Map<String, Object> map = Map.ofEntries( - Map.entry("UUID", uuid), - Map.entry("NAME", name), - Map.entry("ANALYSIS_UUID", "analysisUuid"), - Map.entry("CATEGORY", category), - Map.entry("CREATED_AT", 1_500_000_000_000L), - Map.entry("EVENT_DATE", 1_500_000_000_000L), - Map.entry("COMPONENT_UUID", componentUuid), - Map.entry("EVENT_DATA", eventData) - ); - - db.executeInsert("events", map); - } - - private void insertEventChanges(String uuid, String eventUuid, String componentUuid) { - Map<String, Object> map = Map.ofEntries( - Map.entry("UUID", uuid), - Map.entry("EVENT_UUID", eventUuid), - Map.entry("EVENT_COMPONENT_UUID", componentUuid), - Map.entry("EVENT_ANALYSIS_UUID", "analysisUuid"), - Map.entry("CHANGE_CATEGORY", "FAILED_QG"), - Map.entry("COMPONENT_UUID", uuid), - Map.entry("COMPONENT_KEY", "app"), - Map.entry("COMPONENT_NAME", "app"), - Map.entry("COMPONENT_BRANCH_KEY", 1_500_000_000_000L), - Map.entry("CREATED_AT", 1_500_000_000_000L) - ); - - db.executeInsert("event_component_changes", map); - } - - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/DropSystemTagsInRulesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/DropSystemTagsInRulesIT.java deleted file mode 100644 index cb2da4c5f24..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/DropSystemTagsInRulesIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropSystemTagsInRulesIT { - private static final String TABLE_NAME = "rules"; - private static final String COLUMN_NAME = "system_tags"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropSystemTagsInRules.class); - private final DdlChange underTest = new DropSystemTagsInRules(db.database()); - - @Test - void executed_whenRun_shouldDropSystemTagsColumn() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 4000, true); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void execute_whenRunMoreThanOnce_shouldBeReentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 4000, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/DropTagsInRulesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/DropTagsInRulesIT.java deleted file mode 100644 index f19c47c1302..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/DropTagsInRulesIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropTagsInRulesIT { - static final String TABLE_NAME = "rules"; - static final String COLUMN_NAME = "tags"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropTagsInRules.class); - private final DdlChange underTest = new DropTagsInRules(db.database()); - - @Test - void executed_whenRun_shouldDropTagsColumn() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 4000, true); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void execute_whenExecutedMoreThanOnce_shouldBeReentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 4000, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/MakeUuidInGroupsUsersNotNullableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/MakeUuidInGroupsUsersNotNullableIT.java deleted file mode 100644 index fe60acbfbf9..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/MakeUuidInGroupsUsersNotNullableIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; -import static org.sonar.server.platform.db.migration.version.v104.AddUuidColumnToGroupsUsers.GROUPS_USERS_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v104.AddUuidColumnToGroupsUsers.GROUPS_USERS_UUID_COLUMN_NAME; - -class MakeUuidInGroupsUsersNotNullableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep( MakeUuidInGroupsUsersNotNullable.class); - private final MakeUuidInGroupsUsersNotNullable underTest = new MakeUuidInGroupsUsersNotNullable(db.database()); - - @Test - void execute_whenUuidColumnIsNullable_shouldMakeItNonNullable() throws SQLException { - db.assertColumnDefinition(GROUPS_USERS_TABLE_NAME, GROUPS_USERS_UUID_COLUMN_NAME, VARCHAR, null, true); - underTest.execute(); - db.assertColumnDefinition(GROUPS_USERS_TABLE_NAME, GROUPS_USERS_UUID_COLUMN_NAME, VARCHAR, null, false); - } - - @Test - void execute_whenUuidColumnIsNullable_shouldKeepItNullableAndNotFail() throws SQLException { - db.assertColumnDefinition(GROUPS_USERS_TABLE_NAME, GROUPS_USERS_UUID_COLUMN_NAME, VARCHAR, null, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(GROUPS_USERS_TABLE_NAME, GROUPS_USERS_UUID_COLUMN_NAME, VARCHAR, null, false); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/PopulateGroupsUsersUuidIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/PopulateGroupsUsersUuidIT.java deleted file mode 100644 index bc01c870478..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/PopulateGroupsUsersUuidIT.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import java.util.List; -import java.util.Map; -import org.assertj.core.groups.Tuple; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.UuidFactoryFast; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; - -class PopulateGroupsUsersUuidIT { - - private static final String GROUPS_USERS_TABLE_NAME = "groups_users"; - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulateGroupsUsersUuid.class); - - private final PopulateGroupsUsersUuid migration = new PopulateGroupsUsersUuid(db.database(), UuidFactoryFast.getInstance()); - - @Test - void execute_whenTableIsEmpty_shouldPopulate() throws SQLException { - insertRowsWithoutUuid(); - - migration.execute(); - - verifyUuidPresentAndUnique(); - } - - - - @Test - void execute_isReentrant() throws SQLException { - insertRowsWithoutUuid(); - migration.execute(); - List<Tuple> existingUuids = getExistingUuids(); - - migration.execute(); - verifyUuidsNotChanged(existingUuids); - - migration.execute(); - verifyUuidsNotChanged(existingUuids); - } - - private void insertRowsWithoutUuid() { - db.executeInsert(GROUPS_USERS_TABLE_NAME, - "uuid", null, - "group_uuid", "group1_uuid", - "user_uuid", "user1_uuid"); - - db.executeInsert(GROUPS_USERS_TABLE_NAME, - "uuid", null, - "group_uuid", "group2_uuid", - "user_uuid", "user2_uuid"); - - db.executeInsert(GROUPS_USERS_TABLE_NAME, - "uuid", null, - "group_uuid", "group3_uuid", - "user_uuid", "user3_uuid"); - } - - private void verifyUuidPresentAndUnique() { - List<Map<String, Object>> rows = db.select("select uuid, group_uuid, user_uuid from groups_users"); - rows - .forEach(stringObjectMap -> assertThat(stringObjectMap.get("UUID")).isNotNull()); - long uniqueCount = rows.stream().map(row -> row.get("UUID")).distinct().count(); - assertThat(uniqueCount).isEqualTo(rows.size()); - - } - - private List<Tuple> getExistingUuids() { - return db.select("select uuid, group_uuid, user_uuid from groups_users") - .stream() - .map(stringObjectMap -> tuple(stringObjectMap.get("UUID"), stringObjectMap.get("GROUP_UUID"), stringObjectMap.get("USER_UUID"))) - .toList(); - } - - private void verifyUuidsNotChanged(List<Tuple> existingUuids) { - assertThat(db.select("select uuid, group_uuid, user_uuid from groups_users")) - .extracting(stringObjectMap -> tuple(stringObjectMap.get("UUID"), stringObjectMap.get("GROUP_UUID"), stringObjectMap.get("USER_UUID"))) - .containsExactlyInAnyOrderElementsOf(existingUuids); - } - - - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/PopulateRuleTagsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/PopulateRuleTagsTableIT.java deleted file mode 100644 index f57865659a9..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/PopulateRuleTagsTableIT.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; - -class PopulateRuleTagsTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulateRuleTagsTable.class); - - private final PopulateRuleTagsTable migration = new PopulateRuleTagsTable(db.database()); - - @Test - void execute_whenTagsExist_shouldPopulateProperly() throws SQLException { - insertRule("uuid-1", null, "tag_1,tag_2"); - insertRule("uuid-2", "systag_1,systag_2", null); - insertRule("uuid-3", "systag_3,systag_4", "tag_3,tag_4"); - - migration.execute(); - - assertThat(db.select("select value, is_system_tag, rule_uuid from rule_tags")) - .extracting(t -> t.get("value"), t -> t.get("is_system_tag"), t -> t.get("rule_uuid")) - .containsExactlyInAnyOrder( - tuple("systag_1", true, "uuid-2"), - tuple("systag_2", true, "uuid-2"), - tuple("tag_1", false, "uuid-1"), - tuple("tag_2", false, "uuid-1"), - tuple("systag_3", true, "uuid-3"), - tuple("systag_4", true, "uuid-3"), - tuple("tag_3", false, "uuid-3"), - tuple("tag_4", false, "uuid-3") - ); - } - - @Test - void execute_whenEmptyOrDuplicateTagsExist_shouldNotBeMigrated() throws SQLException { - insertRule("uuid-1", null, "tag_1,,tag_2"); - insertRule("uuid-2", "systag_1,,systag_2,systag_2,", null); - - migration.execute(); - - assertThat(db.select("select value, is_system_tag, rule_uuid from rule_tags")) - .extracting(t -> t.get("value"), t -> t.get("is_system_tag"), t -> t.get("rule_uuid")) - .containsExactlyInAnyOrder( - tuple("systag_1", true, "uuid-2"), - tuple("systag_2", true, "uuid-2"), - tuple("tag_1", false, "uuid-1"), - tuple("tag_2", false, "uuid-1") - ); - } - - @Test - void execute_whenSystemAndCustomTagShareTheSameTag_removeDuplicates() throws SQLException { - insertRule("uuid-1", "test,other1", "test,other2"); - - migration.execute(); - - assertThat(db.select("select value, is_system_tag, rule_uuid from rule_tags")) - .extracting(t -> t.get("value"), t -> t.get("is_system_tag"), t -> t.get("rule_uuid")) - .containsExactlyInAnyOrder( - tuple("test", true, "uuid-1"), - tuple("other1", true, "uuid-1"), - tuple("other2", false, "uuid-1") - ); - } - - @Test - void execute_whenRunMoreThanOnce_shouldBeReentrant() throws SQLException { - insertRule("uuid-3", "sys_tag", "tag"); - migration.execute(); - migration.execute(); - migration.execute(); - verifyMapping(); - } - - private void verifyMapping() { - assertThat(db.select("select value, is_system_tag, rule_uuid from rule_tags")) - .extracting(t -> t.get("value"), t -> t.get("is_system_tag"), t -> t.get("rule_uuid")) - .containsExactlyInAnyOrder( - tuple("sys_tag", true, "uuid-3"), - tuple("tag", false, "uuid-3") - ); - } - - private void insertRule(String uuid, @Nullable String systemTags, @Nullable String tags) { - db.executeInsert("rules", - "UUID", uuid, - "PLUGIN_RULE_KEY", uuid, - "PLUGIN_NAME", uuid, - "SCOPE", "1", - "IS_TEMPLATE", false, - "IS_AD_HOC", false, - "SYSTEM_TAGS", systemTags, - "TAGS", tags, - "IS_EXTERNAL", false); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/RemoveCleanCodeAttributeFromCustomHotspotRulesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/RemoveCleanCodeAttributeFromCustomHotspotRulesIT.java deleted file mode 100644 index d3d7e415472..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/RemoveCleanCodeAttributeFromCustomHotspotRulesIT.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; - -class RemoveCleanCodeAttributeFromCustomHotspotRulesIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RemoveCleanCodeAttributeFromCustomHotspotRules.class); - private final RemoveCleanCodeAttributeFromCustomHotspotRules underTest = new RemoveCleanCodeAttributeFromCustomHotspotRules(db.database()); - - @Test - void execute_whenRulesTableIsEmpty_shouldDoNothing() throws SQLException { - underTest.execute(); - - assertThat(db.select("select clean_code_attribute from rules")).isEmpty(); - } - - @Test - void execute_whenCustomHotspotRuleExist_shouldRemoveCleanCodeAttributeOnlyFromHotspot() throws SQLException { - insertRule("custom_hotspot_rule", 4, "CONVENTIONAL"); - insertRule("other_rule", 1, "ETHICAL"); - - underTest.execute(); - - List<Map<String, Object>> selectResult = db.select("select name, clean_code_attribute, updated_at from rules"); - - assertThat(selectResult) - .extracting(stringObjectMap -> stringObjectMap.get("name"), stringObjectMap -> stringObjectMap.get("clean_code_attribute")) - .containsExactlyInAnyOrder(tuple("custom_hotspot_rule", null), tuple("other_rule", "ETHICAL")); - - Optional<Object> updatedAtForHotspotRule = selectResult.stream().filter(map -> map.containsValue("custom_hotspot_rule")) - .map(map -> map.get("updated_at")).findFirst(); - assertThat(updatedAtForHotspotRule.get()).isNotEqualTo(0L); - - Optional<Object> updatedAtForOtherRule = selectResult.stream().filter(map -> map.containsValue("other_rule")) - .map(map -> map.get("updated_at")).findFirst(); - assertThat(updatedAtForOtherRule).contains(0L); - } - - @Test - void execute_whenCustomHotspotRuleExist_isReentrant() throws SQLException { - insertRule("custom_hotspot_rule", 4, "CONVENTIONAL"); - insertRule("other_rule", 1, "ETHICAL"); - - underTest.execute(); - underTest.execute(); - - List<Map<String, Object>> selectResult = db.select("select name, clean_code_attribute from rules"); - - assertThat(selectResult) - .extracting(stringObjectMap -> stringObjectMap.get("name"), stringObjectMap -> stringObjectMap.get("clean_code_attribute")) - .containsExactlyInAnyOrder(tuple("custom_hotspot_rule", null), tuple("other_rule", "ETHICAL")); - } - - private void insertRule(String name, int ruleType, String cleanCodeAttribute) { - db.executeInsert("rules", - "PLUGIN_RULE_KEY", name, - "PLUGIN_NAME", name, - "SCOPE", name, - "NAME", name, - "IS_EXTERNAL", true, - "IS_AD_HOC", false, - "UUID", name, - "RULE_TYPE", ruleType, - "UPDATED_AT", 0L, - "CLEAN_CODE_ATTRIBUTE", cleanCodeAttribute); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/RenameWontFixIssuesMetricIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/RenameWontFixIssuesMetricIT.java deleted file mode 100644 index 8ddb78496e1..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v104/RenameWontFixIssuesMetricIT.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; - - -class RenameWontFixIssuesMetricIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameWontFixIssuesMetric.class); - private final RenameWontFixIssuesMetric underTest = new RenameWontFixIssuesMetric(db.database()); - - @Test - void execute_whenMetricsTableIsEmpty_shouldDoNothing() throws SQLException { - underTest.execute(); - - assertThat(db.select("select name from metrics")).isEmpty(); - } - - @Test - void execute_whenWontFixMetricExist_shouldRenameToAccepted() throws SQLException { - insertMetric("wont_fix_issues"); - insertMetric("other_metric"); - - underTest.execute(); - - assertThat(db.select("select name from metrics")) - .extracting(stringObjectMap -> stringObjectMap.get("NAME")) - .containsExactlyInAnyOrder("accepted_issues", "other_metric"); - } - - @Test - void execute_isReentrant() throws SQLException { - insertMetric("wont_fix_issues"); - insertMetric("other_metric"); - - underTest.execute(); - underTest.execute(); - - assertThat(db.select("select name from metrics")) - .extracting(stringObjectMap -> stringObjectMap.get("NAME")) - .containsExactlyInAnyOrder("accepted_issues", "other_metric"); - } - - private void insertMetric(String name) { - db.executeInsert("metrics", - "NAME", name, - "DESCRIPTION", "description " + name, - "DIRECTION", -1, - "DOMAIN", "Issues", - "SHORT_NAME", name, - "QUALITATIVE", true, - "VAL_TYPE", "int", - "ENABLED", true, - "OPTIMIZED_BEST_VALUE", true, - "HIDDEN", false, - "DELETE_HISTORICAL_DATA", false, - "UUID", name); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/CreatePrimaryKeyOnIssuesImpactsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/CreatePrimaryKeyOnIssuesImpactsTableIT.java deleted file mode 100644 index 14b5f1ab0f7..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/CreatePrimaryKeyOnIssuesImpactsTableIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v105.CreatePrimaryKeyOnIssuesImpactsTable.ISSUE_KEY_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v105.CreatePrimaryKeyOnIssuesImpactsTable.PK_NAME; -import static org.sonar.server.platform.db.migration.version.v105.CreatePrimaryKeyOnIssuesImpactsTable.SOFTWARE_QUALITY_COLUMN; -import static org.sonar.server.platform.db.migration.version.v105.CreatePrimaryKeyOnIssuesImpactsTable.TABLE_NAME; - -class CreatePrimaryKeyOnIssuesImpactsTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreatePrimaryKeyOnIssuesImpactsTable.class); - - private final CreatePrimaryKeyOnIssuesImpactsTable createIndex = new CreatePrimaryKeyOnIssuesImpactsTable(db.database()); - - @Test - void execute_whenPrimaryKeyDoesntExist_shouldCreatePrimaryKey() throws SQLException { - db.assertNoPrimaryKey(TABLE_NAME); - - createIndex.execute(); - db.assertPrimaryKey(TABLE_NAME, PK_NAME, ISSUE_KEY_COLUMN_NAME, SOFTWARE_QUALITY_COLUMN); - } - - @Test - void execute_whenPrimaryKeyAlreadyExist_shouldKeepThePrimaryKeyAndNotFail() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertPrimaryKey(TABLE_NAME, PK_NAME, ISSUE_KEY_COLUMN_NAME, SOFTWARE_QUALITY_COLUMN); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/CreatePrimaryKeyOnRulesDefaultImpactsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/CreatePrimaryKeyOnRulesDefaultImpactsTableIT.java deleted file mode 100644 index 6f208062da2..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/CreatePrimaryKeyOnRulesDefaultImpactsTableIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v105.CreatePrimaryKeyOnRulesDefaultImpactsTable.PK_NAME; -import static org.sonar.server.platform.db.migration.version.v105.CreatePrimaryKeyOnRulesDefaultImpactsTable.RULE_UUID_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v105.CreatePrimaryKeyOnRulesDefaultImpactsTable.SOFTWARE_QUALITY_COLUMN; -import static org.sonar.server.platform.db.migration.version.v105.CreatePrimaryKeyOnRulesDefaultImpactsTable.TABLE_NAME; - -class CreatePrimaryKeyOnRulesDefaultImpactsTableIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreatePrimaryKeyOnRulesDefaultImpactsTable.class); - - private final CreatePrimaryKeyOnRulesDefaultImpactsTable createIndex = new CreatePrimaryKeyOnRulesDefaultImpactsTable(db.database()); - - @Test - void execute_whenPrimaryKeyDoesntExist_shouldCreatePrimaryKey() throws SQLException { - db.assertNoPrimaryKey(TABLE_NAME); - - createIndex.execute(); - db.assertPrimaryKey(TABLE_NAME, PK_NAME, RULE_UUID_COLUMN_NAME, SOFTWARE_QUALITY_COLUMN); - } - - @Test - void execute_whenPrimaryKeyAlreadyExist_shouldKeepThePrimaryKeyAndNotFail() throws SQLException { - createIndex.execute(); - createIndex.execute(); - - db.assertPrimaryKey(TABLE_NAME, PK_NAME, RULE_UUID_COLUMN_NAME, SOFTWARE_QUALITY_COLUMN); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DeleteLanguageSpecificParametersPropertySetIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DeleteLanguageSpecificParametersPropertySetIT.java deleted file mode 100644 index 1a8d44fb80d..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DeleteLanguageSpecificParametersPropertySetIT.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import java.sql.SQLException; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -class DeleteLanguageSpecificParametersPropertySetIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DeleteLanguageSpecificParametersPropertySet.class); - private final DataChange underTest = new DeleteLanguageSpecificParametersPropertySet(db.database()); - - @Test - void migration_should_remove_root_property_and_children() throws SQLException { - insertLanguageSpecificParametersPropertySet(db); - - underTest.execute(); - - Assertions.assertThat(db.select("select * from properties")).isEmpty(); - } - - @Test - void migration_is_reentrant() throws SQLException { - insertLanguageSpecificParametersPropertySet(db); - - underTest.execute(); - underTest.execute(); - - Assertions.assertThat(db.select("select * from properties")).isEmpty(); - } - - private void insertLanguageSpecificParametersPropertySet(MigrationDbTester db) { - db.executeInsert("properties ", - "prop_key", "languageSpecificParameters", - "is_empty", false, - "text_value", "0,1", - "created_at", 100_000L, - "uuid", "some-random-uuid1"); - db.executeInsert("properties ", - "prop_key", "languageSpecificParameters.0.language", - "is_empty", false, - "text_value", "java", - "created_at", 100_000L, - "uuid", "some-random-uuid2"); - db.executeInsert("properties ", - "prop_key", "languageSpecificParameters.0.man_days", - "is_empty", false, - "text_value", "10", - "created_at", 100_000L, - "uuid", "some-random-uuid3"); - db.executeInsert("properties ", - "prop_key", "languageSpecificParameters.1.language", - "is_empty", false, - "text_value", "php", - "created_at", 100_000L, - "uuid", "some-random-uuid4"); - db.executeInsert("properties ", - "prop_key", "languageSpecificParameters.1.man_days", - "is_empty", false, - "text_value", "20", - "created_at", 100_000L, - "uuid", "some-random-uuid5"); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DropPrimaryKeyConstraintInIssuesImpactsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DropPrimaryKeyConstraintInIssuesImpactsTableIT.java deleted file mode 100644 index 11ae8577308..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DropPrimaryKeyConstraintInIssuesImpactsTableIT.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.sql.DbPrimaryKeyConstraintFinder; -import org.sonar.server.platform.db.migration.sql.DropPrimaryKeySqlGenerator; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v105.DropPrimaryKeyConstraintInIssuesImpactsTable.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v105.DropPrimaryKeyConstraintInIssuesImpactsTable.CONSTRAINT_NAME; -import static org.sonar.server.platform.db.migration.version.v105.DropPrimaryKeyConstraintInIssuesImpactsTable.TABLE_NAME; - -class DropPrimaryKeyConstraintInIssuesImpactsTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropPrimaryKeyConstraintInIssuesImpactsTable.class); - - private final DbPrimaryKeyConstraintFinder dbPrimaryKeyConstraintFinder = new DbPrimaryKeyConstraintFinder(db.database()); - private final DdlChange underTest = new DropPrimaryKeyConstraintInIssuesImpactsTable(db.database(), - new DropPrimaryKeySqlGenerator(db.database(), dbPrimaryKeyConstraintFinder), dbPrimaryKeyConstraintFinder); - - @Test - void execute_shouldRemoveExistingPrimaryKey() throws SQLException { - db.assertPrimaryKey(TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME); - underTest.execute(); - db.assertNoPrimaryKey(TABLE_NAME); - } - - @Test - void execute_when_reentrant_shouldRemoveExistingPrimaryKey() throws SQLException { - db.assertPrimaryKey(TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertNoPrimaryKey(TABLE_NAME); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DropPrimaryKeyConstraintInRulesDefaultImpactsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DropPrimaryKeyConstraintInRulesDefaultImpactsTableIT.java deleted file mode 100644 index 40d99c3efdc..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DropPrimaryKeyConstraintInRulesDefaultImpactsTableIT.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.sql.DbPrimaryKeyConstraintFinder; -import org.sonar.server.platform.db.migration.sql.DropPrimaryKeySqlGenerator; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v105.DropPrimaryKeyConstraintInRulesDefaultImpactsTable.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v105.DropPrimaryKeyConstraintInRulesDefaultImpactsTable.CONSTRAINT_NAME; -import static org.sonar.server.platform.db.migration.version.v105.DropPrimaryKeyConstraintInRulesDefaultImpactsTable.TABLE_NAME; - -class DropPrimaryKeyConstraintInRulesDefaultImpactsTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropPrimaryKeyConstraintInRulesDefaultImpactsTable.class); - - private final DbPrimaryKeyConstraintFinder dbPrimaryKeyConstraintFinder = new DbPrimaryKeyConstraintFinder(db.database()); - private final DdlChange underTest = new DropPrimaryKeyConstraintInRulesDefaultImpactsTable(db.database(), - new DropPrimaryKeySqlGenerator(db.database(), dbPrimaryKeyConstraintFinder), dbPrimaryKeyConstraintFinder); - - @Test - void execute_shouldRemoveExistingPrimaryKey() throws SQLException { - db.assertPrimaryKey(TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME); - underTest.execute(); - db.assertNoPrimaryKey(TABLE_NAME); - } - - @Test - void execute_when_reentrant_shouldRemoveExistingPrimaryKey() throws SQLException { - db.assertPrimaryKey(TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertNoPrimaryKey(TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DropUuidColumnInIssuesImpactsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DropUuidColumnInIssuesImpactsTableIT.java deleted file mode 100644 index 3ba5f31b7cc..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DropUuidColumnInIssuesImpactsTableIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v105.DropUuidColumnInIssuesImpactsTable.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v105.DropUuidColumnInIssuesImpactsTable.TABLE_NAME; - -class DropUuidColumnInIssuesImpactsTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropUuidColumnInIssuesImpactsTable.class); - private final DdlChange underTest = new DropUuidColumnInIssuesImpactsTable(db.database()); - - @Test - void executed_whenRun_shouldDropSystemTagsColumn() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 40, false); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void execute_whenRunMoreThanOnce_shouldBeReentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 40, false); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DropUuidColumnInRulesDefaultImpactsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DropUuidColumnInRulesDefaultImpactsTableIT.java deleted file mode 100644 index 73d57722d9e..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v105/DropUuidColumnInRulesDefaultImpactsTableIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropUuidColumnInRulesDefaultImpactsTableIT { - private static final String TABLE_NAME = "issues_impacts"; - private static final String COLUMN_NAME = "uuid"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropUuidColumnInIssuesImpactsTable.class); - private final DdlChange underTest = new DropUuidColumnInIssuesImpactsTable(db.database()); - - @Test - void executed_whenRun_shouldDropSystemTagsColumn() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 40, false); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void execute_whenRunMoreThanOnce_shouldBeReentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, 40, false); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v106/AddPrioritizedRuleColumnToActiveRulesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v106/AddPrioritizedRuleColumnToActiveRulesTableIT.java deleted file mode 100644 index 401848cc8e5..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v106/AddPrioritizedRuleColumnToActiveRulesTableIT.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v106; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; -import static org.sonar.server.platform.db.migration.version.v106.AddPrioritizedRuleColumnToActiveRulesTable.ACTIVE_RULES_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v106.AddPrioritizedRuleColumnToActiveRulesTable.PRIORITIZED_RULE_COLUMN_NAME; - -class AddPrioritizedRuleColumnToActiveRulesTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddPrioritizedRuleColumnToActiveRulesTable.class); - private final AddPrioritizedRuleColumnToActiveRulesTable underTest = new AddPrioritizedRuleColumnToActiveRulesTable(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(ACTIVE_RULES_TABLE_NAME, PRIORITIZED_RULE_COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(ACTIVE_RULES_TABLE_NAME, PRIORITIZED_RULE_COLUMN_NAME, Types.BOOLEAN, null, true); - } - - @Test - void execute_whenColumnsAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v106/AddPrioritizedRuleColumnToIssuesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v106/AddPrioritizedRuleColumnToIssuesTableIT.java deleted file mode 100644 index 6e26fef4bf3..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v106/AddPrioritizedRuleColumnToIssuesTableIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v106; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; -import static org.sonar.server.platform.db.migration.version.v106.AddPrioritizedRuleColumnToIssuesTable.PRIORITIZED_RULE_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v106.AddPrioritizedRuleColumnToIssuesTable.ISSUES_TABLE_NAME; - - -class AddPrioritizedRuleColumnToIssuesTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddPrioritizedRuleColumnToIssuesTable.class); - private final AddPrioritizedRuleColumnToIssuesTable underTest = new AddPrioritizedRuleColumnToIssuesTable(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(ISSUES_TABLE_NAME, PRIORITIZED_RULE_COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(ISSUES_TABLE_NAME, PRIORITIZED_RULE_COLUMN_NAME, Types.BOOLEAN, null, true); - } - - @Test - void execute_whenColumnsAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v106/ResizeValueColumnInRuleTagsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v106/ResizeValueColumnInRuleTagsTableIT.java deleted file mode 100644 index 04cb0373153..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v106/ResizeValueColumnInRuleTagsTableIT.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v106; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.CoreDbTester; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.version.v104.CreateRuleTagsTable; - -class ResizeValueColumnInRuleTagsTableIT { - - private static final String EXPECTED_TABLE_NAME = "rule_tags"; - private static final String EXPECTED_COLUMN_NAME = "value"; - - /** - * This is database that has run the new version of the {@link CreateRuleTagsTable} migration with the 400 limit of the value column. - */ - @RegisterExtension - public final MigrationDbTester dbWith400LimitOnValueColumn = MigrationDbTester.createForMigrationStep(ResizeValueColumnInRuleTagsTable.class); - - /** - * This is the database that has run the old version of the {@link CreateRuleTagsTable} migration with the 40 limit of the value column. - */ - @RegisterExtension - public final CoreDbTester dbWith40LimitOnValueColumn = CoreDbTester.createForSchema(ResizeValueColumnInRuleTagsTableIT.class, "schema.sql"); - - private final ResizeValueColumnInRuleTagsTable underTestNoAction = new ResizeValueColumnInRuleTagsTable(dbWith400LimitOnValueColumn.database()); - private final ResizeValueColumnInRuleTagsTable underTestThatFixesColumnSize = new ResizeValueColumnInRuleTagsTable(dbWith40LimitOnValueColumn.database()); - - @Test - void execute_whenColumnIsNotResized_shouldResizeTheColumn() throws SQLException { - dbWith40LimitOnValueColumn.assertColumnDefinition(EXPECTED_TABLE_NAME, EXPECTED_COLUMN_NAME, Types.VARCHAR, 40, false); - underTestThatFixesColumnSize.execute(); - dbWith40LimitOnValueColumn.assertColumnDefinition(EXPECTED_TABLE_NAME, EXPECTED_COLUMN_NAME, Types.VARCHAR, 400, false); - } - - @Test - void execute_whenColumnIsAlreadyResized_shouldDoNothing() throws SQLException { - dbWith400LimitOnValueColumn.assertColumnDefinition(EXPECTED_TABLE_NAME, EXPECTED_COLUMN_NAME, Types.VARCHAR, 400, false); - underTestNoAction.execute(); - dbWith400LimitOnValueColumn.assertColumnDefinition(EXPECTED_TABLE_NAME, EXPECTED_COLUMN_NAME, Types.VARCHAR, 400, false); - } - - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/AddAiCodeAssuranceColumnInProjectsTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/AddAiCodeAssuranceColumnInProjectsTableIT.java deleted file mode 100644 index 9139b434319..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/AddAiCodeAssuranceColumnInProjectsTableIT.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import java.util.Map; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.BOOLEAN; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.sonar.server.platform.db.migration.version.v107.AddAiCodeAssuranceColumnInProjectsTable.AI_CODE_ASSURANCE; -import static org.sonar.server.platform.db.migration.version.v107.AddAiCodeAssuranceColumnInProjectsTable.DEFAULT_COLUMN_VALUE; -import static org.sonar.server.platform.db.migration.version.v107.AddAiCodeAssuranceColumnInProjectsTable.PROJECTS_TABLE_NAME; - -class AddAiCodeAssuranceColumnInProjectsTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddAiCodeAssuranceColumnInProjectsTable.class); - - private final AddAiCodeAssuranceColumnInProjectsTable underTest = new AddAiCodeAssuranceColumnInProjectsTable(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(PROJECTS_TABLE_NAME, AI_CODE_ASSURANCE); - underTest.execute(); - assertColumnExists(); - } - - @Test - void execute_whenColumnsAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertColumnExists(); - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } - - @Test - void execute_whenDataAlreadyExists_shouldCreateColumnWithDefaultValue() throws SQLException { - db.executeInsert(PROJECTS_TABLE_NAME, - "UUID", "uuid", - "KEE", "uuid", - "QUALIFIER", "TRK", - "PRIVATE", true, - "UPDATED_AT", 1, - "CREATION_METHOD", "UI"); - - underTest.execute(); - assertAiCodeAssuranceColumnSetToDefault(); - assertColumnExists(); - } - - private void assertAiCodeAssuranceColumnSetToDefault() { - Map<String, Object> selectResult = db.selectFirst("select ai_code_assurance from projects where uuid = 'uuid'"); - assertThat(selectResult).containsEntry(AI_CODE_ASSURANCE, DEFAULT_COLUMN_VALUE); - } - - private void assertColumnExists() { - db.assertColumnDefinition(PROJECTS_TABLE_NAME, AI_CODE_ASSURANCE, BOOLEAN, null, false); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/AddDevopsPlatformColumnInDevopsPermsMappingIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/AddDevopsPlatformColumnInDevopsPermsMappingIT.java deleted file mode 100644 index f2e21319c6e..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/AddDevopsPlatformColumnInDevopsPermsMappingIT.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import java.util.Map; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.platform.db.migration.version.v107.AddDevopsPlatformColumnInDevopsPermsMapping.DEVOPS_PLATFORM_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v107.AddDevopsPlatformColumnInDevopsPermsMapping.DEFAULT_COLUMN_VALUE; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; - -class AddDevopsPlatformColumnInDevopsPermsMappingIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddDevopsPlatformColumnInDevopsPermsMapping.class); - - private final AddDevopsPlatformColumnInDevopsPermsMapping underTest = new AddDevopsPlatformColumnInDevopsPermsMapping(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(DEVOPS_PERMS_MAPPING_TABLE_NAME, DEVOPS_PLATFORM_COLUMN_NAME); - underTest.execute(); - assertColumnExists(); - } - - @Test - void execute_whenColumnsAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertColumnExists(); - underTest.execute(); - } - - @Test - void execute_whenDataAlreadyExists_shouldCreateColumnWithDefaultValue() throws SQLException { - db.executeInsert(DEVOPS_PERMS_MAPPING_TABLE_NAME, "uuid", "UUID", "devops_platform_role", "uniqAdmin", "sonarqube_permission", "uniqPermission"); - underTest.execute(); - assertDevopsPlatformColumnSetToDefault(); - assertColumnExists(); - } - - private void assertDevopsPlatformColumnSetToDefault() { - Map<String, Object> selectResult = db.selectFirst("select devops_platform from devops_perms_mapping where uuid = 'UUID'"); - assertThat(selectResult).containsEntry("devops_platform", DEFAULT_COLUMN_VALUE); - } - - private void assertColumnExists() { - db.assertColumnDefinition(DEVOPS_PERMS_MAPPING_TABLE_NAME, DEVOPS_PLATFORM_COLUMN_NAME, VARCHAR, 40, false); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/AddUserConsentRequiredIfGitlabAutoProvisioningEnabledIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/AddUserConsentRequiredIfGitlabAutoProvisioningEnabledIT.java deleted file mode 100644 index e2cc100e655..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/AddUserConsentRequiredIfGitlabAutoProvisioningEnabledIT.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.slf4j.event.Level; -import org.sonar.api.testfixtures.log.LogTesterJUnit5; -import org.sonar.api.utils.System2; -import org.sonar.core.util.UuidFactoryImpl; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.platform.db.migration.version.v107.AddUserConsentRequiredIfGitlabAutoProvisioningEnabled.PROP_KEY; -import static org.sonar.server.platform.db.migration.version.v107.AddUserConsentRequiredIfGitlabAutoProvisioningEnabled.PROVISIONING_GITLAB_ENABLED_PROP_KEY; - -class AddUserConsentRequiredIfGitlabAutoProvisioningEnabledIT { - @RegisterExtension - public final LogTesterJUnit5 logger = new LogTesterJUnit5(); - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddUserConsentRequiredIfGitlabAutoProvisioningEnabled.class); - private final DataChange underTest = new AddUserConsentRequiredIfGitlabAutoProvisioningEnabled(db.database(), new System2(), UuidFactoryImpl.INSTANCE); - - @BeforeEach - public void before() { - logger.clear(); - } - - @Test - void migration_whenGitlabAutoProvisioningPropertyNotPresent_shouldNotRequireConsent() throws SQLException { - underTest.execute(); - - assertThat(logger.logs(Level.WARN)).isEmpty(); - assertThat(isConsentRequired()).isFalse(); - } - - @Test - void migration_whenGitlabAutoProvisioningDisabled_shouldNotRequireConsent() throws SQLException { - disableGitlabProvisioning(); - underTest.execute(); - - assertThat(logger.logs(Level.WARN)).isEmpty(); - assertThat(isConsentRequired()).isFalse(); - } - - @Test - void migration_whenGitlabAutoProvisioningEnabled_shouldRequireConsent() throws SQLException { - enableGitlabProvisioning(); - - underTest.execute(); - - assertThat(logger.logs(Level.WARN)).containsExactly("Automatic synchronization was previously activated for Gitlab. It requires user consent to continue working as new" - + " features were added with the synchronization. Please read the upgrade notes."); - assertThat(isConsentRequired()).isTrue(); - } - - @Test - void migration_is_reentrant() throws SQLException { - enableGitlabProvisioning(); - - underTest.execute(); - underTest.execute(); - - assertThat(logger.logs(Level.WARN)).containsExactly("Automatic synchronization was previously activated for Gitlab. It requires user consent to continue working as new" - + " features were added with the synchronization. Please read the upgrade notes."); - assertThat(isConsentRequired()).isTrue(); - } - - private void disableGitlabProvisioning() { - toggleGitlabProvisioning(false); - } - private void enableGitlabProvisioning() { - toggleGitlabProvisioning(true); - } - - private boolean isConsentRequired() { - return db.countSql("select count(*) from properties where prop_key = '" + PROP_KEY + "'") >= 1; - } - - private void toggleGitlabProvisioning(boolean enabled) { - db.executeInsert("properties", "prop_key", PROVISIONING_GITLAB_ENABLED_PROP_KEY, "text_value", String.valueOf(enabled), "is_empty", true, "created_at", 0, "uuid", "uuid"); - } -}
\ No newline at end of file diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreatePrimaryKeyConstraintOnDevopsPermsMappingTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreatePrimaryKeyConstraintOnDevopsPermsMappingTableIT.java deleted file mode 100644 index ffce4c1536f..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreatePrimaryKeyConstraintOnDevopsPermsMappingTableIT.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v107.CreatePrimaryKeyConstraintOnDevopsPermsMappingTable.UUID_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; - -class CreatePrimaryKeyConstraintOnDevopsPermsMappingTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreatePrimaryKeyConstraintOnDevopsPermsMappingTable.class); - private final CreatePrimaryKeyConstraintOnDevopsPermsMappingTable underTest = new CreatePrimaryKeyConstraintOnDevopsPermsMappingTable(db.database()); - private static final String PK_DEVOPS_PERMS_MAPPING = "pk_devops_perms_mapping"; - - @Test - void execute_whenPrimaryKeyDoesNotExist_shouldCreateIt() throws Exception { - db.assertNoPrimaryKey(DEVOPS_PERMS_MAPPING_TABLE_NAME); - underTest.execute(); - db.assertPrimaryKey(DEVOPS_PERMS_MAPPING_TABLE_NAME, PK_DEVOPS_PERMS_MAPPING, UUID_COLUMN_NAME); - } - - @Test - void execute_whenPrimaryKeyAlreadyExists_shouldDoNothing() throws Exception { - underTest.execute(); - underTest.execute(); - db.assertPrimaryKey(DEVOPS_PERMS_MAPPING_TABLE_NAME, PK_DEVOPS_PERMS_MAPPING, UUID_COLUMN_NAME); - } - -}
\ No newline at end of file diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreateTelemetryMetricsSentTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreateTelemetryMetricsSentTableIT.java deleted file mode 100644 index c8c38227a3e..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreateTelemetryMetricsSentTableIT.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class CreateTelemetryMetricsSentTableIT { - - private static final String EXPECTED_TABLE_NAME = "telemetry_metrics_sent"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateTelemetryMetricsSentTable.class); - - private final DdlChange underTest = new CreateTelemetryMetricsSentTable(db.database()); - - @Test - void migration_should_create_a_table() throws SQLException { - db.assertTableDoesNotExist(EXPECTED_TABLE_NAME); - - underTest.execute(); - - db.assertTableExists(EXPECTED_TABLE_NAME); - db.assertColumnDefinition(EXPECTED_TABLE_NAME, "metric_key", Types.VARCHAR, 40, false); - db.assertColumnDefinition(EXPECTED_TABLE_NAME, "dimension", Types.VARCHAR, 40, false); - db.assertColumnDefinition(EXPECTED_TABLE_NAME, "last_sent", Types.BIGINT, null, false); - db.assertPrimaryKey(EXPECTED_TABLE_NAME, null, "metric_key", "dimension"); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertTableDoesNotExist(EXPECTED_TABLE_NAME); - - underTest.execute(); - // re-entrant - underTest.execute(); - - db.assertTableExists(EXPECTED_TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreateUniqueIndexOnDevopsPermsMappingTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreateUniqueIndexOnDevopsPermsMappingTableIT.java deleted file mode 100644 index 6a0fa7f13d3..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreateUniqueIndexOnDevopsPermsMappingTableIT.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v107.AddDevopsPlatformColumnInDevopsPermsMapping.DEVOPS_PLATFORM_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v107.CreateUniqueIndexOnDevopsPermsMappingTable.DEVOPS_ROLE_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v107.CreateUniqueIndexOnDevopsPermsMappingTable.INDEX_NAME; -import static org.sonar.server.platform.db.migration.version.v107.CreateUniqueIndexOnDevopsPermsMappingTable.SONARQUBE_PERMISSION_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; - -class CreateUniqueIndexOnDevopsPermsMappingTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateUniqueIndexOnDevopsPermsMappingTable.class); - private final DdlChange underTest = new CreateUniqueIndexOnDevopsPermsMappingTable(db.database()); - - @Test - void execute_givenIndexDoNotExist_shouldCreateIndex() throws Exception { - db.assertIndexDoesNotExist(DEVOPS_PERMS_MAPPING_TABLE_NAME, INDEX_NAME); - underTest.execute(); - db.assertUniqueIndex(DEVOPS_PERMS_MAPPING_TABLE_NAME, INDEX_NAME, DEVOPS_ROLE_COLUMN_NAME, SONARQUBE_PERMISSION_COLUMN_NAME, DEVOPS_PLATFORM_COLUMN_NAME); - } - - @Test - void execute_givenIndexAlreadyExist_shouldBeReentrant() throws SQLException { - underTest.execute(); - underTest.execute(); - db.assertUniqueIndex(DEVOPS_PERMS_MAPPING_TABLE_NAME, INDEX_NAME, DEVOPS_ROLE_COLUMN_NAME, SONARQUBE_PERMISSION_COLUMN_NAME, DEVOPS_PLATFORM_COLUMN_NAME); - } - -}
\ No newline at end of file diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/DropGithubPermsMappingTableIfDevopsPermsMappingTableExistsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/DropGithubPermsMappingTableIfDevopsPermsMappingTableExistsIT.java deleted file mode 100644 index cba780cbaf7..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/DropGithubPermsMappingTableIfDevopsPermsMappingTableExistsIT.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.GITHUB_PERMS_MAPPING_TABLE_NAME; - -class DropGithubPermsMappingTableIfDevopsPermsMappingTableExistsIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropGithubPermsMappingTableIfDevopsPermsMappingTableExists.class); - - private final DropGithubPermsMappingTableIfDevopsPermsMappingTableExists underTest = new DropGithubPermsMappingTableIfDevopsPermsMappingTableExists(db.database()); - - @Test - void execute_givenGithubDevopsPermsMappingTableExistsAndDevopsPermsMappingTableDoesNotExist_doNothing() throws SQLException { - db.assertTableExists(GITHUB_PERMS_MAPPING_TABLE_NAME); - db.assertTableDoesNotExist(DEVOPS_PERMS_MAPPING_TABLE_NAME); - - underTest.execute(); - - db.assertTableExists(GITHUB_PERMS_MAPPING_TABLE_NAME); - db.assertTableDoesNotExist(DEVOPS_PERMS_MAPPING_TABLE_NAME); - } - - @Test - void execute_givenDevopsPermsMappingTableExistsAndGithubPermsMappingTableDoNotExist_doNothing() throws SQLException { - db.executeDdl("CREATE TABLE " + DEVOPS_PERMS_MAPPING_TABLE_NAME + " (id INT PRIMARY KEY)"); - db.executeDdl("DROP TABLE " + GITHUB_PERMS_MAPPING_TABLE_NAME); - db.assertTableExists(DEVOPS_PERMS_MAPPING_TABLE_NAME); - db.assertTableDoesNotExist(GITHUB_PERMS_MAPPING_TABLE_NAME); - - underTest.execute(); - - db.assertTableExists(DEVOPS_PERMS_MAPPING_TABLE_NAME); - db.assertTableDoesNotExist(GITHUB_PERMS_MAPPING_TABLE_NAME); - } - - @Test - void execute_givenDevopsPermsMappingTableExistsAndGithubPermsMappingTableExist_dropGithubPermsMappingTable() throws SQLException { - db.executeDdl("CREATE TABLE " + DEVOPS_PERMS_MAPPING_TABLE_NAME + " (id INT PRIMARY KEY)"); - db.assertTableExists(DEVOPS_PERMS_MAPPING_TABLE_NAME); - db.assertTableExists(GITHUB_PERMS_MAPPING_TABLE_NAME); - - underTest.execute(); - - db.assertTableExists(DEVOPS_PERMS_MAPPING_TABLE_NAME); - db.assertTableDoesNotExist(GITHUB_PERMS_MAPPING_TABLE_NAME); - } - - @Test - void execute_givenDevopsPermsMappingTableDoesNotExistsAndGithubPermsMappingTableDoesNotExist_doNothing() throws SQLException { - db.executeDdl("DROP TABLE " + GITHUB_PERMS_MAPPING_TABLE_NAME); - db.assertTableDoesNotExist(DEVOPS_PERMS_MAPPING_TABLE_NAME); - db.assertTableDoesNotExist(GITHUB_PERMS_MAPPING_TABLE_NAME); - - underTest.execute(); - - db.assertTableDoesNotExist(DEVOPS_PERMS_MAPPING_TABLE_NAME); - db.assertTableDoesNotExist(GITHUB_PERMS_MAPPING_TABLE_NAME); - } - -}
\ No newline at end of file diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/DropIndexUniqGithubPermsMappingInDevopsPermsMappingTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/DropIndexUniqGithubPermsMappingInDevopsPermsMappingTableIT.java deleted file mode 100644 index 417a5595530..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/DropIndexUniqGithubPermsMappingInDevopsPermsMappingTableIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v107.DropIndexUniqGithubPermsMappingInDevopsPermsMappingTable.UNIQ_GITHUB_PERM_MAPPINGS_INDEX_NAME; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; - -class DropIndexUniqGithubPermsMappingInDevopsPermsMappingTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropIndexUniqGithubPermsMappingInDevopsPermsMappingTable.class); - private final DdlChange underTest = new DropIndexUniqGithubPermsMappingInDevopsPermsMappingTable(db.database()); - - @Test - void execute_givenIndexExists_dropsIndex() throws Exception { - db.assertUniqueIndex(DEVOPS_PERMS_MAPPING_TABLE_NAME, UNIQ_GITHUB_PERM_MAPPINGS_INDEX_NAME, "devops_platform_role", "sonarqube_permission"); - underTest.execute(); - db.assertIndexDoesNotExist(DEVOPS_PERMS_MAPPING_TABLE_NAME, UNIQ_GITHUB_PERM_MAPPINGS_INDEX_NAME); - } - - @Test - void execute_is_reentrant() throws Exception { - db.assertUniqueIndex(DEVOPS_PERMS_MAPPING_TABLE_NAME, UNIQ_GITHUB_PERM_MAPPINGS_INDEX_NAME, "devops_platform_role", "sonarqube_permission"); - underTest.execute(); - underTest.execute(); - db.assertIndexDoesNotExist(DEVOPS_PERMS_MAPPING_TABLE_NAME, UNIQ_GITHUB_PERM_MAPPINGS_INDEX_NAME); - } - -}
\ No newline at end of file diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/DropPrimaryKeyOnDevopsPermsMappingTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/DropPrimaryKeyOnDevopsPermsMappingTableIT.java deleted file mode 100644 index 13c8c62464a..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/DropPrimaryKeyOnDevopsPermsMappingTableIT.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.sql.DbPrimaryKeyConstraintFinder; -import org.sonar.server.platform.db.migration.sql.DropPrimaryKeySqlGenerator; - -import static org.sonar.server.platform.db.migration.version.v107.DropPrimaryKeyOnDevopsPermsMappingTable.CONSTRAINT_NAME; -import static org.sonar.server.platform.db.migration.version.v107.DropPrimaryKeyOnDevopsPermsMappingTable.UUID_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; - -class DropPrimaryKeyOnDevopsPermsMappingTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropPrimaryKeyOnDevopsPermsMappingTable.class); - - private final DbPrimaryKeyConstraintFinder dbPrimaryKeyConstraintFinder = new DbPrimaryKeyConstraintFinder(db.database()); - private final DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator = new DropPrimaryKeySqlGenerator(db.database(), dbPrimaryKeyConstraintFinder); - private final DropPrimaryKeyOnDevopsPermsMappingTable underTest = new DropPrimaryKeyOnDevopsPermsMappingTable(db.database(), dropPrimaryKeySqlGenerator, dbPrimaryKeyConstraintFinder); - - @Test - void execute_shouldRemoveExistingPrimaryKey() throws Exception { - db.assertPrimaryKey(DEVOPS_PERMS_MAPPING_TABLE_NAME, CONSTRAINT_NAME, UUID_COLUMN_NAME); - underTest.execute(); - db.assertNoPrimaryKey(DEVOPS_PERMS_MAPPING_TABLE_NAME); - } - - @Test - void execute_when_reentrant_shouldRemoveExistingPrimaryKey() throws Exception { - db.assertPrimaryKey(DEVOPS_PERMS_MAPPING_TABLE_NAME, CONSTRAINT_NAME, UUID_COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertNoPrimaryKey(DEVOPS_PERMS_MAPPING_TABLE_NAME); - } - -}
\ No newline at end of file diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/MigrateSmtpConfigurationIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/MigrateSmtpConfigurationIT.java deleted file mode 100644 index d34b6053474..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/MigrateSmtpConfigurationIT.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.assertj.core.groups.Tuple; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.sonar.api.testfixtures.log.LogTesterJUnit5; -import org.sonar.api.utils.System2; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static java.lang.Math.min; -import static java.lang.String.format; -import static java.util.stream.Collectors.joining; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.sonar.server.platform.db.migration.version.v107.MigrateSmtpConfiguration.EMAIL_AUTH_METHOD; -import static org.sonar.server.platform.db.migration.version.v107.MigrateSmtpConfiguration.EMAIL_FROM; -import static org.sonar.server.platform.db.migration.version.v107.MigrateSmtpConfiguration.EMAIL_FROM_NAME; -import static org.sonar.server.platform.db.migration.version.v107.MigrateSmtpConfiguration.EMAIL_PREFIX; -import static org.sonar.server.platform.db.migration.version.v107.MigrateSmtpConfiguration.EMAIL_SMTP_HOST_SECURED; -import static org.sonar.server.platform.db.migration.version.v107.MigrateSmtpConfiguration.EMAIL_SMTP_PASSWORD_SECURED; -import static org.sonar.server.platform.db.migration.version.v107.MigrateSmtpConfiguration.EMAIL_SMTP_PORT_SECURED; -import static org.sonar.server.platform.db.migration.version.v107.MigrateSmtpConfiguration.EMAIL_SMTP_SECURE_CONNECTION_SECURED; -import static org.sonar.server.platform.db.migration.version.v107.MigrateSmtpConfiguration.EMAIL_SMTP_USERNAME_SECURED; -import static org.sonar.server.platform.db.migration.version.v107.MigrateSmtpConfiguration.SMTP_LEGACY_CONFIG_PROP_KEYS; - -class MigrateSmtpConfigurationIT { - - public static final String RANDOM_PROPERTY_KEY = "random.property"; - public static final String RANDOM_PROPERTY_VALUE = "random value"; - public static final String RANDOM_INTERNAL_PROPERTY_KEY = "random.internal.property"; - public static final String RANDOM_INTERNAL_PROPERTY_VALUE = "random internal value"; - - @RegisterExtension - public final LogTesterJUnit5 logger = new LogTesterJUnit5(); - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(MigrateSmtpConfiguration.class); - - private final System2 system2 = mock(); - private final DataChange underTest = new MigrateSmtpConfiguration(db.database(), system2); - - @BeforeEach - public void before() { - logger.clear(); - } - - @Test - void execute_whenNoSmtpConfig_shouldDoNothing() throws SQLException { - insertRandomProperty(); - insertRandomInternalProperty(); - - underTest.execute(); - - assertNoInternalPropertiesHadBeenAdded(); - assertOtherPropertiesLeftUntouched(); - } - - private void assertNoInternalPropertiesHadBeenAdded() { - Map<String, String> dbRows = new HashMap<>(); - db.select(format("select kee, text_value from internal_properties where kee in (%s)", getPropertyKeysAsSqlList())) - .forEach(map -> dbRows.put((String) map.get("kee"), (String) map.get("text_value"))); - assertThat(dbRows).isEmpty(); - } - - @Test - void execute_whenPartialSmtpConfig_shouldMigrate() throws SQLException { - Map<String, String> smtpProperties = new HashMap<>(); - smtpProperties.put(EMAIL_SMTP_HOST_SECURED, "host"); - smtpProperties.put(EMAIL_SMTP_USERNAME_SECURED, "username"); - smtpProperties.put(EMAIL_FROM, "from"); - - insertProperties(smtpProperties); - insertRandomProperty(); - insertRandomInternalProperty(); - - underTest.execute(); - - assertThatPropertiesAreMigrated(smtpProperties); - assertOtherPropertiesLeftUntouched(); - } - - @Test - void execute_whenFullSmtpConfig_shouldMigrate() throws SQLException { - Map<String, String> smtpProperties = new HashMap<>(); - smtpProperties.put(EMAIL_SMTP_HOST_SECURED, "host"); - smtpProperties.put(EMAIL_SMTP_PORT_SECURED, "port"); - smtpProperties.put(EMAIL_SMTP_SECURE_CONNECTION_SECURED, "secure connection"); - smtpProperties.put(EMAIL_SMTP_USERNAME_SECURED, "username"); - smtpProperties.put(EMAIL_SMTP_PASSWORD_SECURED, "password"); - smtpProperties.put(EMAIL_FROM, "from"); - smtpProperties.put(EMAIL_FROM_NAME, "name"); - smtpProperties.put(EMAIL_PREFIX, "prefix"); - - insertProperties(smtpProperties); - insertRandomProperty(); - insertRandomInternalProperty(); - - underTest.execute(); - - assertThatPropertiesAreMigrated(smtpProperties); - assertOtherPropertiesLeftUntouched(); - } - - @Test - void execute_whenDefaultValuesUsed_shouldDefineThem() throws SQLException { - Map<String, String> smtpProperties = new HashMap<>(); - smtpProperties.put(EMAIL_SMTP_HOST_SECURED, "host"); - - insertProperties(smtpProperties); - - underTest.execute(); - - // This method adds all default values to the properties list - assertThatPropertiesAreMigrated(smtpProperties); - } - - @ParameterizedTest - @MethodSource("secureConnectionOldToNewValues") - void execute_shouldMapSecureConnectionValues(String oldValue, String newValue) throws SQLException { - Map<String, String> smtpProperties = new HashMap<>(); - smtpProperties.put(EMAIL_SMTP_SECURE_CONNECTION_SECURED, oldValue); - - insertProperties(smtpProperties); - - underTest.execute(); - - assertSecureConnectionValuesIsCorrectlyMapped(newValue); - } - - private void assertSecureConnectionValuesIsCorrectlyMapped(String newValue) { - Map<String, String> dbRows = new HashMap<>(); - db.select(format("select kee, text_value from internal_properties where kee = '%s'", EMAIL_SMTP_SECURE_CONNECTION_SECURED)) - .forEach(map -> dbRows.put((String) map.get("kee"), (String) map.get("text_value"))); - assertThat(dbRows).containsEntry(EMAIL_SMTP_SECURE_CONNECTION_SECURED, newValue); - } - - static Object[][] secureConnectionOldToNewValues() { - return new Object[][]{ - {"ssl", "SSLTLS"}, - {"starttls", "STARTTLS"}, - {null, "NONE"}, - {"", "NONE"}, - {"null", "NONE"}, - {"random", "NONE"} - }; - } - - @Test - void execute_shouldBeReentrant() throws SQLException { - Map<String, String> smtpProperties = new HashMap<>(); - smtpProperties.put(EMAIL_SMTP_HOST_SECURED, "host"); - smtpProperties.put(EMAIL_SMTP_PORT_SECURED, "port"); - smtpProperties.put(EMAIL_SMTP_SECURE_CONNECTION_SECURED, "secure connection"); - smtpProperties.put(EMAIL_SMTP_USERNAME_SECURED, "username"); - smtpProperties.put(EMAIL_SMTP_PASSWORD_SECURED, "password"); - smtpProperties.put(EMAIL_FROM, "from"); - smtpProperties.put(EMAIL_FROM_NAME, "name"); - smtpProperties.put(EMAIL_PREFIX, "prefix"); - - insertProperties(smtpProperties); - insertRandomProperty(); - insertRandomInternalProperty(); - - underTest.execute(); - underTest.execute(); - - assertThatPropertiesAreMigrated(smtpProperties); - assertOtherPropertiesLeftUntouched(); - } - - private void insertRandomProperty() { - insertProperty(RANDOM_PROPERTY_KEY, RANDOM_PROPERTY_VALUE); - } - - private void insertRandomInternalProperty() { - insertInternalProperty(RANDOM_INTERNAL_PROPERTY_KEY, RANDOM_INTERNAL_PROPERTY_VALUE); - } - - private void assertThatPropertiesAreMigrated(Map<String, String> properties) { - addDefaultProperties(properties); - updatePropertyValues(properties); - assertThatPropertiesAreInInternalProperties(properties); - assertThatPropertiesAreNotInProperties(); - } - - private void updatePropertyValues(Map<String, String> properties) { - String currentValue = properties.get(EMAIL_SMTP_SECURE_CONNECTION_SECURED); - String newValue = switch (currentValue) { - case "ssl" -> "SSLTLS"; - case "starttls" -> "STARTTLS"; - default -> "NONE"; - }; - properties.put(EMAIL_SMTP_SECURE_CONNECTION_SECURED, newValue); - } - - private void addDefaultProperties(Map<String, String> properties) { - Map<String, String> defaultPropertyValues = Map.of( - EMAIL_SMTP_SECURE_CONNECTION_SECURED, "NONE", - EMAIL_FROM, "noreply@nowhere", - EMAIL_FROM_NAME, "SonarQube", - EMAIL_PREFIX, "[SONARQUBE]", - EMAIL_AUTH_METHOD, "BASIC" - ); - defaultPropertyValues.forEach((key, value) -> { - if (!properties.containsKey(key)) { - properties.put(key, value); - } - }); - } - - private void assertThatPropertiesAreInInternalProperties(Map<String, String> properties) { - Map<String, String> dbRows = new HashMap<>(); - db.select(format("select kee, text_value from internal_properties where kee in (%s)", getPropertyKeysAsSqlList())) - .forEach(map -> dbRows.put((String) map.get("kee"), (String) map.get("text_value"))); - assertThat(dbRows).containsExactlyInAnyOrderEntriesOf(properties); - } - - private void assertThatPropertiesAreNotInProperties() { - assertThat(db.select(format("select * from properties where prop_key in (%s)", getPropertyKeysAsSqlList()))).isEmpty(); - } - - private static String getPropertyKeysAsSqlList() { - return SMTP_LEGACY_CONFIG_PROP_KEYS.stream().map(key -> "'" + key + "'").collect(joining(",")); - } - - private void assertOtherPropertiesLeftUntouched() { - assertRandomPropertyIsIntact(); - assertRandomInternalPropertyIsIntact(); - } - - private void assertRandomPropertyIsIntact() { - List<Tuple> results = db.select("select * from properties") - .stream().map(map -> new Tuple(map.get("prop_key"), map.get("text_value"))) - .toList(); - assertThat(results).containsExactly(new Tuple(RANDOM_PROPERTY_KEY, RANDOM_PROPERTY_VALUE)); - } - - private void assertRandomInternalPropertyIsIntact() { - List<Tuple> resultsInternal = db.select(format("select kee, text_value from internal_properties where kee in ('%s')", RANDOM_INTERNAL_PROPERTY_KEY)) - .stream().map(map -> new Tuple(map.get("kee"), map.get("text_value"))) - .toList(); - assertThat(resultsInternal).containsExactly(new Tuple(RANDOM_INTERNAL_PROPERTY_KEY, RANDOM_INTERNAL_PROPERTY_VALUE)); - } - - private void insertProperties(Map<String, String> properties) { - properties.forEach(this::insertProperty); - } - - private void insertProperty(String key, String value) { - db.executeInsert("properties", "uuid", "uuid_" + key.substring(0, min(key.length() - 1, 35)), "prop_key", key, "is_empty", false, "text_value", value, "created_at", 0); - } - - private void insertInternalProperty(String key, String value) { - db.executeInsert("internal_properties", "kee", key, "is_empty", false, "text_value", value, "created_at", 0); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/PopulateGitlabDevopsPermissionsMappingIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/PopulateGitlabDevopsPermissionsMappingIT.java deleted file mode 100644 index f8b33c65931..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/PopulateGitlabDevopsPermissionsMappingIT.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.testfixtures.log.LogTesterJUnit5; -import org.sonar.core.util.UuidFactoryImpl; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; - -class PopulateGitlabDevopsPermissionsMappingIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(PopulateGitlabDevOpsPermissionsMapping.class); - @RegisterExtension - public final LogTesterJUnit5 logTester = new LogTesterJUnit5(); - - private final PopulateGitlabDevOpsPermissionsMapping migration = new PopulateGitlabDevOpsPermissionsMapping(db.database(), UuidFactoryImpl.INSTANCE); - - @Test - void execute_whenTableIsEmpty_shouldPopulate() throws SQLException { - migration.execute(); - - verifyMapping(); - } - - @Test - void execute_isReentrant() throws SQLException { - migration.execute(); - migration.execute(); - - verifyMapping(); - } - - @Test - void execute_whenTableAlreadyPopulated_doesNothing() throws SQLException { - db.executeInsert(DEVOPS_PERMS_MAPPING_TABLE_NAME, - "UUID", UuidFactoryImpl.INSTANCE.create(), - "devops_platform", "gitlab", - "devops_platform_role", "role1", - "sonarqube_permission", "sq_perm"); - - migration.execute(); - - assertThat(db.select("select devops_platform_role, sonarqube_permission from devops_perms_mapping")) - .extracting(stringObjectMap -> stringObjectMap.get("DEVOPS_PLATFORM_ROLE"), stringObjectMap -> stringObjectMap.get("SONARQUBE_PERMISSION")) - .containsExactly(tuple("role1", "sq_perm")); - } - - @Test - void execute_whenTableAlreadyPopulatedWithGithub_appliesMigration() throws SQLException { - db.executeInsert(DEVOPS_PERMS_MAPPING_TABLE_NAME, - "UUID", UuidFactoryImpl.INSTANCE.create(), - "devops_platform", "github", - "devops_platform_role", "role1", - "sonarqube_permission", "sq_perm"); - - migration.execute(); - - verifyMapping(); - } - - private void verifyMapping() { - assertThat(db.select("select devops_platform_role, sonarqube_permission from devops_perms_mapping where devops_platform = 'gitlab'")) - .extracting(stringObjectMap -> stringObjectMap.get("DEVOPS_PLATFORM_ROLE"), stringObjectMap -> stringObjectMap.get("SONARQUBE_PERMISSION")) - .containsExactlyInAnyOrder( - tuple("guest", "user"), - tuple("reporter", "codeviewer"), - tuple("reporter", "user"), - tuple("developer", "codeviewer"), - tuple("developer", "user"), - tuple("developer", "issueadmin"), - tuple("developer", "securityhotspotadmin"), - tuple("developer", "scan"), - tuple("maintainer", "codeviewer"), - tuple("maintainer", "user"), - tuple("maintainer", "issueadmin"), - tuple("maintainer", "securityhotspotadmin"), - tuple("maintainer", "scan"), - tuple("maintainer", "admin"), - tuple("owner", "codeviewer"), - tuple("owner", "user"), - tuple("owner", "issueadmin"), - tuple("owner", "securityhotspotadmin"), - tuple("owner", "scan"), - tuple("owner", "admin") - ); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/RenameGithubPermsMappingTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/RenameGithubPermsMappingTableIT.java deleted file mode 100644 index 864f52924ee..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/RenameGithubPermsMappingTableIT.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.RenameTableChange; - -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.GITHUB_PERMS_MAPPING_TABLE_NAME; - -class RenameGithubPermsMappingTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameGithubPermsMappingTable.class); - private final RenameTableChange underTest = new RenameGithubPermsMappingTable(db.database()); - - @Test - void migration_shouldUpdateTableName() throws SQLException { - db.assertTableExists(GITHUB_PERMS_MAPPING_TABLE_NAME); - underTest.execute(); - db.assertTableDoesNotExist(GITHUB_PERMS_MAPPING_TABLE_NAME); - db.assertTableExists(DEVOPS_PERMS_MAPPING_TABLE_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertTableExists(GITHUB_PERMS_MAPPING_TABLE_NAME); - underTest.execute(); - db.assertTableDoesNotExist(GITHUB_PERMS_MAPPING_TABLE_NAME); - underTest.execute(); - db.assertTableDoesNotExist(GITHUB_PERMS_MAPPING_TABLE_NAME); - db.assertTableExists(DEVOPS_PERMS_MAPPING_TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/RenameGithubRoleInDevopsPermsMappingIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/RenameGithubRoleInDevopsPermsMappingIT.java deleted file mode 100644 index 318a19427b0..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/RenameGithubRoleInDevopsPermsMappingIT.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.VARCHAR; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubRoleInDevopsPermsMapping.OLD_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubRoleInDevopsPermsMapping.NEW_COLUMN_NAME; - -class RenameGithubRoleInDevopsPermsMappingIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameGithubRoleInDevopsPermsMapping.class); - - private final RenameGithubRoleInDevopsPermsMapping underTest = new RenameGithubRoleInDevopsPermsMapping(db.database()); - - @Test - void execute_renameColumn() throws SQLException { - db.assertColumnDoesNotExist(DEVOPS_PERMS_MAPPING_TABLE_NAME, NEW_COLUMN_NAME); - db.assertColumnDefinition(DEVOPS_PERMS_MAPPING_TABLE_NAME, OLD_COLUMN_NAME, VARCHAR, 100, false); - underTest.execute(); - db.assertColumnDefinition(DEVOPS_PERMS_MAPPING_TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 100, false); - db.assertColumnDoesNotExist(DEVOPS_PERMS_MAPPING_TABLE_NAME, OLD_COLUMN_NAME); - } - - @Test - void execute_whenRunTwice_isReentrant() throws SQLException { - db.assertColumnDoesNotExist(DEVOPS_PERMS_MAPPING_TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(DEVOPS_PERMS_MAPPING_TABLE_NAME, NEW_COLUMN_NAME, VARCHAR, 100, false); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/AddManualSeverityColumnInIssuesImpactsTableTest.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/AddManualSeverityColumnInIssuesImpactsTableTest.java deleted file mode 100644 index 6ab38a2f22a..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/AddManualSeverityColumnInIssuesImpactsTableTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.junit.jupiter.api.Assertions.*; - -class AddManualSeverityColumnInIssuesImpactsTableTest { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddManualSeverityColumnInIssuesImpactsTable.class); - private final AddManualSeverityColumnInIssuesImpactsTable underTest = new AddManualSeverityColumnInIssuesImpactsTable(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws Exception { - db.assertColumnDoesNotExist(AddManualSeverityColumnInIssuesImpactsTable.TABLE_NAME, AddManualSeverityColumnInIssuesImpactsTable.MANUAL_SEVERITY); - underTest.execute(); - db.assertColumnDefinition(AddManualSeverityColumnInIssuesImpactsTable.TABLE_NAME, AddManualSeverityColumnInIssuesImpactsTable.MANUAL_SEVERITY, java.sql.Types.BOOLEAN, null, false); - } - - @Test - void execute_whenColumnAlreadyExists_shouldNotFail() throws Exception { - underTest.execute(); - assertDoesNotThrow(() -> underTest.execute()); - } - - @Test - void execute_is_reentrant() throws Exception { - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(AddManualSeverityColumnInIssuesImpactsTable.TABLE_NAME, AddManualSeverityColumnInIssuesImpactsTable.MANUAL_SEVERITY, java.sql.Types.BOOLEAN, null, false); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/AddMeasuresMigratedColumnToPortfoliosTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/AddMeasuresMigratedColumnToPortfoliosTableIT.java deleted file mode 100644 index e4db0e8f246..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/AddMeasuresMigratedColumnToPortfoliosTableIT.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; -import static org.sonar.server.platform.db.migration.version.v108.AddMeasuresMigratedColumnToPortfoliosTable.MIGRATION_FLAG_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v108.AddMeasuresMigratedColumnToPortfoliosTable.PORTFOLIOS_TABLE_NAME; - -class AddMeasuresMigratedColumnToPortfoliosTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddMeasuresMigratedColumnToPortfoliosTable.class); - private final AddMeasuresMigratedColumnToPortfoliosTable underTest = new AddMeasuresMigratedColumnToPortfoliosTable(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(PORTFOLIOS_TABLE_NAME, MIGRATION_FLAG_COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(PORTFOLIOS_TABLE_NAME, MIGRATION_FLAG_COLUMN_NAME, Types.BOOLEAN, null, false); - } - - @Test - void execute_whenColumnAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/AddMeasuresMigratedColumnToProjectBranchesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/AddMeasuresMigratedColumnToProjectBranchesTableIT.java deleted file mode 100644 index af76e852d06..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/AddMeasuresMigratedColumnToProjectBranchesTableIT.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; -import static org.sonar.server.platform.db.migration.version.v108.AddMeasuresMigratedColumnToProjectBranchesTable.MIGRATION_FLAG_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v108.AddMeasuresMigratedColumnToProjectBranchesTable.PROJECT_BRANCHES_TABLE_NAME; - -class AddMeasuresMigratedColumnToProjectBranchesTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddMeasuresMigratedColumnToProjectBranchesTable.class); - private final AddMeasuresMigratedColumnToProjectBranchesTable underTest = new AddMeasuresMigratedColumnToProjectBranchesTable(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(PROJECT_BRANCHES_TABLE_NAME, MIGRATION_FLAG_COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(PROJECT_BRANCHES_TABLE_NAME, MIGRATION_FLAG_COLUMN_NAME, Types.BOOLEAN, null, false); - } - - @Test - void execute_whenColumnAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnMeasuresTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnMeasuresTableIT.java deleted file mode 100644 index 60a14d350bc..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnMeasuresTableIT.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v108.CreateIndexOnMeasuresTable.INDEX_NAME; -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.COLUMN_BRANCH_UUID; -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.MEASURES_TABLE_NAME; - - -class CreateIndexOnMeasuresTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexOnMeasuresTable.class); - - private final DdlChange underTest = new CreateIndexOnMeasuresTable(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(MEASURES_TABLE_NAME, INDEX_NAME); - - underTest.execute(); - - db.assertIndex(MEASURES_TABLE_NAME, INDEX_NAME, COLUMN_BRANCH_UUID); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - db.assertIndexDoesNotExist(MEASURES_TABLE_NAME, INDEX_NAME); - - underTest.execute(); - underTest.execute(); - - db.assertIndex(MEASURES_TABLE_NAME, INDEX_NAME, COLUMN_BRANCH_UUID); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnPortfoliosMeasuresMigratedIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnPortfoliosMeasuresMigratedIT.java deleted file mode 100644 index eba18206b8d..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnPortfoliosMeasuresMigratedIT.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v108.CreateIndexOnPortfoliosMeasuresMigrated.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v108.CreateIndexOnPortfoliosMeasuresMigrated.TABLE_NAME; - -class CreateIndexOnPortfoliosMeasuresMigratedIT { - - private static final String INDEX_NAME = "portfolios_measures_migrated"; - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexOnPortfoliosMeasuresMigrated.class); - private final CreateIndexOnPortfoliosMeasuresMigrated underTest = new CreateIndexOnPortfoliosMeasuresMigrated(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - - underTest.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - underTest.execute(); - underTest.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnProjectBranchesMeasuresMigratedIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnProjectBranchesMeasuresMigratedIT.java deleted file mode 100644 index 75d1da955c0..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnProjectBranchesMeasuresMigratedIT.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.sonar.server.platform.db.migration.version.v108.CreateIndexOnProjectBranchesMeasuresMigrated.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v108.CreateIndexOnProjectBranchesMeasuresMigrated.TABLE_NAME; - -class CreateIndexOnProjectBranchesMeasuresMigratedIT { - - private static final String INDEX_NAME = "pb_measures_migrated"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateIndexOnProjectBranchesMeasuresMigrated.class); - private final CreateIndexOnProjectBranchesMeasuresMigrated underTest = new CreateIndexOnProjectBranchesMeasuresMigrated(db.database()); - - @Test - void migration_should_create_index() throws SQLException { - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - - underTest.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - } - - @Test - void migration_should_be_reentrant() throws SQLException { - underTest.execute(); - underTest.execute(); - - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateMeasuresTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateMeasuresTableIT.java deleted file mode 100644 index 0edf5a3bb24..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateMeasuresTableIT.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.COLUMN_BRANCH_UUID; -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.COLUMN_COMPONENT_UUID; -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.COLUMN_CREATED_AT; -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.COLUMN_JSON_VALUE; -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.COLUMN_JSON_VALUE_HASH; -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.COLUMN_UPDATED_AT; -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.MEASURES_TABLE_NAME; - -class CreateMeasuresTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateMeasuresTable.class); - - private final DdlChange underTest = new CreateMeasuresTable(db.database()); - - @Test - void execute_shouldCreateTable() throws SQLException { - db.assertTableDoesNotExist(MEASURES_TABLE_NAME); - - underTest.execute(); - - db.assertTableExists(MEASURES_TABLE_NAME); - db.assertNoPrimaryKey(MEASURES_TABLE_NAME); - db.assertColumnDefinition(MEASURES_TABLE_NAME, COLUMN_COMPONENT_UUID, Types.VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(MEASURES_TABLE_NAME, COLUMN_BRANCH_UUID, Types.VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(MEASURES_TABLE_NAME, COLUMN_JSON_VALUE, Types.CLOB, null, false); - db.assertColumnDefinition(MEASURES_TABLE_NAME, COLUMN_JSON_VALUE_HASH, Types.BIGINT, null, false); - db.assertColumnDefinition(MEASURES_TABLE_NAME, COLUMN_CREATED_AT, Types.BIGINT, null, false); - db.assertColumnDefinition(MEASURES_TABLE_NAME, COLUMN_UPDATED_AT, Types.BIGINT, null, false); - } - - @Test - void execute_shouldBeReentrant() throws SQLException { - db.assertTableDoesNotExist(MEASURES_TABLE_NAME); - - underTest.execute(); - underTest.execute(); - - db.assertTableExists(MEASURES_TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateNewSoftwareQualityMetricsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateNewSoftwareQualityMetricsIT.java deleted file mode 100644 index 443aaabaf7f..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateNewSoftwareQualityMetricsIT.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import java.util.Map; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.UuidFactoryImpl; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; - -class CreateNewSoftwareQualityMetricsIT { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateNewSoftwareQualityMetrics.class); - private final CreateNewSoftwareQualityMetrics underTest = new CreateNewSoftwareQualityMetrics(db.database(), UuidFactoryImpl.INSTANCE); - - @Test - void execute_shouldCreateMetrics() throws SQLException { - assertThat(db.select("select name,direction,qualitative,enabled,best_value,optimized_best_value,delete_historical_data from metrics")) - .isEmpty(); - underTest.execute(); - assertThat(db.select("select name,direction,qualitative,enabled,best_value,optimized_best_value,delete_historical_data from metrics")) - .hasSize(6) - .extracting(s -> s.get("name"), s -> s.get("direction"), s -> s.get("qualitative"), s -> s.get("enabled"), s -> ((Number) s.get("best_value")).longValue(), - s -> s.get("optimized_best_value"), - s -> s.get("delete_historical_data")) - - .containsExactlyInAnyOrder( - tuple("software_quality_reliability_issues", -1L, false, true, 0L, true, false), - tuple("software_quality_security_issues", -1L, false, true, 0L, true, false), - tuple("new_software_quality_reliability_issues", -1L, true, true, 0L, true, true), - tuple("new_software_quality_security_issues", -1L, true, true, 0L, true, true), - tuple("new_software_quality_maintainability_issues", -1L, true, true, 0L, true, true), - tuple("software_quality_maintainability_issues", -1L, false, true, 0L, true, false)); - } - - @Test - void execute_shouldBeReentrant() throws SQLException { - underTest.execute(); - underTest.execute(); - assertThat(db.select("select name,direction,qualitative,enabled,best_value,optimized_best_value,delete_historical_data from metrics")) - .hasSize(6); - } - - @Test - void execute_whenOnlyOneMetricExists_shouldCreateOtherOnes() throws SQLException { - String existingMetricUuid = insertMetric("software_quality_security_issues"); - underTest.execute(); - - assertThat(db.select("select uuid from metrics")) - .hasSize(6) - .extracting(e -> e.get("uuid")) - .contains(existingMetricUuid); - } - - private String insertMetric(String key) { - String uuid = UuidFactoryImpl.INSTANCE.create(); - Map<String, Object> map = Map.ofEntries( - Map.entry("UUID", uuid), - Map.entry("NAME", key)); - db.executeInsert("metrics", map); - return uuid; - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreatePrimaryKeyOnMeasuresTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreatePrimaryKeyOnMeasuresTableIT.java deleted file mode 100644 index 7cb6287b855..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreatePrimaryKeyOnMeasuresTableIT.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.COLUMN_COMPONENT_UUID; -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.MEASURES_TABLE_NAME; - -class CreatePrimaryKeyOnMeasuresTableIT { - - private static final String PK_NAME = "pk_measures"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreatePrimaryKeyOnMeasuresTable.class); - - private final DdlChange underTest = new CreatePrimaryKeyOnMeasuresTable(db.database()); - - @Test - void execute_shouldCreatePrimaryKey() throws SQLException { - db.assertNoPrimaryKey(MEASURES_TABLE_NAME); - - underTest.execute(); - - db.assertPrimaryKey(MEASURES_TABLE_NAME, PK_NAME, COLUMN_COMPONENT_UUID); - } - - @Test - void execute_shouldBeReentrant() throws SQLException { - db.assertNoPrimaryKey(MEASURES_TABLE_NAME); - - underTest.execute(); - underTest.execute(); - - db.assertPrimaryKey(MEASURES_TABLE_NAME, PK_NAME, COLUMN_COMPONENT_UUID); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DeleteSoftwareQualityRatingFromProjectMeasuresIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DeleteSoftwareQualityRatingFromProjectMeasuresIT.java deleted file mode 100644 index 843a379f046..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DeleteSoftwareQualityRatingFromProjectMeasuresIT.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import java.util.Map; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.Mockito; -import org.sonar.core.util.UuidFactoryImpl; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.es.MigrationEsClient; - -import static org.assertj.core.api.Assertions.assertThat; - -class DeleteSoftwareQualityRatingFromProjectMeasuresIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DeleteSoftwareQualityRatingFromProjectMeasures.class); - - private final MigrationEsClient migrationEsClient = Mockito.mock(MigrationEsClient.class); - - private final DeleteSoftwareQualityRatingFromProjectMeasures underTest = new DeleteSoftwareQualityRatingFromProjectMeasures(db.database(), migrationEsClient); - - @Test - void execute_whenMeasuresExists_shouldDeleteMeasures() throws SQLException { - DeleteSoftwareQualityRatingFromProjectMeasures.SOFTWARE_QUALITY_METRICS_TO_DELETE.forEach(key -> { - String metricUUid = insertMetric(key); - insertProjectMeasure(metricUUid); - }); - - assertThat(db.countSql("select count(1) from project_measures")) - .isEqualTo(DeleteSoftwareQualityRatingFromProjectMeasures.SOFTWARE_QUALITY_METRICS_TO_DELETE.size()); - - underTest.execute(); - - assertThat(db.countSql("select count(1) from project_measures")).isZero(); - Mockito.verify(migrationEsClient, Mockito.times(1)).deleteIndexes("projectmeasures"); - } - - @Test - void execute_whenOtherMeasuresExists_shouldNotDeleteMeasures() throws SQLException { - String metricUUid = insertMetric("other_metric"); - insertProjectMeasure(metricUUid); - - assertThat(db.countSql("select count(1) from project_measures")).isEqualTo(1); - - underTest.execute(); - - assertThat(db.countSql("select count(1) from project_measures")).isEqualTo(1); - } - - @Test - void execute_shouldBeReentrant() throws SQLException { - DeleteSoftwareQualityRatingFromProjectMeasures.SOFTWARE_QUALITY_METRICS_TO_DELETE.forEach(key -> { - String metricUUid = insertMetric(key); - insertProjectMeasure(metricUUid); - }); - - String metricUUid = insertMetric("other_metric"); - insertProjectMeasure(metricUUid); - - assertThat(db.countSql("select count(1) from project_measures")) - .isEqualTo(DeleteSoftwareQualityRatingFromProjectMeasures.SOFTWARE_QUALITY_METRICS_TO_DELETE.size() + 1); - - underTest.execute(); - underTest.execute(); - - assertThat(db.countSql("select count(1) from project_measures")).isOne(); - } - - private String insertMetric(String key) { - String uuid = UuidFactoryImpl.INSTANCE.create(); - Map<String, Object> map = Map.ofEntries( - Map.entry("UUID", uuid), - Map.entry("NAME", key)); - db.executeInsert("metrics", map); - return uuid; - } - - private void insertProjectMeasure(String metricUuid) { - Map<String, Object> map = Map.ofEntries( - Map.entry("UUID", UuidFactoryImpl.INSTANCE.create()), - Map.entry("METRIC_UUID", metricUuid), - Map.entry("COMPONENT_UUID", UuidFactoryImpl.INSTANCE.create()), - Map.entry("ANALYSIS_UUID", UuidFactoryImpl.INSTANCE.create())); - db.executeInsert("project_measures", map); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropColumnFromHotspotInIssuesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropColumnFromHotspotInIssuesIT.java deleted file mode 100644 index 9b29bb41d14..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropColumnFromHotspotInIssuesIT.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -class DropColumnFromHotspotInIssuesIT { - private static final String TABLE_NAME = "issues"; - private static final String COLUMN_NAME = "from_hotspot"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropColumnFromHotspotInIssues.class); - private final DdlChange underTest = new DropColumnFromHotspotInIssues(db.database()); - - @Test - void drops_column() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.BOOLEAN, null, true); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.BOOLEAN, null, true); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropIndexOnPortfoliosMeasuresMigratedIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropIndexOnPortfoliosMeasuresMigratedIT.java deleted file mode 100644 index 6a35dcb10bd..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropIndexOnPortfoliosMeasuresMigratedIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - - -class DropIndexOnPortfoliosMeasuresMigratedIT { - - private static final String TABLE_NAME = "portfolios"; - private static final String COLUMN_NAME = "measures_migrated"; - private static final String INDEX_NAME = "portfolios_measures_migrated"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropIndexOnPortfoliosMeasuresMigrated.class); - private final DdlChange underTest = new DropIndexOnPortfoliosMeasuresMigrated(db.database()); - - @Test - void execute_givenIndexExists_dropsIndex() throws Exception { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - underTest.execute(); - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - } - - @Test - void execute_is_reentrant() throws Exception { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropIndexOnProjectBranchesMeasuresMigratedIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropIndexOnProjectBranchesMeasuresMigratedIT.java deleted file mode 100644 index b1f20641335..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropIndexOnProjectBranchesMeasuresMigratedIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - - -class DropIndexOnProjectBranchesMeasuresMigratedIT { - - private static final String TABLE_NAME = "project_branches"; - private static final String COLUMN_NAME = "measures_migrated"; - private static final String INDEX_NAME = "pb_measures_migrated"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropIndexOnProjectBranchesMeasuresMigrated.class); - private final DdlChange underTest = new DropIndexOnProjectBranchesMeasuresMigrated(db.database()); - - @Test - void execute_givenIndexExists_dropsIndex() throws Exception { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - underTest.execute(); - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - } - - @Test - void execute_is_reentrant() throws Exception { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropLiveMeasuresTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropLiveMeasuresTableIT.java deleted file mode 100644 index 0b874c17dd2..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropLiveMeasuresTableIT.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - - -class DropLiveMeasuresTableIT { - public static final String TABLE_NAME = "live_measures"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropLiveMeasuresTable.class); - private final DropLiveMeasuresTable underTest = new DropLiveMeasuresTable(db.database()); - - @Test - void execute_shouldDropTable() throws SQLException { - db.assertTableExists(TABLE_NAME); - underTest.execute(); - db.assertTableDoesNotExist(TABLE_NAME); - } - - @Test - void execute_shouldSupportReentrantMigrationExecution() throws SQLException { - db.assertTableExists(TABLE_NAME); - underTest.execute(); - underTest.execute(); - db.assertTableDoesNotExist(TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropMeasuresMigratedInPortfoliosTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropMeasuresMigratedInPortfoliosTableIT.java deleted file mode 100644 index 397ac28b71d..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropMeasuresMigratedInPortfoliosTableIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v108.DropMeasuresMigratedColumnInPortfoliosTable.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v108.DropMeasuresMigratedColumnInPortfoliosTable.TABLE_NAME; - -class DropMeasuresMigratedInPortfoliosTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropMeasuresMigratedColumnInPortfoliosTable.class); - private final DdlChange underTest = new DropMeasuresMigratedColumnInPortfoliosTable(db.database()); - - @Test - void executed_whenRun_shouldDropSystemTagsColumn() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.BOOLEAN, null, false); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void execute_whenRunMoreThanOnce_shouldBeReentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.BOOLEAN, null, false); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropMeasuresMigratedInProjectBranchesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropMeasuresMigratedInProjectBranchesTableIT.java deleted file mode 100644 index d48cedb7e29..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/DropMeasuresMigratedInProjectBranchesTableIT.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import java.sql.Types; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v108.DropMeasuresMigratedColumnInProjectBranchesTable.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v108.DropMeasuresMigratedColumnInProjectBranchesTable.TABLE_NAME; - -class DropMeasuresMigratedInProjectBranchesTableIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropMeasuresMigratedColumnInProjectBranchesTable.class); - private final DdlChange underTest = new DropMeasuresMigratedColumnInProjectBranchesTable(db.database()); - - @Test - void executed_whenRun_shouldDropSystemTagsColumn() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.BOOLEAN, null, false); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } - - @Test - void execute_whenRunMoreThanOnce_shouldBeReentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.BOOLEAN, null, false); - underTest.execute(); - underTest.execute(); - db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/EnableSpecificMqrModeIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/EnableSpecificMqrModeIT.java deleted file mode 100644 index a5b01c86a08..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/EnableSpecificMqrModeIT.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.sonar.api.impl.utils.TestSystem2; -import org.sonar.api.utils.System2; -import org.sonar.core.util.SequenceUuidFactory; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.history.MigrationHistory; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.core.config.MQRModeConstants.MULTI_QUALITY_MODE_ENABLED; - -class EnableSpecificMqrModeIT { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(EnableSpecificMqrMode.class); - - private final UuidFactory uuidFactory = new SequenceUuidFactory(); - private final MigrationHistory migrationHistory = mock(MigrationHistory.class); - private final System2 system2 = new TestSystem2().setNow(2_000_000_000L); - - private final DataChange underTest = new EnableSpecificMqrMode(db.database(), migrationHistory, uuidFactory, system2); - - @ParameterizedTest - @MethodSource("versions") - void execute_correctlyInsertsProperty(long version, String expectedResult) throws SQLException { - when(migrationHistory.getInitialDbVersion()).thenReturn(version); - underTest.execute(); - - assertThat(getPropertyFromDB()).hasSize(1); - assertThat(getPropertyFromDB().get(0)) - .containsEntry("text_value", expectedResult) - .containsEntry("is_empty", false) - .containsEntry("created_at", 2_000_000_000L) - .containsEntry("uuid", "00000000-0000-0000-0000-000000000001"); - } - - @ParameterizedTest - @MethodSource("versions") - void execute_doesNothingIfPropertyAlreadyExists(long version) throws SQLException { - when(migrationHistory.getInitialDbVersion()).thenReturn(version); - - String uuid = uuidFactory.create(); - db.executeInsert("properties", - "prop_key", MULTI_QUALITY_MODE_ENABLED, - "text_value", "false", - "is_empty", false, - "created_at", 1_000_000_000L, - "uuid", uuid); - underTest.execute(); - - assertThat(getPropertyFromDB()).hasSize(1); - assertThat(getPropertyFromDB().get(0)) - .containsEntry("text_value", "false") - .containsEntry("is_empty", false) - .containsEntry("created_at", 1_000_000_000L) - .containsEntry("uuid", uuid); - } - - @Test - void execute_shouldBeReentrant() throws SQLException { - when(migrationHistory.getInitialDbVersion()).thenReturn(102_000L); - underTest.execute(); - underTest.execute(); - - assertThat(getPropertyFromDB()).hasSize(1); - assertThat(getPropertyFromDB().get(0)) - .containsEntry("text_value", "true") - .containsEntry("is_empty", false) - .containsEntry("created_at", 2_000_000_000L) - .containsEntry("uuid", "00000000-0000-0000-0000-000000000001"); - } - - private List<Map<String, Object>> getPropertyFromDB() { - String sql = "SELECT text_value, is_empty, created_at, uuid FROM properties WHERE prop_key = '" + MULTI_QUALITY_MODE_ENABLED + "'"; - return db.select(sql); - } - - private static Stream<Arguments> versions() { - return Stream.of( - Arguments.of(102_000L, "true"), - Arguments.of(-1L, "true"), - Arguments.of(101_990L, "false")); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/MigrateAiSuggestionEnabledValuesTest.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/MigrateAiSuggestionEnabledValuesTest.java deleted file mode 100644 index 1989467a7cd..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/MigrateAiSuggestionEnabledValuesTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.platform.db.migration.version.v108.MigrateAiSuggestionEnabledValues.AI_CODEFIX_ENABLED_PROP_KEY; -import static org.sonar.server.platform.db.migration.version.v108.MigrateAiSuggestionEnabledValues.DISABLED; -import static org.sonar.server.platform.db.migration.version.v108.MigrateAiSuggestionEnabledValues.ENABLED_FOR_ALL_PROJECTS; - -class MigrateAiSuggestionEnabledValuesTest { - @RegisterExtension - private final MigrationDbTester db = MigrationDbTester.createForMigrationStep(MigrateAiSuggestionEnabledValues.class); - private final MigrateAiSuggestionEnabledValues underTest = new MigrateAiSuggestionEnabledValues(db.database()); - - @BeforeEach - void init() { - insertProjects(); - } - - @Test - void execute_shouldNotUpdateAnything_whenThePropertyDoesNotExists() throws SQLException { - underTest.execute(); - - assertThat(db.countSql(String.format("select count(*) from properties where prop_key = '%s'", AI_CODEFIX_ENABLED_PROP_KEY))).isZero(); - assertThat(db.countSql("select count(*) from projects where ai_code_fix_enabled = " + getBool(true))).isZero(); - } - - @Test - void execute_shouldUpdatePropertyToDisabled_whenThePropertyIsFalse() throws SQLException { - addAISuggestionEnabledProperty(false); - underTest.execute(); - - assertThat(db.select(String.format("select text_value from properties where prop_key = '%s'", AI_CODEFIX_ENABLED_PROP_KEY))) - .extracting(r -> r.get("TEXT_VALUE")) - .containsExactly(DISABLED); - - assertThat(db.countSql("select count(*) from projects where ai_code_fix_enabled = " + getBool(true))).isZero(); - } - - @Test - void execute_shouldUpdatePropertyAndProjects_whenThePropertyIsTrue() throws SQLException { - addAISuggestionEnabledProperty(true); - underTest.execute(); - - assertThat(db.select(String.format("select text_value from properties where prop_key = '%s'", AI_CODEFIX_ENABLED_PROP_KEY))) - .extracting(r -> r.get("TEXT_VALUE")) - .containsExactly(ENABLED_FOR_ALL_PROJECTS); - - assertThat(db.countSql("select count(*) from projects where ai_code_fix_enabled = " + getBool(true))).isEqualTo(2); - assertThat(db.countSql("select count(*) from projects where ai_code_fix_enabled = " + getBool(false))).isZero(); - } - - private void insertProjects() { - db.executeInsert("projects", - "kee", "proj1", - "qualifier", "TRK", - "uuid", "uuid1", - "private", false, - "creation_method", "LOCAL_BROWSER", - "ai_code_fix_enabled", false, - "created_at", 1L, - "updated_at", 1L); - db.executeInsert("projects", - "kee", "proj2", - "qualifier", "TRK", - "uuid", "uuid2", - "private", false, - "creation_method", "LOCAL_BROWSER", - "ai_code_fix_enabled", false, - "created_at", 1L, - "updated_at", 1L); - } - - private void addAISuggestionEnabledProperty(boolean enabled) { - db.executeInsert("properties", - "prop_key", AI_CODEFIX_ENABLED_PROP_KEY, - "is_empty", false, - "uuid", "uuid2", - "text_value", enabled, - "created_at", 1L); - } - - private String getBool(boolean isTrue) { - var dialect = db.database().getDialect(); - return isTrue ? dialect.getTrueSqlValue() : dialect.getFalseSqlValue(); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/MigrateBranchesLiveMeasuresToMeasuresIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/MigrateBranchesLiveMeasuresToMeasuresIT.java deleted file mode 100644 index 6418fdeddc4..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/MigrateBranchesLiveMeasuresToMeasuresIT.java +++ /dev/null @@ -1,384 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import com.google.gson.Gson; -import java.nio.charset.StandardCharsets; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.slf4j.event.Level; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.testfixtures.log.LogTesterJUnit5; -import org.sonar.api.utils.System2; -import org.sonar.core.metric.SoftwareQualitiesMetrics; -import org.sonar.core.util.SequenceUuidFactory; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static java.lang.String.format; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.tuple; -import static org.mockito.Mockito.mock; - -class MigrateBranchesLiveMeasuresToMeasuresIT { - - private static final String MEASURES_MIGRATED_COLUMN = "measures_migrated"; - public static final String SELECT_MEASURE = "select component_uuid, branch_uuid, json_value, json_value_hash, created_at, updated_at " + - "from measures where component_uuid = '%s'"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(MigrateBranchesLiveMeasuresToMeasures.class); - - @RegisterExtension - private final LogTesterJUnit5 logTester = new LogTesterJUnit5(); - - private final SequenceUuidFactory uuidFactory = new SequenceUuidFactory(); - private final System2 system2 = mock(); - private final DataChange underTest = new MigrateBranchesLiveMeasuresToMeasures(db.database(), system2); - - @Test - void shall_complete_when_tables_are_empty() throws SQLException { - underTest.execute(); - - assertThat(db.countRowsOfTable("measures")).isZero(); - } - - @Test - void migration_does_nothing_if_live_measures_table_is_missing() { - db.executeDdl("drop table live_measures"); - db.assertTableDoesNotExist("live_measures"); - String branch = "branch_3"; - insertNotMigratedBranch(branch); - - assertThatCode(underTest::execute) - .doesNotThrowAnyException(); - } - - @Test - void log_the_item_uuid_when_the_migration_fails() { - String nclocMetricUuid = insertMetric("ncloc", "INT"); - String branch1 = "branch_1"; - insertNotMigratedBranch(branch1); - insertMeasure(branch1, nclocMetricUuid, Map.of("value", 120)); - - db.executeDdl("drop table measures"); - db.assertTableDoesNotExist("measures"); - - assertThatExceptionOfType(SQLException.class) - .isThrownBy(underTest::execute); - - assertThat(logTester.logs(Level.ERROR)) - .contains("Migration of branch branch_1 failed"); - } - - @Test - void shall_not_migrate_when_branch_is_already_flagged() throws SQLException { - String nclocMetricUuid = insertMetric("ncloc", "INT"); - String qgStatusMetricUuid = insertMetric("quality_gate_status", "STRING"); - String metricWithDataUuid = insertMetric("metric_with_data", "DATA"); - String branch1 = "branch_1"; - insertMigratedBranch(branch1); - insertMeasure(branch1, nclocMetricUuid, Map.of("value", 120)); - insertMeasure(branch1, qgStatusMetricUuid, Map.of("text_value", "ok")); - insertMeasure(branch1, metricWithDataUuid, Map.of("measure_data", "some data".getBytes(StandardCharsets.UTF_8))); - - insertMigratedBranch("branch_2"); - insertMeasure("branch_2", nclocMetricUuid, Map.of("value", 14220)); - - underTest.execute(); - - assertThat(db.countRowsOfTable("measures")).isZero(); - } - - @Test - void should_flag_branch_with_no_measures() throws SQLException { - String branch = "branch_3"; - insertNotMigratedBranch(branch); - - underTest.execute(); - - assertBranchMigrated(branch); - assertThat(db.countRowsOfTable("measures")).isZero(); - } - - @Test - void should_migrate_branch_with_measures() throws SQLException { - String nclocMetricUuid = insertMetric("ncloc", "INT"); - String qgStatusMetricUuid = insertMetric("quality_gate_status", "STRING"); - String metricWithDataUuid = insertMetric("metric_with_data", "DATA"); - - String branch1 = "branch_4"; - insertNotMigratedBranch(branch1); - String component1 = uuidFactory.create(); - String component2 = uuidFactory.create(); - insertMeasure(branch1, component1, nclocMetricUuid, Map.of("value", 120)); - insertMeasure(branch1, component1, qgStatusMetricUuid, Map.of("text_value", "ok")); - insertMeasure(branch1, component2, metricWithDataUuid, Map.of("measure_data", "some data".getBytes(StandardCharsets.UTF_8))); - - String branch2 = "branch_5"; - insertNotMigratedBranch(branch2); - insertMeasure(branch2, nclocMetricUuid, Map.of("value", 64)); - - String migratedBranch = "branch_6"; - insertMigratedBranch(migratedBranch); - insertMeasure(migratedBranch, nclocMetricUuid, Map.of("value", 3684)); - - underTest.execute(); - - assertBranchMigrated(branch1); - assertBranchMigrated(branch2); - assertThat(db.countRowsOfTable("measures")).isEqualTo(3); - - assertThat(db.select(format(SELECT_MEASURE, component1))) - .hasSize(1) - .extracting(t -> t.get("component_uuid"), t -> t.get("branch_uuid"), t -> t.get("json_value"), t -> t.get("json_value_hash")) - .containsOnly(tuple(component1, branch1, "{\"ncloc\":120.0,\"quality_gate_status\":\"ok\"}", 6033012287291512746L)); - - assertThat(db.select(format(SELECT_MEASURE, component2))) - .hasSize(1) - .extracting(t -> t.get("component_uuid"), t -> t.get("branch_uuid"), t -> t.get("json_value"), t -> t.get("json_value_hash")) - .containsOnly(tuple(component2, branch1, "{\"metric_with_data\":\"some data\"}", -4524184678167636687L)); - } - - @Test - void should_not_migrate_measures_planned_for_deletion() throws SQLException { - String nclocMetricUuid = insertMetric("ncloc", "INT"); - Set<String> deletedMetricUuid = DeleteSoftwareQualityRatingFromProjectMeasures.SOFTWARE_QUALITY_METRICS_TO_DELETE.stream().map(e -> insertMetric(e, "INT")) - .collect(Collectors.toSet()); - - String branch1 = "branch_4"; - insertNotMigratedBranch(branch1); - String component1 = uuidFactory.create(); - String component2 = uuidFactory.create(); - insertMeasure(branch1, component1, nclocMetricUuid, Map.of("value", 120)); - deletedMetricUuid.forEach(metricUuid -> insertMeasure(branch1, component1, metricUuid, Map.of("value", 120))); - deletedMetricUuid.forEach(metricUuid -> insertMeasure(branch1, component2, metricUuid, Map.of("value", 120))); - - underTest.execute(); - - assertBranchMigrated(branch1); - assertThat(db.countRowsOfTable("measures")).isEqualTo(1); - - assertThat(db.select(format(SELECT_MEASURE, component1))) - .hasSize(1) - .extracting(t -> t.get("component_uuid"), t -> t.get("branch_uuid"), t -> t.get("json_value"), t -> t.get("json_value_hash")) - .containsOnly(tuple(component1, branch1, "{\"ncloc\":120.0}", -1557106439558598045L)); - - assertThat(db.select(format(SELECT_MEASURE, component2))) - .isEmpty(); - } - - @Test - void should_include_new_measures_based_on_previous_available_measures() throws SQLException { - Set<String> metricsToMigrate = MeasureMigration.MIGRATION_MAP.keySet().stream().map(e -> insertMetric(e, "DATA")) - .collect(Collectors.toSet()); - - String branch = "branch_4"; - insertNotMigratedBranch(branch); - String component1 = uuidFactory.create(); - metricsToMigrate.forEach(metricUuid -> insertMeasure(branch, component1, metricUuid, - Map.of("measure_data", "{\"LOW\":3,\"MEDIUM\":0,\"HIGH\":4,\"total\":7}".getBytes(StandardCharsets.UTF_8)))); - - underTest.execute(); - - assertBranchMigrated(branch); - assertThat(db.countRowsOfTable("measures")).isEqualTo(1); - - List<Map<String, Object>> measuresFromDB = db.select(format(SELECT_MEASURE, component1)); - assertThat(measuresFromDB).hasSize(1); - - Gson gson = new Gson(); - Map<String, Object> jsonValue = gson.fromJson((String) measuresFromDB.get(0).get("json_value"), Map.class); - - Map<String, Object> expectedExistingMetrics = MeasureMigration.MIGRATION_MAP.keySet().stream().collect( - Collectors.toMap(s -> s, s -> "{\"LOW\":3,\"MEDIUM\":0,\"HIGH\":4,\"total\":7}")); - - Map<String, Object> expectedNewMetrics = MeasureMigration.MIGRATION_MAP.values().stream().collect( - Collectors.toMap(s -> s, s -> 7.0)); - - assertThat(jsonValue).containsAllEntriesOf(expectedExistingMetrics).containsAllEntriesOf(expectedNewMetrics); - } - - @Test - void should_migrate_other_measures_when_there_is_an_error_converting_previous_measures() throws SQLException { - String nclocMetricUuid = insertMetric("ncloc", "INT"); - String maintainabilityMetricUuid = insertMetric(CoreMetrics.MAINTAINABILITY_ISSUES_KEY, "DATA"); - String reliabilityMetricUuid = insertMetric(CoreMetrics.RELIABILITY_ISSUES_KEY, "DATA"); - String securityMetricUuid = insertMetric(CoreMetrics.SECURITY_ISSUES_KEY, "DATA"); - - String branch = "branch_4"; - insertNotMigratedBranch(branch); - String component1 = uuidFactory.create(); - insertMeasure(branch, component1, nclocMetricUuid, Map.of("value", 120)); - // total is not a number - insertMeasure(branch, component1, maintainabilityMetricUuid, Map.of("measure_data", "{\"LOW\":3,\"MEDIUM\":0,\"HIGH\":4,\"total\":\"ABC\"}" - .getBytes(StandardCharsets.UTF_8))); - // total cannot fit in a long - insertMeasure(branch, component1, reliabilityMetricUuid, Map.of("measure_data", "{\"LOW\":3,\"MEDIUM\":0,\"HIGH\":4,\"total\":98723987498723987429874928748748}" - .getBytes(StandardCharsets.UTF_8))); - insertMeasure(branch, component1, securityMetricUuid, Map.of("measure_data", "{\"LOW\":3,\"MEDIUM\":0,\"HIGH\":4,\"total\":37}".getBytes(StandardCharsets.UTF_8))); - - logTester.setLevel(Level.DEBUG); - underTest.execute(); - - assertBranchMigrated(branch); - assertThat(db.countRowsOfTable("measures")).isEqualTo(1); - - List<Map<String, Object>> measuresFromDB = db.select(format(SELECT_MEASURE, component1)); - assertThat(measuresFromDB).hasSize(1); - - Gson gson = new Gson(); - Map<String, Object> jsonValue = gson.fromJson((String) measuresFromDB.get(0).get("json_value"), Map.class); - - Map<String, Object> expectedExistingMetrics = Map.of( - "ncloc", 120.0, - CoreMetrics.MAINTAINABILITY_ISSUES_KEY, "{\"LOW\":3,\"MEDIUM\":0,\"HIGH\":4,\"total\":\"ABC\"}", - CoreMetrics.RELIABILITY_ISSUES_KEY, "{\"LOW\":3,\"MEDIUM\":0,\"HIGH\":4,\"total\":98723987498723987429874928748748}", - CoreMetrics.SECURITY_ISSUES_KEY, "{\"LOW\":3,\"MEDIUM\":0,\"HIGH\":4,\"total\":37}"); - - Map<String, Object> expectedNewMetrics = Map.of(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_ISSUES_KEY, 37.0); - - assertThat(jsonValue).hasSize(5).containsAllEntriesOf(expectedExistingMetrics).containsAllEntriesOf(expectedNewMetrics); - assertThat(logTester.logs(Level.DEBUG)).contains("Failed to migrate metric reliability_issues with value {\"LOW\":3,\"MEDIUM\":0," + - "\"HIGH\":4,\"total\":98723987498723987429874928748748}"); - } - - @Test - void should_not_migrate_large_measures() throws SQLException { - String nclocMetricUuid = insertMetric("ncloc", "INT"); - String metricWithDataUuid = insertMetric("metric_with_data", "DATA"); - String metricWithLargeDataUuid = insertMetric("metric_with_large_data", "DATA"); - - String branch1 = "branch_1"; - insertNotMigratedBranch(branch1); - String component1 = uuidFactory.create(); - insertMeasure(branch1, component1, nclocMetricUuid, Map.of("value", 120)); - byte[] largeValue = createLargeValue(999_999); - insertMeasure(branch1, component1, metricWithDataUuid, Map.of("measure_data", largeValue)); - insertMeasure(branch1, component1, metricWithLargeDataUuid, Map.of("measure_data", createLargeValue(1_000_000))); - - underTest.execute(); - - assertBranchMigrated(branch1); - assertThat(db.countRowsOfTable("measures")).isEqualTo(1); - - assertThat(db.select(format(SELECT_MEASURE, component1))) - .hasSize(1) - .extracting(t -> t.get("component_uuid"), t -> t.get("branch_uuid"), - t -> t.get("json_value"), t -> t.get("json_value_hash")) - .containsOnly(tuple(component1, branch1, "{\"ncloc\":120.0,\"metric_with_data\":\"" + - new String(largeValue, StandardCharsets.UTF_8) + "\"}", -8442559321192521885L)); - } - - @Test - void should_not_migrate_not_persisted_metrics() throws SQLException { - String devCostMetricUuid = insertMetric(CoreMetrics.DEVELOPMENT_COST_KEY, "STRING"); - String nclocDataMetricUuid = insertMetric(CoreMetrics.NCLOC_DATA_KEY, "STRING"); - String executableLinesDataMetricUuid = insertMetric(CoreMetrics.EXECUTABLE_LINES_DATA_KEY, "STRING"); - - String branch1 = "branch_1"; - insertNotMigratedBranch(branch1); - String component1 = uuidFactory.create(); - insertMeasure(branch1, component1, devCostMetricUuid, Map.of("text_value", "123")); - insertMeasure(branch1, component1, nclocDataMetricUuid, Map.of("text_value", "456")); - insertMeasure(branch1, component1, executableLinesDataMetricUuid, Map.of("text_value", "789")); - - underTest.execute(); - - assertBranchMigrated(branch1); - assertThat(db.countRowsOfTable("measures")).isEqualTo(1); - - assertThat(db.select(format(SELECT_MEASURE, component1))) - .hasSize(1) - .extracting(t -> t.get("component_uuid"), t -> t.get("branch_uuid"), - t -> t.get("json_value"), t -> t.get("json_value_hash")) - .containsOnly(tuple(component1, branch1, "{\"development_cost\":\"123\"}", -4081454374503046534L)); - } - - private byte[] createLargeValue(int size) { - byte[] value = new byte[size]; - Arrays.fill(value, (byte) 'a'); - return value; - } - - private void assertBranchMigrated(String branch) { - List<Map<String, Object>> result = db.select(format("select %s as \"MIGRATED\" from project_branches where uuid = '%s'", MEASURES_MIGRATED_COLUMN, branch)); - assertThat(result) - .hasSize(1) - .extracting(t -> t.get("MIGRATED")) - .containsOnly(true); - } - - private String insertMetric(String metricName, String valueType) { - String metricUuid = uuidFactory.create(); - db.executeInsert("metrics", - "uuid", metricUuid, - "name", metricName, - "val_type", valueType); - return metricUuid; - } - - private void insertMeasure(String branchUuid, String metricUuid, Map<String, Object> data) { - insertMeasure(branchUuid, uuidFactory.create(), metricUuid, data); - } - - private void insertMeasure(String branchUuid, String componentUuid, String metricUuid, Map<String, Object> data) { - Map<String, Object> dataMap = new HashMap<>(data); - dataMap.put("uuid", uuidFactory.create()); - dataMap.put("component_uuid", componentUuid); - dataMap.put("project_uuid", branchUuid); - dataMap.put("metric_uuid", metricUuid); - dataMap.put("created_at", 12L); - dataMap.put("updated_at", 12L); - - db.executeInsert("live_measures", dataMap); - } - - private void insertNotMigratedBranch(String branchUuid) { - insertBranch(branchUuid, false); - } - - private void insertMigratedBranch(String branchUuid) { - insertBranch(branchUuid, true); - } - - private void insertBranch(String branchUuid, boolean migrated) { - db.executeInsert("project_branches", - "uuid", branchUuid, - "kee", branchUuid, - "branch_type", "LONG", - "project_uuid", uuidFactory.create(), - MEASURES_MIGRATED_COLUMN, migrated, - "need_issue_sync", false, - "is_main", true, - "created_at", 12L, - "updated_at", 12L); - } - -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/MigratePortfoliosLiveMeasuresToMeasuresIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/MigratePortfoliosLiveMeasuresToMeasuresIT.java deleted file mode 100644 index f0a197af534..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/MigratePortfoliosLiveMeasuresToMeasuresIT.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.nio.charset.StandardCharsets; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.slf4j.event.Level; -import org.sonar.api.testfixtures.log.LogTesterJUnit5; -import org.sonar.api.utils.System2; -import org.sonar.core.util.SequenceUuidFactory; -import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DataChange; - -import static java.lang.String.format; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.tuple; -import static org.mockito.Mockito.mock; - -class MigratePortfoliosLiveMeasuresToMeasuresIT { - - private static final String MEASURES_MIGRATED_COLUMN = "measures_migrated"; - public static final String SELECT_MEASURE = "select component_uuid, branch_uuid, json_value, json_value_hash, created_at, updated_at " + - "from measures where component_uuid = '%s'"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(MigratePortfoliosLiveMeasuresToMeasures.class); - - @RegisterExtension - private final LogTesterJUnit5 logTester = new LogTesterJUnit5(); - - private final SequenceUuidFactory uuidFactory = new SequenceUuidFactory(); - private final System2 system2 = mock(); - private final DataChange underTest = new MigratePortfoliosLiveMeasuresToMeasures(db.database(), system2); - - @Test - void shall_complete_when_tables_are_empty() throws SQLException { - underTest.execute(); - - assertThat(db.countRowsOfTable("measures")).isZero(); - } - - @Test - void migration_does_nothing_if_live_measures_table_is_missing() { - db.executeDdl("drop table live_measures"); - db.assertTableDoesNotExist("live_measures"); - String branch = "portfolio_1"; - insertNotMigratedPortfolio(branch); - - assertThatCode(underTest::execute) - .doesNotThrowAnyException(); - } - - @Test - void log_the_item_uuid_when_the_migration_fails() { - String nclocMetricUuid = insertMetric("ncloc", "INT"); - String portfolio = "portfolio_1"; - insertNotMigratedPortfolio(portfolio); - insertMeasure(portfolio, nclocMetricUuid, Map.of("value", 120)); - - db.executeDdl("drop table measures"); - db.assertTableDoesNotExist("measures"); - - assertThatExceptionOfType(SQLException.class) - .isThrownBy(underTest::execute); - - assertThat(logTester.logs(Level.ERROR)) - .contains("Migration of portfolio portfolio_1 failed"); - } - - @Test - void shall_not_migrate_when_portfolio_is_already_flagged() throws SQLException { - String nclocMetricUuid = insertMetric("ncloc", "INT"); - String qgStatusMetricUuid = insertMetric("quality_gate_status", "STRING"); - String metricWithDataUuid = insertMetric("metric_with_data", "DATA"); - String portfolio1 = "portfolio_1"; - insertMigratedPortfolio(portfolio1); - insertMeasure(portfolio1, nclocMetricUuid, Map.of("value", 120)); - insertMeasure(portfolio1, qgStatusMetricUuid, Map.of("text_value", "ok")); - insertMeasure(portfolio1, metricWithDataUuid, Map.of("measure_data", "some data".getBytes(StandardCharsets.UTF_8))); - - insertMigratedPortfolio("portfolio_2"); - insertMeasure("portfolio_2", nclocMetricUuid, Map.of("value", 14220)); - - underTest.execute(); - - assertThat(db.countRowsOfTable("measures")).isZero(); - } - - @Test - void should_flag_portfolio_with_no_measures() throws SQLException { - String portfolio = "portfolio_3"; - insertNotMigratedPortfolio(portfolio); - - underTest.execute(); - - assertPortfolioMigrated(portfolio); - assertThat(db.countRowsOfTable("measures")).isZero(); - } - - @Test - void should_migrate_portfolio_with_measures() throws SQLException { - String nclocMetricUuid = insertMetric("ncloc", "INT"); - String qgStatusMetricUuid = insertMetric("quality_gate_status", "STRING"); - String metricWithDataUuid = insertMetric("metric_with_data", "DATA"); - - String portfolio1 = "portfolio_4"; - insertNotMigratedPortfolio(portfolio1); - String component1 = uuidFactory.create(); - String component2 = uuidFactory.create(); - insertMeasure(portfolio1, component1, nclocMetricUuid, Map.of("value", 120)); - insertMeasure(portfolio1, component1, qgStatusMetricUuid, Map.of("text_value", "ok")); - insertMeasure(portfolio1, component2, metricWithDataUuid, Map.of("measure_data", "some data".getBytes(StandardCharsets.UTF_8))); - - String portfolio2 = "portfolio_5"; - insertNotMigratedPortfolio(portfolio2); - insertMeasure(portfolio2, nclocMetricUuid, Map.of("value", 64)); - - String migratedPortfolio = "portfolio_6"; - insertMigratedPortfolio(migratedPortfolio); - insertMeasure(migratedPortfolio, nclocMetricUuid, Map.of("value", 3684)); - - underTest.execute(); - - assertPortfolioMigrated(portfolio1); - assertPortfolioMigrated(portfolio2); - assertThat(db.countRowsOfTable("measures")).isEqualTo(3); - - assertThat(db.select(format(SELECT_MEASURE, component1))) - .hasSize(1) - .extracting(t -> t.get("component_uuid"), t -> t.get("branch_uuid"), t -> t.get("json_value"), t -> t.get("json_value_hash")) - .containsOnly(tuple(component1, portfolio1, "{\"ncloc\":120.0,\"quality_gate_status\":\"ok\"}", 6033012287291512746L)); - - assertThat(db.select(format(SELECT_MEASURE, component2))) - .hasSize(1) - .extracting(t -> t.get("component_uuid"), t -> t.get("branch_uuid"), t -> t.get("json_value"), t -> t.get("json_value_hash")) - .containsOnly(tuple(component2, portfolio1, "{\"metric_with_data\":\"some data\"}", -4524184678167636687L)); - } - - @Test - void should_not_migrate_measures_planned_for_deletion() throws SQLException { - String nclocMetricUuid = insertMetric("ncloc", "INT"); - Set<String> deletedMetricUuid = DeleteSoftwareQualityRatingFromProjectMeasures.SOFTWARE_QUALITY_METRICS_TO_DELETE.stream().map(e -> insertMetric(e, "INT")) - .collect(Collectors.toSet()); - - String portfolio1 = "portfolio_4"; - insertNotMigratedPortfolio(portfolio1); - String component1 = uuidFactory.create(); - String component2 = uuidFactory.create(); - insertMeasure(portfolio1, component1, nclocMetricUuid, Map.of("value", 120)); - deletedMetricUuid.forEach(metricUuid -> insertMeasure(portfolio1, component1, metricUuid, Map.of("value", 120))); - deletedMetricUuid.forEach(metricUuid -> insertMeasure(portfolio1, component2, metricUuid, Map.of("value", 120))); - - underTest.execute(); - - assertPortfolioMigrated(portfolio1); - - assertThat(db.select(format(SELECT_MEASURE, component1))) - .hasSize(1) - .extracting(t -> t.get("component_uuid"), t -> t.get("branch_uuid"), t -> t.get("json_value"), t -> t.get("json_value_hash")) - .containsOnly(tuple(component1, portfolio1, "{\"ncloc\":120.0}", -1557106439558598045L)); - } - - private void assertPortfolioMigrated(String portfolio) { - List<Map<String, Object>> result = db.select(format("select %s as \"MIGRATED\" from portfolios where uuid = '%s'", MEASURES_MIGRATED_COLUMN, portfolio)); - assertThat(result) - .hasSize(1) - .extracting(t -> t.get("MIGRATED")) - .containsOnly(true); - } - - private String insertMetric(String metricName, String valueType) { - String metricUuid = uuidFactory.create(); - db.executeInsert("metrics", - "uuid", metricUuid, - "name", metricName, - "val_type", valueType); - return metricUuid; - } - - private void insertMeasure(String portfolioUuid, String metricUuid, Map<String, Object> data) { - insertMeasure(portfolioUuid, uuidFactory.create(), metricUuid, data); - } - - private void insertMeasure(String portfolioUuid, String componentUuid, String metricUuid, Map<String, Object> data) { - Map<String, Object> dataMap = new HashMap<>(data); - dataMap.put("uuid", uuidFactory.create()); - dataMap.put("component_uuid", componentUuid); - dataMap.put("project_uuid", portfolioUuid); - dataMap.put("metric_uuid", metricUuid); - dataMap.put("created_at", 12L); - dataMap.put("updated_at", 12L); - - db.executeInsert("live_measures", dataMap); - } - - private void insertNotMigratedPortfolio(String portfolioUuid) { - insertPortfolio(portfolioUuid, false); - } - - private void insertMigratedPortfolio(String portfolioUuid) { - insertPortfolio(portfolioUuid, true); - } - - private void insertPortfolio(String portfolioUuid, boolean migrated) { - db.executeInsert("portfolios", - "uuid", portfolioUuid, - "kee", portfolioUuid, - "name", portfolioUuid, - "private", true, - "root_uuid", portfolioUuid, - "selection_mode", "MANUAL", - MEASURES_MIGRATED_COLUMN, migrated, - "created_at", 12L, - "updated_at", 12L); - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/MigrateProjectMeasuresDeprecatedMetricsTest.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/MigrateProjectMeasuresDeprecatedMetricsTest.java deleted file mode 100644 index a38a693cb3f..00000000000 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/MigrateProjectMeasuresDeprecatedMetricsTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Collectors; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.core.util.UuidFactoryImpl; -import org.sonar.db.MigrationDbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.measures.CoreMetrics.MAINTAINABILITY_ISSUES_KEY; -import static org.sonar.api.measures.CoreMetrics.NEW_MAINTAINABILITY_ISSUES_KEY; -import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_ISSUES_KEY; -import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_ISSUES_KEY; -import static org.sonar.api.measures.CoreMetrics.RELIABILITY_ISSUES_KEY; -import static org.sonar.api.measures.CoreMetrics.SECURITY_ISSUES_KEY; -import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY; -import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY; -import static org.sonar.core.metric.SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_ISSUES_KEY; -import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY; -import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY; -import static org.sonar.core.metric.SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_ISSUES_KEY; -import static org.sonar.server.platform.db.migration.version.v108.MeasureMigration.MIGRATION_MAP; - -class MigrateProjectMeasuresDeprecatedMetricsTest { - private static final String ANALYSIS_UUID_1 = UuidFactoryImpl.INSTANCE.create(); - private static final String ANALYSIS_UUID_2 = UuidFactoryImpl.INSTANCE.create(); - @RegisterExtension - private final MigrationDbTester db = MigrationDbTester.createForMigrationStep(MigrateProjectMeasuresDeprecatedMetrics.class); - private final MigrateProjectMeasuresDeprecatedMetrics underTest = new MigrateProjectMeasuresDeprecatedMetrics(db.database(), - UuidFactoryImpl.INSTANCE); - private Map<String, String> metricsToMigrate; - private Map<String, String> replacementMetrics; - - @BeforeEach - void init() { - metricsToMigrate = insertMetricsToMigrate(); - replacementMetrics = insertReplacementMetrics(); - } - - @Test - void execute_shouldCreateNewMetrics() throws SQLException { - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "1"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "3"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "5"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "11"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "13"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "15"); - underTest.execute(); - - assertThat(db.select("select metric_uuid, value from project_measures where metric_uuid in (%s)" - .formatted(replacementMetrics.values().stream().map(s -> "'" + s + "'").collect(Collectors.joining(","))))) - .hasSize(6) - .map(m -> Map.of("metric_uuid", m.get("metric_uuid"), "value", ((Number) m.get("value")).longValue())) - .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 1L))) - .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY), "value", 3L))) - .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_SECURITY_ISSUES_KEY), "value", 5L))) - .contains((Map.of("metric_uuid", replacementMetrics.get(NEW_SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 11L))) - .contains((Map.of("metric_uuid", replacementMetrics.get(NEW_SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY), "value", 13L))) - .contains((Map.of("metric_uuid", replacementMetrics.get(NEW_SOFTWARE_QUALITY_SECURITY_ISSUES_KEY), "value", 15L))); - } - - @Test - void execute_shouldBeReentrant() throws SQLException { - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "1"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "3"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "5"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "11"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "13"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(NEW_SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "15"); - underTest.execute(); - underTest.execute(); - assertThat(db.select("select * from project_measures")) - .hasSize(MIGRATION_MAP.size() * 2); - } - - @Test - void execute_whenValueCannotBeConverted_shouldCreateOtherNewMetrics() throws SQLException { - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "1"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(RELIABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "NOT_VALID_NUMBER"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(SECURITY_ISSUES_KEY), ANALYSIS_UUID_1, "5"); - underTest.execute(); - - assertThat(db.select("select metric_uuid, value from project_measures where metric_uuid in (%s)" - .formatted(replacementMetrics.values().stream().map(s -> "'" + s + "'").collect(Collectors.joining(","))))) - .hasSize(2) - .map(m -> Map.of("metric_uuid", m.get("metric_uuid"), "value", ((Number) m.get("value")).longValue())) - .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 1L))) - .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_SECURITY_ISSUES_KEY), "value", 5L))); - } - - @Test - void execute_whenWasPartiallyMigrated_shouldContinueWithOtherAnalysis() throws SQLException { - - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, "1"); - createProjectMeasureForNewMetric(replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_1, 1); - - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(MAINTAINABILITY_ISSUES_KEY), ANALYSIS_UUID_2, "4"); - createProjectMeasureForDeprecatedMetric(metricsToMigrate.get(SECURITY_ISSUES_KEY), ANALYSIS_UUID_2, "5"); - underTest.execute(); - - assertThat(db.select("select metric_uuid, value, analysis_uuid from project_measures where metric_uuid in (%s)" - .formatted(replacementMetrics.values().stream().map(s -> "'" + s + "'").collect(Collectors.joining(","))))) - .hasSize(3) - .map(m -> Map.of("metric_uuid", m.get("metric_uuid"), "value", ((Number) m.get("value")).longValue(), "analysis_uuid", m.get("analysis_uuid"))) - .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 1L, "analysis_uuid", ANALYSIS_UUID_1))) - .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY), "value", 4L, "analysis_uuid", ANALYSIS_UUID_2))) - .contains((Map.of("metric_uuid", replacementMetrics.get(SOFTWARE_QUALITY_SECURITY_ISSUES_KEY), "value", 5L, "analysis_uuid", - ANALYSIS_UUID_2))); - } - - private void createProjectMeasureForDeprecatedMetric(String metricUuid, String analysisUuid, String totalIssues) { - String uuid = UuidFactoryImpl.INSTANCE.create(); - Map<String, Object> map = Map.ofEntries( - Map.entry("UUID", uuid), - Map.entry("TEXT_VALUE", "{\"LOW\":X,\"MEDIUM\":Y,\"HIGH\":Z,\"total\":" + totalIssues + "}"), - Map.entry("ANALYSIS_UUID", analysisUuid), - Map.entry("METRIC_UUID", metricUuid), - Map.entry("COMPONENT_UUID", UuidFactoryImpl.INSTANCE.create())); - db.executeInsert("project_measures", map); - } - - private void createProjectMeasureForNewMetric(String metricUuid, String analysisUuid, int totalIssues) { - String uuid = UuidFactoryImpl.INSTANCE.create(); - Map<String, Object> map = Map.ofEntries( - Map.entry("UUID", uuid), - Map.entry("VALUE", totalIssues), - Map.entry("ANALYSIS_UUID", analysisUuid), - Map.entry("METRIC_UUID", metricUuid), - Map.entry("COMPONENT_UUID", UuidFactoryImpl.INSTANCE.create())); - db.executeInsert("project_measures", map); - } - - private Map<String, String> insertMetricsToMigrate() { - Map<String, String> createdMetrics = new HashMap<>(); - MIGRATION_MAP.keySet().forEach(metricKey -> createdMetrics.put(metricKey, insertMetric(metricKey))); - return createdMetrics; - } - - private Map<String, String> insertReplacementMetrics() { - Map<String, String> createdMetrics = new HashMap<>(); - MIGRATION_MAP.values().forEach(metricKey -> createdMetrics.put(metricKey, insertMetric(metricKey))); - return createdMetrics; - } - - private String insertMetric(String key) { - String uuid = UuidFactoryImpl.INSTANCE.create(); - Map<String, Object> map = Map.ofEntries( - Map.entry("UUID", uuid), - Map.entry("NAME", key)); - db.executeInsert("metrics", map); - return uuid; - } -} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/MakeColumnUserLocalNotNullableInUsersIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/AddNewInPullRequestToScaDependenciesTableIT.java index 3cf711ebcdf..4cd230a13fc 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/MakeColumnUserLocalNotNullableInUsersIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/AddNewInPullRequestToScaDependenciesTableIT.java @@ -17,33 +17,35 @@ * 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.platform.db.migration.version.v100; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; +import org.sonar.server.platform.db.migration.step.DdlChange; import static java.sql.Types.BOOLEAN; +import static org.sonar.db.MigrationDbTester.createForMigrationStep; -class MakeColumnUserLocalNotNullableInUsersIT { - private static final String TABLE_NAME = "users"; - private static final String COLUMN_NAME = "user_local"; +class AddNewInPullRequestToScaDependenciesTableIT { + private static final String TABLE_NAME = "sca_dependencies"; + private static final String COLUMN_NAME = "new_in_pull_request"; @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(MakeColumnUserLocalNotNullableInUsers.class); - private final MakeColumnUserLocalNotNullableInUsers underTest = new MakeColumnUserLocalNotNullableInUsers(db.database()); + public final MigrationDbTester db = createForMigrationStep(AddNewInPullRequestToScaDependenciesTable.class); + private final DdlChange underTest = new AddNewInPullRequestToScaDependenciesTable(db.database()); @Test - void user_local_column_is_not_null() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, true); + void execute_shouldAddColumn() throws SQLException { + db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); underTest.execute(); db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, false); } @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, true); + void execute_shouldBeReentrant() throws SQLException { + db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); underTest.execute(); underTest.execute(); db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, false); diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateBooleanPurgedColumnInSnapshotsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/AddNewInPullRequestToScaReleasesTableIT.java index 95755bbcec9..6374d67709d 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/CreateBooleanPurgedColumnInSnapshotsIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/AddNewInPullRequestToScaReleasesTableIT.java @@ -17,37 +17,37 @@ * 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.platform.db.migration.version.v102; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; +import org.sonar.server.platform.db.migration.step.DdlChange; import static java.sql.Types.BOOLEAN; +import static org.sonar.db.MigrationDbTester.createForMigrationStep; -class CreateBooleanPurgedColumnInSnapshotsIT { - - private static final String TABLE_NAME = "snapshots"; - private static final String COLUMN_NAME = "purged"; +class AddNewInPullRequestToScaReleasesTableIT { + private static final String TABLE_NAME = "sca_releases"; + private static final String COLUMN_NAME = "new_in_pull_request"; @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateBooleanPurgedColumnInSnapshots.class); - - private final CreateBooleanPurgedColumnInSnapshots underTest = new CreateBooleanPurgedColumnInSnapshots(db.database()); + public final MigrationDbTester db = createForMigrationStep(AddNewInPullRequestToScaReleasesTable.class); + private final DdlChange underTest = new AddNewInPullRequestToScaReleasesTable(db.database()); @Test - void execute_whenColumnDoesNotExist_shouldCreatePurgedColumn() throws SQLException { + void execute_shouldAddColumn() throws SQLException { db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, null); + db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, false); } @Test - void execute_whenExecutedTwice_shouldNotFail() throws SQLException { + void execute_shouldBeReentrant() throws SQLException { db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); underTest.execute(); underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, null); + db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, false); } } diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AddIsMainColumnInProjectBranchesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/AddProductionScopeToScaDependenciesTableIT.java index 05a62aa1c07..8ed2cb41454 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AddIsMainColumnInProjectBranchesIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/AddProductionScopeToScaDependenciesTableIT.java @@ -17,36 +17,37 @@ * 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.platform.db.migration.version.v101; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; +import org.sonar.server.platform.db.migration.step.DdlChange; import static java.sql.Types.BOOLEAN; +import static org.sonar.db.MigrationDbTester.createForMigrationStep; -class AddIsMainColumnInProjectBranchesIT { - - private static final String TABLE_NAME = "project_branches"; - private static final String COLUMN_NAME = "is_main"; +class AddProductionScopeToScaDependenciesTableIT { + private static final String TABLE_NAME = "sca_dependencies"; + private static final String COLUMN_NAME = "production_scope"; @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddIsMainColumnInProjectBranches.class); - private final AddIsMainColumnInProjectBranches underTest = new AddIsMainColumnInProjectBranches(db.database()); + public final MigrationDbTester db = createForMigrationStep(AddProductionScopeToScaDependenciesTable.class); + private final DdlChange underTest = new AddProductionScopeToScaDependenciesTable(db.database()); @Test - void is_main_column_exists_with_null_value() throws SQLException { + void execute_shouldAddColumn() throws SQLException { db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, null); + db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, false); } @Test - void migration_is_reentrant() throws SQLException { + void execute_shouldBeReentrant() throws SQLException { db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); underTest.execute(); underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, null); + db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, BOOLEAN, null, false); } } diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AddReportSchedulesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateArchitectureGraphsTableIT.java index ef2fc8cd56f..0e1c8670f2c 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v101/AddReportSchedulesTableIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateArchitectureGraphsTableIT.java @@ -17,49 +17,40 @@ * 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.platform.db.migration.version.v101; +package org.sonar.server.platform.db.migration.version.v202502; + +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; import java.sql.SQLException; import java.sql.Types; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; -import org.sonar.server.platform.db.migration.step.DdlChange; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.version.v101.AddReportSchedulesTable.TABLE_NAME; +class CreateArchitectureGraphsTableIT { + public static final String TABLE_NAME = "architecture_graphs"; -class AddReportSchedulesTableIT { @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddReportSchedulesTable.class); - - private final DdlChange underTest = new AddReportSchedulesTable(db.database()); + public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateArchitectureGraphsTable.class); + private final CreateArchitectureGraphsTable underTest = new CreateArchitectureGraphsTable(db.database()); @Test - void migration_should_create_a_table() throws SQLException { + void execute_shouldCreateTable() throws SQLException { db.assertTableDoesNotExist(TABLE_NAME); - underTest.execute(); - db.assertTableExists(TABLE_NAME); db.assertColumnDefinition(TABLE_NAME, "uuid", Types.VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, "portfolio_uuid", Types.VARCHAR, UUID_SIZE, true); - db.assertColumnDefinition(TABLE_NAME, "branch_uuid", Types.VARCHAR, UUID_SIZE, true); - db.assertColumnDefinition(TABLE_NAME, "last_send_time_in_ms", Types.BIGINT, null, false); - db.assertPrimaryKey(TABLE_NAME, "pk_report_schedules", "uuid"); - + db.assertColumnDefinition(TABLE_NAME, "branch_uuid", Types.VARCHAR, UUID_SIZE, false); + db.assertColumnDefinition(TABLE_NAME, "source", Types.VARCHAR, 255, false); + db.assertColumnDefinition(TABLE_NAME, "type", Types.VARCHAR, 255, false); + db.assertColumnDefinition(TABLE_NAME, "graph_data", Types.CLOB, null, false); } @Test - void migration_should_be_reentrant() throws SQLException { + void execute_shouldSupportReentrantMigrationExecution() throws SQLException { db.assertTableDoesNotExist(TABLE_NAME); - underTest.execute(); - // re-entrant underTest.execute(); - db.assertTableExists(TABLE_NAME); } - - } diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnArchitectureGraphsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnArchitectureGraphsIT.java new file mode 100644 index 00000000000..cc1d462e536 --- /dev/null +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnArchitectureGraphsIT.java @@ -0,0 +1,55 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.db.migration.version.v202502; + +import java.sql.SQLException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.sonar.db.MigrationDbTester; +import org.sonar.server.platform.db.migration.step.DdlChange; + +import static org.sonar.db.MigrationDbTester.createForMigrationStep; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnArchitectureGraphs.COLUMN_NAME_BRANCH_UUID; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnArchitectureGraphs.COLUMN_NAME_SOURCE; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnArchitectureGraphs.COLUMN_NAME_TYPE; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnArchitectureGraphs.INDEX_NAME; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnArchitectureGraphs.TABLE_NAME; + +class CreateIndexOnArchitectureGraphsIT { + + @RegisterExtension + public final MigrationDbTester db = createForMigrationStep(CreateUniqueIndexOnArchitectureGraphs.class); + private final DdlChange underTest = new CreateUniqueIndexOnArchitectureGraphs(db.database()); + + @Test + void execute_shouldCreateIndex() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + underTest.execute(); + db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_BRANCH_UUID, COLUMN_NAME_TYPE, COLUMN_NAME_SOURCE); + } + + @Test + void execute_shouldBeReentrant() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + underTest.execute(); + underTest.execute(); + db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_BRANCH_UUID, COLUMN_NAME_TYPE, COLUMN_NAME_SOURCE); + } +} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/CreateUniqueIndexForScimGroupsUuidIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaDependenciesReleaseIT.java index f9af83bd81a..5791894be9c 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/CreateUniqueIndexForScimGroupsUuidIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaDependenciesReleaseIT.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v100; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.junit.jupiter.api.Test; @@ -25,31 +25,28 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; import org.sonar.server.platform.db.migration.step.DdlChange; -import static org.sonar.server.platform.db.migration.version.v100.CreateScimGroupsTable.TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v100.CreateUniqueIndexForScimGroupsUuid.COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v100.CreateUniqueIndexForScimGroupsUuid.INDEX_NAME; +import static org.sonar.db.MigrationDbTester.createForMigrationStep; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaDependenciesRelease.COLUMN_NAME_SCA_RELEASE_UUID; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaDependenciesRelease.INDEX_NAME; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaDependenciesRelease.TABLE_NAME; -class CreateUniqueIndexForScimGroupsUuidIT { +class CreateIndexOnScaDependenciesReleaseIT { @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(CreateUniqueIndexForScimGroupsUuid.class); - private final DdlChange underTest = new CreateUniqueIndexForScimGroupsUuid(db.database()); + public final MigrationDbTester db = createForMigrationStep(CreateIndexOnScaDependenciesRelease.class); + private final DdlChange underTest = new CreateIndexOnScaDependenciesRelease(db.database()); @Test - void migration_should_create_index() throws SQLException { + void execute_shouldCreateIndex() throws SQLException { db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - underTest.execute(); - - db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_SCA_RELEASE_UUID); } @Test - void migration_should_be_reentrant() throws SQLException { + void execute_shouldBeReentrant() throws SQLException { db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); - underTest.execute(); underTest.execute(); - - db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_SCA_RELEASE_UUID); } } diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexOnMainBranchProjectUuidIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaIssuesReleasesScaIssueUuidIT.java index 94972bcb48e..6d52822cade 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexOnMainBranchProjectUuidIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaIssuesReleasesScaIssueUuidIT.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v102; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.junit.jupiter.api.Test; @@ -25,27 +25,28 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; import org.sonar.server.platform.db.migration.step.DdlChange; -class DropIndexOnMainBranchProjectUuidIT { - private static final String TABLE_NAME = "components"; - private static final String COLUMN_NAME = "main_branch_project_uuid"; - private static final String INDEX_NAME = "idx_main_branch_prj_uuid"; +import static org.sonar.db.MigrationDbTester.createForMigrationStep; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaIssuesReleasesScaIssueUuid.COLUMN_NAME_SCA_ISSUE_UUID; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaIssuesReleasesScaIssueUuid.INDEX_NAME; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaIssuesReleasesScaIssueUuid.TABLE_NAME; +class CreateIndexOnScaIssuesReleasesScaIssueUuidIT { @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropIndexOnMainBranchProjectUuid.class); - private final DdlChange underTest = new DropIndexOnMainBranchProjectUuid(db.database()); + public final MigrationDbTester db = createForMigrationStep(CreateIndexOnScaIssuesReleasesScaIssueUuid.class); + private final DdlChange underTest = new CreateIndexOnScaIssuesReleasesScaIssueUuid(db.database()); @Test - void drops_index() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - underTest.execute(); + void execute_shouldCreateIndex() throws SQLException { db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + underTest.execute(); + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_SCA_ISSUE_UUID); } @Test - void migration_is_reentrant() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); + void execute_shouldBeReentrant() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); underTest.execute(); underTest.execute(); - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_SCA_ISSUE_UUID); } } diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaIssuesReleasesScaReleaseUuidIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaIssuesReleasesScaReleaseUuidIT.java new file mode 100644 index 00000000000..143ac8c8a45 --- /dev/null +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaIssuesReleasesScaReleaseUuidIT.java @@ -0,0 +1,52 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.db.migration.version.v202502; + +import java.sql.SQLException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.sonar.db.MigrationDbTester; +import org.sonar.server.platform.db.migration.step.DdlChange; + +import static org.sonar.db.MigrationDbTester.createForMigrationStep; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaIssuesReleasesScaReleaseUuid.COLUMN_NAME_SCA_RELEASE_UUID; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaIssuesReleasesScaReleaseUuid.INDEX_NAME; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaIssuesReleasesScaReleaseUuid.TABLE_NAME; + +class CreateIndexOnScaIssuesReleasesScaReleaseUuidIT { + @RegisterExtension + public final MigrationDbTester db = createForMigrationStep(CreateIndexOnScaIssuesReleasesScaReleaseUuid.class); + private final DdlChange underTest = new CreateIndexOnScaIssuesReleasesScaReleaseUuid(db.database()); + + @Test + void execute_shouldCreateIndex() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + underTest.execute(); + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_SCA_RELEASE_UUID); + } + + @Test + void execute_shouldBeReentrant() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + underTest.execute(); + underTest.execute(); + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_SCA_RELEASE_UUID); + } +} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropIndexProjectsRootUuidInComponentsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaReleasesComponentIT.java index 2d1216f19cf..8c9514474ac 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v100/DropIndexProjectsRootUuidInComponentsIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaReleasesComponentIT.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v100; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.junit.jupiter.api.Test; @@ -25,27 +25,28 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; import org.sonar.server.platform.db.migration.step.DdlChange; -class DropIndexProjectsRootUuidInComponentsIT { - private static final String TABLE_NAME = "components"; - private static final String COLUMN_NAME = "root_uuid"; - private static final String INDEX_NAME = "projects_root_uuid"; +import static org.sonar.db.MigrationDbTester.createForMigrationStep; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaReleasesComponent.INDEX_NAME; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaReleasesComponent.TABLE_NAME; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaReleasesComponent.COLUMN_NAME_COMPONENT_UUID; +class CreateIndexOnScaReleasesComponentIT { @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropIndexProjectsRootUuidInComponents.class); - private final DdlChange underTest = new DropIndexProjectsRootUuidInComponents(db.database()); + public final MigrationDbTester db = createForMigrationStep(CreateIndexOnScaReleasesComponent.class); + private final DdlChange underTest = new CreateIndexOnScaReleasesComponent(db.database()); @Test - void drops_index() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); - underTest.execute(); + void execute_shouldCreateIndex() throws SQLException { db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + underTest.execute(); + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_COMPONENT_UUID); } @Test - void migration_is_reentrant() throws SQLException { - db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME); + void execute_shouldBeReentrant() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); underTest.execute(); underTest.execute(); - db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_COMPONENT_UUID); } } diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/AlterCveColumnsToNullableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaReleasesComponentUuidTest.java index f7f18ad1427..05857305b63 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/AlterCveColumnsToNullableIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaReleasesComponentUuidTest.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v108; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.junit.jupiter.api.Test; @@ -25,39 +25,29 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; import org.sonar.server.platform.db.migration.step.DdlChange; -import static java.sql.Types.BIGINT; import static org.sonar.db.MigrationDbTester.createForMigrationStep; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaReleasesComponentUuid.COLUMN_NAME_COMPONENT_UUID; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaReleasesComponentUuid.COLUMN_NAME_UUID; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaReleasesComponentUuid.INDEX_NAME; +import static org.sonar.server.platform.db.migration.version.v202502.CreateIndexOnScaReleasesComponentUuid.TABLE_NAME; -class AlterCveColumnsToNullableIT { - - private static final String TABLE_NAME = "cves"; - +class CreateIndexOnScaReleasesComponentUuidTest { @RegisterExtension - public final MigrationDbTester db = createForMigrationStep(AlterCveColumnsToNullable.class); - - private final DdlChange underTest = new AlterCveColumnsToNullable(db.database()); + public final MigrationDbTester db = createForMigrationStep(CreateIndexOnScaReleasesComponentUuid.class); + private final DdlChange underTest = new CreateIndexOnScaReleasesComponentUuid(db.database()); @Test - void execute_shouldUpdateConstraints() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, "published_at", BIGINT, null, false); - db.assertColumnDefinition(TABLE_NAME, "last_modified_at", BIGINT, null, false); - + void execute_shouldCreateIndex() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); underTest.execute(); - - db.assertColumnDefinition(TABLE_NAME, "published_at", BIGINT, null, true); - db.assertColumnDefinition(TABLE_NAME, "last_modified_at", BIGINT, null, true); + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_COMPONENT_UUID, COLUMN_NAME_UUID); } @Test void execute_shouldBeReentrant() throws SQLException { - db.assertColumnDefinition(TABLE_NAME, "published_at", BIGINT, null, false); - db.assertColumnDefinition(TABLE_NAME, "last_modified_at", BIGINT, null, false); + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); underTest.execute(); - underTest.execute(); - - db.assertColumnDefinition(TABLE_NAME, "published_at", BIGINT, null, true); - db.assertColumnDefinition(TABLE_NAME, "last_modified_at", BIGINT, null, true); + db.assertIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_COMPONENT_UUID, COLUMN_NAME_UUID); } - } diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreateCvesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaDependenciesTableIT.java index 54ed9aa5611..10f31a1c908 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreateCvesTableIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaDependenciesTableIT.java @@ -17,58 +17,50 @@ * 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.platform.db.migration.version.v107; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; -import java.sql.Types; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; import org.sonar.server.platform.db.migration.step.DdlChange; import static java.sql.Types.BIGINT; +import static java.sql.Types.BOOLEAN; import static java.sql.Types.VARCHAR; +import static java.sql.Types.CLOB; import static org.sonar.db.MigrationDbTester.createForMigrationStep; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.DESCRIPTION_SECTION_KEY_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.MAX_SIZE; import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -class CreateCvesTableIT { - - private static final String TABLE_NAME = "cves"; +class CreateScaDependenciesTableIT { + private static final String TABLE_NAME = "sca_dependencies"; @RegisterExtension - public final MigrationDbTester db = createForMigrationStep(CreateCvesTable.class); + public final MigrationDbTester db = createForMigrationStep(CreateScaDependenciesTable.class); + private final DdlChange underTest = new CreateScaDependenciesTable(db.database()); - private final DdlChange createCvesTable = new CreateCvesTable(db.database()); - @Test void execute_shouldCreateTable() throws SQLException { db.assertTableDoesNotExist(TABLE_NAME); - - createCvesTable.execute(); - + underTest.execute(); db.assertTableExists(TABLE_NAME); + db.assertPrimaryKey(TABLE_NAME, "pk_sca_dependencies", "uuid"); db.assertColumnDefinition(TABLE_NAME, "uuid", VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, "id", VARCHAR, DESCRIPTION_SECTION_KEY_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, "description", VARCHAR, MAX_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, "cvss_score", Types.DOUBLE, null, true); - db.assertColumnDefinition(TABLE_NAME, "epss_score", Types.DOUBLE, null, true); - db.assertColumnDefinition(TABLE_NAME, "epss_percentile", Types.DOUBLE, null, true); - db.assertColumnDefinition(TABLE_NAME, "published_at", BIGINT, null, false); - db.assertColumnDefinition(TABLE_NAME, "last_modified_at", BIGINT, null, false); + db.assertColumnDefinition(TABLE_NAME, "sca_release_uuid", VARCHAR, UUID_SIZE, false); + db.assertColumnDefinition(TABLE_NAME, "direct", BOOLEAN, null, false); + db.assertColumnDefinition(TABLE_NAME, "scope", VARCHAR, 100, false); + db.assertColumnDefinition(TABLE_NAME, "user_dependency_file_path", VARCHAR, 1000, true); + db.assertColumnDefinition(TABLE_NAME, "lockfile_dependency_file_path", VARCHAR, 1000, true); + db.assertColumnDefinition(TABLE_NAME, "chains", CLOB, null, true); db.assertColumnDefinition(TABLE_NAME, "created_at", BIGINT, null, false); db.assertColumnDefinition(TABLE_NAME, "updated_at", BIGINT, null, false); - db.assertPrimaryKey(TABLE_NAME, "pk_cves", "uuid"); } @Test void execute_shouldBeReentrant() throws SQLException { db.assertTableDoesNotExist(TABLE_NAME); - createCvesTable.execute(); - - createCvesTable.execute(); - + underTest.execute(); + underTest.execute(); db.assertTableExists(TABLE_NAME); } } diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreateIssuesDependencyTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaIssuesReleasesTableIT.java index e8ef6b79c97..5e143238d21 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreateIssuesDependencyTableIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaIssuesReleasesTableIT.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v107; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.junit.jupiter.api.Test; @@ -25,38 +25,39 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; import org.sonar.server.platform.db.migration.step.DdlChange; +import static java.sql.Types.BIGINT; +import static java.sql.Types.INTEGER; import static java.sql.Types.VARCHAR; import static org.sonar.db.MigrationDbTester.createForMigrationStep; import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -class CreateIssuesDependencyTableIT { - - private static final String TABLE_NAME = "issues_dependency"; +class CreateScaIssuesReleasesTableIT { + private static final String TABLE_NAME = "sca_issues_releases"; @RegisterExtension - public final MigrationDbTester db = createForMigrationStep(CreateIssuesDependencyTable.class); - - private final DdlChange createIssuesDependencyTable = new CreateIssuesDependencyTable(db.database()); + public final MigrationDbTester db = createForMigrationStep(CreateScaIssuesReleasesTable.class); + private final DdlChange underTest = new CreateScaIssuesReleasesTable(db.database()); @Test void execute_shouldCreateTable() throws SQLException { db.assertTableDoesNotExist(TABLE_NAME); - - createIssuesDependencyTable.execute(); - + underTest.execute(); db.assertTableExists(TABLE_NAME); - db.assertColumnDefinition(TABLE_NAME, "issue_uuid", VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, "cve_uuid", VARCHAR, UUID_SIZE, false); - db.assertPrimaryKey(TABLE_NAME, "pk_issues_dependency", "issue_uuid"); + db.assertPrimaryKey(TABLE_NAME, "pk_sca_issues_releases", "uuid"); + db.assertColumnDefinition(TABLE_NAME, "uuid", VARCHAR, UUID_SIZE, false); + db.assertColumnDefinition(TABLE_NAME, "sca_issue_uuid", VARCHAR, UUID_SIZE, false); + db.assertColumnDefinition(TABLE_NAME, "sca_release_uuid", VARCHAR, UUID_SIZE, false); + db.assertColumnDefinition(TABLE_NAME, "severity", VARCHAR, 15, false); + db.assertColumnDefinition(TABLE_NAME, "severity_sort_key", INTEGER, null, false); + db.assertColumnDefinition(TABLE_NAME, "created_at", BIGINT, null, false); + db.assertColumnDefinition(TABLE_NAME, "updated_at", BIGINT, null, false); } @Test void execute_shouldBeReentrant() throws SQLException { db.assertTableDoesNotExist(TABLE_NAME); - createIssuesDependencyTable.execute(); - - createIssuesDependencyTable.execute(); - + underTest.execute(); + underTest.execute(); db.assertTableExists(TABLE_NAME); } } diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreateCveCweTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaIssuesTableIT.java index 1c985989678..b017bce767e 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v107/CreateCveCweTableIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaIssuesTableIT.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v107; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.junit.jupiter.api.Test; @@ -25,39 +25,38 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; import org.sonar.server.platform.db.migration.step.DdlChange; +import static java.sql.Types.BIGINT; import static java.sql.Types.VARCHAR; import static org.sonar.db.MigrationDbTester.createForMigrationStep; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.DESCRIPTION_SECTION_KEY_SIZE; import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -class CreateCveCweTableIT { - - private static final String TABLE_NAME = "cve_cwe"; +class CreateScaIssuesTableIT { + private static final String TABLE_NAME = "sca_issues"; @RegisterExtension - public final MigrationDbTester db = createForMigrationStep(CreateCveCweTable.class); - - private final DdlChange createCveCweTable = new CreateCveCweTable(db.database()); + public final MigrationDbTester db = createForMigrationStep(CreateScaIssuesTable.class); + private final DdlChange underTest = new CreateScaIssuesTable(db.database()); @Test void execute_shouldCreateTable() throws SQLException { db.assertTableDoesNotExist(TABLE_NAME); - - createCveCweTable.execute(); - + underTest.execute(); db.assertTableExists(TABLE_NAME); - db.assertColumnDefinition(TABLE_NAME, "cve_uuid", VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, "cwe", VARCHAR, DESCRIPTION_SECTION_KEY_SIZE, false); - db.assertPrimaryKey(TABLE_NAME, "pk_cve_cwe", "cve_uuid", "cwe"); + db.assertPrimaryKey(TABLE_NAME, "pk_sca_issues", "uuid"); + db.assertColumnDefinition(TABLE_NAME, "uuid", VARCHAR, UUID_SIZE, false); + db.assertColumnDefinition(TABLE_NAME, "sca_issue_type", VARCHAR, 40, false); + db.assertColumnDefinition(TABLE_NAME, "package_url", VARCHAR, 400, false); + db.assertColumnDefinition(TABLE_NAME, "vulnerability_id", VARCHAR, 63, false); + db.assertColumnDefinition(TABLE_NAME, "spdx_license_id", VARCHAR, 127, false); + db.assertColumnDefinition(TABLE_NAME, "created_at", BIGINT, null, false); + db.assertColumnDefinition(TABLE_NAME, "updated_at", BIGINT, null, false); } @Test void execute_shouldBeReentrant() throws SQLException { db.assertTableDoesNotExist(TABLE_NAME); - createCveCweTable.execute(); - - createCveCweTable.execute(); - + underTest.execute(); + underTest.execute(); db.assertTableExists(TABLE_NAME); } } diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaReleasesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaReleasesTableIT.java new file mode 100644 index 00000000000..c9dc4ff2e67 --- /dev/null +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaReleasesTableIT.java @@ -0,0 +1,66 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.db.migration.version.v202502; + +import java.sql.SQLException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.sonar.db.MigrationDbTester; +import org.sonar.server.platform.db.migration.step.DdlChange; + +import static java.sql.Types.BIGINT; +import static java.sql.Types.BOOLEAN; +import static java.sql.Types.VARCHAR; +import static org.sonar.db.MigrationDbTester.createForMigrationStep; +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; + +class CreateScaReleasesTableIT { + private static final String TABLE_NAME = "sca_releases"; + + @RegisterExtension + public final MigrationDbTester db = createForMigrationStep(CreateScaReleasesTable.class); + private final DdlChange underTest = new CreateScaReleasesTable(db.database()); + + @Test + void execute_shouldCreateTable() throws SQLException { + db.assertTableDoesNotExist(TABLE_NAME); + underTest.execute(); + db.assertTableExists(TABLE_NAME); + db.assertPrimaryKey(TABLE_NAME, "pk_sca_releases", "uuid"); + db.assertColumnDefinition(TABLE_NAME, "uuid", VARCHAR, UUID_SIZE, false); + db.assertColumnDefinition(TABLE_NAME, "component_uuid", VARCHAR, UUID_SIZE, false); + db.assertColumnDefinition(TABLE_NAME, "package_url", VARCHAR, 400, false); + db.assertColumnDefinition(TABLE_NAME, "package_manager", VARCHAR, 20, false); + db.assertColumnDefinition(TABLE_NAME, "package_name", VARCHAR, 400, false); + db.assertColumnDefinition(TABLE_NAME, "version", VARCHAR, 400, false); + db.assertColumnDefinition(TABLE_NAME, "license_expression", VARCHAR, 400, false); + db.assertColumnDefinition(TABLE_NAME, "known", BOOLEAN, null, false); + db.assertColumnDefinition(TABLE_NAME, "created_at", BIGINT, null, false); + db.assertColumnDefinition(TABLE_NAME, "updated_at", BIGINT, null, false); + } + + @Test + void execute_shouldBeReentrant() throws SQLException { + db.assertTableDoesNotExist(TABLE_NAME); + underTest.execute(); + underTest.execute(); + db.assertTableExists(TABLE_NAME); + } +} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateProjectDependenciesTableIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaVulnerabilityIssuesTableIT.java index 63d49ea7682..3ebed16766c 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v108/CreateProjectDependenciesTableIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaVulnerabilityIssuesTableIT.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v108; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.junit.jupiter.api.Test; @@ -26,32 +26,28 @@ import org.sonar.db.MigrationDbTester; import org.sonar.server.platform.db.migration.step.DdlChange; import static java.sql.Types.BIGINT; -import static java.sql.Types.CLOB; +import static java.sql.Types.DECIMAL; import static java.sql.Types.VARCHAR; import static org.sonar.db.MigrationDbTester.createForMigrationStep; import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -class CreateProjectDependenciesTableIT { - - private static final String TABLE_NAME = "project_dependencies"; +class CreateScaVulnerabilityIssuesTableIT { + private static final String TABLE_NAME = "sca_vulnerability_issues"; @RegisterExtension - public final MigrationDbTester db = createForMigrationStep(CreateProjectDependenciesTable.class); - - private final DdlChange underTest = new CreateProjectDependenciesTable(db.database()); + public final MigrationDbTester db = createForMigrationStep(CreateScaVulnerabilityIssuesTable.class); + private final DdlChange underTest = new CreateScaVulnerabilityIssuesTable(db.database()); @Test void execute_shouldCreateTable() throws SQLException { db.assertTableDoesNotExist(TABLE_NAME); - underTest.execute(); - db.assertTableExists(TABLE_NAME); - db.assertPrimaryKey(TABLE_NAME, "pk_project_dependencies", "uuid"); + db.assertPrimaryKey(TABLE_NAME, "pk_sca_vulnerability_issues", "uuid"); db.assertColumnDefinition(TABLE_NAME, "uuid", VARCHAR, UUID_SIZE, false); - db.assertColumnDefinition(TABLE_NAME, "version", CLOB, null, true); - db.assertColumnDefinition(TABLE_NAME, "include_paths", CLOB, null, true); - db.assertColumnDefinition(TABLE_NAME, "package_manager", VARCHAR, 50, true); + db.assertColumnDefinition(TABLE_NAME, "base_severity", VARCHAR, 15, false); + db.assertColumnDefinition(TABLE_NAME, "cwe_ids", VARCHAR, 255, false); + db.assertColumnDefinition(TABLE_NAME, "cvss_score", DECIMAL, null, true); db.assertColumnDefinition(TABLE_NAME, "created_at", BIGINT, null, false); db.assertColumnDefinition(TABLE_NAME, "updated_at", BIGINT, null, false); } @@ -60,10 +56,7 @@ class CreateProjectDependenciesTableIT { void execute_shouldBeReentrant() throws SQLException { db.assertTableDoesNotExist(TABLE_NAME); underTest.execute(); - underTest.execute(); - db.assertTableExists(TABLE_NAME); } - } diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnScaIssuesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnScaIssuesIT.java new file mode 100644 index 00000000000..cbc4bc13457 --- /dev/null +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnScaIssuesIT.java @@ -0,0 +1,55 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.db.migration.version.v202502; + +import java.sql.SQLException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.sonar.db.MigrationDbTester; +import org.sonar.server.platform.db.migration.step.DdlChange; + +import static org.sonar.db.MigrationDbTester.createForMigrationStep; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnScaIssues.COLUMN_NAME_PACKAGE_URL; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnScaIssues.COLUMN_NAME_SCA_ISSUE_TYPE; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnScaIssues.COLUMN_NAME_SPDX_LICENSE_ID; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnScaIssues.COLUMN_NAME_VULNERABILITY_ID; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnScaIssues.INDEX_NAME; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnScaIssues.TABLE_NAME; + +class CreateUniqueIndexOnScaIssuesIT { + @RegisterExtension + public final MigrationDbTester db = createForMigrationStep(CreateUniqueIndexOnScaIssues.class); + private final DdlChange underTest = new CreateUniqueIndexOnScaIssues(db.database()); + + @Test + void execute_shouldCreateIndex() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + underTest.execute(); + db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_SCA_ISSUE_TYPE, COLUMN_NAME_VULNERABILITY_ID, COLUMN_NAME_PACKAGE_URL, COLUMN_NAME_SPDX_LICENSE_ID); + } + + @Test + void execute_shouldBeReentrant() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + underTest.execute(); + underTest.execute(); + db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_SCA_ISSUE_TYPE, COLUMN_NAME_VULNERABILITY_ID, COLUMN_NAME_PACKAGE_URL, COLUMN_NAME_SPDX_LICENSE_ID); + } +} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnScaIssuesReleasesIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnScaIssuesReleasesIT.java new file mode 100644 index 00000000000..5c40f262fc4 --- /dev/null +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnScaIssuesReleasesIT.java @@ -0,0 +1,53 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.db.migration.version.v202502; + +import java.sql.SQLException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.sonar.db.MigrationDbTester; +import org.sonar.server.platform.db.migration.step.DdlChange; + +import static org.sonar.db.MigrationDbTester.createForMigrationStep; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnScaIssuesReleases.COLUMN_NAME_SCA_ISSUE_UUID; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnScaIssuesReleases.COLUMN_NAME_SCA_RELEASE_UUID; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnScaIssuesReleases.INDEX_NAME; +import static org.sonar.server.platform.db.migration.version.v202502.CreateUniqueIndexOnScaIssuesReleases.TABLE_NAME; + +class CreateUniqueIndexOnScaIssuesReleasesIT { + @RegisterExtension + public final MigrationDbTester db = createForMigrationStep(CreateUniqueIndexOnScaIssuesReleases.class); + private final DdlChange underTest = new CreateUniqueIndexOnScaIssuesReleases(db.database()); + + @Test + void execute_shouldCreateIndex() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + underTest.execute(); + db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_SCA_ISSUE_UUID, COLUMN_NAME_SCA_RELEASE_UUID); + } + + @Test + void execute_shouldBeReentrant() throws SQLException { + db.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME); + underTest.execute(); + underTest.execute(); + db.assertUniqueIndex(TABLE_NAME, INDEX_NAME, COLUMN_NAME_SCA_ISSUE_UUID, COLUMN_NAME_SCA_RELEASE_UUID); + } +} diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInSnapshotsIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/DropIndexOnScaReleasesComponentTest.java index 479405de7ba..ec377d5fb96 100644 --- a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInSnapshotsIT.java +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/DropIndexOnScaReleasesComponentTest.java @@ -17,24 +17,25 @@ * 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.platform.db.migration.version.v102; + +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; +import static org.sonar.db.MigrationDbTester.createForMigrationStep; +class DropIndexOnScaReleasesComponentTest { -class DropIndexComponentUuidInSnapshotsIT { - - private static final String TABLE_NAME = "snapshots"; + private static final String TABLE_NAME = "sca_releases"; private static final String COLUMN_NAME = "component_uuid"; - private static final String INDEX_NAME = "snapshot_component"; + private static final String INDEX_NAME = "sca_releases_comp_uuid"; @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(DropIndexComponentUuidInSnapshots.class); - private final DropIndexComponentUuidInSnapshots underTest = new DropIndexComponentUuidInSnapshots(db.database()); + public final MigrationDbTester db = createForMigrationStep(DropIndexOnScaReleasesComponent.class); + private final DropIndexOnScaReleasesComponent underTest = new DropIndexOnScaReleasesComponent(db.database()); @Test void index_is_dropped() throws SQLException { diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/InsertDefaultAiSuggestionProviderKeyAndModelKeyPropertiesTest.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/InsertDefaultAiSuggestionProviderKeyAndModelKeyPropertiesTest.java new file mode 100644 index 00000000000..8fc64e7347e --- /dev/null +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202502/InsertDefaultAiSuggestionProviderKeyAndModelKeyPropertiesTest.java @@ -0,0 +1,90 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.db.migration.version.v202502; + +import java.sql.SQLException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.sonar.api.impl.utils.TestSystem2; +import org.sonar.api.utils.System2; +import org.sonar.core.util.SequenceUuidFactory; +import org.sonar.db.MigrationDbTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.core.config.AiCodeFixEnablementConstants.SUGGESTION_FEATURE_ENABLED_PROPERTY; +import static org.sonar.core.config.AiCodeFixEnablementConstants.SUGGESTION_PROVIDER_KEY_PROPERTY; +import static org.sonar.core.config.AiCodeFixEnablementConstants.SUGGESTION_PROVIDER_MODEL_KEY_PROPERTY; +import static org.sonar.server.platform.db.migration.version.v202502.InsertDefaultAiSuggestionProviderKeyAndModelKeyProperties.DEFAULT_PROVIDER_KEY; +import static org.sonar.server.platform.db.migration.version.v202502.InsertDefaultAiSuggestionProviderKeyAndModelKeyProperties.DEFAULT_PROVIDER_MODEL_KEY; +import static org.sonar.server.platform.db.migration.version.v202502.InsertDefaultAiSuggestionProviderKeyAndModelKeyProperties.DISABLED; + +class InsertDefaultAiSuggestionProviderKeyAndModelKeyPropertiesTest { + private static final long NOW = 1; + + @RegisterExtension + private final MigrationDbTester db = MigrationDbTester.createForMigrationStep(InsertDefaultAiSuggestionProviderKeyAndModelKeyProperties.class); + private final System2 system2 = new TestSystem2().setNow(NOW); + private final InsertDefaultAiSuggestionProviderKeyAndModelKeyProperties underTest = new InsertDefaultAiSuggestionProviderKeyAndModelKeyProperties(db.database(), system2, + new SequenceUuidFactory()); + + @Test + void execute_shouldNotUpdateAnything_whenTheAiCodeFixNotSet() throws SQLException { + underTest.execute(); + + assertThat(db.countSql(String.format("select count(*) from properties where prop_key = '%s'", SUGGESTION_FEATURE_ENABLED_PROPERTY))).isZero(); + assertThat(db.countSql(String.format("select count(*) from properties where prop_key = '%s'", SUGGESTION_PROVIDER_KEY_PROPERTY))).isZero(); + assertThat(db.countSql(String.format("select count(*) from properties where prop_key = '%s'", SUGGESTION_PROVIDER_MODEL_KEY_PROPERTY))).isZero(); + } + + @Test + void execute_shouldNotUpdateAnything_whenTheAiCodeFixDisabled() throws SQLException { + insertProperty(SUGGESTION_FEATURE_ENABLED_PROPERTY, DISABLED); + underTest.execute(); + + assertThat(db.selectFirst(String.format("select text_value from properties where prop_key = '%s'", SUGGESTION_FEATURE_ENABLED_PROPERTY))).containsEntry("text_value", DISABLED); + assertThat(db.countSql(String.format("select count(*) from properties where prop_key = '%s'", SUGGESTION_PROVIDER_KEY_PROPERTY))).isZero(); + assertThat(db.countSql(String.format("select count(*) from properties where prop_key = '%s'", SUGGESTION_PROVIDER_MODEL_KEY_PROPERTY))).isZero(); + } + + @ParameterizedTest + @ValueSource(strings = {"ENABLED_FOR_ALL_PROJECTS", "ENABLED_FOR_SOME_PROJECTS"}) + void execute_shouldSetDefaultValues_whenTheAiCodeFixEnabled(String enablement) throws SQLException { + insertProperty(SUGGESTION_FEATURE_ENABLED_PROPERTY, enablement); + underTest.execute(); + + assertThat(db.selectFirst(String.format("select text_value from properties where prop_key = '%s'", SUGGESTION_FEATURE_ENABLED_PROPERTY))).containsEntry("text_value", + enablement); + assertThat(db.selectFirst(String.format("select text_value from properties where prop_key = '%s'", SUGGESTION_PROVIDER_KEY_PROPERTY))).containsEntry("text_value", + DEFAULT_PROVIDER_KEY); + assertThat(db.selectFirst(String.format("select text_value from properties where prop_key = '%s'", SUGGESTION_PROVIDER_MODEL_KEY_PROPERTY))).containsEntry("text_value", + DEFAULT_PROVIDER_MODEL_KEY); + } + + private void insertProperty(String key, String value) { + db.executeInsert("properties", + "uuid", "uuid-1", + "prop_key", key, + "is_empty", false, + "text_value", value, + "created_at", NOW); + } +} diff --git a/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInGroupRolesIT/schema.sql b/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInGroupRolesIT/schema.sql deleted file mode 100644 index 28453ffd067..00000000000 --- a/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInGroupRolesIT/schema.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE "GROUP_ROLES"( - "UUID" CHARACTER VARYING(40) NOT NULL, - "ROLE" CHARACTER VARYING(64) NOT NULL, - "COMPONENT_UUID" CHARACTER VARYING(40), - "GROUP_UUID" CHARACTER VARYING(40) -); -ALTER TABLE "GROUP_ROLES" ADD CONSTRAINT "PK_GROUP_ROLES" PRIMARY KEY("UUID"); -CREATE INDEX "GROUP_ROLES_COMPONENT_UUID" ON "GROUP_ROLES"("COMPONENT_UUID" NULLS FIRST); -CREATE UNIQUE INDEX "UNIQ_GROUP_ROLES" ON "GROUP_ROLES"("GROUP_UUID" NULLS FIRST, "COMPONENT_UUID" NULLS FIRST, "ROLE" NULLS FIRST); diff --git a/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInUserRolesIT/schema.sql b/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInUserRolesIT/schema.sql deleted file mode 100644 index f19732423ab..00000000000 --- a/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInUserRolesIT/schema.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE "USER_ROLES"( - "UUID" CHARACTER VARYING(40) NOT NULL, - "ROLE" CHARACTER VARYING(64) NOT NULL, - "COMPONENT_UUID" CHARACTER VARYING(40), - "USER_UUID" CHARACTER VARYING(255) -); -ALTER TABLE "USER_ROLES" ADD CONSTRAINT "PK_USER_ROLES" PRIMARY KEY("UUID"); -CREATE INDEX "USER_ROLES_COMPONENT_UUID" ON "USER_ROLES"("COMPONENT_UUID" NULLS FIRST); -CREATE INDEX "USER_ROLES_USER" ON "USER_ROLES"("USER_UUID" NULLS FIRST); diff --git a/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v102/DropIndexProjectUuidInWebhookDeliveriesIT/schema.sql b/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v102/DropIndexProjectUuidInWebhookDeliveriesIT/schema.sql deleted file mode 100644 index 9b4b255b6e5..00000000000 --- a/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v102/DropIndexProjectUuidInWebhookDeliveriesIT/schema.sql +++ /dev/null @@ -1,19 +0,0 @@ -CREATE TABLE "WEBHOOK_DELIVERIES"( - "UUID" CHARACTER VARYING(40) NOT NULL, - "WEBHOOK_UUID" CHARACTER VARYING(40) NOT NULL, - "PROJECT_UUID" CHARACTER VARYING(40) NOT NULL, - "CE_TASK_UUID" CHARACTER VARYING(40), - "ANALYSIS_UUID" CHARACTER VARYING(40), - "NAME" CHARACTER VARYING(100) NOT NULL, - "URL" CHARACTER VARYING(2000) NOT NULL, - "SUCCESS" BOOLEAN NOT NULL, - "HTTP_STATUS" INTEGER, - "DURATION_MS" BIGINT NOT NULL, - "PAYLOAD" CHARACTER LARGE OBJECT NOT NULL, - "ERROR_STACKTRACE" CHARACTER LARGE OBJECT, - "CREATED_AT" BIGINT NOT NULL -); -ALTER TABLE "WEBHOOK_DELIVERIES" ADD CONSTRAINT "PK_WEBHOOK_DELIVERIES" PRIMARY KEY("UUID"); -CREATE INDEX "CE_TASK_UUID" ON "WEBHOOK_DELIVERIES"("CE_TASK_UUID" NULLS FIRST); -CREATE INDEX "WD_PROJECT_UUID" ON "WEBHOOK_DELIVERIES"("PROJECT_UUID" NULLS FIRST); -CREATE INDEX "WD_WEBHOOK_UUID_CREATED_AT" ON "WEBHOOK_DELIVERIES"("WEBHOOK_UUID", "CREATED_AT" NULLS FIRST); diff --git a/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v106/ResizeValueColumnInRuleTagsTableIT/schema.sql b/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v106/ResizeValueColumnInRuleTagsTableIT/schema.sql deleted file mode 100644 index ed4f3118592..00000000000 --- a/server/sonar-db-migration/src/it/resources/org/sonar/server/platform/db/migration/version/v106/ResizeValueColumnInRuleTagsTableIT/schema.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE "RULE_TAGS"( - "RULE_UUID" CHARACTER VARYING(40) NOT NULL, - "IS_SYSTEM_TAG" BOOLEAN NOT NULL, - "VALUE" CHARACTER VARYING(40) NOT NULL -);
\ No newline at end of file diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java index f844369bf02..a4ea57f9d35 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java @@ -28,15 +28,6 @@ import org.sonar.server.platform.db.migration.sql.DropPrimaryKeySqlGenerator; import org.sonar.server.platform.db.migration.step.MigrationStepRegistryImpl; import org.sonar.server.platform.db.migration.step.MigrationStepsProvider; import org.sonar.server.platform.db.migration.version.v00.DbVersion00; -import org.sonar.server.platform.db.migration.version.v100.DbVersion100; -import org.sonar.server.platform.db.migration.version.v101.DbVersion101; -import org.sonar.server.platform.db.migration.version.v102.DbVersion102; -import org.sonar.server.platform.db.migration.version.v103.DbVersion103; -import org.sonar.server.platform.db.migration.version.v104.DbVersion104; -import org.sonar.server.platform.db.migration.version.v105.DbVersion105; -import org.sonar.server.platform.db.migration.version.v106.DbVersion106; -import org.sonar.server.platform.db.migration.version.v107.DbVersion107; -import org.sonar.server.platform.db.migration.version.v108.DbVersion108; import org.sonar.server.platform.db.migration.version.v202501.DbVersion202501; import org.sonar.server.platform.db.migration.version.v202502.DbVersion202502; @@ -47,15 +38,6 @@ public class MigrationConfigurationModule extends Module { MigrationHistoryTableImpl.class, // DbVersion implementations DbVersion00.class, - DbVersion100.class, - DbVersion101.class, - DbVersion102.class, - DbVersion103.class, - DbVersion104.class, - DbVersion105.class, - DbVersion106.class, - DbVersion107.class, - DbVersion108.class, DbVersion202501.class, DbVersion202502.class, diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/DatabaseVersion.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/DatabaseVersion.java index a1222487b07..409f4d7c039 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/DatabaseVersion.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/DatabaseVersion.java @@ -30,8 +30,11 @@ public class DatabaseVersion { * versions must be previously upgraded to LTA version. * Note that the value can't be less than current LTA version. */ - public static final long MIN_UPGRADE_VERSION = 6_802; - public static final String MIN_UPGRADE_VERSION_HUMAN_READABLE = "9.9"; + public static final long MIN_UPGRADE_VERSION = 108026; + + // In reality user is required to upgrade just to 10.8 but we want to 'market' 2025.1 + public static final String MIN_UPGRADE_VERSION_HUMAN_READABLE = "2025.1"; + public static final String MIN_UPGRADE_VERSION_COMMUNITY_BUILD_READABLE = "24.12"; private final MigrationSteps migrationSteps; diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v00/CreateInitialSchema.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v00/CreateInitialSchema.java index 4328a19367f..c162ae2c79c 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v00/CreateInitialSchema.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v00/CreateInitialSchema.java @@ -24,10 +24,12 @@ import org.sonar.db.Database; import org.sonar.server.platform.db.migration.def.BigIntegerColumnDef; import org.sonar.server.platform.db.migration.def.BooleanColumnDef; import org.sonar.server.platform.db.migration.def.ColumnDef; +import org.sonar.server.platform.db.migration.def.DecimalColumnDef; import org.sonar.server.platform.db.migration.def.IntegerColumnDef; import org.sonar.server.platform.db.migration.def.TimestampColumnDef; import org.sonar.server.platform.db.migration.def.TinyIntColumnDef; import org.sonar.server.platform.db.migration.def.VarcharColumnDef; +import org.sonar.server.platform.db.migration.sql.AddPrimaryKeyBuilder; import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; import org.sonar.server.platform.db.migration.step.DdlChange; @@ -103,6 +105,7 @@ public class CreateInitialSchema extends DdlChange { createActiveRules(context); createAlmPats(context); createAlmSettings(context); + createAnticipatedTransitions(context); createProjectAlmSettings(context); createAnalysisProperties(context); createAppBranchProjectBranch(context); @@ -115,22 +118,30 @@ public class CreateInitialSchema extends DdlChange { createCeTaskInput(context); createCeTaskMessage(context); createComponents(context); + createCves(context); + createCveCwe(context); createDefaultQProfiles(context); createDeprecatedRuleKeys(context); createDuplicationsIndex(context); + createDevopsPermsMapping(context); createEsQueue(context); createEventComponentChanges(context); createEvents(context); + createExternalGroups(context); createFileSources(context); + createGithubOrganizationGroups(context); createGroupRoles(context); createGroups(context); createGroupsUsers(context); createInternalComponentProps(context); createInternalProperties(context); createIssueChanges(context); + createIssueImpacts(context); createIssues(context); - createLiveMeasures(context); + createIssuesDependency(context); + createIssuesFixed(context); createMetrics(context); + createMeasures(context); createNewCodePeriods(context); createNewCodeReferenceIssues(context); createNotifications(context); @@ -146,14 +157,16 @@ public class CreateInitialSchema extends DdlChange { createPortfolios(context); createProjectBadgeToken(context); createProjectBranches(context); + createProjectDependencies(context); createProjectLinks(context); - createProjectMappings(context); createProjectMeasures(context); createProjectQprofiles(context); createProjects(context); createProjectQGates(context); createProperties(context); createPushEvents(context); + createReportSchedules(context); + createReportSubscriptions(context); createQGateGroupPermissions(context); createQGateUserPermissions(context); createQProfileChanges(context); @@ -161,11 +174,18 @@ public class CreateInitialSchema extends DdlChange { createQProfileEditUsers(context); createQualityGateConditions(context); createQualityGates(context); + createRuleChanges(context); + createRuleImpactChanges(context); + createRuleTags(context); + createScimGroups(context); createScimUsers(context); + createScmAccounts(context); createSessionTokens(context); + createTelemetryMetricsSent(context); createRulesRepository(context); createRuleDescSections(context); createRules(context); + createRulesDefaultImpacts(context); createRulesParameters(context); createRulesProfiles(context); createSamlMessageIds(context); @@ -179,6 +199,22 @@ public class CreateInitialSchema extends DdlChange { createWebhooks(context); } + private void createAnticipatedTransitions(Context context) { + context.execute(new CreateTableBuilder(getDialect(), "anticipated_transitions") + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("project_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("user_uuid").setIsNullable(false).setLimit(USER_UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("transition").setIsNullable(false).setLimit(20).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("transition_comment").setLimit(MAX_SIZE).build()) + .addColumn(newIntegerColumnDefBuilder().setColumnName("line").build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("message").setLimit(MAX_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("line_hash").setLimit(255).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("rule_key").setIsNullable(false).setLimit(200).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("file_path").setIsNullable(false).setLimit(1500).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName("created_at").setIsNullable(false).build()) + .build()); + } + private void createActiveRuleParameters(Context context) { String tableName = "active_rule_parameters"; VarcharColumnDef activeRuleUuidColumnDef = newVarcharColumnDefBuilder("active_rule_uuid").setLimit(UUID_SIZE).setIsNullable(false).build(); @@ -206,6 +242,8 @@ public class CreateInitialSchema extends DdlChange { .addColumn(NULLABLE_TECHNICAL_UPDATED_AT_COL) .addColumn(profileUuidCol) .addColumn(ruleUuidCol) + .addColumn(newBooleanColumnDefBuilder().setColumnName("prioritized_rule").setIsNullable(true).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("impacts").setIsNullable(true).setLimit(500).build()) .build()); addIndex(context, "active_rules", "uniq_profile_rule_uuids", true, profileUuidCol, ruleUuidCol); } @@ -349,20 +387,19 @@ public class CreateInitialSchema extends DdlChange { private void createCeActivity(Context context) { String tableName = "ce_activity"; - VarcharColumnDef uuidCol = UUID_COL; - VarcharColumnDef mainComponentUuidCol = newVarcharColumnDefBuilder("main_component_uuid").setLimit(UUID_SIZE).setIsNullable(true).build(); - VarcharColumnDef componentUuidCol = newVarcharColumnDefBuilder(COMPONENT_UUID_COL_NAME).setLimit(UUID_SIZE).setIsNullable(true).build(); + VarcharColumnDef componentUuidColumn = newVarcharColumnDefBuilder("component_uuid").setLimit(UUID_SIZE).setIsNullable(true).build(); + VarcharColumnDef entityUuidColumn = newVarcharColumnDefBuilder("entity_uuid").setLimit(UUID_SIZE).setIsNullable(true).build(); VarcharColumnDef statusCol = newVarcharColumnDefBuilder(STATUS_COL_NAME).setLimit(15).setIsNullable(false).build(); BooleanColumnDef mainIsLastCol = newBooleanColumnDefBuilder().setColumnName("main_is_last").setIsNullable(false).build(); - VarcharColumnDef mainIsLastKeyCol = newVarcharColumnDefBuilder("main_is_last_key").setLimit(55).setIsNullable(false).build(); + VarcharColumnDef mainIsLastKeyCol = newVarcharColumnDefBuilder("main_is_last_key").setLimit(80).setIsNullable(false).build(); BooleanColumnDef isLastCol = newBooleanColumnDefBuilder().setColumnName("is_last").setIsNullable(false).build(); - VarcharColumnDef isLastKeyCol = newVarcharColumnDefBuilder("is_last_key").setLimit(55).setIsNullable(false).build(); + VarcharColumnDef isLastKeyCol = newVarcharColumnDefBuilder("is_last_key").setLimit(80).setIsNullable(false).build(); context.execute( newTableBuilder(tableName) - .addPkColumn(uuidCol) - .addColumn(newVarcharColumnDefBuilder("task_type").setLimit(15).setIsNullable(false).build()) - .addColumn(mainComponentUuidCol) - .addColumn(componentUuidCol) + .addPkColumn(UUID_COL) + .addColumn(newVarcharColumnDefBuilder("task_type").setLimit(40).setIsNullable(false).build()) + .addColumn(entityUuidColumn) + .addColumn(componentUuidColumn) .addColumn(statusCol) .addColumn(mainIsLastCol) .addColumn(mainIsLastKeyCol) @@ -383,24 +420,23 @@ public class CreateInitialSchema extends DdlChange { .addColumn(TECHNICAL_UPDATED_AT_COL) .addColumn(newVarcharColumnDefBuilder("node_name").setLimit(100).setIsNullable(true).build()) .build()); - addIndex(context, tableName, "ce_activity_component", false, componentUuidCol); + addIndex(context, tableName, "ce_activity_component", false, componentUuidColumn); addIndex(context, tableName, "ce_activity_islast", false, isLastCol, statusCol); addIndex(context, tableName, "ce_activity_islast_key", false, isLastKeyCol); - addIndex(context, tableName, "ce_activity_main_component", false, mainComponentUuidCol); addIndex(context, tableName, "ce_activity_main_islast", false, mainIsLastCol, statusCol); addIndex(context, tableName, "ce_activity_main_islast_key", false, mainIsLastKeyCol); + addIndex(context, tableName, "ce_activity_entity_uuid", false, entityUuidColumn); } private void createCeQueue(Context context) { String tableName = "ce_queue"; - VarcharColumnDef uuidCol = UUID_COL; - VarcharColumnDef mainComponentUuidCol = newVarcharColumnDefBuilder("main_component_uuid").setLimit(UUID_SIZE).setIsNullable(true).build(); + VarcharColumnDef entityUuidColumn = newVarcharColumnDefBuilder("entity_uuid").setLimit(UUID_SIZE).setIsNullable(true).build(); VarcharColumnDef componentUuidCol = newVarcharColumnDefBuilder(COMPONENT_UUID_COL_NAME).setLimit(UUID_SIZE).setIsNullable(true).build(); context.execute( newTableBuilder(tableName) - .addPkColumn(uuidCol) - .addColumn(newVarcharColumnDefBuilder("task_type").setLimit(15).setIsNullable(false).build()) - .addColumn(mainComponentUuidCol) + .addPkColumn(UUID_COL) + .addColumn(newVarcharColumnDefBuilder("task_type").setLimit(40).setIsNullable(false).build()) + .addColumn(entityUuidColumn) .addColumn(componentUuidCol) .addColumn(newVarcharColumnDefBuilder(STATUS_COL_NAME).setLimit(15).setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("submitter_uuid").setLimit(USER_UUID_SIZE).setIsNullable(true).build()) @@ -410,8 +446,8 @@ public class CreateInitialSchema extends DdlChange { .addColumn(TECHNICAL_CREATED_AT_COL) .addColumn(TECHNICAL_UPDATED_AT_COL) .build()); - addIndex(context, tableName, "ce_queue_main_component", false, mainComponentUuidCol); addIndex(context, tableName, "ce_queue_component", false, componentUuidCol); + addIndex(context, tableName, "ce_queue_entity_uuid", false, entityUuidColumn); } private void createCeScannerContext(Context context) { @@ -469,12 +505,9 @@ public class CreateInitialSchema extends DdlChange { private void createComponents(Context context) { String tableName = "components"; VarcharColumnDef keeCol = newVarcharColumnDefBuilder("kee").setIsNullable(true).setLimit(1000).build(); - VarcharColumnDef moduleUuidCol = newVarcharColumnDefBuilder("module_uuid").setIsNullable(true).setLimit(50).build(); VarcharColumnDef branchUuidCol = newVarcharColumnDefBuilder(BRANCH_UUID_COL_NAME).setIsNullable(false).setLimit(50).build(); VarcharColumnDef qualifierCol = newVarcharColumnDefBuilder("qualifier").setIsNullable(true).setLimit(10).build(); - VarcharColumnDef rootUuidCol = newVarcharColumnDefBuilder("root_uuid").setIsNullable(false).setLimit(50).build(); VarcharColumnDef uuidCol = newVarcharColumnDefBuilder("uuid").setIsNullable(false).setLimit(50).build(); - VarcharColumnDef mainBranchProjectUuidCol = newVarcharColumnDefBuilder("main_branch_project_uuid").setIsNullable(true).setLimit(50).build(); context.execute(newTableBuilder(tableName) .addColumn(uuidCol) @@ -487,15 +520,11 @@ public class CreateInitialSchema extends DdlChange { .addColumn(newVarcharColumnDefBuilder("scope").setIsNullable(true).setLimit(3).build()) .addColumn(qualifierCol) .addColumn(newBooleanColumnDefBuilder().setColumnName(PRIVATE_COL_NAME).setIsNullable(false).build()) - .addColumn(rootUuidCol) .addColumn(newVarcharColumnDefBuilder(LANGUAGE_COL_NAME).setIsNullable(true).setLimit(20).build()) .addColumn(newVarcharColumnDefBuilder("copy_component_uuid").setIsNullable(true).setLimit(50).build()) .addColumn(newVarcharColumnDefBuilder("path").setIsNullable(true).setLimit(2000).build()) .addColumn(newVarcharColumnDefBuilder("uuid_path").setIsNullable(false).setLimit(1500).build()) .addColumn(branchUuidCol) - .addColumn(moduleUuidCol) - .addColumn(newVarcharColumnDefBuilder("module_uuid_path").setIsNullable(true).setLimit(1500).build()) - .addColumn(mainBranchProjectUuidCol) .addColumn(newBooleanColumnDefBuilder().setColumnName("b_changed").setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("b_name").setIsNullable(true).setLimit(500).build()) .addColumn(newVarcharColumnDefBuilder("b_long_name").setIsNullable(true).setLimit(500).build()) @@ -506,20 +535,65 @@ public class CreateInitialSchema extends DdlChange { .addColumn(newVarcharColumnDefBuilder("b_copy_component_uuid").setIsNullable(true).setLimit(50).build()) .addColumn(newVarcharColumnDefBuilder("b_path").setIsNullable(true).setLimit(2000).build()) .addColumn(newVarcharColumnDefBuilder("b_uuid_path").setIsNullable(true).setLimit(1500).build()) - .addColumn(newVarcharColumnDefBuilder("b_module_uuid").setIsNullable(true).setLimit(50).build()) - .addColumn(newVarcharColumnDefBuilder("b_module_uuid_path").setIsNullable(true).setLimit(1500).build()) .addColumn(newTimestampColumnDefBuilder().setColumnName(CREATED_AT_COL_NAME).setIsNullable(true).build()) .build()); - addIndex(context, tableName, "projects_module_uuid", false, moduleUuidCol); addIndex(context, tableName, "projects_qualifier", false, qualifierCol); - addIndex(context, tableName, "projects_root_uuid", false, rootUuidCol); - addIndex(context, tableName, "idx_main_branch_prj_uuid", false, mainBranchProjectUuidCol); addIndex(context, tableName, "components_uuid", true, uuidCol); addIndex(context, tableName, "components_branch_uuid", false, branchUuidCol); addIndex(context, tableName, "components_kee_branch_uuid", true, keeCol, branchUuidCol); } + + private void createCves(Context context) { + String tableName = "cves"; + + VarcharColumnDef uuidColumn = newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build(); + VarcharColumnDef idColumn = newVarcharColumnDefBuilder().setColumnName("id").setIsNullable(false).setLimit(DESCRIPTION_SECTION_KEY_SIZE).build(); + VarcharColumnDef descriptionColumn = newVarcharColumnDefBuilder().setColumnName("description").setIsNullable(false).setLimit(MAX_SIZE).build(); + BigIntegerColumnDef updatedAtColumn = newBigIntegerColumnDefBuilder().setColumnName("updated_at").setIsNullable(false).build(); + BigIntegerColumnDef createdAtColumn = newBigIntegerColumnDefBuilder().setColumnName("created_at").setIsNullable(false).build(); + BigIntegerColumnDef lastModifiedColumn = newBigIntegerColumnDefBuilder().setColumnName("last_modified_at").setIsNullable(true).build(); + BigIntegerColumnDef publishedColumn = newBigIntegerColumnDefBuilder().setColumnName("published_at").setIsNullable(true).build(); + DecimalColumnDef cvssScoreColumn = newDecimalColumnDefBuilder().setColumnName("cvss_score").setIsNullable(true).build(); + DecimalColumnDef epssScoreColumn = newDecimalColumnDefBuilder().setColumnName("epss_score").setIsNullable(true).build(); + DecimalColumnDef epssPercentileColumn = newDecimalColumnDefBuilder().setColumnName("epss_percentile").setIsNullable(true).build(); + + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(uuidColumn) + .addColumn(idColumn) + .addColumn(descriptionColumn) + .addColumn(cvssScoreColumn) + .addColumn(epssScoreColumn) + .addColumn(epssPercentileColumn) + .addColumn(publishedColumn) + .addColumn(lastModifiedColumn) + .addColumn(createdAtColumn) + .addColumn(updatedAtColumn) + .build()); + } + + private void createCveCwe(Context context) { + String tableName = "cve_cwe"; + + VarcharColumnDef cveUuidColumn = newVarcharColumnDefBuilder().setColumnName("cve_uuid").setIsNullable(false).setLimit(UUID_SIZE).build(); + VarcharColumnDef cweColumn = newVarcharColumnDefBuilder().setColumnName("cwe").setIsNullable(false).setLimit(DESCRIPTION_SECTION_KEY_SIZE).build(); + + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(cveUuidColumn) + .addPkColumn(cweColumn) + .build()); + } + + private void createIssuesDependency(Context context) { + String tableName = "issues_dependency"; + + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("issue_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("cve_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .build()); + } + private void createDefaultQProfiles(Context context) { String tableName = "default_qprofiles"; VarcharColumnDef profileUuidColumn = newVarcharColumnDefBuilder(QPROFILE_UUID_COL_NAME) @@ -633,6 +707,19 @@ public class CreateInitialSchema extends DdlChange { addIndex(context, tableName, "events_component_uuid", false, componentUuid); } + private void createExternalGroups(Context context) { + String tableName = "external_groups"; + ColumnDef externalIdentityColumn = newVarcharColumnDefBuilder().setColumnName("external_identity_provider").setIsNullable(false).setLimit(100).build(); + ColumnDef externalGroupIdColumn = newVarcharColumnDefBuilder().setColumnName("external_group_id").setIsNullable(false).setLimit(255).build(); + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("group_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(externalGroupIdColumn) + .addColumn(externalIdentityColumn) + .build()); + + addIndex(context, tableName, "uniq_ext_grp_ext_id_provider", true, externalIdentityColumn, externalGroupIdColumn); + } + private void createFileSources(Context context) { String tableName = "file_sources"; VarcharColumnDef projectUuidCol = newVarcharColumnDefBuilder(PROJECT_UUID_COL_NAME).setLimit(OLD_UUID_VARCHAR_SIZE).setIsNullable(false).build(); @@ -658,10 +745,34 @@ public class CreateInitialSchema extends DdlChange { addIndex(context, tableName, "file_sources_updated_at", false, updatedAtCol); } + + private void createGithubOrganizationGroups(Context context) { + String tableName = "github_orgs_groups"; + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("group_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("organization_name").setIsNullable(false).setLimit(100).build()) + .build()); + } + + private void createDevopsPermsMapping(Context context) { + String tableName = "devops_perms_mapping"; + VarcharColumnDef devopsPlatformRoleColumn = newVarcharColumnDefBuilder().setColumnName("devops_platform_role").setIsNullable(false).setLimit(100).build(); + VarcharColumnDef sonarqubePermissionColumn = newVarcharColumnDefBuilder().setColumnName("sonarqube_permission").setIsNullable(false).setLimit(64).build(); + VarcharColumnDef devopsPlatformColumn = newVarcharColumnDefBuilder().setColumnName("devops_platform").setLimit(40).setIsNullable(false).setDefaultValue("github").build(); + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(devopsPlatformRoleColumn) + .addColumn(sonarqubePermissionColumn) + .addColumn(devopsPlatformColumn) + .build()); + + addIndex(context, tableName, "uniq_devops_perms_mapping", true, devopsPlatformColumn, devopsPlatformRoleColumn, sonarqubePermissionColumn); + } + private void createGroupRoles(Context context) { String tableName = "group_roles"; VarcharColumnDef roleCol = newVarcharColumnDefBuilder("role").setLimit(64).setIsNullable(false).build(); - VarcharColumnDef componentUuidCol = newVarcharColumnDefBuilder(COMPONENT_UUID_COL_NAME).setIsNullable(true).setLimit(UUID_SIZE).build(); + VarcharColumnDef componentUuidCol = newVarcharColumnDefBuilder("entity_uuid").setIsNullable(true).setLimit(UUID_SIZE).build(); VarcharColumnDef groupUuidCol = newVarcharColumnDefBuilder(GROUP_UUID_COL_NAME).setIsNullable(true).setLimit(UUID_SIZE).build(); context.execute( newTableBuilder(tableName) @@ -670,8 +781,8 @@ public class CreateInitialSchema extends DdlChange { .addColumn(componentUuidCol) .addColumn(groupUuidCol) .build()); - addIndex(context, tableName, "group_roles_component_uuid", false, componentUuidCol); addIndex(context, tableName, "uniq_group_roles", true, groupUuidCol, componentUuidCol, roleCol); + addIndex(context, tableName, "group_roles_entity_uuid", false, componentUuidCol); } private void createGroups(Context context) { @@ -696,6 +807,7 @@ public class CreateInitialSchema extends DdlChange { newTableBuilder(tableName) .addColumn(groupUuidCol) .addColumn(userUuidCol) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setLimit(UUID_SIZE).setIsNullable(false).build()) .build()); addIndex(context, tableName, "index_groups_users_group_uuid", false, groupUuidCol); addIndex(context, tableName, "index_groups_users_user_uuid", false, userUuidCol); @@ -720,7 +832,7 @@ public class CreateInitialSchema extends DdlChange { private void createInternalProperties(Context context) { context.execute( newTableBuilder("internal_properties") - .addPkColumn(newVarcharColumnDefBuilder("kee").setLimit(20).setIsNullable(false).build()) + .addPkColumn(newVarcharColumnDefBuilder("kee").setLimit(40).setIsNullable(false).build()) .addColumn(newBooleanColumnDefBuilder().setColumnName(IS_EMPTY_COL_NAME).setIsNullable(false).build()) .addColumn(newVarcharColumnDefBuilder().setColumnName(TEXT_VALUE_COL_NAME).setLimit(MAX_SIZE).setIgnoreOracleUnit(true).build()) .addColumn(newClobColumnDefBuilder().setColumnName(CLOB_VALUE_COL_NAME).setIsNullable(true).build()) @@ -753,6 +865,31 @@ public class CreateInitialSchema extends DdlChange { addIndex(context, tableName, "issue_changes_issue_key_type", false, issueKeyCol, changeTypeCol); } + private void createIssuesFixed(Context context) { + String tableName = "issues_fixed"; + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("pull_request_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("issue_key").setIsNullable(false).setLimit(50).build()) + .build()); + } + + private void createIssueImpacts(Context context) { + String tableName = "issues_impacts"; + + VarcharColumnDef issueKeyColumn = newVarcharColumnDefBuilder().setColumnName("issue_key").setIsNullable(false).setLimit(UUID_SIZE).build(); + VarcharColumnDef softwareQualityColumn = newVarcharColumnDefBuilder().setColumnName("software_quality").setIsNullable(false).setLimit(40).build(); + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addColumn(issueKeyColumn) + .addColumn(softwareQualityColumn) + .addColumn(newVarcharColumnDefBuilder().setColumnName("severity").setIsNullable(false).setLimit(40).build()) + .addColumn(newBooleanColumnDefBuilder().setColumnName("manual_severity").setIsNullable(false).setDefaultValue(false).build()) + .build()); + + addIndex(context, tableName, "uniq_iss_key_sof_qual", true, issueKeyColumn, softwareQualityColumn); + + context.execute(new AddPrimaryKeyBuilder(tableName, "issue_key", "software_quality").build()); + } + private void createIssues(Context context) { var tableName = "issues"; VarcharColumnDef assigneeCol = newVarcharColumnDefBuilder("assignee").setLimit(USER_UUID_SIZE).build(); @@ -789,10 +926,12 @@ public class CreateInitialSchema extends DdlChange { .addColumn(projectUuidCol) .addColumn(newBlobColumnDefBuilder().setColumnName("locations").build()) .addColumn(new TinyIntColumnDef.Builder().setColumnName("issue_type").build()) - .addColumn(newBooleanColumnDefBuilder().setColumnName("from_hotspot").setIsNullable(true).build()) .addColumn(newBooleanColumnDefBuilder().setColumnName("quick_fix_available").setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("rule_description_context_key").setLimit(50).build()) .addColumn(newBlobColumnDefBuilder().setColumnName("message_formattings").build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("code_variants").setLimit(4000).setIsNullable(true).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("clean_code_attribute").setLimit(40).setIsNullable(true).build()) + .addColumn(newBooleanColumnDefBuilder().setColumnName("prioritized_rule").setIsNullable(true).build()) .build()); addIndex(context, tableName, "issues_assignee", false, assigneeCol); @@ -804,25 +943,27 @@ public class CreateInitialSchema extends DdlChange { addIndex(context, tableName, "issues_rule_uuid", false, ruleUuidCol); } - private void createLiveMeasures(Context context) { - String tableName = "live_measures"; - VarcharColumnDef projectUuidCol = newVarcharColumnDefBuilder(PROJECT_UUID_COL_NAME).setIsNullable(false).setLimit(OLD_UUID_VARCHAR_SIZE).build(); - VarcharColumnDef componentUuidCol = newVarcharColumnDefBuilder(COMPONENT_UUID_COL_NAME).setIsNullable(false).setLimit(OLD_UUID_VARCHAR_SIZE).build(); - VarcharColumnDef metricUuidCol = newVarcharColumnDefBuilder(METRIC_UUID_COL_NAME).setLimit(UUID_SIZE).setIsNullable(false).build(); - context.execute(newTableBuilder(tableName) - .addPkColumn(UUID_COL) - .addColumn(projectUuidCol) - .addColumn(componentUuidCol) - .addColumn(metricUuidCol) - .addColumn(newDecimalColumnDefBuilder().setColumnName(VALUE_COL_NAME).setPrecision(38).setScale(20).build()) - .addColumn(newVarcharColumnDefBuilder(TEXT_VALUE_COL_NAME).setIsNullable(true).setLimit(MAX_SIZE).build()) - .addColumn(newBlobColumnDefBuilder().setColumnName("measure_data").setIsNullable(true).build()) - .addColumn(newVarcharColumnDefBuilder("update_marker").setIsNullable(true).setLimit(UUID_SIZE).build()) - .addColumn(TECHNICAL_CREATED_AT_COL) - .addColumn(TECHNICAL_UPDATED_AT_COL) + private void createMeasures(Context context) { + String columnComponentUuid = "component_uuid"; + String columnBranchUuid = "branch_uuid"; + String columnJsonValue = "json_value"; + String columnJsonValueHash = "json_value_hash"; + String columnCreatedAt = "created_at"; + String columnUpdatedAt = "updated_at"; + + String tableName = "measures"; + + VarcharColumnDef branchUuidColumnDef = newVarcharColumnDefBuilder().setColumnName(columnBranchUuid).setIsNullable(false).setLimit(UUID_SIZE).build(); + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName(columnComponentUuid).setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(branchUuidColumnDef) + .addColumn(newClobColumnDefBuilder().setColumnName(columnJsonValue).setIsNullable(false).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(columnJsonValueHash).setIsNullable(false).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(columnCreatedAt).setIsNullable(false).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(columnUpdatedAt).setIsNullable(false).build()) .build()); - addIndex(context, tableName, "live_measures_project", false, projectUuidCol); - addIndex(context, tableName, "live_measures_component", true, componentUuidCol, metricUuidCol); + + addIndex(context, tableName, "measures_branch_uuid", false, branchUuidColumnDef); } private void createMetrics(Context context) { @@ -864,6 +1005,7 @@ public class CreateInitialSchema extends DdlChange { .addColumn(valueCol) .addColumn(TECHNICAL_UPDATED_AT_COL) .addColumn(TECHNICAL_CREATED_AT_COL) + .addColumn(newVarcharColumnDefBuilder().setColumnName("previous_non_compliant_value").setLimit(255).setIsNullable(true).build()) .build()); addIndex(context, tableName, "uniq_new_code_periods", true, projectUuidCol, branchUuidCol); @@ -1073,8 +1215,30 @@ public class CreateInitialSchema extends DdlChange { .addColumn(TECHNICAL_UPDATED_AT_COL) .addColumn(newBooleanColumnDefBuilder("exclude_from_purge").setDefaultValue(false).setIsNullable(false).build()) .addColumn(newBooleanColumnDefBuilder("need_issue_sync").setIsNullable(false).build()) + .addColumn(newBooleanColumnDefBuilder().setColumnName("is_main").setIsNullable(false).build()) .build()); addIndex(context, tableName, "uniq_project_branches", true, branchTypeCol, projectUuidCol, keeCol); + addIndex(context, tableName, "project_branches_project_uuid", false, projectUuidCol); + } + + private void createProjectDependencies(Context context) { + String tableName = "project_dependencies"; + + String columnUuidName = "uuid"; + String columnVersionName = "version"; + String columnIncludePathsName = "include_paths"; + String columnPackageManagerName = "package_manager"; + String columnCreatedAtName = "created_at"; + String columnUpdatedAtName = "updated_at"; + + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName(columnUuidName).setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newClobColumnDefBuilder().setColumnName(columnVersionName).setIsNullable(true).build()) + .addColumn(newClobColumnDefBuilder().setColumnName(columnIncludePathsName).setIsNullable(true).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(columnPackageManagerName).setIsNullable(true).setLimit(50).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(columnCreatedAtName).setIsNullable(false).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(columnUpdatedAtName).setIsNullable(false).build()) + .build()); } private void createProjectLinks(Context context) { @@ -1092,22 +1256,6 @@ public class CreateInitialSchema extends DdlChange { addIndex(context, tableName, "project_links_project", false, projectUuidCol); } - private void createProjectMappings(Context context) { - String tableName = "project_mappings"; - VarcharColumnDef keyTypeCol = newVarcharColumnDefBuilder("key_type").setIsNullable(false).setLimit(200).build(); - VarcharColumnDef keyCol = newVarcharColumnDefBuilder("kee").setIsNullable(false).setLimit(MAX_SIZE).build(); - VarcharColumnDef projectUuidCol = newVarcharColumnDefBuilder(PROJECT_UUID_COL_NAME).setIsNullable(false).setLimit(UUID_SIZE).build(); - context.execute(newTableBuilder(tableName) - .addPkColumn(UUID_COL) - .addColumn(keyTypeCol) - .addColumn(keyCol) - .addColumn(projectUuidCol) - .addColumn(TECHNICAL_CREATED_AT_COL) - .build()); - addIndex(context, tableName, "key_type_kee", true, keyTypeCol, keyCol); - addIndex(context, tableName, PROJECT_UUID_COL_NAME, false, projectUuidCol); - } - private void createProjectMeasures(Context context) { String tableName = "project_measures"; IntegerColumnDef personIdCol = newIntegerColumnDefBuilder().setColumnName("person_id").build(); @@ -1147,12 +1295,11 @@ public class CreateInitialSchema extends DdlChange { private void createProjects(Context context) { String tableName = "projects"; - VarcharColumnDef uuidCol = UUID_COL; VarcharColumnDef keeCol = newVarcharColumnDefBuilder("kee").setLimit(400).setIsNullable(false).build(); VarcharColumnDef qualifierCol = newVarcharColumnDefBuilder("qualifier").setLimit(10).setIsNullable(false).build(); context.execute( newTableBuilder(tableName) - .addPkColumn(uuidCol) + .addPkColumn(UUID_COL) .addColumn(keeCol) .addColumn(qualifierCol) .addColumn(newVarcharColumnDefBuilder("name").setLimit(2_000).setIsNullable(true).build()) @@ -1161,6 +1308,10 @@ public class CreateInitialSchema extends DdlChange { .addColumn(newVarcharColumnDefBuilder("tags").setLimit(500).setIsNullable(true).build()) .addColumn(NULLABLE_TECHNICAL_CREATED_AT_COL) .addColumn(TECHNICAL_UPDATED_AT_COL) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName("ncloc").setIsNullable(true).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("creation_method").setLimit(50).setIsNullable(false).build()) + .addColumn(newBooleanColumnDefBuilder().setColumnName("contains_ai_code").setIsNullable(false).setDefaultValue(false).build()) + .addColumn(newBooleanColumnDefBuilder().setColumnName("ai_code_fix_enabled").setIsNullable(false).setDefaultValue(false).build()) .withPkConstraintName("pk_new_projects") .build()); addIndex(context, tableName, "uniq_projects_kee", true, keeCol); @@ -1182,6 +1333,8 @@ public class CreateInitialSchema extends DdlChange { private void createProperties(Context context) { String tableName = "properties"; VarcharColumnDef propKey = newVarcharColumnDefBuilder("prop_key").setLimit(512).setIsNullable(false).build(); + VarcharColumnDef entityUuidColumn = newVarcharColumnDefBuilder().setColumnName("entity_uuid").setIsNullable(true).setLimit(UUID_SIZE).build(); + VarcharColumnDef userUuidColumn = newVarcharColumnDefBuilder().setColumnName(USER_UUID_COL_NAME).setIsNullable(true).setLimit(USER_UUID_SIZE).build(); context.execute(newTableBuilder(tableName) .addPkColumn(UUID_COL) .addColumn(propKey) @@ -1189,12 +1342,13 @@ public class CreateInitialSchema extends DdlChange { .addColumn(newVarcharColumnDefBuilder(TEXT_VALUE_COL_NAME).setLimit(MAX_SIZE).build()) .addColumn(newClobColumnDefBuilder().setColumnName(CLOB_VALUE_COL_NAME).setIsNullable(true).build()) .addColumn(TECHNICAL_CREATED_AT_COL) - .addColumn(newVarcharColumnDefBuilder().setColumnName(COMPONENT_UUID_COL_NAME).setIsNullable(true).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName(USER_UUID_COL_NAME).setIsNullable(true).setLimit(USER_UUID_SIZE).build()) + .addColumn(entityUuidColumn) + .addColumn(userUuidColumn) // table with be renamed to properties in following migration, use final constraint name right away .withPkConstraintName("pk_properties") .build()); addIndex(context, tableName, "properties_key", false, propKey); + addIndex(context, tableName, "uniq_properties", true, propKey, entityUuidColumn, userUuidColumn); } private void createPushEvents(Context context) { @@ -1211,6 +1365,59 @@ public class CreateInitialSchema extends DdlChange { addIndex(context, tableName, "idx_push_even_crea_uuid_proj", false, TECHNICAL_CREATED_AT_COL, UUID_COL, projectUuidCol); } + private void createReportSchedules(Context context) { + String tableName = "report_schedules"; + VarcharColumnDef portfolioUuidColumn = newVarcharColumnDefBuilder().setColumnName("portfolio_uuid").setIsNullable(true).setLimit(UUID_SIZE).build(); + VarcharColumnDef branchUuidColumn = newVarcharColumnDefBuilder().setColumnName("branch_uuid").setIsNullable(true).setLimit(UUID_SIZE).build(); + context.execute(new CreateTableBuilder(getDialect(), "report_schedules") + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(portfolioUuidColumn) + .addColumn(branchUuidColumn) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName("last_send_time_in_ms").setIsNullable(false).build()) + .build()); + + addIndex(context, tableName, "uniq_report_schedules", true, portfolioUuidColumn, branchUuidColumn); + } + + private void createReportSubscriptions(Context context) { + String tableName = "report_subscriptions"; + VarcharColumnDef portfolioUuidColumn = newVarcharColumnDefBuilder().setColumnName("portfolio_uuid").setIsNullable(true).setLimit(UUID_SIZE).build(); + VarcharColumnDef branchUuidColumn = newVarcharColumnDefBuilder().setColumnName("branch_uuid").setIsNullable(true).setLimit(UUID_SIZE).build(); + VarcharColumnDef userUuidColumn = newVarcharColumnDefBuilder().setColumnName("user_uuid").setIsNullable(false).setLimit(UUID_SIZE).build(); + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(portfolioUuidColumn) + .addColumn(branchUuidColumn) + .addColumn(userUuidColumn) + .build()); + + addIndex(context, tableName, "uniq_report_subscriptions", true, portfolioUuidColumn, branchUuidColumn, userUuidColumn); + } + + private void createRuleChanges(Context context) { + String tableName = "rule_changes"; + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("new_clean_code_attribute").setIsNullable(true).setLimit(40).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("old_clean_code_attribute").setIsNullable(true).setLimit(40).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("rule_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .build()); + } + + private void createRuleImpactChanges(Context context) { + String tableName = "rule_impact_changes"; + VarcharColumnDef ruleChangeUuidColumn = newVarcharColumnDefBuilder().setColumnName("rule_change_uuid").setIsNullable(false).setLimit(40).build(); + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addColumn(newVarcharColumnDefBuilder().setColumnName("new_software_quality").setIsNullable(true).setLimit(40).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("old_software_quality").setIsNullable(true).setLimit(40).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("new_severity").setIsNullable(true).setLimit(40).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("old_severity").setIsNullable(true).setLimit(40).build()) + .addColumn(ruleChangeUuidColumn) + .build()); + + addIndex(context, tableName, "rule_impact_changes_r_c_uuid", false, ruleChangeUuidColumn); + } + private void createQGateGroupPermissions(Context context) { String tableName = "qgate_group_permissions"; VarcharColumnDef qualityGateUuidColumn = newVarcharColumnDefBuilder(QUALITY_GATE_UUID_COL_NAME).setLimit(UUID_SIZE).setIsNullable(false).build(); @@ -1245,6 +1452,8 @@ public class CreateInitialSchema extends DdlChange { .addColumn(newVarcharColumnDefBuilder(USER_UUID_COL_NAME).setLimit(USER_UUID_SIZE).setIsNullable(true).build()) .addColumn(newClobColumnDefBuilder().setColumnName("change_data").setIsNullable(true).build()) .addColumn(TECHNICAL_CREATED_AT_COL) + .addColumn(newVarcharColumnDefBuilder().setColumnName("rule_change_uuid").setLimit(40).setIsNullable(true).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("sq_version").setLimit(40).setIsNullable(true).build()) .build()); addIndex(context, tableName, "qp_changes_rules_profile_uuid", false, rulesProfileUuidCol); } @@ -1298,9 +1507,22 @@ public class CreateInitialSchema extends DdlChange { .addColumn(newBooleanColumnDefBuilder().setColumnName("is_built_in").setIsNullable(false).build()) .addColumn(DEPRECATED_TECHNICAL_CREATED_AT_COL) .addColumn(DEPRECATED_TECHNICAL_UPDATED_AT_COL) + .addColumn(newBooleanColumnDefBuilder().setColumnName("ai_code_supported").setIsNullable(false).setDefaultValue(false).build()) .build()); } + + private void createScimGroups(Context context) { + String tableName = "scim_groups"; + VarcharColumnDef groupUuidColumn = newVarcharColumnDefBuilder().setColumnName("group_uuid").setIsNullable(false).setLimit(UUID_SIZE).build(); + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("scim_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(groupUuidColumn) + .build()); + + addIndex(context, tableName, "uniq_scim_group_uuid", true, groupUuidColumn); + } + private void createScimUsers(Context context) { String tableName = "scim_users"; VarcharColumnDef userUuidCol = newVarcharColumnDefBuilder(USER_UUID_COL_NAME).setLimit(UUID_SIZE).setIsNullable(false).build(); @@ -1313,6 +1535,18 @@ public class CreateInitialSchema extends DdlChange { addIndex(context, tableName, "uniq_scim_users_user_uuid", true, userUuidCol); } + private void createScmAccounts(Context context) { + String tableName = "scm_accounts"; + ColumnDef scmAccountColumn = newVarcharColumnDefBuilder().setColumnName("scm_account").setIsNullable(false).setLimit(255).build(); + + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName(USER_UUID_COL_NAME).setIsNullable(false).setLimit(USER_UUID_SIZE).build()) + .addPkColumn(scmAccountColumn) + .build()); + + addIndex(context, tableName, "scm_accounts_scm_account", false, scmAccountColumn); + } + private void createSessionTokens(Context context) { String tableName = "session_tokens"; VarcharColumnDef userUuidCol = newVarcharColumnDefBuilder(USER_UUID_COL_NAME).setLimit(255).setIsNullable(false).build(); @@ -1374,7 +1608,6 @@ public class CreateInitialSchema extends DdlChange { .addColumn(newVarcharColumnDefBuilder("def_remediation_gap_mult").setLimit(20).setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("def_remediation_base_effort").setLimit(20).setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("gap_description").setLimit(MAX_SIZE).setIsNullable(true).build()) - .addColumn(newVarcharColumnDefBuilder("system_tags").setLimit(MAX_SIZE).setIsNullable(true).build()) .addColumn(newBooleanColumnDefBuilder().setColumnName("is_template").setIsNullable(false).setDefaultValue(false).build()) .addColumn(newVarcharColumnDefBuilder("description_format").setLimit(20).setIsNullable(true).build()) .addColumn(new TinyIntColumnDef.Builder().setColumnName("rule_type").setIsNullable(true).build()) @@ -1391,16 +1624,31 @@ public class CreateInitialSchema extends DdlChange { .addColumn(newVarcharColumnDefBuilder("remediation_function").setLimit(20).setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("remediation_gap_mult").setLimit(20).setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("remediation_base_effort").setLimit(20).setIsNullable(true).build()) - .addColumn(newVarcharColumnDefBuilder("tags").setLimit(4_000).setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("ad_hoc_name").setLimit(200).setIsNullable(true).build()) .addColumn(newClobColumnDefBuilder().setColumnName("ad_hoc_description").setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("ad_hoc_severity").setLimit(10).setIsNullable(true).build()) .addColumn(newTinyIntColumnDefBuilder().setColumnName("ad_hoc_type").setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("education_principles").setLimit(255).setIsNullable(true).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("clean_code_attribute").setLimit(40).setIsNullable(true).build()) .build()); addIndex(context, "rules", "rules_repo_key", true, pluginRuleKeyCol, pluginNameCol); } + private void createRulesDefaultImpacts(Context context) { + String tableName = "rules_default_impacts"; + VarcharColumnDef ruleUuidColumn = newVarcharColumnDefBuilder().setColumnName("rule_uuid").setIsNullable(false).setLimit(UUID_SIZE).build(); + VarcharColumnDef softwareQualityColumn = newVarcharColumnDefBuilder().setColumnName("software_quality").setIsNullable(false).setLimit(40).build(); + context.execute(new CreateTableBuilder(getDialect(), "rules_default_impacts") + .addColumn(ruleUuidColumn) + .addColumn(softwareQualityColumn) + .addColumn(newVarcharColumnDefBuilder().setColumnName("severity").setIsNullable(false).setLimit(40).build()) + .build()); + + addIndex(context, tableName, "uniq_rul_uuid_sof_qual", true, ruleUuidColumn, softwareQualityColumn); + + context.execute(new AddPrimaryKeyBuilder(tableName, "rule_uuid", "software_quality").build()); + } + private void createRulesParameters(Context context) { String tableName = "rules_parameters"; VarcharColumnDef ruleUuidCol = newVarcharColumnDefBuilder(RULE_UUID_COL_NAME).setLimit(UUID_SIZE).setIsNullable(false).build(); @@ -1432,6 +1680,15 @@ public class CreateInitialSchema extends DdlChange { .build()); } + private void createRuleTags(Context context) { + String tableName = "rule_tags"; + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("value").setIsNullable(false).setLimit(400).build()) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("rule_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newBooleanColumnDefBuilder().setColumnName("is_system_tag").setIsNullable(false).build()) + .build()); + } + private void createSamlMessageIds(Context context) { String tableName = "saml_message_ids"; VarcharColumnDef messageIdCol = newVarcharColumnDefBuilder("message_id").setLimit(255).setIsNullable(false).build(); @@ -1457,29 +1714,40 @@ public class CreateInitialSchema extends DdlChange { private void createSnapshots(Context context) { String tableName = "snapshots"; VarcharColumnDef uuidCol = newVarcharColumnDefBuilder("uuid").setLimit(OLD_UUID_VARCHAR_SIZE).setIsNullable(false).build(); - VarcharColumnDef componentUuidCol = newVarcharColumnDefBuilder(COMPONENT_UUID_COL_NAME).setLimit(OLD_UUID_VARCHAR_SIZE).setIsNullable(false).build(); + VarcharColumnDef rootComponentUuidColumn = newVarcharColumnDefBuilder("root_component_uuid").setLimit(OLD_UUID_VARCHAR_SIZE).setIsNullable(false).build(); context.execute( newTableBuilder(tableName) .addPkColumn(uuidCol) - .addColumn(componentUuidCol) + .addColumn(rootComponentUuidColumn) .addColumn(newVarcharColumnDefBuilder(STATUS_COL_NAME).setLimit(4).setIsNullable(false).setDefaultValue("U").build()) .addColumn(newBooleanColumnDefBuilder().setColumnName("islast").setIsNullable(false).setDefaultValue(false).build()) .addColumn(newVarcharColumnDefBuilder("version").setLimit(500).setIsNullable(true).build()) - .addColumn(newIntegerColumnDefBuilder().setColumnName("purge_status").setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("build_string").setLimit(100).setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("revision").setLimit(100).setIsNullable(true).build()) - .addColumn(newBigIntegerColumnDefBuilder().setColumnName("build_date").setIsNullable(true).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName("analysis_date").setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("period1_mode").setLimit(100).setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("period1_param").setLimit(100).setIsNullable(true).build()) .addColumn(newBigIntegerColumnDefBuilder().setColumnName("period1_date").setIsNullable(true).build()) .addColumn(NULLABLE_TECHNICAL_CREATED_AT_COL) + .addColumn(newBooleanColumnDefBuilder("purged").setIsNullable(false).build()) .build()); - addIndex(context, tableName, "snapshot_component", false, componentUuidCol); + addIndex(context, tableName, "snapshots_root_component_uuid", false, rootComponentUuidColumn); + } + + private void createTelemetryMetricsSent(Context context) { + String tableName = "telemetry_metrics_sent"; + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("metric_key").setIsNullable(false) + .setLimit(40).build()) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName("dimension").setIsNullable(false) + .setLimit(40).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName("last_sent").setIsNullable(false).build()) + .build()); } private void createUserRoles(Context context) { String tableName = "user_roles"; - VarcharColumnDef componentUuidCol = newVarcharColumnDefBuilder(COMPONENT_UUID_COL_NAME).setLimit(UUID_SIZE).setIsNullable(true).build(); + VarcharColumnDef componentUuidCol = newVarcharColumnDefBuilder("entity_uuid").setLimit(UUID_SIZE).setIsNullable(true).build(); VarcharColumnDef userUuidCol = newVarcharColumnDefBuilder(USER_UUID_COL_NAME).setLimit(USER_UUID_SIZE).setIsNullable(true).build(); context.execute( newTableBuilder(tableName) @@ -1488,14 +1756,14 @@ public class CreateInitialSchema extends DdlChange { .addColumn(componentUuidCol) .addColumn(userUuidCol) .build()); - addIndex(context, tableName, "user_roles_component_uuid", false, componentUuidCol); addIndex(context, tableName, "user_roles_user", false, userUuidCol); + addIndex(context, tableName, "user_roles_entity_uuid", false, componentUuidCol); } private void createUserDismissedMessage(Context context) { String tableName = "user_dismissed_messages"; VarcharColumnDef userUuidCol = newVarcharColumnDefBuilder(USER_UUID_COL_NAME).setLimit(USER_UUID_SIZE).setIsNullable(false).build(); - VarcharColumnDef projectUuidCol = newVarcharColumnDefBuilder(PROJECT_UUID_COL_NAME).setLimit(UUID_SIZE).setIsNullable(false).build(); + VarcharColumnDef projectUuidCol = newVarcharColumnDefBuilder(PROJECT_UUID_COL_NAME).setLimit(UUID_SIZE).setIsNullable(true).build(); VarcharColumnDef messageTypeCol = newVarcharColumnDefBuilder("message_type").setLimit(255).setIsNullable(false).build(); context.execute( newTableBuilder(tableName) @@ -1515,7 +1783,6 @@ public class CreateInitialSchema extends DdlChange { VarcharColumnDef userUuidCol = newVarcharColumnDefBuilder(USER_UUID_COL_NAME).setLimit(USER_UUID_SIZE).setIsNullable(false).build(); VarcharColumnDef nameCol = newVarcharColumnDefBuilder("name").setLimit(100).setIsNullable(false).build(); VarcharColumnDef tokenHashCol = newVarcharColumnDefBuilder("token_hash").setLimit(255).setIsNullable(false).build(); - VarcharColumnDef projectKeyCol = newVarcharColumnDefBuilder("project_key").setLimit(255).setIsNullable(true).build(); VarcharColumnDef typeCol = newVarcharColumnDefBuilder("type").setLimit(100).setIsNullable(false).build(); context.execute( newTableBuilder(tableName) @@ -1525,9 +1792,9 @@ public class CreateInitialSchema extends DdlChange { .addColumn(tokenHashCol) .addColumn(newBigIntegerColumnDefBuilder().setColumnName("last_connection_date").setIsNullable(true).build()) .addColumn(TECHNICAL_CREATED_AT_COL) - .addColumn(projectKeyCol) .addColumn(typeCol) .addColumn(newBigIntegerColumnDefBuilder().setColumnName(EXPIRATION_DATE_COL_NAME).setIsNullable(true).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("project_uuid").setIsNullable(true).setLimit(UUID_SIZE).build()) .build()); addIndex(context, tableName, "user_tokens_user_uuid_name", true, userUuidCol, nameCol); addIndex(context, tableName, "user_tokens_token_hash", true, tokenHashCol); @@ -1539,21 +1806,21 @@ public class CreateInitialSchema extends DdlChange { VarcharColumnDef externalLoginCol = newVarcharColumnDefBuilder("external_login").setLimit(255).setIsNullable(false).build(); VarcharColumnDef externalIdentityProviderCol = newVarcharColumnDefBuilder("external_identity_provider").setLimit(100).setIsNullable(false).build(); VarcharColumnDef externalIdCol = newVarcharColumnDefBuilder("external_id").setLimit(255).setIsNullable(false).build(); + VarcharColumnDef emailColumn = newVarcharColumnDefBuilder("email").setLimit(100).setIsNullable(true).build(); context.execute( newTableBuilder(tableName) .addPkColumn(newVarcharColumnDefBuilder("uuid").setLimit(USER_UUID_SIZE).setIsNullable(false).build()) .addColumn(loginCol) .addColumn(newVarcharColumnDefBuilder("name").setLimit(200).setIsNullable(true).build()) - .addColumn(newVarcharColumnDefBuilder("email").setLimit(100).setIsNullable(true).build()) + .addColumn(emailColumn) .addColumn(newVarcharColumnDefBuilder("crypted_password").setLimit(100).setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("salt").setLimit(40).setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("hash_method").setLimit(10).setIsNullable(true).build()) .addColumn(newBooleanColumnDefBuilder().setColumnName("active").setDefaultValue(true).setIsNullable(true).build()) - .addColumn(newVarcharColumnDefBuilder("scm_accounts").setLimit(MAX_SIZE).build()) .addColumn(externalLoginCol) .addColumn(externalIdentityProviderCol) .addColumn(externalIdCol) - .addColumn(newBooleanColumnDefBuilder().setColumnName("user_local").setIsNullable(true).build()) + .addColumn(newBooleanColumnDefBuilder().setColumnName("user_local").setIsNullable(false).build()) .addColumn(newVarcharColumnDefBuilder("homepage_type").setLimit(40).setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("homepage_parameter").setLimit(40).setIsNullable(true).build()) .addColumn(newBigIntegerColumnDefBuilder().setColumnName("last_connection_date").setIsNullable(true).build()) @@ -1562,21 +1829,23 @@ public class CreateInitialSchema extends DdlChange { .addColumn(newBooleanColumnDefBuilder().setColumnName("reset_password").setIsNullable(false).build()) .addColumn(newBigIntegerColumnDefBuilder().setColumnName("last_sonarlint_connection").setIsNullable(true).build()) .build()); + addIndex(context, tableName, "users_login", true, loginCol); addIndex(context, tableName, "users_updated_at", false, NULLABLE_TECHNICAL_UPDATED_AT_COL); addIndex(context, tableName, "uniq_external_id", true, externalIdentityProviderCol, externalIdCol); addIndex(context, tableName, "uniq_external_login", true, externalIdentityProviderCol, externalLoginCol); + addIndex(context, tableName, "users_email", false, emailColumn); } private void createWebhookDeliveries(Context context) { String tableName = "webhook_deliveries"; - VarcharColumnDef componentUuidColumn = newVarcharColumnDefBuilder(COMPONENT_UUID_COL_NAME).setLimit(UUID_SIZE).setIsNullable(false).build(); + VarcharColumnDef projectUuidColumn = newVarcharColumnDefBuilder("project_uuid").setLimit(UUID_SIZE).setIsNullable(false).build(); VarcharColumnDef ceTaskUuidColumn = newVarcharColumnDefBuilder("ce_task_uuid").setLimit(UUID_SIZE).setIsNullable(true).build(); VarcharColumnDef webhookUuidColumn = newVarcharColumnDefBuilder("webhook_uuid").setLimit(UUID_SIZE).setIsNullable(false).build(); context.execute(newTableBuilder(tableName) .addPkColumn(UUID_COL) .addColumn(webhookUuidColumn) - .addColumn(componentUuidColumn) + .addColumn(projectUuidColumn) .addColumn(ceTaskUuidColumn) .addColumn(newVarcharColumnDefBuilder(ANALYSIS_UUID_COL_NAME).setLimit(UUID_SIZE).setIsNullable(true).build()) .addColumn(newVarcharColumnDefBuilder("name").setLimit(100).setIsNullable(false).build()) @@ -1588,9 +1857,11 @@ public class CreateInitialSchema extends DdlChange { .addColumn(newClobColumnDefBuilder().setColumnName("error_stacktrace").setIsNullable(true).build()) .addColumn(TECHNICAL_CREATED_AT_COL) .build()); - addIndex(context, tableName, COMPONENT_UUID_COL_NAME, false, componentUuidColumn); - addIndex(context, tableName, "ce_task_uuid", false, ceTaskUuidColumn); - addIndex(context, tableName, "idx_wbhk_dlvrs_wbhk_uuid", false, webhookUuidColumn); + + addIndex(context, tableName, "wd_webhook_uuid_created_at", false, webhookUuidColumn, TECHNICAL_CREATED_AT_COL); + addIndex(context, tableName, "wd_project_uuid_created_at", false, projectUuidColumn, TECHNICAL_CREATED_AT_COL); + addIndex(context, tableName, "wd_ce_task_uuid_created_at", false, ceTaskUuidColumn, TECHNICAL_CREATED_AT_COL); + addIndex(context, tableName, "wd_created_at", false, TECHNICAL_CREATED_AT_COL); } private void createWebhooks(Context context) { diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v00/PopulateInitialSchema.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v00/PopulateInitialSchema.java index 67a25b6dbbd..d1326657d87 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v00/PopulateInitialSchema.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v00/PopulateInitialSchema.java @@ -19,15 +19,21 @@ */ package org.sonar.server.platform.db.migration.version.v00; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.Set; import org.sonar.api.utils.System2; import org.sonar.core.config.CorePropertyDefinitions; import org.sonar.core.platform.SonarQubeVersion; import org.sonar.core.util.UuidFactory; import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.history.MigrationHistory; import org.sonar.server.platform.db.migration.step.DataChange; import org.sonar.server.platform.db.migration.step.Upsert; @@ -36,6 +42,13 @@ import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.joining; import static java.util.stream.Stream.concat; import static java.util.stream.Stream.of; +import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.api.web.UserRole.CODEVIEWER; +import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.api.web.UserRole.SCAN; +import static org.sonar.api.web.UserRole.SECURITYHOTSPOT_ADMIN; +import static org.sonar.api.web.UserRole.USER; +import static org.sonar.core.config.MQRModeConstants.MULTI_QUALITY_MODE_ENABLED; public class PopulateInitialSchema extends DataChange { @@ -49,12 +62,15 @@ public class PopulateInitialSchema extends DataChange { private final System2 system2; private final UuidFactory uuidFactory; private final SonarQubeVersion sonarQubeVersion; + private final MigrationHistory migrationHistory; - public PopulateInitialSchema(Database db, System2 system2, UuidFactory uuidFactory, SonarQubeVersion sonarQubeVersion) { + public PopulateInitialSchema(Database db, System2 system2, UuidFactory uuidFactory, SonarQubeVersion sonarQubeVersion, + MigrationHistory migrationHistory) { super(db); this.system2 = system2; this.uuidFactory = uuidFactory; this.sonarQubeVersion = sonarQubeVersion; + this.migrationHistory = migrationHistory; } @Override @@ -66,6 +82,46 @@ public class PopulateInitialSchema extends DataChange { insertProperties(context, defaultQGUuid); insertGroupRoles(context, groups); insertGroupUsers(context, adminUserUuid, groups); + insertDevopsPermissionMapping(context); + insertGitlabPermissionMapping(context); + enableSpecificMqrMode(context); + } + + private void insertGitlabPermissionMapping(Context context) throws SQLException { + String insertQuery = """ + insert into devops_perms_mapping (uuid, devops_platform, devops_platform_role, sonarqube_permission) + values (?, ?, ?, ?) + """; + + Map<String, Set<String>> gitlabRoleToSqPermissions = Map.of( + "guest", Set.of(USER), + "reporter", Set.of(USER, CODEVIEWER), + "developer", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN), + "maintainer", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN, ADMIN), + "owner", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN, ADMIN) + ); + + try (Upsert upsert = context.prepareUpsert(insertQuery)) { + gitlabRoleToSqPermissions.forEach((role, permissions) -> insertGitlabRoleToSonarqubePermissionMapping(upsert, role, permissions)); + upsert.commit(); + } + } + + private void insertGitlabRoleToSonarqubePermissionMapping(Upsert upsert, String role, Set<String> sonarqubePermissions) { + sonarqubePermissions.forEach(permission -> insertGitlabRoleToSonarqubePermissionMapping(upsert, role, permission)); + } + + private void insertGitlabRoleToSonarqubePermissionMapping(Upsert upsert, String role, String sonarqubePermission) { + try { + upsert + .setString(1, uuidFactory.create()) + .setString(2, "gitlab") + .setString(3, role) + .setString(4, sonarqubePermission) + .execute(); + } catch (SQLException e) { + throw new IllegalStateException(e); + } } private String insertAdminUser(Context context) throws SQLException { @@ -237,17 +293,84 @@ public class PopulateInitialSchema extends DataChange { .commit(); } - private static void insertGroupUsers(Context context, String adminUserUuid, Groups groups) throws SQLException { + private void insertDevopsPermissionMapping(Context context) throws SQLException { + Map<String, Set<String>> devopsRoleToSqPermissions = Map.of( + "read", Set.of(USER, CODEVIEWER), + "triage", Set.of(USER, CODEVIEWER), + "write", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN), + "maintain", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN), + "admin", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN, ADMIN)); + + String insertQuery = """ + insert into devops_perms_mapping (uuid, devops_platform_role, sonarqube_permission) + values (?, ?, ?) + """; + try (Upsert upsert = context.prepareUpsert(insertQuery)) { + devopsRoleToSqPermissions.forEach((key, value) -> insertGithubRoleToSonarqubePermissionMapping(upsert, key, value)); + upsert.commit(); + } + } + + private void insertGithubRoleToSonarqubePermissionMapping(Upsert upsert, String githubRole, Set<String> sonarqubePermissions) { + sonarqubePermissions.forEach(permission -> insertGithubRoleToSonarqubePermissionMapping(upsert, githubRole, permission)); + } + + private void insertGithubRoleToSonarqubePermissionMapping(Upsert upsert, String githubRole, String sonarqubePermission) { + try { + upsert + .setString(1, uuidFactory.create()) + .setString(2, githubRole) + .setString(3, sonarqubePermission) + .execute(); + } catch (SQLException e) { + throw new IllegalStateException(e); + } + } + + + private void enableSpecificMqrMode(Context context) throws SQLException { + try (Connection connection = getDatabase().getDataSource().getConnection()) { + if (!paramExists(connection)) { + long version = migrationHistory.getInitialDbVersion(); + boolean mqrModeEnabled = version >= 102_000L || version == -1L; + Upsert upsert = context.prepareUpsert( + createInsertStatement("properties", + "uuid", + "prop_key", + "is_empty", + "text_value", + "created_at")); + upsert.setString(1, uuidFactory.create()) + .setString(2, MULTI_QUALITY_MODE_ENABLED) + .setBoolean(3, false) + .setString(4, String.valueOf(mqrModeEnabled)) + .setLong(5, system2.now()); + upsert.execute().commit(); + } + } + } + + private static boolean paramExists(Connection connection) throws SQLException { + String sql = "SELECT count(1) FROM properties WHERE prop_key = '" + MULTI_QUALITY_MODE_ENABLED + "'"; + try (PreparedStatement statement = connection.prepareStatement(sql)) { + ResultSet result = statement.executeQuery(); + return result.next() && result.getInt(1) > 0; + } + } + + private void insertGroupUsers(Context context, String adminUserUuid, Groups groups) throws SQLException { truncateTable(context, "groups_users"); - Upsert upsert = context.prepareUpsert(createInsertStatement("groups_users", "user_uuid", "group_uuid")); + Upsert upsert = context.prepareUpsert(createInsertStatement("groups_users", "uuid", "user_uuid", "group_uuid")); upsert - .setString(1, adminUserUuid) - .setString(2, groups.userGroupUuid()) + .setString(1, uuidFactory.create()) + .setString(2, adminUserUuid) + .setString(3, groups.userGroupUuid()) .addBatch(); upsert - .setString(1, adminUserUuid) - .setString(2, groups.adminGroupUuid()) + .setString(1, uuidFactory.create()) + .setString(2, adminUserUuid) + .setString(3, groups.adminGroupUuid()) .addBatch(); upsert .execute() diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/AddNclocToProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/AddNclocToProjects.java deleted file mode 100644 index 35be11c30b7..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/AddNclocToProjects.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.BigIntegerColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AddNclocToProjects extends DdlChange { - - public static final String PROJECT_TABLE_NAME = "projects"; - public static final String NCLOC_COLUMN_NAME = "ncloc"; - - public AddNclocToProjects(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - if (checkIfColumnExists()) { - return; - } - BigIntegerColumnDef columnDef = BigIntegerColumnDef.newBigIntegerColumnDefBuilder().setColumnName(NCLOC_COLUMN_NAME).setIsNullable(true).build(); - String request = new AddColumnsBuilder(getDialect(), PROJECT_TABLE_NAME).addColumn(columnDef).build(); - context.execute(request); - } - - public boolean checkIfColumnExists() throws SQLException { - try (var connection = getDatabase().getDataSource().getConnection()) { - if (DatabaseUtils.tableColumnExists(connection, PROJECT_TABLE_NAME, NCLOC_COLUMN_NAME)) { - return true; - } - } - return false; - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/CreateScimGroupsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/CreateScimGroupsTable.java deleted file mode 100644 index 3b3a1c540e0..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/CreateScimGroupsTable.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateScimGroupsTable extends CreateTableChange { - static final String TABLE_NAME = "scim_groups"; - - public CreateScimGroupsTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName("scim_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("group_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DbVersion100.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DbVersion100.java deleted file mode 100644 index 3b42c43444f..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DbVersion100.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import org.sonar.server.platform.db.migration.step.MigrationStepRegistry; -import org.sonar.server.platform.db.migration.version.DbVersion; - -// ignoring bad number formatting, as it's indented that we align the migration numbers to SQ versions -@SuppressWarnings("java:S3937") -public class DbVersion100 implements DbVersion { - - /** - * We use the start of the 10.X cycle as an opportunity to align migration numbers with the SQ version number. - * Please follow this pattern: - * 10_0_000 - * 10_0_001 - * 10_0_002 - * 10_1_000 - * 10_1_001 - * 10_1_002 - * 10_2_000 - */ - - @Override - public void addSteps(MigrationStepRegistry registry) { - registry - .add(10_0_000, "Remove orphan rules in Quality Profiles", RemoveOrphanRulesFromQualityProfiles.class) - .add(10_0_001, "Drop index 'projects_module_uuid' in the 'Components' table", DropIndexProjectsModuleUuidInComponents.class) - .add(10_0_002, "Drop column 'module_uuid' in the 'Components' table", DropModuleUuidInComponents.class) - .add(10_0_003, "Drop column 'module_uuid_path' in the 'Components' table", DropModuleUuidPathInComponents.class) - .add(10_0_004, "Drop column 'b_module_uuid' in the 'Components' table", DropBModuleUuidInComponents.class) - .add(10_0_005, "Drop column 'b_module_uuid_path' in the 'Components' table", DropBModuleUuidPathInComponents.class) - .add(10_0_006, "Drop index 'projects_root_uuid' in the 'Components' table", DropIndexProjectsRootUuidInComponents.class) - .add(10_0_007, "Drop column 'root_uuid' in the 'Components' table", DropRootUuidInComponents.class) - .add(10_0_008, "Update value of 'user_local' in the 'users' table", UpdateUserLocalValueInUsers.class) - .add(10_0_009, "Make column 'user_local' not nullable in the 'users' table", MakeColumnUserLocalNotNullableInUsers.class) - .add(10_0_010, "Create 'scim_groups' table", CreateScimGroupsTable.class) - .add(10_0_011, "Create unique index on scim_groups.group_uuid", CreateUniqueIndexForScimGroupsUuid.class) - .add(10_0_012, "Log a warning message if 'sonar.scim.enabled' is used", LogMessageIfSonarScimEnabledPresentProperty.class) - .add(10_0_013, "Drop 'sonar.scim.enabled' property", DropSonarScimEnabledProperty.class) - .add(10_0_014, "Drop any SCIM User provisioning, turning all users local", DropScimUserProvisioning.class) - .add(10_0_015, "Add ncloc to 'Projects' table", AddNclocToProjects.class) - .add(10_0_016, "Populate ncloc in 'Projects' table", PopulateNclocForForProjects.class) - ; - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropBModuleUuidInComponents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropBModuleUuidInComponents.java deleted file mode 100644 index bf6ed5b9184..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropBModuleUuidInComponents.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropBModuleUuidInComponents extends DropColumnChange { - private static final String COLUMN_NAME = "b_module_uuid"; - private static final String TABLE_NAME = "components"; - - public DropBModuleUuidInComponents(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropBModuleUuidPathInComponents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropBModuleUuidPathInComponents.java deleted file mode 100644 index b309dd7dff8..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropBModuleUuidPathInComponents.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropBModuleUuidPathInComponents extends DropColumnChange { - private static final String COLUMN_NAME = "b_module_uuid_path"; - private static final String TABLE_NAME = "components"; - - public DropBModuleUuidPathInComponents(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropIndexProjectsModuleUuidInComponents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropIndexProjectsModuleUuidInComponents.java deleted file mode 100644 index 1e17a225b38..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropIndexProjectsModuleUuidInComponents.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -public class DropIndexProjectsModuleUuidInComponents extends DropIndexChange { - private static final String INDEX_NAME = "projects_module_uuid"; - private static final String TABLE_NAME = "components"; - - public DropIndexProjectsModuleUuidInComponents(Database db) { - super(db, INDEX_NAME, TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropIndexProjectsRootUuidInComponents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropIndexProjectsRootUuidInComponents.java deleted file mode 100644 index d95fe0d6bec..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropIndexProjectsRootUuidInComponents.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -public class DropIndexProjectsRootUuidInComponents extends DropIndexChange { - private static final String INDEX_NAME = "projects_root_uuid"; - private static final String TABLE_NAME = "components"; - - public DropIndexProjectsRootUuidInComponents(Database db) { - super(db, INDEX_NAME, TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropModuleUuidInComponents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropModuleUuidInComponents.java deleted file mode 100644 index 683f8bfb89f..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropModuleUuidInComponents.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropModuleUuidInComponents extends DropColumnChange { - private static final String COLUMN_NAME = "module_uuid"; - private static final String TABLE_NAME = "components"; - - public DropModuleUuidInComponents(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropModuleUuidPathInComponents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropModuleUuidPathInComponents.java deleted file mode 100644 index 9a4e3c8778f..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropModuleUuidPathInComponents.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropModuleUuidPathInComponents extends DropColumnChange { - private static final String COLUMN_NAME = "module_uuid_path"; - private static final String TABLE_NAME = "components"; - - public DropModuleUuidPathInComponents(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropRootUuidInComponents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropRootUuidInComponents.java deleted file mode 100644 index 0556df3679a..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropRootUuidInComponents.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropRootUuidInComponents extends DropColumnChange { - private static final String COLUMN_NAME = "root_uuid"; - private static final String TABLE_NAME = "components"; - - protected DropRootUuidInComponents(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropSonarScimEnabledProperty.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropSonarScimEnabledProperty.java deleted file mode 100644 index 8395bb55ee4..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/DropSonarScimEnabledProperty.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; - -public class DropSonarScimEnabledProperty extends DataChange { - - public DropSonarScimEnabledProperty(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - context.prepareUpsert("delete from properties where prop_key = ?") - .setString(1, "sonar.scim.enabled") - .execute() - .commit(); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/LogMessageIfSonarScimEnabledPresentProperty.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/LogMessageIfSonarScimEnabledPresentProperty.java deleted file mode 100644 index 23fc107fe3a..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/LogMessageIfSonarScimEnabledPresentProperty.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; - -public class LogMessageIfSonarScimEnabledPresentProperty extends DataChange { - - private static final Logger LOG = LoggerFactory.getLogger(LogMessageIfSonarScimEnabledPresentProperty.class); - public static final String SONAR_SCIM_ENABLED = "sonar.scim.enabled"; - private static final String SCIM_DOC_URL = "https://docs.sonarsource.com/sonarqube/10.1/instance-administration/authentication/saml/scim/overview/"; - - public LogMessageIfSonarScimEnabledPresentProperty(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - context.prepareSelect("select * from properties where prop_key = ?") - .setString(1, SONAR_SCIM_ENABLED) - .scroll(row -> LOG.warn("'{}' property is defined but not read anymore." + - " Please read the upgrade notes for the instruction to upgrade. User provisioning is deactivated until reactivated" + - " from the SonarQube Administration Interface (\"General->Authentication\"). See documentation: {}", SONAR_SCIM_ENABLED, - SCIM_DOC_URL)); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/MakeColumnUserLocalNotNullableInUsers.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/MakeColumnUserLocalNotNullableInUsers.java deleted file mode 100644 index c4bd9eaad10..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/MakeColumnUserLocalNotNullableInUsers.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.BooleanColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class MakeColumnUserLocalNotNullableInUsers extends DdlChange { - private static final String TABLE_NAME = "users"; - private static final String COLUMN_NAME = "user_local"; - - private static final BooleanColumnDef columnDefinition = BooleanColumnDef.newBooleanColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setIsNullable(false) - .build(); - - public MakeColumnUserLocalNotNullableInUsers(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - context.execute(new AlterColumnsBuilder(getDialect(), TABLE_NAME) - .updateColumn(columnDefinition) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/PopulateNclocForForProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/PopulateNclocForForProjects.java deleted file mode 100644 index fb4bcee8bef..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/PopulateNclocForForProjects.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class PopulateNclocForForProjects extends DataChange { - - private static final String SELECT_QUERY = """ - SELECT b.project_uuid AS projectUuid, max(lm.value) AS maxncloc - FROM live_measures lm - INNER JOIN metrics m ON m.uuid = lm.metric_uuid - INNER JOIN project_branches b ON b.uuid = lm.component_uuid - INNER JOIN projects p on p.uuid = b.project_uuid and p.qualifier = 'TRK' - WHERE m.name = 'ncloc' - GROUP BY b.project_uuid - """; - - public PopulateNclocForForProjects(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - try (Connection c = getDatabase().getDataSource().getConnection()) { - // the table is deleted in 10.8, this check ensures the migration re-entrance - if (!DatabaseUtils.tableExists("live_measures", c)) { - return; - } - } - - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update("update projects set ncloc = ? where uuid = ?"); - massUpdate.execute((row, update) -> { - String uuid = row.getString(1); - Long ncloc = row.getLong(2); - update.setLong(1, ncloc); - update.setString(2, uuid); - return true; - }); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/RemoveOrphanRulesFromQualityProfiles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/RemoveOrphanRulesFromQualityProfiles.java deleted file mode 100644 index 22693377d98..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/RemoveOrphanRulesFromQualityProfiles.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import org.sonar.api.utils.System2; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; -import org.sonar.server.platform.db.migration.step.Select; -import org.sonar.server.platform.db.migration.step.SqlStatement; - -public class RemoveOrphanRulesFromQualityProfiles extends DataChange { - - private final UuidFactory uuidFactory; - private final System2 system2; - - public RemoveOrphanRulesFromQualityProfiles(Database db, UuidFactory uuidFactory, System2 system2) { - super(db); - this.uuidFactory = uuidFactory; - this.system2 = system2; - } - - @Override - protected void execute(Context context) throws SQLException { - final String SELECT_QUERY = "select ar.uuid, ar.profile_uuid, ar.rule_uuid from rules_profiles rp " + - "inner join active_rules ar on ar.profile_uuid = rp.uuid " + - "inner join rules r on r.uuid = ar.rule_uuid " + - "where rp.language != r.language"; - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - - final String UPDATE_QUERY = """ - INSERT INTO qprofile_changes - (kee, rules_profile_uuid, change_type, created_at, user_uuid, change_data) - VALUES(?, ?, ?, ?, ?, ?) - """; - massUpdate.update(UPDATE_QUERY); - massUpdate.update("delete from active_rules where uuid = ?"); - - massUpdate.execute((row, update, index) -> { - if (index == 0) { - prepareUpdateForQProfileChanges(row, update); - } - if (index == 1) { - update.setString(1, row.getString(1)); - } - return true; - }); - } - - private void prepareUpdateForQProfileChanges(Select.Row selectedRow, SqlStatement update) throws SQLException { - update.setString(1, uuidFactory.create()) - .setString(2, selectedRow.getString(2)) - .setString(3, "DEACTIVATED") - .setLong(4, system2.now()) - .setString(5, null) - .setString(6, "ruleUuid=" + selectedRow.getString(3)); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/UpdateUserLocalValueInUsers.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/UpdateUserLocalValueInUsers.java deleted file mode 100644 index 81bbeca7108..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/UpdateUserLocalValueInUsers.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v100; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class UpdateUserLocalValueInUsers extends DataChange { - - public UpdateUserLocalValueInUsers(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select("select uuid from users where user_local is null"); - massUpdate.update("update users set user_local = ? where uuid = ?"); - massUpdate.execute((row, update) -> { - String uuid = row.getString(1); - update.setBoolean(1, true); - update.setString(2, uuid); - return true; - }); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddCodeVariantsColumnInIssuesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddCodeVariantsColumnInIssuesTable.java deleted file mode 100644 index edffe2da451..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddCodeVariantsColumnInIssuesTable.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AddCodeVariantsColumnInIssuesTable extends DdlChange { - - private static final String TABLE_NAME = "issues"; - private static final String COLUMN_NAME = "code_variants"; - private static final int COLUMN_SIZE = 4000; - - public AddCodeVariantsColumnInIssuesTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { - ColumnDef columnDef = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setLimit(COLUMN_SIZE) - .setIsNullable(true) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME).addColumn(columnDef).build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddIsMainColumnInProjectBranches.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddIsMainColumnInProjectBranches.java deleted file mode 100644 index 7cb20f6702b..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddIsMainColumnInProjectBranches.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.BooleanColumnDef; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AddIsMainColumnInProjectBranches extends DdlChange { - - private static final String TABLE_NAME = "project_branches"; - private static final String COLUMN_NAME = "is_main"; - - public AddIsMainColumnInProjectBranches(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection c = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(c, TABLE_NAME, COLUMN_NAME)) { - ColumnDef columnDef = BooleanColumnDef.newBooleanColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setIsNullable(true) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME).addColumn(columnDef).build()); - } - } - - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddReportSubscriptionsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddReportSubscriptionsTable.java deleted file mode 100644 index 5e0e2d4af40..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddReportSubscriptionsTable.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class AddReportSubscriptionsTable extends CreateTableChange { - - static final String TABLE_NAME = "report_subscriptions"; - - public AddReportSubscriptionsTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("portfolio_uuid").setIsNullable(true).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("branch_uuid").setIsNullable(true).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("user_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AlterIsMainColumnInProjectBranches.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AlterIsMainColumnInProjectBranches.java deleted file mode 100644 index 7d6030cdf1a..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AlterIsMainColumnInProjectBranches.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.BooleanColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AlterIsMainColumnInProjectBranches extends DdlChange { - - private static final String TABLE_NAME = "project_branches"; - private static final String COLUMN_NAME = "is_main"; - - public AlterIsMainColumnInProjectBranches(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - BooleanColumnDef newColumnDef = new BooleanColumnDef.Builder() - .setColumnName(COLUMN_NAME) - .setIsNullable(false) - .build(); - context.execute(new AlterColumnsBuilder(getDialect(), TABLE_NAME).updateColumn(newColumnDef).build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateExternalGroupsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateExternalGroupsTable.java deleted file mode 100644 index 8db848e63cf..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateExternalGroupsTable.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateExternalGroupsTable extends CreateTableChange { - - static final String TABLE_NAME = "external_groups"; - @VisibleForTesting - static final String GROUP_UUID_COLUMN_NAME = "group_uuid"; - static final String EXTERNAL_GROUP_ID_COLUMN_NAME = "external_group_id"; - static final String EXTERNAL_IDENTITY_PROVIDER_COLUMN_NAME = "external_identity_provider"; - - public CreateExternalGroupsTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName(GROUP_UUID_COLUMN_NAME).setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName(EXTERNAL_GROUP_ID_COLUMN_NAME).setIsNullable(false).setLimit(255).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName(EXTERNAL_IDENTITY_PROVIDER_COLUMN_NAME).setIsNullable(false).setLimit(100).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexForScmAccountOnScmAccountsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexForScmAccountOnScmAccountsTable.java deleted file mode 100644 index 4c421ff3628..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexForScmAccountOnScmAccountsTable.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v101.CreateScmAccountsTable.SCM_ACCOUNT_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateScmAccountsTable.SCM_ACCOUNTS_TABLE_NAME; - -class CreateIndexForScmAccountOnScmAccountsTable extends DdlChange { - - @VisibleForTesting - static final String INDEX_NAME = "scm_accounts_scm_account"; - - public CreateIndexForScmAccountOnScmAccountsTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - createIndex(context, connection); - } - } - - private void createIndex(Context context, Connection connection) { - if (!DatabaseUtils.indexExistsIgnoreCase(SCM_ACCOUNTS_TABLE_NAME, INDEX_NAME, connection)) { - context.execute(new CreateIndexBuilder(getDialect()) - .setTable(SCM_ACCOUNTS_TABLE_NAME) - .setName(INDEX_NAME) - .addColumn(SCM_ACCOUNT_COLUMN_NAME, false) - .setUnique(false) - .build()); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateProjectUuidInUserTokens.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateProjectUuidInUserTokens.java deleted file mode 100644 index b8d62a3a04b..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateProjectUuidInUserTokens.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; - -public class CreateProjectUuidInUserTokens extends DdlChange { - - private static final String TABLE_NAME = "user_tokens"; - private static final String COLUMN_NAME = "project_uuid"; - - public CreateProjectUuidInUserTokens(Database db) { - super(db); - } - - @Override - public void execute(DdlChange.Context context) throws SQLException { - try (Connection c = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(c, TABLE_NAME, COLUMN_NAME)) { - ColumnDef columnDef = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setIsNullable(true) - .setLimit(UUID_SIZE) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME).addColumn(columnDef).build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateScmAccountsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateScmAccountsTable.java deleted file mode 100644 index f74d6b2ed08..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateScmAccountsTable.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.USER_UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -class CreateScmAccountsTable extends CreateTableChange { - static final String SCM_ACCOUNTS_TABLE_NAME = "scm_accounts"; - static final String SCM_ACCOUNT_COLUMN_NAME = "scm_account"; - @VisibleForTesting - static final String USER_UUID_COLUMN_NAME = "user_uuid"; - - @VisibleForTesting - static final int SCM_ACCOUNT_SIZE = 255; - - public CreateScmAccountsTable(Database db) { - super(db, SCM_ACCOUNTS_TABLE_NAME); - } - - @Override - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName(USER_UUID_COLUMN_NAME).setIsNullable(false).setLimit(USER_UUID_SIZE).build()) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName(SCM_ACCOUNT_COLUMN_NAME).setIsNullable(false).setLimit(SCM_ACCOUNT_SIZE).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateUniqueIndexForReportSchedulesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateUniqueIndexForReportSchedulesTable.java deleted file mode 100644 index 84cb2766d2d..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateUniqueIndexForReportSchedulesTable.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v101.AddReportSchedulesTable.TABLE_NAME; - -public class CreateUniqueIndexForReportSchedulesTable extends DdlChange { - - @VisibleForTesting - static final String COLUMN_NAME_PORTFOLIO = "portfolio_uuid"; - @VisibleForTesting - static final String COLUMN_NAME_BRANCH = "branch_uuid"; - - @VisibleForTesting - static final String INDEX_NAME = "uniq_report_schedules"; - - - public CreateUniqueIndexForReportSchedulesTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - - try (Connection connection = getDatabase().getDataSource().getConnection()) { - createUserUuidUniqueIndex(context, connection); - } - } - - private void createUserUuidUniqueIndex(Context context, Connection connection) { - if (!DatabaseUtils.indexExistsIgnoreCase(TABLE_NAME, INDEX_NAME, connection)) { - context.execute(new CreateIndexBuilder(getDialect()) - .setTable(TABLE_NAME) - .setName(INDEX_NAME) - .addColumn(COLUMN_NAME_PORTFOLIO, true) - .addColumn(COLUMN_NAME_BRANCH, true) - .setUnique(true) - .build()); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateUniqueIndexForReportSubscriptionsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateUniqueIndexForReportSubscriptionsTable.java deleted file mode 100644 index f2ab4199379..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateUniqueIndexForReportSubscriptionsTable.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v101.AddReportSubscriptionsTable.TABLE_NAME; - - -public class CreateUniqueIndexForReportSubscriptionsTable extends DdlChange { - - @VisibleForTesting - static final String COLUMN_NAME_PORTFOLIO = "portfolio_uuid"; - @VisibleForTesting - static final String COLUMN_NAME_BRANCH = "branch_uuid"; - @VisibleForTesting - static final String COLUMN_NAME_USER = "user_uuid"; - - @VisibleForTesting - static final String INDEX_NAME = "uniq_report_subscriptions"; - - - public CreateUniqueIndexForReportSubscriptionsTable(Database db) { - super(db); - } - - @Override - public void execute(DdlChange.Context context) throws SQLException { - - try (Connection connection = getDatabase().getDataSource().getConnection()) { - createUserUuidUniqueIndex(context, connection); - } - } - - private void createUserUuidUniqueIndex(DdlChange.Context context, Connection connection) { - if (!DatabaseUtils.indexExistsIgnoreCase(TABLE_NAME, INDEX_NAME, connection)) { - context.execute(new CreateIndexBuilder(getDialect()) - .setTable(TABLE_NAME) - .setName(INDEX_NAME) - .addColumn(COLUMN_NAME_PORTFOLIO, true) - .addColumn(COLUMN_NAME_BRANCH, true) - .addColumn(COLUMN_NAME_USER, false) - .setUnique(true) - .build()); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/DbVersion101.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/DbVersion101.java deleted file mode 100644 index e4d928c20fa..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/DbVersion101.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import org.sonar.server.platform.db.migration.step.MigrationStepRegistry; -import org.sonar.server.platform.db.migration.version.DbVersion; - -// ignoring bad number formatting, as it's indented that we align the migration numbers to SQ versions -@SuppressWarnings("java:S3937") -public class DbVersion101 implements DbVersion { - - /** - * We use the start of the 10.X cycle as an opportunity to align migration numbers with the SQ version number. - * Please follow this pattern: - * 10_0_000 - * 10_0_001 - * 10_0_002 - * 10_1_000 - * 10_1_001 - * 10_1_002 - * 10_2_000 - */ - - @Override - public void addSteps(MigrationStepRegistry registry) { - registry - .add(10_1_000, "Add 'scm_accounts' table", CreateScmAccountsTable.class) - .add(10_1_001, "Migrate scm accounts from 'users' to 'scm_accounts' table", MigrateScmAccountsFromUsersToScmAccounts.class) - .add(10_1_002, "Add index on 'scm_accounts.scm_account'", CreateIndexForScmAccountOnScmAccountsTable.class) - .add(10_1_003, "Add index on 'users.email'", CreateIndexForEmailOnUsersTable.class) - .add(10_1_004, "Drop 'scm_accounts' column in 'users' table", DropScmAccountsInUsers.class) - .add(10_1_005, "Add column 'is_main' to 'project_branches' table", AddIsMainColumnInProjectBranches.class) - .add(10_1_006, "Update value of 'is_main' in 'project_branches' table", UpdateIsMainColumnInProjectBranches.class) - .add(10_1_007, "Alter column 'is_main' in 'project_branches' table - make it not nullable", AlterIsMainColumnInProjectBranches.class) - .add(10_1_008, "Increase size of 'internal_properties.kee' from 20 to 40 characters", IncreaseKeeColumnSizeInInternalProperties.class) - .add(10_1_009, "Create column 'project_uuid' in 'user_tokens", CreateProjectUuidInUserTokens.class) - .add(10_1_010, "Remove user tokens linked to unexistent project", RemoveOrphanUserTokens.class) - .add(10_1_011, "Populate 'project_key' in 'user_tokens'", PopulateProjectUuidInUserTokens.class) - .add(10_1_012, "Drop column 'project_key' in 'user_tokens", DropProjectKeyInUserTokens.class) - .add(10_1_013, "Increase size of 'ce_queue.task_type' from 15 to 40 characters", IncreaseTaskTypeColumnSizeInCeQueue.class) - .add(10_1_014, "Increase size of 'ce_activity.task_type' from 15 to 40 characters", IncreaseTaskTypeColumnSizeInCeActivity.class) - .add(10_1_015, "Add 'external_groups' table.", CreateExternalGroupsTable.class) - .add(10_1_016, "Add index on 'external_groups(external_identity_provider, external_id).", CreateIndexOnExternalIdAndIdentityOnExternalGroupsTable.class) - .add(10_1_017, "Add 'code_variants' column in 'issues' table", AddCodeVariantsColumnInIssuesTable.class) - .add(10_1_018, "Fix different uuids for subportfolios", FixDifferentUuidsForSubportfolios.class) - .add(10_1_019, "Add report_schedules table", AddReportSchedulesTable.class) - .add(10_1_020, "Add report_subscriptions table", AddReportSubscriptionsTable.class) - .add(10_1_021, "Add report_schedules unique index", CreateUniqueIndexForReportSchedulesTable.class) - .add(10_1_022, "Add report_subscriptions unique index", CreateUniqueIndexForReportSubscriptionsTable.class) - .add(10_1_023, "Rename column 'component_uuid' to 'entity_uuid' in the 'properties' table", RenameColumnComponentUuidInProperties.class) - .add(10_1_024, "Populate report_schedules table", PopulateReportSchedules.class) - .add(10_1_025, "Populate report_subscriptions table", PopulateReportSubscriptions.class) - .add(10_1_026, "Remove report properties", RemoveReportProperties.class) - ; - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/DropProjectKeyInUserTokens.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/DropProjectKeyInUserTokens.java deleted file mode 100644 index bfa60525602..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/DropProjectKeyInUserTokens.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -class DropProjectKeyInUserTokens extends DropColumnChange { - static final String TABLE_NAME = "user_tokens"; - static final String COLUMN_NAME = "project_key"; - - public DropProjectKeyInUserTokens(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/DropScmAccountsInUsers.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/DropScmAccountsInUsers.java deleted file mode 100644 index 48b875b97b4..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/DropScmAccountsInUsers.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -class DropScmAccountsInUsers extends DropColumnChange { - static final String TABLE_NAME = "users"; - static final String COLUMN_NAME = "scm_accounts"; - - public DropScmAccountsInUsers(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/FixDifferentUuidsForSubportfolios.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/FixDifferentUuidsForSubportfolios.java deleted file mode 100644 index 78621d88931..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/FixDifferentUuidsForSubportfolios.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class FixDifferentUuidsForSubportfolios extends DataChange { - private static final String SELECT_QUERY = """ - SELECT p.uuid, c.uuid - FROM portfolios p - INNER join components c on p.kee = c.kee AND p.uuid != c.uuid - and p.parent_uuid IS NOT NULL and p.root_uuid = c.branch_uuid and c.qualifier = 'SVW' - """; - - public FixDifferentUuidsForSubportfolios(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update("update portfolios set parent_uuid=? where parent_uuid=?"); - massUpdate.update("update portfolios set uuid=? where uuid=?"); - massUpdate.update("update portfolio_projects set portfolio_uuid=? where portfolio_uuid=?"); - massUpdate.update("update portfolio_references set portfolio_uuid=? where portfolio_uuid=?"); - - massUpdate.execute((row, update, index) -> { - String portfolioUuid = row.getString(1); - String componentUuid = row.getString(2); - update.setString(1, componentUuid); - update.setString(2, portfolioUuid); - return true; - }); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/IncreaseKeeColumnSizeInInternalProperties.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/IncreaseKeeColumnSizeInInternalProperties.java deleted file mode 100644 index 22be1e2a78e..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/IncreaseKeeColumnSizeInInternalProperties.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class IncreaseKeeColumnSizeInInternalProperties extends DdlChange { - @VisibleForTesting - static final String TABLE_NAME = "internal_properties"; - @VisibleForTesting - static final String COLUMN_NAME = "kee"; - @VisibleForTesting - static final int NEW_COLUMN_SIZE = 40; - - private static final VarcharColumnDef COLUMN_DEFINITION = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setLimit(NEW_COLUMN_SIZE) - .setIsNullable(false) - .build(); - - public IncreaseKeeColumnSizeInInternalProperties(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - context.execute(new AlterColumnsBuilder(getDialect(), TABLE_NAME) - .updateColumn(COLUMN_DEFINITION) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/IncreaseTaskTypeColumnSizeInCeActivity.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/IncreaseTaskTypeColumnSizeInCeActivity.java deleted file mode 100644 index 69518021b42..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/IncreaseTaskTypeColumnSizeInCeActivity.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class IncreaseTaskTypeColumnSizeInCeActivity extends DdlChange { - @VisibleForTesting - static final String TABLE_NAME = "ce_activity"; - @VisibleForTesting - static final String COLUMN_NAME = "task_type"; - @VisibleForTesting - static final int NEW_COLUMN_SIZE = 40; - - private static final VarcharColumnDef COLUMN_DEFINITION = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setLimit(NEW_COLUMN_SIZE) - .setIsNullable(false) - .build(); - - public IncreaseTaskTypeColumnSizeInCeActivity(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - context.execute(new AlterColumnsBuilder(getDialect(), TABLE_NAME) - .updateColumn(COLUMN_DEFINITION) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/IncreaseTaskTypeColumnSizeInCeQueue.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/IncreaseTaskTypeColumnSizeInCeQueue.java deleted file mode 100644 index 7d0d59aac4c..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/IncreaseTaskTypeColumnSizeInCeQueue.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class IncreaseTaskTypeColumnSizeInCeQueue extends DdlChange { - @VisibleForTesting - static final String TABLE_NAME = "ce_queue"; - @VisibleForTesting - static final String COLUMN_NAME = "task_type"; - @VisibleForTesting - static final int NEW_COLUMN_SIZE = 40; - - private static final VarcharColumnDef COLUMN_DEFINITION = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setLimit(NEW_COLUMN_SIZE) - .setIsNullable(false) - .build(); - - public IncreaseTaskTypeColumnSizeInCeQueue(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - context.execute(new AlterColumnsBuilder(getDialect(), TABLE_NAME) - .updateColumn(COLUMN_DEFINITION) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/MigrateScmAccountsFromUsersToScmAccounts.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/MigrateScmAccountsFromUsersToScmAccounts.java deleted file mode 100644 index f67bada71bc..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/MigrateScmAccountsFromUsersToScmAccounts.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.Set; -import org.apache.commons.lang3.StringUtils; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassRowSplitter; -import org.sonar.server.platform.db.migration.step.Select; - -import static java.util.Collections.emptySet; -import static java.util.stream.Collectors.toSet; - -class MigrateScmAccountsFromUsersToScmAccounts extends DataChange { - - @VisibleForTesting - static final char SCM_ACCOUNTS_SEPARATOR_CHAR = '\n'; - - public MigrateScmAccountsFromUsersToScmAccounts(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - if (isScmColumnDropped()) { - return; - } - migrateData(context); - } - - private boolean isScmColumnDropped() throws SQLException { - try (var connection = getDatabase().getDataSource().getConnection()) { - return !DatabaseUtils.tableColumnExists(connection, DropScmAccountsInUsers.TABLE_NAME, DropScmAccountsInUsers.COLUMN_NAME); - } - } - - private static void migrateData(Context context) throws SQLException { - MassRowSplitter<ScmAccountRow> massRowSplitter = context.prepareMassRowSplitter(); - - massRowSplitter.select("select u.uuid, lower(u.scm_accounts) from users u where u.active=? and not exists (select 1 from scm_accounts sa where sa.user_uuid = u.uuid)") - .setBoolean(1, true); - - massRowSplitter.insert("insert into scm_accounts (user_uuid, scm_account) values (?, ?)"); - - massRowSplitter.splitRow(MigrateScmAccountsFromUsersToScmAccounts::toScmAccountRows); - - massRowSplitter.execute((scmAccountRow, insert) -> { - insert.setString(1, scmAccountRow.userUuid()); - insert.setString(2, scmAccountRow.scmAccount()); - return true; - }); - } - - private static Set<ScmAccountRow> toScmAccountRows(Select.Row row) { - try { - String userUuid = row.getString(1); - String[] scmAccounts = StringUtils.split(row.getString(2), SCM_ACCOUNTS_SEPARATOR_CHAR); - if (scmAccounts == null) { - return emptySet(); - } - return Arrays.stream(scmAccounts) - .map(scmAccount -> new ScmAccountRow(userUuid, scmAccount)) - .collect(toSet()); - } catch (SQLException sqlException) { - throw new RuntimeException(sqlException); - } - } - - @VisibleForTesting - record ScmAccountRow(String userUuid, String scmAccount) { - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/PopulateProjectUuidInUserTokens.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/PopulateProjectUuidInUserTokens.java deleted file mode 100644 index 297a8106975..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/PopulateProjectUuidInUserTokens.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class PopulateProjectUuidInUserTokens extends DataChange { - private static final String SELECT_QUERY = """ - SELECT ut.uuid as tokenUuid, p.uuid as projectUuid - FROM user_tokens ut - INNER JOIN projects p ON ut.project_key = p.kee and ut.project_key is not null - """; - - public PopulateProjectUuidInUserTokens(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, "user_tokens", "project_key")) { - return; - } - } - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update("update user_tokens set project_uuid = ? where uuid = ?"); - massUpdate.execute((row, update) -> { - String uuid = row.getString(1); - String projectUuid = row.getString(2); - update.setString(1, projectUuid); - update.setString(2, uuid); - return true; - }); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/PopulateReportSchedules.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/PopulateReportSchedules.java deleted file mode 100644 index 88dac773119..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/PopulateReportSchedules.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.sonar.core.util.UuidFactoryImpl; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class PopulateReportSchedules extends DataChange { - private static final String SELECT_QUERY = """ - SELECT port.uuid as portfolioUuid, pb.uuid as branchUuid, p.text_value as value - FROM properties p - LEFT JOIN portfolios port ON p.entity_uuid = port.uuid - LEFT JOIN project_branches pb ON p.entity_uuid = pb.uuid - WHERE p.prop_key = 'sonar.governance.report.lastSendTimeInMs' or p.prop_key = 'sonar.governance.report.project.branch.lastSendTimeInMs' - AND NOT EXISTS ( - SELECT * FROM report_schedules rs - WHERE rs.branch_uuid = p.entity_uuid or rs.portfolio_uuid = p.entity_uuid - ) - """; - - public PopulateReportSchedules(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update("insert into report_schedules (uuid, branch_uuid, portfolio_uuid, last_send_time_in_ms) values (?, ?, ?, ?)"); - massUpdate.execute((row, update) -> { - String portfolioUuid = row.getString(1); - String branchUuid = row.getString(2); - - // one and only one needs to be null - if ((portfolioUuid == null) == (branchUuid == null)) { - return false; - } - - String value = row.getString(3); - long ms = Long.parseLong(value); - - update.setString(1, UuidFactoryImpl.INSTANCE.create()); - update.setString(2, branchUuid); - update.setString(3, portfolioUuid); - update.setLong(4, ms); - return true; - }); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/PopulateReportSubscriptions.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/PopulateReportSubscriptions.java deleted file mode 100644 index e9c00891375..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/PopulateReportSubscriptions.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.sonar.core.util.UuidFactoryImpl; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class PopulateReportSubscriptions extends DataChange { - - private static final String SELECT_QUERY = """ - SELECT port.uuid as portfolioUuid, pb.uuid as branchUuid, p.user_uuid as userUuid - FROM properties p - LEFT JOIN portfolios port ON p.entity_uuid = port.uuid - LEFT JOIN project_branches pb ON p.entity_uuid = pb.uuid - WHERE p.prop_key = 'sonar.governance.report.userNotification' or p.prop_key = 'sonar.governance.report.project.branch.userNotification' - AND NOT EXISTS ( - SELECT * FROM report_subscriptions rs - WHERE (rs.branch_uuid = p.entity_uuid or rs.portfolio_uuid = p.entity_uuid) and rs.user_uuid = p.user_uuid - ) - """; - - public PopulateReportSubscriptions(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update("insert into report_subscriptions (uuid, branch_uuid, portfolio_uuid, user_uuid) values (?, ?, ?, ?)"); - massUpdate.execute((row, update) -> { - String portfolioUuid = row.getString(1); - String branchUuid = row.getString(2); - - // one and only one needs to be null - if ((portfolioUuid == null) == (branchUuid == null)) { - return false; - } - - String userUuid = row.getString(3); - update.setString(1, UuidFactoryImpl.INSTANCE.create()); - update.setString(2, branchUuid); - update.setString(3, portfolioUuid); - update.setString(4, userUuid); - return true; - }); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/RemoveOrphanUserTokens.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/RemoveOrphanUserTokens.java deleted file mode 100644 index 9a9231d406b..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/RemoveOrphanUserTokens.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class RemoveOrphanUserTokens extends DataChange { - private static final String SELECT_QUERY = """ - SELECT ut.uuid as tokenUuid - FROM user_tokens ut - LEFT OUTER JOIN projects p ON ut.project_key = p.kee - WHERE p.uuid is null and ut.project_key IS NOT NULL - """; - - public RemoveOrphanUserTokens(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (DatabaseUtils.tableColumnExists(connection, "user_tokens", "project_key")) { - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update("delete from user_tokens where uuid = ?"); - massUpdate.execute((row, update) -> { - String uuid = row.getString(1); - update.setString(1, uuid); - return true; - }); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/RemoveReportProperties.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/RemoveReportProperties.java deleted file mode 100644 index 3bd753cc4a8..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/RemoveReportProperties.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class RemoveReportProperties extends DataChange { - private static final String SELECT_QUERY = """ - SELECT p.uuid as uuid from properties p - WHERE p.prop_key = 'sonar.governance.report.lastSendTimeInMs' or p.prop_key = 'sonar.governance.report.project.branch.lastSendTimeInMs' - or p.prop_key = 'sonar.governance.report.userNotification' or p.prop_key = 'sonar.governance.report.project.branch.userNotification' - """; - - public RemoveReportProperties(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update("delete from properties where uuid = ?"); - massUpdate.execute((row, delete) -> { - String uuid = row.getString(1); - delete.setString(1, uuid); - return true; - }); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/RenameColumnComponentUuidInProperties.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/RenameColumnComponentUuidInProperties.java deleted file mode 100644 index 4b3a29566d6..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/RenameColumnComponentUuidInProperties.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.RenameColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class RenameColumnComponentUuidInProperties extends DdlChange { - - public static final String TABLE_NAME = "properties"; - public static final String OLD_COLUMN_NAME = "component_uuid"; - public static final String NEW_COLUMN_NAME = "entity_uuid"; - - public RenameColumnComponentUuidInProperties(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection c = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(c, TABLE_NAME, NEW_COLUMN_NAME)) { - ColumnDef newColumnDef = new VarcharColumnDef.Builder() - .setColumnName(NEW_COLUMN_NAME) - .setIsNullable(true) - .setLimit(40) - .build(); - - context.execute(new RenameColumnsBuilder(getDialect(), TABLE_NAME).renameColumn(OLD_COLUMN_NAME, newColumnDef).build()); - } - } - - } -}
\ No newline at end of file diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/UpdateIsMainColumnInProjectBranches.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/UpdateIsMainColumnInProjectBranches.java deleted file mode 100644 index a416b8eeaed..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/UpdateIsMainColumnInProjectBranches.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v101; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class UpdateIsMainColumnInProjectBranches extends DataChange { - - public UpdateIsMainColumnInProjectBranches(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - MassUpdate massUpdate = context.prepareMassUpdate(); - - // we need to use case/when/then because Oracle doesn't accept simple solution uuid = project_uuid here - massUpdate.select("select uuid, case when uuid = project_uuid then 'true' else 'false' end from project_branches"); - massUpdate.update("update project_branches set is_main = ? where uuid = ?"); - massUpdate.execute((row, update) -> { - String uuid = row.getString(1); - boolean isMain = row.getBoolean(2); - update.setBoolean(1, isMain); - update.setString(2, uuid); - return true; - }); - - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/AddCleanCodeAttributeInRules.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/AddCleanCodeAttributeInRules.java deleted file mode 100644 index 1fd69e453ce..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/AddCleanCodeAttributeInRules.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AddCleanCodeAttributeInRules extends DdlChange { - private static final String TABLE_NAME = "rules"; - private static final String COLUMN_NAME = "clean_code_attribute"; - private static final int NEW_COLUMN_SIZE = 40; - - - public AddCleanCodeAttributeInRules(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { - ColumnDef columnDef = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setLimit(NEW_COLUMN_SIZE) - .setIsNullable(true) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME).addColumn(columnDef).build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/AddUserConsentRequiredIfGithubAutoProvisioningEnabled.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/AddUserConsentRequiredIfGithubAutoProvisioningEnabled.java deleted file mode 100644 index f142ada943e..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/AddUserConsentRequiredIfGithubAutoProvisioningEnabled.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import java.util.Optional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.utils.System2; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.Upsert; - -public class AddUserConsentRequiredIfGithubAutoProvisioningEnabled extends DataChange { - - private static final Logger LOG = LoggerFactory.getLogger(AddUserConsentRequiredIfGithubAutoProvisioningEnabled.class); - @VisibleForTesting - static final String PROVISIONING_GITHUB_ENABLED_PROP_KEY = "provisioning.github.enabled"; - - @VisibleForTesting - static final String PROP_KEY = "sonar.auth.github.userConsentForPermissionProvisioningRequired"; - - private static final String INSERT_QUERY = """ - insert into properties (uuid, prop_key, is_empty, created_at) - values (?, ?, ?, ?) - """; - - private final System2 system2; - private final UuidFactory uuidFactory; - - public AddUserConsentRequiredIfGithubAutoProvisioningEnabled(Database db, System2 system2, UuidFactory uuidFactory) { - super(db); - this.system2 = system2; - this.uuidFactory = uuidFactory; - } - @Override - protected void execute(DataChange.Context context) throws SQLException { - if (!isGithubAutoProvisioningEnabled(context)) { - return; - } - if (isUserConsentAlreadyRequired(context)) { - return; - } - LOG.warn("Automatic synchronization was previously activated for GitHub. It requires user consent to continue working as new " + - " features were added with the synchronization. Please read the upgrade notes."); - Upsert upsert = context.prepareUpsert(INSERT_QUERY); - upsert - .setString(1, uuidFactory.create()) - .setString(2, PROP_KEY) - .setBoolean(3, true) - .setLong(4, system2.now()) - .execute() - .commit(); - } - - private static boolean isUserConsentAlreadyRequired(Context context) throws SQLException { - return Optional.ofNullable(context.prepareSelect("select count(*) from properties where prop_key = ?") - .setString(1, PROP_KEY) - .get(t -> 1 == t.getInt(1))) - .orElseThrow(); - } - - private static boolean isGithubAutoProvisioningEnabled(Context context) throws SQLException { - return Optional.ofNullable(context.prepareSelect("select count(*) from internal_properties where kee = ? and text_value = ?") - .setString(1, PROVISIONING_GITHUB_ENABLED_PROP_KEY) - .setString(2, "true") - .get(t -> 1 == t.getInt(1))) - .orElseThrow(); - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateAnticipatedTransitionsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateAnticipatedTransitionsTable.java deleted file mode 100644 index e43d94da692..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateAnticipatedTransitionsTable.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder; -import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.MAX_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.USER_UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateAnticipatedTransitionsTable extends CreateTableChange { - static final String ANTICIPATED_TRANSITIONS_TABLE_NAME = "anticipated_transitions"; - - public CreateAnticipatedTransitionsTable(Database db) { - super(db, ANTICIPATED_TRANSITIONS_TABLE_NAME); - } - - @Override - public void execute(DdlChange.Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("project_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("user_uuid").setIsNullable(false).setLimit(USER_UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("transition").setIsNullable(false).setLimit(20).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("transition_comment").setLimit(MAX_SIZE).build()) - .addColumn(newIntegerColumnDefBuilder().setColumnName("line").build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("message").setLimit(MAX_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("line_hash").setLimit(255).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("rule_key").setIsNullable(false).setLimit(200).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("file_path").setIsNullable(false).setLimit(1500).build()) - .addColumn(newBigIntegerColumnDefBuilder().setColumnName("created_at").setIsNullable(false).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateBooleanPurgedColumnInSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateBooleanPurgedColumnInSnapshots.java deleted file mode 100644 index 48e758fe25c..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateBooleanPurgedColumnInSnapshots.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.BooleanColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class CreateBooleanPurgedColumnInSnapshots extends DdlChange { - private static final String COLUMN_NAME = "purged"; - private static final String TABLE_NAME = "snapshots"; - - public CreateBooleanPurgedColumnInSnapshots(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - if (checkIfColumnExists()) { - return; - } - BooleanColumnDef columnDef = BooleanColumnDef.newBooleanColumnDefBuilder(COLUMN_NAME).setIsNullable(true).build(); - context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME).addColumn(columnDef).build()); - } - - public boolean checkIfColumnExists() throws SQLException { - try (var connection = getDatabase().getDataSource().getConnection()) { - if (DatabaseUtils.tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { - return true; - } - } - return false; - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateGithubOrganizationsGroupsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateGithubOrganizationsGroupsTable.java deleted file mode 100644 index b37fe068dc2..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateGithubOrganizationsGroupsTable.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateGithubOrganizationsGroupsTable extends CreateTableChange { - @VisibleForTesting - static final String TABLE_NAME = "github_orgs_groups"; - @VisibleForTesting - static final String GROUP_UUID_COLUMN_NAME = "group_uuid"; - @VisibleForTesting - static final String ORGANIZATION_COLUMN_NAME = "organization_name"; - - public CreateGithubOrganizationsGroupsTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName(GROUP_UUID_COLUMN_NAME).setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName(ORGANIZATION_COLUMN_NAME).setIsNullable(false).setLimit(100).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexCreatedAtInWebhookDeliveries.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexCreatedAtInWebhookDeliveries.java deleted file mode 100644 index 2850b199519..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexCreatedAtInWebhookDeliveries.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.CreateIndexOnColumns; - -public class CreateIndexCreatedAtInWebhookDeliveries extends CreateIndexOnColumns { - protected CreateIndexCreatedAtInWebhookDeliveries(Database db) { - super(db, "webhook_deliveries", "wd", false, "created_at"); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInCeActivity.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInCeActivity.java deleted file mode 100644 index 048f618f4d3..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInCeActivity.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.CreateIndexOnColumn; - -public class CreateIndexEntityUuidInCeActivity extends CreateIndexOnColumn { - - private static final String TABLE_NAME = "ce_activity"; - private static final String COLUMN_NAME = "entity_uuid"; - - public CreateIndexEntityUuidInCeActivity(Database db) { - super(db, TABLE_NAME, COLUMN_NAME, false); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInCeQueue.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInCeQueue.java deleted file mode 100644 index 686b3a52569..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInCeQueue.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.CreateIndexOnColumn; - -public class CreateIndexEntityUuidInCeQueue extends CreateIndexOnColumn { - - private static final String TABLE_NAME = "ce_queue"; - private static final String COLUMN_NAME = "entity_uuid"; - - public CreateIndexEntityUuidInCeQueue(Database db) { - super(db, TABLE_NAME, COLUMN_NAME, false); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInGroupRoles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInGroupRoles.java deleted file mode 100644 index cf967f5a72e..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInGroupRoles.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.CreateIndexOnColumn; - -public class CreateIndexEntityUuidInGroupRoles extends CreateIndexOnColumn { - - private static final String TABLE_NAME = "group_roles"; - private static final String COLUMN_NAME = "entity_uuid"; - - public CreateIndexEntityUuidInGroupRoles(Database db) { - super(db, TABLE_NAME, COLUMN_NAME, false); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInUserRoles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInUserRoles.java deleted file mode 100644 index b206d6e4c33..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexEntityUuidInUserRoles.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.CreateIndexOnColumn; - -public class CreateIndexEntityUuidInUserRoles extends CreateIndexOnColumn { - - private static final String TABLE_NAME = "user_roles"; - private static final String COLUMN_NAME = "entity_uuid"; - - public CreateIndexEntityUuidInUserRoles(Database db) { - super(db, TABLE_NAME, COLUMN_NAME, false); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexProjectUuidCreatedAtInWebhookDeliveries.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexProjectUuidCreatedAtInWebhookDeliveries.java deleted file mode 100644 index 999518b76f8..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexProjectUuidCreatedAtInWebhookDeliveries.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.CreateIndexOnColumns; - -public class CreateIndexProjectUuidCreatedAtInWebhookDeliveries extends CreateIndexOnColumns { - protected CreateIndexProjectUuidCreatedAtInWebhookDeliveries(Database db) { - super(db, "webhook_deliveries", "wd", false, "project_uuid", "created_at"); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexProjectUuidInProjectBranches.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexProjectUuidInProjectBranches.java deleted file mode 100644 index 2e898b0c2f0..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexProjectUuidInProjectBranches.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.CreateIndexOnColumn; - -class CreateIndexProjectUuidInProjectBranches extends CreateIndexOnColumn { - - private static final String TABLE_NAME = "project_branches"; - private static final String COLUMN_NAME = "project_uuid"; - - public CreateIndexProjectUuidInProjectBranches(Database db) { - super(db, TABLE_NAME, COLUMN_NAME, false); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexTaskUuidCreatedAtInWebhookDeliveries.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexTaskUuidCreatedAtInWebhookDeliveries.java deleted file mode 100644 index d08538b4540..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexTaskUuidCreatedAtInWebhookDeliveries.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.CreateIndexOnColumns; - -public class CreateIndexTaskUuidCreatedAtInWebhookDeliveries extends CreateIndexOnColumns { - protected CreateIndexTaskUuidCreatedAtInWebhookDeliveries(Database db) { - super(db, "webhook_deliveries", "wd", false, "ce_task_uuid", "created_at"); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexWebhookUuidCreatedAtInWebhookDeliveries.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexWebhookUuidCreatedAtInWebhookDeliveries.java deleted file mode 100644 index cc0bd1fc0d3..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIndexWebhookUuidCreatedAtInWebhookDeliveries.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.CreateIndexOnColumns; - -public class CreateIndexWebhookUuidCreatedAtInWebhookDeliveries extends CreateIndexOnColumns { - protected CreateIndexWebhookUuidCreatedAtInWebhookDeliveries(Database db) { - super(db, "webhook_deliveries", "wd", false, "webhook_uuid", "created_at"); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIssueImpactsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIssueImpactsTable.java deleted file mode 100644 index 86ecf33fa01..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateIssueImpactsTable.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateIssueImpactsTable extends CreateTableChange { - static final String TABLE_NAME = "issues_impacts"; - - public CreateIssueImpactsTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(VarcharColumnDef.UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("issue_key").setIsNullable(false).setLimit(VarcharColumnDef.UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("software_quality").setIsNullable(false).setLimit(40).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("severity").setIsNullable(false).setLimit(40).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreatePreviousNonCompliantValueInNewCodePeriods.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreatePreviousNonCompliantValueInNewCodePeriods.java deleted file mode 100644 index 4c1340a5b9c..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreatePreviousNonCompliantValueInNewCodePeriods.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreatePreviousNonCompliantValueInNewCodePeriods extends DdlChange { - - private static final String COLUMN_NAME= "previous_non_compliant_value"; - - private static final String TABLE_NAME = "new_code_periods"; - - public CreatePreviousNonCompliantValueInNewCodePeriods(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - if (checkIfColumnExists()) { - return; - } - VarcharColumnDef columnDef = newVarcharColumnDefBuilder().setColumnName(COLUMN_NAME).setLimit(255).setIsNullable(true).build(); - context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME).addColumn(columnDef).build()); - } - - public boolean checkIfColumnExists() throws SQLException { - try (var connection = getDatabase().getDataSource().getConnection()) { - if (DatabaseUtils.tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { - return true; - } - } - return false; - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateRulesDefaultImpactsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateRulesDefaultImpactsTable.java deleted file mode 100644 index ef43270c0a8..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateRulesDefaultImpactsTable.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateRulesDefaultImpactsTable extends CreateTableChange { - static final String TABLE_NAME = "rules_default_impacts"; - - public CreateRulesDefaultImpactsTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(VarcharColumnDef.UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("rule_uuid").setIsNullable(false).setLimit(VarcharColumnDef.UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("software_quality").setIsNullable(false).setLimit(40).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("severity").setIsNullable(false).setLimit(40).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DbVersion102.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DbVersion102.java deleted file mode 100644 index 9f3431ded32..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DbVersion102.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.server.platform.db.migration.step.MigrationStepRegistry; -import org.sonar.server.platform.db.migration.version.DbVersion; - -// ignoring bad number formatting, as it's indented that we align the migration numbers to SQ versions -@SuppressWarnings("java:S3937") -public class DbVersion102 implements DbVersion { - - /** - * We use the start of the 10.X cycle as an opportunity to align migration numbers with the SQ version number. - * Please follow this pattern: - * 10_0_000 - * 10_0_001 - * 10_0_002 - * 10_1_000 - * 10_1_001 - * 10_1_002 - * 10_2_000 - */ - - @Override - public void addSteps(MigrationStepRegistry registry) { - registry - .add(10_2_000, "Rename 'component_uuid' in 'user_roles' table to 'entity_uuid'", RenameComponentUuidInUserRoles.class) - .add(10_2_001, "Rename 'component_uuid' in 'group_roles' table to 'entity_uuid'", RenameComponentUuidInGroupRoles.class) - - .add(10_2_002, "Drop index 'group_roles_component_uuid' in 'group_roles'", DropIndexComponentUuidInGroupRoles.class) - .add(10_2_003, "Create index 'entity_uuid_user_roles' in 'group_roles' table", CreateIndexEntityUuidInGroupRoles.class) - - .add(10_2_004, "Drop index 'user_roles_component_uuid' in 'user_roles' table", DropIndexComponentUuidInUserRoles.class) - .add(10_2_005, "Create index 'user_roles_entity_uuid' in 'user_roles'", CreateIndexEntityUuidInUserRoles.class) - - .add(10_2_006, "Drop index 'ce_activity_component' in 'ce_activity'", DropIndexMainComponentUuidInCeActivity.class) - .add(10_2_007, "Rename 'main_component_uuid' in 'ce_activity' table to 'entity_uuid'", RenameMainComponentUuidInCeActivity.class) - .add(10_2_008, "Create index 'ce_activity_entity_uuid' in 'ce_activity' table'", CreateIndexEntityUuidInCeActivity.class) - - .add(10_2_009, "Drop index 'ce_queue_main_component' in 'ce_queue' table", DropIndexMainComponentUuidInCeQueue.class) - .add(10_2_010, "Rename 'main_component_uuid' in 'ce_queue' table to 'entity_uuid'", RenameMainComponentUuidInCeQueue.class) - .add(10_2_011, "Create index 'ce_queue_entity_uuid' in 'ce_queue' table", CreateIndexEntityUuidInCeQueue.class) - - .add(10_2_012, "Drop 'project_mappings' table", DropTableProjectMappings.class) - - .add(10_2_013, "Drop index on 'components.main_branch_project_uuid", DropIndexOnMainBranchProjectUuid.class) - .add(10_2_014, "Drop column 'main_branch_project_uuid' in the components table", DropMainBranchProjectUuidInComponents.class) - - .add(10_2_015, "Drop index 'component_uuid' in 'webhook_deliveries' table", DropIndexComponentUuidInWebhookDeliveries.class) - .add(10_2_016, "Rename 'component_uuid' in 'webhook_deliveries' table to 'project_uuid'", RenameComponentUuidInWebhookDeliveries.class) - - .add(10_2_018, "Drop index 'component_uuid' in 'snapshots' table", DropIndexComponentUuidInSnapshots.class) - .add(10_2_019, "Rename 'component_uuid' in 'snapshots' table to 'root_component_uuid'", RenameComponentUuidInSnapshots.class) - .add(10_2_020, "Create index 'snapshots_root_component_uuid' in 'snapshots' table", CreateIndexRootComponentUuidInSnapshots.class) - - .add(10_2_021, "Create 'purged' column in 'snapshots' table", CreateBooleanPurgedColumnInSnapshots.class) - .add(10_2_022, "Populate 'purged' column in 'snapshots' table", PopulatePurgedColumnInSnapshots.class) - .add(10_2_023, "Make 'purged' column not nullable in 'snapshots' table", MakePurgedColumnNotNullableInSnapshots.class) - .add(10_2_024, "Drop 'purge_status' column in 'snapshots' table", DropPurgeStatusColumnInSnapshots.class) - - .add(10_2_025, "Rename 'build_date' in 'snapshots' table to 'analysis_date", RenameBuildDateInSnapshots.class) - - // Versions 10_2_026 to 10_2_029 were used by a migration that has been rolled back. See SONAR-7704 - - .add(10_2_030, "Create table 'anticipated_transitions'", CreateAnticipatedTransitionsTable.class) - - .add(10_2_031, "Increase size of 'ce_queue.is_last_key' from 55 to 80 characters", IncreaseIsLastKeyInCeActivity.class) - .add(10_2_032, "Increase size of 'ce_queue.main_is_last_key' from 55 to 80 characters", IncreaseMainIsLastKeyInCeActivity.class) - .add(10_2_033, "Add column 'clean_code_attribute' in 'rules' table", AddCleanCodeAttributeInRules.class) - .add(10_2_034, "Populate 'clean_code_attribute' column in 'rules' table", PopulateCleanCodeAttributeColumnInRules.class) - //TODO SONAR-20073 - //.add(10_2_035, "Make 'clean_code_attribute' column not nullable in 'rules' table", MakeCleanCodeAttributeColumnNotNullableInRules.class); - - .add(10_2_036, "Create 'rules_default_impacts' table", CreateRulesDefaultImpactsTable.class) - .add(10_2_037, "Create unique constraint index on 'rules_default_impacts' table", CreateUniqueConstraintOnRulesDefaultImpacts.class) - .add(10_2_038, "Create 'issues_impacts' table", CreateIssueImpactsTable.class) - .add(10_2_039, "Create unique constraint index on 'issues_impacts' table", CreateUniqueConstraintOnIssuesImpacts.class) - .add(10_2_040, "Populate default impacts for existing rules", PopulateDefaultImpactsInRules.class) - .add(10_2_041, "Fix sqale_index metric description in 'metrics' table", FixSqaleIndexMetricDescription.class) - - .add(10_2_042, "Create table 'github_orgs_groups'", CreateGithubOrganizationsGroupsTable.class) - .add(10_2_043, "Create 'previous_non_compliant_value' in 'new_code_periods' table", CreatePreviousNonCompliantValueInNewCodePeriods.class) - .add(10_2_044, "Update column 'value' and populate column 'previous_non_compliant_value' in 'new_code_periods' table", - UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriods.class) - .add(10_2_045, "Alter 'project_uuid' in 'user_dismissed_messages' - make it nullable", MakeProjectUuidNullableInUserDismissedMessages.class) - .add(10_2_046, "Create index 'project_branches_project_uuid' in 'project_branches' table", CreateIndexProjectUuidInProjectBranches.class) - - .add(10_2_047, "Drop index 'idx_wbhk_dlvrs_wbhk_uuid' in 'webhook_deliveries'", DropIndexWebhookUuidInWebhookDeliveries.class) - .add(10_2_048, "Create index 'wb_webhook_uuid_created_at' in 'webhook_deliveries'", CreateIndexWebhookUuidCreatedAtInWebhookDeliveries.class) - .add(10_2_049, "Drop index 'wd_project_uuid' in 'webhook_deliveries'", DropIndexProjectUuidInWebhookDeliveries.class) - .add(10_2_050, "Create index 'wd_project_uuid_created_at' in 'webhook_deliveries'", CreateIndexProjectUuidCreatedAtInWebhookDeliveries.class) - .add(10_2_051, "Drop index 'ce_task_uuid' in 'webhook_deliveries'", DropIndexTaskUuidInWebhookDeliveries.class) - .add(10_2_052, "Create index 'wd_task_uuid_created_at' in 'webhook_deliveries'", CreateIndexTaskUuidCreatedAtInWebhookDeliveries.class) - .add(10_2_053, "Create index 'wd_created_at' in 'webhook_deliveries'", CreateIndexCreatedAtInWebhookDeliveries.class) - - .add(10_2_054, "Insert property github.userConsentementForPermissionProvisioningRequired", AddUserConsentRequiredIfGithubAutoProvisioningEnabled.class) - ; - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInGroupRoles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInGroupRoles.java deleted file mode 100644 index 4deacfe069f..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInGroupRoles.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -public class DropIndexComponentUuidInGroupRoles extends DropIndexChange { - - private static final String TABLE_NAME = "group_roles"; - private static final String INDEX_NAME = "group_roles_component_uuid"; - - public DropIndexComponentUuidInGroupRoles(Database db) { - super(db, INDEX_NAME, TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInSnapshots.java deleted file mode 100644 index acb1bb3e3a8..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInSnapshots.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -public class DropIndexComponentUuidInSnapshots extends DropIndexChange { - - private static final String TABLE_NAME = "snapshots"; - private static final String INDEX_NAME = "snapshot_component"; - - public DropIndexComponentUuidInSnapshots(Database db) { - super(db, INDEX_NAME, TABLE_NAME); - } -}
\ No newline at end of file diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInUserRoles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInUserRoles.java deleted file mode 100644 index f9b0460efe4..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInUserRoles.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -public class DropIndexComponentUuidInUserRoles extends DropIndexChange { - - private static final String TABLE_NAME = "user_roles"; - private static final String INDEX_NAME = "user_roles_component_uuid"; - - public DropIndexComponentUuidInUserRoles(Database db) { - super(db, INDEX_NAME, TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInWebhookDeliveries.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInWebhookDeliveries.java deleted file mode 100644 index fc0edb92381..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexComponentUuidInWebhookDeliveries.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -public class DropIndexComponentUuidInWebhookDeliveries extends DropIndexChange { - - private static final String TABLE_NAME = "webhook_deliveries"; - private static final String INDEX_NAME = "component_uuid"; - - public DropIndexComponentUuidInWebhookDeliveries(Database db) { - super(db, INDEX_NAME, TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexMainComponentUuidInCeActivity.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexMainComponentUuidInCeActivity.java deleted file mode 100644 index 55458705285..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexMainComponentUuidInCeActivity.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -public class DropIndexMainComponentUuidInCeActivity extends DropIndexChange { - - private static final String TABLE_NAME = "ce_activity"; - private static final String INDEX_NAME = "ce_activity_main_component"; - - public DropIndexMainComponentUuidInCeActivity(Database db) { - super(db, INDEX_NAME, TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexMainComponentUuidInCeQueue.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexMainComponentUuidInCeQueue.java deleted file mode 100644 index ae5d47f052e..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexMainComponentUuidInCeQueue.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -public class DropIndexMainComponentUuidInCeQueue extends DropIndexChange { - - private static final String TABLE_NAME = "ce_queue"; - private static final String INDEX_NAME = "ce_queue_main_component"; - - public DropIndexMainComponentUuidInCeQueue(Database db) { - super(db, INDEX_NAME, TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexProjectUuidInWebhookDeliveries.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexProjectUuidInWebhookDeliveries.java deleted file mode 100644 index 7824163142c..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexProjectUuidInWebhookDeliveries.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -public class DropIndexProjectUuidInWebhookDeliveries extends DropIndexChange { - public DropIndexProjectUuidInWebhookDeliveries(Database db) { - super(db, "wd_project_uuid", "webhook_deliveries"); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexWebhookUuidInWebhookDeliveries.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexWebhookUuidInWebhookDeliveries.java deleted file mode 100644 index 772d5b3c611..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexWebhookUuidInWebhookDeliveries.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -public class DropIndexWebhookUuidInWebhookDeliveries extends DropIndexChange { - public DropIndexWebhookUuidInWebhookDeliveries(Database db) { - super(db, "idx_wbhk_dlvrs_wbhk_uuid", "webhook_deliveries"); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropMainBranchProjectUuidInComponents.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropMainBranchProjectUuidInComponents.java deleted file mode 100644 index cae1c8d4001..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropMainBranchProjectUuidInComponents.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -class DropMainBranchProjectUuidInComponents extends DropColumnChange { - static final String TABLE_NAME = "components"; - static final String COLUMN_NAME = "main_branch_project_uuid"; - - public DropMainBranchProjectUuidInComponents(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropPurgeStatusColumnInSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropPurgeStatusColumnInSnapshots.java deleted file mode 100644 index a75dee801df..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropPurgeStatusColumnInSnapshots.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropPurgeStatusColumnInSnapshots extends DropColumnChange { - private static final String COLUMN_NAME = "purge_status"; - private static final String TABLE_NAME = "snapshots"; - - public DropPurgeStatusColumnInSnapshots(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropTableProjectMappings.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropTableProjectMappings.java deleted file mode 100644 index 30b3f744dc0..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropTableProjectMappings.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.DropTableBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class DropTableProjectMappings extends DdlChange { - - private static final String TABLE_NAME = "project_mappings"; - - public DropTableProjectMappings(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection c = getDatabase().getDataSource().getConnection()) { - if (DatabaseUtils.tableExists(TABLE_NAME, c)) { - context.execute(new DropTableBuilder(getDialect(), TABLE_NAME).build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/FixSqaleIndexMetricDescription.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/FixSqaleIndexMetricDescription.java deleted file mode 100644 index 915ac32e6f1..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/FixSqaleIndexMetricDescription.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.Upsert; - -public class FixSqaleIndexMetricDescription extends DataChange { - - public FixSqaleIndexMetricDescription(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - try (Upsert upsert = context.prepareUpsert("update metrics set description = ? where name = ?")) { - upsert.setString(1, "Total effort (in minutes) to fix all the issues on the component and therefore to comply to all the requirements."); - upsert.setString(2, "sqale_index"); - upsert.execute(); - upsert.commit(); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/IncreaseIsLastKeyInCeActivity.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/IncreaseIsLastKeyInCeActivity.java deleted file mode 100644 index 98fb8c6bf58..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/IncreaseIsLastKeyInCeActivity.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class IncreaseIsLastKeyInCeActivity extends DdlChange { - @VisibleForTesting - static final String TABLE_NAME = "ce_activity"; - @VisibleForTesting - static final String COLUMN_NAME = "is_last_key"; - @VisibleForTesting - static final int NEW_COLUMN_SIZE = 80; - - private static final VarcharColumnDef COLUMN_DEFINITION = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setLimit(NEW_COLUMN_SIZE) - .setIsNullable(false) - .build(); - - public IncreaseIsLastKeyInCeActivity(Database db) { - super(db); - } - - @Override - public void execute(DdlChange.Context context) throws SQLException { - context.execute(new AlterColumnsBuilder(getDialect(), TABLE_NAME) - .updateColumn(COLUMN_DEFINITION) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/IncreaseMainIsLastKeyInCeActivity.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/IncreaseMainIsLastKeyInCeActivity.java deleted file mode 100644 index eb851b4442d..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/IncreaseMainIsLastKeyInCeActivity.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class IncreaseMainIsLastKeyInCeActivity extends DdlChange { - - @VisibleForTesting - static final String TABLE_NAME = "ce_activity"; - @VisibleForTesting - static final String COLUMN_NAME = "main_is_last_key"; - @VisibleForTesting - static final int NEW_COLUMN_SIZE = 80; - - private static final VarcharColumnDef COLUMN_DEFINITION = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setLimit(NEW_COLUMN_SIZE) - .setIsNullable(false) - .build(); - - public IncreaseMainIsLastKeyInCeActivity(Database db) { - super(db); - } - - @Override - public void execute(DdlChange.Context context) throws SQLException { - context.execute(new AlterColumnsBuilder(getDialect(), TABLE_NAME) - .updateColumn(COLUMN_DEFINITION) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/MakeProjectUuidNullableInUserDismissedMessages.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/MakeProjectUuidNullableInUserDismissedMessages.java deleted file mode 100644 index e2e4309cb2e..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/MakeProjectUuidNullableInUserDismissedMessages.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class MakeProjectUuidNullableInUserDismissedMessages extends DdlChange { - - private static final String TABLE_NAME = "user_dismissed_messages"; - private static final String COLUMN_NAME = "project_uuid"; - - public MakeProjectUuidNullableInUserDismissedMessages(Database db) { - super(db); - } - - @Override - public void execute(DdlChange.Context context) throws SQLException { - VarcharColumnDef newColumnDef = new VarcharColumnDef.Builder() - .setColumnName(COLUMN_NAME) - .setIsNullable(true) - .setLimit(40) - .build(); - context.execute(new AlterColumnsBuilder(getDialect(), TABLE_NAME).updateColumn(newColumnDef).build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/MakePurgedColumnNotNullableInSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/MakePurgedColumnNotNullableInSnapshots.java deleted file mode 100644 index 6db65f66999..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/MakePurgedColumnNotNullableInSnapshots.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.BooleanColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class MakePurgedColumnNotNullableInSnapshots extends DdlChange { - private static final String COLUMN_NAME = "purged"; - private static final String TABLE_NAME = "snapshots"; - public MakePurgedColumnNotNullableInSnapshots(Database db) { - super(db); - } - @Override - public void execute(Context context) throws SQLException { - BooleanColumnDef columnDef = BooleanColumnDef.newBooleanColumnDefBuilder(COLUMN_NAME).setIsNullable(false).build(); - context.execute(new AlterColumnsBuilder(getDialect(), TABLE_NAME).updateColumn(columnDef).build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/PopulateCleanCodeAttributeColumnInRules.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/PopulateCleanCodeAttributeColumnInRules.java deleted file mode 100644 index 46e7b69d811..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/PopulateCleanCodeAttributeColumnInRules.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; - -public class PopulateCleanCodeAttributeColumnInRules extends DataChange { - - private static final String SELECT_QUERY = """ - SELECT uuid, clean_code_attribute - FROM rules - WHERE clean_code_attribute is null and (rule_type <> %1$s or ad_hoc_type <> %1$s) - """.formatted(SECURITY_HOTSPOT.getDbConstant()); - - private static final String UPDATE_QUERY = """ - UPDATE rules - SET clean_code_attribute=? - WHERE uuid=? - """; - - public PopulateCleanCodeAttributeColumnInRules(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update(UPDATE_QUERY); - - massUpdate.execute((row, update, index) -> { - String ruleUuid = row.getString(1); - update.setString(1, CleanCodeAttribute.CONVENTIONAL.name()) - .setString(2, ruleUuid); - return true; - }); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/PopulateDefaultImpactsInRules.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/PopulateDefaultImpactsInRules.java deleted file mode 100644 index 413ff7f4e4f..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/PopulateDefaultImpactsInRules.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.issue.impact.Severity; -import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; -import org.sonar.api.server.rule.internal.ImpactMapper; -import org.sonar.core.util.Uuids; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; -import org.sonar.server.platform.db.migration.step.Select; - -public class PopulateDefaultImpactsInRules extends DataChange { - - private static final Logger LOG = LoggerFactory.getLogger(PopulateDefaultImpactsInRules.class); - - private static final String SELECT_COUNT_QUERY = """ - SELECT COUNT(*) FROM rules_default_impacts - """; - private static final String SELECT_QUERY = """ - SELECT r.uuid, rule_type, priority, ad_hoc_type, ad_hoc_severity, is_ad_hoc - FROM rules r - LEFT JOIN rules_default_impacts rdi ON rdi.rule_uuid = r.uuid - WHERE rdi.uuid IS NULL - """; - - private static final String INSERT_QUERY = """ - INSERT INTO rules_default_impacts (uuid, rule_uuid, software_quality, severity) - VALUES (?, ?, ?, ?) - """; - - public PopulateDefaultImpactsInRules(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - if (hasImpactsRecords(context)) { - return; - } - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update(INSERT_QUERY); - - massUpdate.execute((row, update, index) -> { - String ruleUuid = row.getString(1); - String ruleType = row.getString(2); - String severity = row.getString(3); - String adhocType = row.getString(4); - String adhocSeverity = row.getString(5); - boolean isAdhoc = row.getBoolean(6); - - SoftwareQuality softwareQuality; - Severity impactSeverity; - - try { - RuleType effectiveType = null; - String effectiveSeverity = null; - if (isAdhoc && adhocType != null && adhocSeverity != null) { - effectiveType = RuleType.valueOf(Integer.valueOf(adhocType)); - effectiveSeverity = adhocSeverity; - } else if (!isAdhoc && ruleType != null && !ruleType.equals("0") && severity != null) { - effectiveType = RuleType.valueOf(Integer.valueOf(ruleType)); - effectiveSeverity = org.sonar.api.rule.Severity.ALL.get(Integer.valueOf(severity)); - } else if (!isAdhoc) { - //When type and severity are missing, we are in the case of a "placeholder" adhoc_rule that was created as default with an external issue. - //In that case, we want to set default values for the impact. Otherwise, we don't populate the impact - return false; - } - if (effectiveType == RuleType.SECURITY_HOTSPOT) { - return false; - } - if (effectiveType != null && effectiveSeverity != null) { - softwareQuality = ImpactMapper.convertToSoftwareQuality(effectiveType); - impactSeverity = ImpactMapper.convertToImpactSeverity(effectiveSeverity); - } else { - softwareQuality = SoftwareQuality.MAINTAINABILITY; - impactSeverity = Severity.MEDIUM; - } - } catch (Exception e) { - LOG.warn("Error while mapping type to impact for rule '%s'".formatted(ruleUuid)); - LOG.debug("Error while mapping type to impact for rule '%s'".formatted(ruleUuid), e); - return false; - } - - update.setString(1, Uuids.create()) - .setString(2, ruleUuid) - .setString(3, softwareQuality.name()) - .setString(4, impactSeverity.name()); - return true; - }); - } - - private static boolean hasImpactsRecords(Context context) throws SQLException { - Long recordNumber = context.prepareSelect(SELECT_COUNT_QUERY).get(Select.LONG_READER); - return recordNumber != null && recordNumber > 0; - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/PopulatePurgedColumnInSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/PopulatePurgedColumnInSnapshots.java deleted file mode 100644 index f18d07f824d..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/PopulatePurgedColumnInSnapshots.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class PopulatePurgedColumnInSnapshots extends DataChange { - private static final String SELECT_QUERY = """ - SELECT s.uuid, s.purge_status - FROM snapshots s - WHERE s.purged is null - """; - - private static final String UPDATE_QUERY = """ - UPDATE snapshots - SET purged=? - WHERE uuid=? - """; - - public PopulatePurgedColumnInSnapshots(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - if (!checkIfColumnExists()) { - return; - } - - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update(UPDATE_QUERY); - - massUpdate.execute((row, update, index) -> { - String snapshotUuid = row.getString(1); - Integer purgedStatus = row.getNullableInt(2); - update.setBoolean(1, purgedStatus != null && purgedStatus == 1) - .setString(2, snapshotUuid); - return true; - }); - } - - public boolean checkIfColumnExists() throws SQLException { - try (var connection = getDatabase().getDataSource().getConnection()) { - if (DatabaseUtils.tableColumnExists(connection, "snapshots", "purge_status")) { - return true; - } - } - return false; - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameBuildDateInSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameBuildDateInSnapshots.java deleted file mode 100644 index ba0fa3a1b35..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameBuildDateInSnapshots.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.BigIntegerColumnDef; -import org.sonar.server.platform.db.migration.sql.RenameColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class RenameBuildDateInSnapshots extends DdlChange { - private static final String TABLE_NAME = "snapshots"; - - private static final BigIntegerColumnDef columnDefinition = BigIntegerColumnDef.newBigIntegerColumnDefBuilder() - .setColumnName("analysis_date") - .setIsNullable(true) - .build(); - - public RenameBuildDateInSnapshots(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, TABLE_NAME, "analysis_date") - && DatabaseUtils.tableColumnExists(connection, TABLE_NAME, "build_date")) { - context.execute(new RenameColumnsBuilder(getDialect(), TABLE_NAME) - .renameColumn("build_date", columnDefinition) - .build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInGroupRoles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInGroupRoles.java deleted file mode 100644 index 7e7b108142c..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInGroupRoles.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.RenameVarcharColumnChange; - -public class RenameComponentUuidInGroupRoles extends RenameVarcharColumnChange { - - private static final String TABLE_NAME = "group_roles"; - private static final String OLD_COLUMN_NAME = "component_uuid"; - private static final String NEW_COLUMN_NAME = "entity_uuid"; - - public RenameComponentUuidInGroupRoles(Database db) { - super(db, TABLE_NAME, OLD_COLUMN_NAME, NEW_COLUMN_NAME); - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInSnapshots.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInSnapshots.java deleted file mode 100644 index 9084b02ac51..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInSnapshots.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.RenameVarcharColumnChange; - -public class RenameComponentUuidInSnapshots extends RenameVarcharColumnChange { - - private static final String TABLE_NAME = "snapshots"; - private static final String OLD_COLUMN_NAME = "component_uuid"; - private static final String NEW_COLUMN_NAME = "root_component_uuid"; - - public RenameComponentUuidInSnapshots(Database db) { - super(db, TABLE_NAME, OLD_COLUMN_NAME, NEW_COLUMN_NAME); - } - -}
\ No newline at end of file diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInUserRoles.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInUserRoles.java deleted file mode 100644 index 742599ae498..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInUserRoles.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.RenameVarcharColumnChange; - -public class RenameComponentUuidInUserRoles extends RenameVarcharColumnChange { - - private static final String TABLE_NAME = "user_roles"; - private static final String OLD_COLUMN_NAME = "component_uuid"; - private static final String NEW_COLUMN_NAME = "entity_uuid"; - - public RenameComponentUuidInUserRoles(Database db) { - super(db, TABLE_NAME, OLD_COLUMN_NAME, NEW_COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInWebhookDeliveries.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInWebhookDeliveries.java deleted file mode 100644 index 4ececf8662c..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameComponentUuidInWebhookDeliveries.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.RenameVarcharColumnChange; - -public class RenameComponentUuidInWebhookDeliveries extends RenameVarcharColumnChange { - - private static final String TABLE_NAME = "webhook_deliveries"; - private static final String OLD_COLUMN_NAME = "component_uuid"; - private static final String NEW_COLUMN_NAME = "project_uuid"; - - public RenameComponentUuidInWebhookDeliveries(Database db) { - super(db, TABLE_NAME, OLD_COLUMN_NAME, NEW_COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameMainComponentUuidInCeActivity.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameMainComponentUuidInCeActivity.java deleted file mode 100644 index 0a94e598baa..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameMainComponentUuidInCeActivity.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.RenameVarcharColumnChange; - -public class RenameMainComponentUuidInCeActivity extends RenameVarcharColumnChange { - - private static final String TABLE_NAME = "ce_activity"; - private static final String OLD_COLUMN_NAME = "main_component_uuid"; - private static final String NEW_COLUMN_NAME = "entity_uuid"; - - public RenameMainComponentUuidInCeActivity(Database db) { - super(db, TABLE_NAME, OLD_COLUMN_NAME, NEW_COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameMainComponentUuidInCeQueue.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameMainComponentUuidInCeQueue.java deleted file mode 100644 index 9be8f1ad55e..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/RenameMainComponentUuidInCeQueue.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.RenameVarcharColumnChange; - -public class RenameMainComponentUuidInCeQueue extends RenameVarcharColumnChange { - - private static final String TABLE_NAME = "ce_queue"; - private static final String OLD_COLUMN_NAME = "main_component_uuid"; - private static final String NEW_COLUMN_NAME = "entity_uuid"; - - public RenameMainComponentUuidInCeQueue(Database db) { - super(db, TABLE_NAME, OLD_COLUMN_NAME, NEW_COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriods.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriods.java deleted file mode 100644 index 63351727502..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriods.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriods extends DataChange { - - private static final String SELECT_QUERY = """ - SELECT uuid, value - FROM new_code_periods - WHERE type = 'NUMBER_OF_DAYS' - """; - private static final String UPDATE_QUERY = """ - UPDATE new_code_periods - SET previous_non_compliant_value=?, value='90', updated_at=? - where uuid=? - """; - - private static final String COLUMN_NAME= "previous_non_compliant_value"; - - private static final String TABLE_NAME = "new_code_periods"; - - public UpdateValueAndPopulatePreviousNonCompliantValueInNewCodePeriods(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - if (!checkIfColumnExists()) { - return; - } - Long updatedAt = System.currentTimeMillis(); - - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update(UPDATE_QUERY); - - massUpdate.execute((row, update, index) -> { - String newCodeDefinitionId = row.getString(1); - String previousNewCodeDefinitionValue = row.getString(2); - if(Integer.parseInt(previousNewCodeDefinitionValue) > 90) { - update.setString(1, previousNewCodeDefinitionValue) - .setLong(2, updatedAt) - .setString(3, newCodeDefinitionId); - return true; - } - return false; - }); - } - - public boolean checkIfColumnExists() throws SQLException { - try (var connection = getDatabase().getDataSource().getConnection()) { - if (DatabaseUtils.tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { - return true; - } - } - return false; - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/AddCleanCodeAttributeColumnInIssuesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/AddCleanCodeAttributeColumnInIssuesTable.java deleted file mode 100644 index c325805e2a6..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/AddCleanCodeAttributeColumnInIssuesTable.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AddCleanCodeAttributeColumnInIssuesTable extends DdlChange { - private static final String TABLE_NAME = "issues"; - private static final String COLUMN_NAME = "clean_code_attribute"; - private static final int NEW_COLUMN_SIZE = 40; - - - public AddCleanCodeAttributeColumnInIssuesTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { - ColumnDef columnDef = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setLimit(NEW_COLUMN_SIZE) - .setIsNullable(true) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME).addColumn(columnDef).build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/AddCreationMethodColumnInProjectsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/AddCreationMethodColumnInProjectsTable.java deleted file mode 100644 index 31bc8ff640a..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/AddCreationMethodColumnInProjectsTable.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AddCreationMethodColumnInProjectsTable extends DdlChange { - static final String PROJECTS_TABLE_NAME = "projects"; - static final String PROJECTS_CREATION_METHOD_COLUMN_NAME = "creation_method"; - static final int PROJECTS_CREATION_METHOD_COLUMN_SIZE = 50; - - public AddCreationMethodColumnInProjectsTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, PROJECTS_TABLE_NAME, PROJECTS_CREATION_METHOD_COLUMN_NAME)) { - ColumnDef columnDef = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(PROJECTS_CREATION_METHOD_COLUMN_NAME) - .setLimit(PROJECTS_CREATION_METHOD_COLUMN_SIZE) - .setIsNullable(true) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), PROJECTS_TABLE_NAME).addColumn(columnDef).build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/AddRuleChangesUuidColumnInQProfileChanges.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/AddRuleChangesUuidColumnInQProfileChanges.java deleted file mode 100644 index b6981bb446d..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/AddRuleChangesUuidColumnInQProfileChanges.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AddRuleChangesUuidColumnInQProfileChanges extends DdlChange { - private static final String TABLE_NAME = "qprofile_changes"; - private static final String COLUMN_NAME = "rule_change_uuid"; - - private static final int NEW_COLUMN_SIZE = 40; - - public AddRuleChangesUuidColumnInQProfileChanges(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { - ColumnDef columnDef = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setLimit(NEW_COLUMN_SIZE) - .setIsNullable(true) - .build(); - - context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME).addColumn(columnDef).build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/AddSqVersionColumnInQprofileChangesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/AddSqVersionColumnInQprofileChangesTable.java deleted file mode 100644 index af5687ad539..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/AddSqVersionColumnInQprofileChangesTable.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AddSqVersionColumnInQprofileChangesTable extends DdlChange { - private static final String TABLE_NAME = "qprofile_changes"; - private static final String COLUMN_NAME = "sq_version"; - private static final int NEW_COLUMN_SIZE = 40; - - - public AddSqVersionColumnInQprofileChangesTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { - ColumnDef columnDef = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(COLUMN_NAME) - .setLimit(NEW_COLUMN_SIZE) - .setIsNullable(true) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME).addColumn(columnDef).build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateGithubPermissionsMappingTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateGithubPermissionsMappingTable.java deleted file mode 100644 index 1e6ec4387cf..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateGithubPermissionsMappingTable.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateGithubPermissionsMappingTable extends CreateTableChange { - static final String GITHUB_PERMISSIONS_MAPPING_TABLE_NAME = "github_perms_mapping"; - static final String GITHUB_ROLE_COLUMN = "github_role"; - static final String SONARQUBE_PERMISSION_COLUMN = "sonarqube_permission"; - - public CreateGithubPermissionsMappingTable(Database db) { - super(db, GITHUB_PERMISSIONS_MAPPING_TABLE_NAME); - } - - @Override - public void execute(DdlChange.Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName(GITHUB_ROLE_COLUMN).setIsNullable(false).setLimit(100).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName(SONARQUBE_PERMISSION_COLUMN).setIsNullable(false).setLimit(64).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateRuleChangesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateRuleChangesTable.java deleted file mode 100644 index f0be252f3c8..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateRuleChangesTable.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateRuleChangesTable extends CreateTableChange { - - static final String TABLE_NAME = "rule_changes"; - - public CreateRuleChangesTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(DdlChange.Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("new_clean_code_attribute").setIsNullable(true).setLimit(40).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("old_clean_code_attribute").setIsNullable(true).setLimit(40).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("rule_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateRuleImpactChangesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateRuleImpactChangesTable.java deleted file mode 100644 index c316af76c52..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateRuleImpactChangesTable.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateRuleImpactChangesTable extends CreateTableChange { - - static final String TABLE_NAME = "rule_impact_changes"; - - public CreateRuleImpactChangesTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(DdlChange.Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addColumn(newVarcharColumnDefBuilder().setColumnName("new_software_quality").setIsNullable(true).setLimit(40).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("old_software_quality").setIsNullable(true).setLimit(40).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("new_severity").setIsNullable(true).setLimit(40).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("old_severity").setIsNullable(true).setLimit(40).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("rule_change_uuid").setIsNullable(false).setLimit(40).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForGithubPermissionsMappingTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForGithubPermissionsMappingTable.java deleted file mode 100644 index 38ec8f70118..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForGithubPermissionsMappingTable.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.GITHUB_PERMISSIONS_MAPPING_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.GITHUB_ROLE_COLUMN; -import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.SONARQUBE_PERMISSION_COLUMN; - -public class CreateUniqueIndexForGithubPermissionsMappingTable extends DdlChange { - - @VisibleForTesting - static final String INDEX_NAME = "uniq_github_perm_mappings"; - - public CreateUniqueIndexForGithubPermissionsMappingTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - createUniqueIndex(context, connection); - } - } - - private void createUniqueIndex(Context context, Connection connection) { - if (!DatabaseUtils.indexExistsIgnoreCase(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, INDEX_NAME, connection)) { - context.execute(new CreateIndexBuilder(getDialect()) - .setTable(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME) - .setName(INDEX_NAME) - .addColumn(GITHUB_ROLE_COLUMN, false) - .addColumn(SONARQUBE_PERMISSION_COLUMN, false) - .setUnique(true) - .build()); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForPropertiesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForPropertiesTable.java deleted file mode 100644 index 437a8fb7c4d..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForPropertiesTable.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class CreateUniqueIndexForPropertiesTable extends DdlChange { - - public static final String INDEX_NAME = "uniq_properties"; - public static final String PROPERTIES_TABLE_NAME = "properties"; - - public CreateUniqueIndexForPropertiesTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.indexExistsIgnoreCase(PROPERTIES_TABLE_NAME, INDEX_NAME, connection)) { - context.execute(new CreateIndexBuilder(getDialect()) - .setTable(PROPERTIES_TABLE_NAME) - .setName(INDEX_NAME) - .addColumn("prop_key", false) - .addColumn("entity_uuid", true) - .addColumn("user_uuid", true) - .setUnique(true) - .build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/DbVersion103.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/DbVersion103.java deleted file mode 100644 index 0a9dea8ca78..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/DbVersion103.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import org.sonar.server.platform.db.migration.step.MigrationStepRegistry; -import org.sonar.server.platform.db.migration.version.DbVersion; - -// ignoring bad number formatting, as it's indented that we align the migration numbers to SQ versions -@SuppressWarnings("java:S3937") -public class DbVersion103 implements DbVersion { - - /** - * We use the start of the 10.X cycle as an opportunity to align migration numbers with the SQ version number. - * Please follow this pattern: - * 10_0_000 - * 10_0_001 - * 10_0_002 - * 10_1_000 - * 10_1_001 - * 10_1_002 - * 10_2_000 - */ - - @Override - public void addSteps(MigrationStepRegistry registry) { - registry - .add(10_3_000, "Set 'sonar.qualityProfiles.allowDisableInheritedRules' to false for upgraded instances", SetAllowQualityProfileDisableInheritedRules.class) - .add(10_3_001, "Add table 'github_perms_mapping'", CreateGithubPermissionsMappingTable.class) - .add(10_3_002, "Create unique index on 'github_perms_mapping'", CreateUniqueIndexForGithubPermissionsMappingTable.class) - .add(10_3_003, "Add default mappings to 'github_perms_mapping'", PopulateGithubPermissionsMapping.class) - .add(10_3_004, "Add 'clean_code_attribute' column in 'issues' table", AddCleanCodeAttributeColumnInIssuesTable.class) - .add(10_3_005, "Add 'creation_method' column in 'projects' table", AddCreationMethodColumnInProjectsTable.class) - .add(10_3_006, "Populate 'creation_method' column in 'projects' table", PopulateCreationMethodColumnInProjectsTable.class) - .add(10_3_007, "Make 'creation_method' column in 'projects' table non-nullable", MakeCreationMethodColumnInProjectsNotNullable.class) - .add(10_3_008, "Add 'rule_changes_uuid' column in 'qprofile_changes'", AddRuleChangesUuidColumnInQProfileChanges.class) - .add(10_3_009, "Create table 'rule_changes'", CreateRuleChangesTable.class) - .add(10_3_010, "Create table 'rule_impact_changes'", CreateRuleImpactChangesTable.class) - .add(10_3_011, "Create index for 'rule_impact_changes'", CreateIndexForRuleImpactChangesTable.class) - .add(10_3_012, "Add 'sq_version' column in 'qprofile_changes' table", AddSqVersionColumnInQprofileChangesTable.class) - .add(10_3_013, "Deduplicate potential records in 'properties' table", DeduplicatePropertiesTable.class) - .add(10_3_014, "Create unique index to 'properties' table", CreateUniqueIndexForPropertiesTable.class); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/MakeCreationMethodColumnInProjectsNotNullable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/MakeCreationMethodColumnInProjectsNotNullable.java deleted file mode 100644 index cf220f8a494..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/MakeCreationMethodColumnInProjectsNotNullable.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v103.AddCreationMethodColumnInProjectsTable.PROJECTS_CREATION_METHOD_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v103.AddCreationMethodColumnInProjectsTable.PROJECTS_CREATION_METHOD_COLUMN_SIZE; -import static org.sonar.server.platform.db.migration.version.v103.AddCreationMethodColumnInProjectsTable.PROJECTS_TABLE_NAME; - -public class MakeCreationMethodColumnInProjectsNotNullable extends DdlChange { - - public MakeCreationMethodColumnInProjectsNotNullable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - VarcharColumnDef columnDef = VarcharColumnDef.newVarcharColumnDefBuilder(PROJECTS_CREATION_METHOD_COLUMN_NAME) - .setIsNullable(false) - .setLimit(PROJECTS_CREATION_METHOD_COLUMN_SIZE) - .build(); - context.execute(new AlterColumnsBuilder(getDialect(), PROJECTS_TABLE_NAME).updateColumn(columnDef).build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/PopulateCreationMethodColumnInProjectsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/PopulateCreationMethodColumnInProjectsTable.java deleted file mode 100644 index fada6ccb11a..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/PopulateCreationMethodColumnInProjectsTable.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -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' - """; - - public PopulateCreationMethodColumnInProjectsTable(Database db) { - super(db); - } - @Override - protected void execute(Context context) throws SQLException { - Upsert upsert = context.prepareUpsert(UPDATE_QUERY); - upsert.execute().commit(); - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMapping.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMapping.java deleted file mode 100644 index 65aa311ba81..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMapping.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.Select; -import org.sonar.server.platform.db.migration.step.Upsert; - -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.api.web.UserRole.SCAN; -import static org.sonar.api.web.UserRole.SECURITYHOTSPOT_ADMIN; -import static org.sonar.api.web.UserRole.USER; - -public class PopulateGithubPermissionsMapping extends DataChange { - - private static final Map<String, Set<String>> GITHUB_ROLE_TO_SQ_PERMISSIONS = Map.of( - "read", Set.of(USER, CODEVIEWER), - "triage", Set.of(USER, CODEVIEWER), - "write", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN), - "maintain", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN), - "admin", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN, ADMIN) - ); - - private static final String INSERT_QUERY = """ - insert into github_perms_mapping (uuid, github_role, sonarqube_permission) - values (?, ?, ?) - """; - - private final UuidFactory uuidFactory; - - public PopulateGithubPermissionsMapping(Database db, UuidFactory uuidFactory) { - super(db); - this.uuidFactory = uuidFactory; - } - - @Override - protected void execute(Context context) throws SQLException { - if (isDefaultMappingAlreadyDefined(context)) { - return; - } - try (Upsert upsert = context.prepareUpsert(INSERT_QUERY)) { - GITHUB_ROLE_TO_SQ_PERMISSIONS.forEach((key, value) -> insertGithubRoleToSonarqubePermissionMapping(upsert, key, value)); - upsert.commit(); - } - } - - private void insertGithubRoleToSonarqubePermissionMapping(Upsert upsert, String githubRole, Set<String> sonarqubePermissions) { - sonarqubePermissions.forEach(permission -> insertGithubRoleToSonarqubePermissionMapping(upsert, githubRole, permission)); - } - - private void insertGithubRoleToSonarqubePermissionMapping(Upsert upsert, String githubRole, String sonarqubePermission) { - try { - upsert - .setString(1, uuidFactory.create()) - .setString(2, githubRole) - .setString(3, sonarqubePermission) - .execute(); - } catch (SQLException e) { - throw new IllegalStateException(e); - } - } - - private static boolean isDefaultMappingAlreadyDefined(Context context) throws SQLException { - try (Select select = context.prepareSelect("select count(*) from github_perms_mapping")) { - return Optional.ofNullable(select.get(t -> t.getInt(1) > 0)) - .orElseThrow(); - } - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/SetAllowQualityProfileDisableInheritedRules.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/SetAllowQualityProfileDisableInheritedRules.java deleted file mode 100644 index c14c2e09d82..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/SetAllowQualityProfileDisableInheritedRules.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import java.sql.SQLException; -import org.sonar.api.utils.System2; -import org.sonar.core.config.CorePropertyDefinitions; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.Select; - -public class SetAllowQualityProfileDisableInheritedRules extends DataChange { - private System2 system2; - private UuidFactory uuidFactory; - - public SetAllowQualityProfileDisableInheritedRules(Database db, System2 system2, UuidFactory uuidFactory) { - super(db); - this.system2 = system2; - this.uuidFactory = uuidFactory; - } - - @Override - protected void execute(Context context) throws SQLException { - if (!propertyIsAlreadyDefined(context)) { - insertPropertyWithValueAsFalse(context); - } - } - - private static boolean propertyIsAlreadyDefined(Context context) throws SQLException { - Select select = context.prepareSelect("select p.text_value from properties p where p.prop_key = ?") - .setString(1, CorePropertyDefinitions.ALLOW_DISABLE_INHERITED_RULES); - String value = select.get(row -> row.getString(1)); - return value != null; - } - - private void insertPropertyWithValueAsFalse(Context context) throws SQLException { - context.prepareUpsert("INSERT INTO properties" - + "(prop_key, is_empty, text_value, created_at, uuid) " - + "VALUES(?, ?, ?, ?, ?)") - .setString(1, CorePropertyDefinitions.ALLOW_DISABLE_INHERITED_RULES) - .setBoolean(2, false) - .setString(3, "false") - .setLong(4, system2.now()) - .setString(5, uuidFactory.create()) - .execute() - .commit(); - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/package-info.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/package-info.java deleted file mode 100644 index fd23746e2ce..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.server.platform.db.migration.version.v103; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/AddUuidColumnToGroupsUsers.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/AddUuidColumnToGroupsUsers.java deleted file mode 100644 index 9d29d1bd62c..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/AddUuidColumnToGroupsUsers.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; - -public class AddUuidColumnToGroupsUsers extends DdlChange { - - public static final String GROUPS_USERS_TABLE_NAME = "groups_users"; - public static final String GROUPS_USERS_UUID_COLUMN_NAME = "uuid"; - - public AddUuidColumnToGroupsUsers(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, GROUPS_USERS_TABLE_NAME, GROUPS_USERS_UUID_COLUMN_NAME)) { - ColumnDef columnDef = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(GROUPS_USERS_UUID_COLUMN_NAME) - .setLimit(UUID_SIZE) - .setIsNullable(true) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), GROUPS_USERS_TABLE_NAME).addColumn(columnDef).build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/CreateIssuesFixedTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/CreateIssuesFixedTable.java deleted file mode 100644 index 73f9b8e21df..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/CreateIssuesFixedTable.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateIssuesFixedTable extends CreateTableChange { - - static final String TABLE_NAME = "issues_fixed"; - static final String COLUMN_PULL_REQUEST_UUID = "pull_request_uuid"; - static final String COLUMN_ISSUE_KEY = "issue_key"; - - public CreateIssuesFixedTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_PULL_REQUEST_UUID).setIsNullable(false).setLimit(UUID_SIZE).build()) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_ISSUE_KEY).setIsNullable(false).setLimit(50).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/CreatePrimaryKeyOnGroupsUsersTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/CreatePrimaryKeyOnGroupsUsersTable.java deleted file mode 100644 index 42bdd7fc18f..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/CreatePrimaryKeyOnGroupsUsersTable.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.AddPrimaryKeyBuilder; -import org.sonar.server.platform.db.migration.sql.DbPrimaryKeyConstraintFinder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v104.AddUuidColumnToGroupsUsers.GROUPS_USERS_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v104.AddUuidColumnToGroupsUsers.GROUPS_USERS_UUID_COLUMN_NAME; - -public class CreatePrimaryKeyOnGroupsUsersTable extends DdlChange { - - @VisibleForTesting - static final String PK_NAME = "pk_groups_users"; - - public CreatePrimaryKeyOnGroupsUsersTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - createPrimaryKey(context); - } - - private void createPrimaryKey(Context context) throws SQLException { - boolean pkExists = new DbPrimaryKeyConstraintFinder(getDatabase()).findConstraintName(GROUPS_USERS_TABLE_NAME).isPresent(); - if (!pkExists) { - context.execute(new AddPrimaryKeyBuilder(GROUPS_USERS_TABLE_NAME, GROUPS_USERS_UUID_COLUMN_NAME).build()); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/CreateRuleTagsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/CreateRuleTagsTable.java deleted file mode 100644 index 6cd00c87472..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/CreateRuleTagsTable.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateRuleTagsTable extends CreateTableChange { - - static final String RULE_TAGS_TABLE_NAME = "rule_tags"; - - static final String VALUE_COLUMN_NAME = "value"; - static final String IS_SYSTEM_TAG_COLUMN_NAME = "is_system_tag"; - static final String RULE_UUID_COLUMN_NAME = "rule_uuid"; - static final int VALUE_COLUMN_SIZE = 400; - - public CreateRuleTagsTable(Database db) { - super(db, RULE_TAGS_TABLE_NAME); - } - - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName(VALUE_COLUMN_NAME).setIsNullable(false).setLimit(VALUE_COLUMN_SIZE).build()) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName(RULE_UUID_COLUMN_NAME).setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newBooleanColumnDefBuilder().setColumnName(IS_SYSTEM_TAG_COLUMN_NAME).setIsNullable(false).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/DbVersion104.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/DbVersion104.java deleted file mode 100644 index 8ad36896a6d..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/DbVersion104.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import org.sonar.server.platform.db.migration.step.MigrationStepRegistry; -import org.sonar.server.platform.db.migration.version.DbVersion; - -// ignoring bad number formatting, as it's indented that we align the migration numbers to SQ versions -@SuppressWarnings("java:S3937") -public class DbVersion104 implements DbVersion { - - /** - * We use the start of the 10.X cycle as an opportunity to align migration numbers with the SQ version number. - * Please follow this pattern: - * 10_0_000 - * 10_0_001 - * 10_0_002 - * 10_1_000 - * 10_1_001 - * 10_1_002 - * 10_2_000 - */ - - @Override - public void addSteps(MigrationStepRegistry registry) { - registry - .add(10_4_000, "Delete redundant Failed Alerts for Applications", DeleteRedundantFailedAlertsForApplications.class) - .add(10_4_001, "Rename metric 'wont_fix_issues' to 'accepted_issues'", RenameWontFixIssuesMetric.class) - .add(10_4_002, "Create table 'rules_tags'", CreateRuleTagsTable.class) - .add(10_4_003, "Populate 'rule_tags' table", PopulateRuleTagsTable.class) - .add(10_4_004, "Drop column 'tags' in the 'rules' table", DropTagsInRules.class) - .add(10_4_005, "Drop column 'system_tags' in the 'rules' table", DropSystemTagsInRules.class) - .add(10_4_006, "Add 'uuid' column to 'groups_users'", AddUuidColumnToGroupsUsers.class) - .add(10_4_007, "Populate 'uuid' column in 'groups_users'", PopulateGroupsUsersUuid.class) - .add(10_4_008, "Make 'uuid' column in 'groups_users' table non-nullable", MakeUuidInGroupsUsersNotNullable.class) - .add(10_4_009, "Create primary key on 'groups_users.uuid'", CreatePrimaryKeyOnGroupsUsersTable.class) - .add(10_4_010, "Set nulls in 'clean_code_attribute' column of 'rules' table for security hotspots", - RemoveCleanCodeAttributeFromCustomHotspotRules.class) - .add(10_4_011, "Create 'issues_fixed' table", CreateIssuesFixedTable.class); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/DeleteRedundantFailedAlertsForApplications.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/DeleteRedundantFailedAlertsForApplications.java deleted file mode 100644 index bb869985f6d..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/DeleteRedundantFailedAlertsForApplications.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class DeleteRedundantFailedAlertsForApplications extends DataChange { - - private static final String SELECT_QUERY = """ - SELECT E.uuid - FROM events E - JOIN components C ON E.component_uuid = C.uuid - WHERE E.name = 'Failed' - AND E.category = 'Alert' - AND E.event_data = '{ stillFailing: false, status: "ERROR" }' - AND C.qualifier = 'APP'"""; - - private static final String DELETE_EVENTS_STATEMENT = "DELETE FROM events WHERE uuid = ?"; - private static final String DELETE_EVENTS_COMPONENT_CHANGES_STATEMENT = "DELETE FROM event_component_changes WHERE event_uuid = ?"; - - public DeleteRedundantFailedAlertsForApplications(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - MassUpdate massUpdate = context.prepareMassUpdate(); - var select = massUpdate.select(SELECT_QUERY); - var deleteEventComponentChanges = massUpdate.update(DELETE_EVENTS_COMPONENT_CHANGES_STATEMENT); - var deleteEvents = massUpdate.update(DELETE_EVENTS_STATEMENT); - try (select; deleteEventComponentChanges; deleteEvents) { - massUpdate.execute((row, delete, index) -> { - // both updates use the same select, so no need to differentiate for the 2 update indexes - String uuid = row.getString(1); - delete.setString(1, uuid); - return true; - }); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/DropSystemTagsInRules.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/DropSystemTagsInRules.java deleted file mode 100644 index df45918c350..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/DropSystemTagsInRules.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropSystemTagsInRules extends DropColumnChange { - static final String COLUMN_NAME = "system_tags"; - static final String TABLE_NAME = "rules"; - - public DropSystemTagsInRules(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/DropTagsInRules.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/DropTagsInRules.java deleted file mode 100644 index d4d50599439..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/DropTagsInRules.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropTagsInRules extends DropColumnChange { - private static final String COLUMN_NAME = "tags"; - private static final String TABLE_NAME = "rules"; - - public DropTagsInRules(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/MakeUuidInGroupsUsersNotNullable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/MakeUuidInGroupsUsersNotNullable.java deleted file mode 100644 index 9b7b1063376..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/MakeUuidInGroupsUsersNotNullable.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.version.v104.AddUuidColumnToGroupsUsers.GROUPS_USERS_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v104.AddUuidColumnToGroupsUsers.GROUPS_USERS_UUID_COLUMN_NAME; - -public class MakeUuidInGroupsUsersNotNullable extends DdlChange { - - private static final VarcharColumnDef UUID_COLUMN_DEF = VarcharColumnDef.newVarcharColumnDefBuilder(GROUPS_USERS_UUID_COLUMN_NAME) - .setIsNullable(false) - .setLimit(UUID_SIZE) - .build(); - - public MakeUuidInGroupsUsersNotNullable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - context.execute(new AlterColumnsBuilder(getDialect(), GROUPS_USERS_TABLE_NAME).updateColumn(UUID_COLUMN_DEF).build()); - - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/PopulateGroupsUsersUuid.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/PopulateGroupsUsersUuid.java deleted file mode 100644 index b25c8f49c7a..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/PopulateGroupsUsersUuid.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; -import org.sonar.server.platform.db.migration.step.Select; -import org.sonar.server.platform.db.migration.step.SqlStatement; -import org.sonar.server.platform.db.migration.step.Upsert; - -public class PopulateGroupsUsersUuid extends DataChange { - - private static final String SELECT_QUERY = """ - SELECT group_uuid, user_uuid - FROM groups_users - WHERE uuid IS NULL - """; - - private static final String SET_UUID_STATEMENT = """ - UPDATE groups_users - SET uuid=? - WHERE group_uuid=? AND user_uuid=? - """; - - private final UuidFactory uuidFactory; - - public PopulateGroupsUsersUuid(Database db, UuidFactory uuidFactory) { - super(db); - this.uuidFactory = uuidFactory; - } - - @Override - protected void execute(Context context) throws SQLException { - MassUpdate massUpdate = context.prepareMassUpdate(); - SqlStatement<Select> select = massUpdate.select(SELECT_QUERY); - Upsert setUuid = massUpdate.update(SET_UUID_STATEMENT); - try (select; setUuid) { - massUpdate.execute((row, update, index) -> { - String groupUuid = row.getString(1); - String userUuid = row.getString(2); - String uuid = uuidFactory.create(); - update.setString(1, uuid); - update.setString(2, groupUuid); - update.setString(3, userUuid); - return true; - }); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/PopulateRuleTagsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/PopulateRuleTagsTable.java deleted file mode 100644 index 5b4b2fd5dcb..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/PopulateRuleTagsTable.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.Select; -import org.sonar.server.platform.db.migration.step.Upsert; - -public class PopulateRuleTagsTable extends DataChange { - - private static final String SELECT_QUERY = """ - SELECT uuid, system_tags AS tag, 1 as is_system_tag - FROM rules - WHERE system_tags IS NOT NULL - UNION ALL - SELECT uuid, tags AS tag, 0 as is_system_tag - FROM rules - WHERE tags IS NOT NULL - """; - - private static final String INSERT_QUERY = """ - INSERT INTO rule_tags (rule_uuid, is_system_tag, value) - VALUES (?, ?, ?) - """; - - public PopulateRuleTagsTable(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - if (isTableAlreadyPopulated(context)) { - return; - } - - List<Tags> allTags = findAllTags(context); - if (allTags.isEmpty()) { - return; - } - allTags = removeDuplicatesForAllRule(allTags); - - Upsert insertTagsQuery = context.prepareUpsert(INSERT_QUERY); - for (Tags tags : allTags) { - insertEveryTag(insertTagsQuery, tags.ruleUuid(), tags.values(), tags.isSystemTag()); - } - insertTagsQuery.execute().commit(); - } - - /** - * System tags and custom tags can contain the same values. In this case, we keep only the system tag. - */ - private static List<Tags> removeDuplicatesForAllRule(List<Tags> allTags) { - Map<String, List<Tags>> tagsByRuleUuid = allTags.stream().collect(Collectors.groupingBy(Tags::ruleUuid)); - List<Tags> listWithoutDuplicates = new ArrayList<>(); - - for (Map.Entry<String, List<Tags>> entry : tagsByRuleUuid.entrySet()) { - listWithoutDuplicates.addAll(removeDuplicateForRule(entry.getValue())); - } - return listWithoutDuplicates; - } - - private static List<Tags> removeDuplicateForRule(List<Tags> ruleTags) { - Optional<Tags> systemTags = ruleTags.stream().filter(Tags::isSystemTag).findFirst(); - Optional<Tags> manualTags = ruleTags.stream().filter(t -> !t.isSystemTag()).findFirst(); - - if (systemTags.isEmpty()) { - return List.of(manualTags.orElseThrow()); - } else if (manualTags.isEmpty()) { - return List.of(systemTags.orElseThrow()); - } else { - Set<String> systemTagValues = systemTags.get().values(); - Set<String> manualTagValues = manualTags.get().values(); - Set<String> commonValues = new HashSet<>(systemTagValues); - commonValues.retainAll(manualTagValues); - - if (commonValues.isEmpty()) { - return List.of(manualTags.orElseThrow(), systemTags.orElseThrow()); - } else { - manualTagValues.removeAll(commonValues); - return List.of(systemTags.orElseThrow(), new Tags(manualTags.get().ruleUuid(), manualTagValues, false)); - } - } - } - - private static void insertEveryTag(Upsert insertRuleTags, String ruleUuid, Set<String> values, boolean isSystemTag) throws SQLException { - for (String tag : values) { - insertRuleTags - .setString(1, ruleUuid) - .setBoolean(2, isSystemTag) - .setString(3, tag) - .addBatch(); - } - } - - private static List<Tags> findAllTags(Context context) throws SQLException { - return context.prepareSelect(SELECT_QUERY) - .list(r -> new Tags(r.getString(1), parseTagString(r.getString(2)), r.getBoolean(3))); - } - - private static boolean isTableAlreadyPopulated(Context context) throws SQLException { - try (Select select = context.prepareSelect("select count(*) from rule_tags")) { - return Optional.ofNullable(select.get(t -> t.getInt(1) > 0)) - .orElseThrow(); - } - } - - private static Set<String> parseTagString(String tagString) { - return Arrays.stream(tagString.split(",")) - .filter(s -> !s.isEmpty()) - .collect(Collectors.toSet()); - } - - private record Tags(String ruleUuid, Set<String> values, boolean isSystemTag) { - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/RemoveCleanCodeAttributeFromCustomHotspotRules.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/RemoveCleanCodeAttributeFromCustomHotspotRules.java deleted file mode 100644 index 1d94a0ddf90..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/RemoveCleanCodeAttributeFromCustomHotspotRules.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class RemoveCleanCodeAttributeFromCustomHotspotRules extends DataChange { - - private static final String SELECT = """ - SELECT uuid - FROM rules - WHERE rule_type = 4 - AND clean_code_attribute IS NOT NULL - """; - private static final String UPDATE = """ - UPDATE rules SET clean_code_attribute = NULL, updated_at = ? WHERE uuid = ? - """; - - public RemoveCleanCodeAttributeFromCustomHotspotRules(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - MassUpdate massUpdate = context.prepareMassUpdate(); - Long updatedAt = System.currentTimeMillis(); - massUpdate.select(SELECT); - massUpdate.update(UPDATE); - massUpdate.execute((row, update) -> { - String uuid = row.getString(1); - update.setLong(1, updatedAt); - update.setString(2, uuid); - return true; - }); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/RenameWontFixIssuesMetric.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/RenameWontFixIssuesMetric.java deleted file mode 100644 index e04f182e68f..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/RenameWontFixIssuesMetric.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.Upsert; - -public class RenameWontFixIssuesMetric extends DataChange { - - private static final String UPDATE_QUERY = """ - update metrics set name='accepted_issues', description='Accepted issues', short_name='Accepted issues' where name='wont_fix_issues' - """; - - public RenameWontFixIssuesMetric(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - Upsert upsert = context.prepareUpsert(UPDATE_QUERY); - upsert.execute().commit(); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/package-info.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/package-info.java deleted file mode 100644 index 89b67fc58f5..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.server.platform.db.migration.version.v104; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/CreatePrimaryKeyOnIssuesImpactsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/CreatePrimaryKeyOnIssuesImpactsTable.java deleted file mode 100644 index f1e42169f6f..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/CreatePrimaryKeyOnIssuesImpactsTable.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.AddPrimaryKeyBuilder; -import org.sonar.server.platform.db.migration.sql.DbPrimaryKeyConstraintFinder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class CreatePrimaryKeyOnIssuesImpactsTable extends DdlChange { - @VisibleForTesting - static final String PK_NAME = "pk_issues_impacts"; - @VisibleForTesting - static final String TABLE_NAME = "issues_impacts"; - @VisibleForTesting - static final String ISSUE_KEY_COLUMN_NAME = "issue_key"; - @VisibleForTesting - static final String SOFTWARE_QUALITY_COLUMN = "software_quality"; - - - public CreatePrimaryKeyOnIssuesImpactsTable(Database db) { - super(db); - } - - @Override - public void execute(DdlChange.Context context) throws SQLException { - createPrimaryKey(context); - } - - private void createPrimaryKey(DdlChange.Context context) throws SQLException { - boolean pkExists = new DbPrimaryKeyConstraintFinder(getDatabase()).findConstraintName(TABLE_NAME).isPresent(); - if (!pkExists) { - context.execute(new AddPrimaryKeyBuilder(TABLE_NAME, ISSUE_KEY_COLUMN_NAME, SOFTWARE_QUALITY_COLUMN).build()); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/CreatePrimaryKeyOnRulesDefaultImpactsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/CreatePrimaryKeyOnRulesDefaultImpactsTable.java deleted file mode 100644 index bcd27f1b1dd..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/CreatePrimaryKeyOnRulesDefaultImpactsTable.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.AddPrimaryKeyBuilder; -import org.sonar.server.platform.db.migration.sql.DbPrimaryKeyConstraintFinder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class CreatePrimaryKeyOnRulesDefaultImpactsTable extends DdlChange { - @VisibleForTesting - static final String PK_NAME = "pk_rules_default_impacts"; - @VisibleForTesting - static final String TABLE_NAME = "rules_default_impacts"; - @VisibleForTesting - static final String RULE_UUID_COLUMN_NAME = "rule_uuid"; - @VisibleForTesting - static final String SOFTWARE_QUALITY_COLUMN = "software_quality"; - - - public CreatePrimaryKeyOnRulesDefaultImpactsTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - createPrimaryKey(context); - } - - private void createPrimaryKey(Context context) throws SQLException { - boolean pkExists = new DbPrimaryKeyConstraintFinder(getDatabase()).findConstraintName(TABLE_NAME).isPresent(); - if (!pkExists) { - context.execute(new AddPrimaryKeyBuilder(TABLE_NAME, RULE_UUID_COLUMN_NAME, SOFTWARE_QUALITY_COLUMN).build()); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DbVersion105.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DbVersion105.java deleted file mode 100644 index 39c6cea8d13..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DbVersion105.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import org.sonar.server.platform.db.migration.step.MigrationStepRegistry; -import org.sonar.server.platform.db.migration.version.DbVersion; - -// ignoring bad number formatting, as it's indented that we align the migration numbers to SQ versions -@SuppressWarnings("java:S3937") -public class DbVersion105 implements DbVersion { - - /** - * We use the start of the 10.X cycle as an opportunity to align migration numbers with the SQ version number. - * Please follow this pattern: - * 10_0_000 - * 10_0_001 - * 10_0_002 - * 10_1_000 - * 10_1_001 - * 10_1_002 - * 10_2_000 - */ - - @Override - public void addSteps(MigrationStepRegistry registry) { - registry - .add(10_5_000, "Drop constraint on 'uuid' from 'issues_impacts' table", DropPrimaryKeyConstraintInIssuesImpactsTable.class) - .add(10_5_001, "Drop constraint on 'uuid' from 'rules_default_impacts' table", DropPrimaryKeyConstraintInRulesDefaultImpactsTable.class) - .add(10_5_002, "Drop column 'uuid' from 'issues_impacts' table", DropUuidColumnInIssuesImpactsTable.class) - .add(10_5_003, "Drop column 'uuid' from 'rules_default_impacts' table", DropUuidColumnInRulesDefaultImpactsTable.class) - .add(10_5_004, "Create primary key on 'issues_impacts' table", CreatePrimaryKeyOnIssuesImpactsTable.class) - .add(10_5_005, "Create primary key on 'rules_default_impacts' table", CreatePrimaryKeyOnRulesDefaultImpactsTable.class) - .add(10_5_006, "Delete 'languageSpecificParameters' property set from 'properties' table", DeleteLanguageSpecificParametersPropertySet.class); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DeleteLanguageSpecificParametersPropertySet.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DeleteLanguageSpecificParametersPropertySet.java deleted file mode 100644 index 417edadd0a2..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DeleteLanguageSpecificParametersPropertySet.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; - -public class DeleteLanguageSpecificParametersPropertySet extends DataChange { - - public DeleteLanguageSpecificParametersPropertySet(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - context.prepareUpsert("delete from properties where prop_key like ?") - .setString(1, "languageSpecificParameters%") - .execute() - .commit(); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DropPrimaryKeyConstraintInIssuesImpactsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DropPrimaryKeyConstraintInIssuesImpactsTable.java deleted file mode 100644 index c1b203bf9bd..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DropPrimaryKeyConstraintInIssuesImpactsTable.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.List; -import java.util.Optional; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.DbPrimaryKeyConstraintFinder; -import org.sonar.server.platform.db.migration.sql.DropPrimaryKeySqlGenerator; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class DropPrimaryKeyConstraintInIssuesImpactsTable extends DdlChange { - @VisibleForTesting - static final String TABLE_NAME = "issues_impacts"; - @VisibleForTesting - static final String COLUMN_NAME = "uuid"; - @VisibleForTesting - static final String CONSTRAINT_NAME = "pk_issues_impacts"; - private final DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator; - private final DbPrimaryKeyConstraintFinder dbConstraintFinder; - - public DropPrimaryKeyConstraintInIssuesImpactsTable(Database db, DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator, DbPrimaryKeyConstraintFinder dbConstraintFinder) { - super(db); - this.dropPrimaryKeySqlGenerator = dropPrimaryKeySqlGenerator; - this.dbConstraintFinder = dbConstraintFinder; - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (DatabaseUtils.tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { - Optional<String> constraintName = dbConstraintFinder.findConstraintName(TABLE_NAME); - if (constraintName.isPresent() && constraintName.get().equalsIgnoreCase(CONSTRAINT_NAME)) { - List<String> statements = dropPrimaryKeySqlGenerator.generate(TABLE_NAME, COLUMN_NAME, false); - context.execute(statements); - } - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DropPrimaryKeyConstraintInRulesDefaultImpactsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DropPrimaryKeyConstraintInRulesDefaultImpactsTable.java deleted file mode 100644 index a33791c7420..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DropPrimaryKeyConstraintInRulesDefaultImpactsTable.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.List; -import java.util.Optional; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.DbPrimaryKeyConstraintFinder; -import org.sonar.server.platform.db.migration.sql.DropPrimaryKeySqlGenerator; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class DropPrimaryKeyConstraintInRulesDefaultImpactsTable extends DdlChange { - @VisibleForTesting - static final String TABLE_NAME = "rules_default_impacts"; - @VisibleForTesting - static final String COLUMN_NAME = "uuid"; - @VisibleForTesting - static final String CONSTRAINT_NAME = "pk_rules_default_impacts"; - private final DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator; - private final DbPrimaryKeyConstraintFinder dbConstraintFinder; - - public DropPrimaryKeyConstraintInRulesDefaultImpactsTable(Database db, DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator, DbPrimaryKeyConstraintFinder dbConstraintFinder) { - super(db); - this.dropPrimaryKeySqlGenerator = dropPrimaryKeySqlGenerator; - this.dbConstraintFinder = dbConstraintFinder; - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (DatabaseUtils.tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { - Optional<String> constraintName = dbConstraintFinder.findConstraintName(TABLE_NAME); - if (constraintName.isPresent() && constraintName.get().equalsIgnoreCase(CONSTRAINT_NAME)) { - List<String> statements = dropPrimaryKeySqlGenerator.generate(TABLE_NAME, COLUMN_NAME, false); - context.execute(statements); - } - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DropUuidColumnInIssuesImpactsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DropUuidColumnInIssuesImpactsTable.java deleted file mode 100644 index 845e74c859c..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DropUuidColumnInIssuesImpactsTable.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import com.google.common.annotations.VisibleForTesting; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropUuidColumnInIssuesImpactsTable extends DropColumnChange { - @VisibleForTesting - static final String COLUMN_NAME = "uuid"; - @VisibleForTesting - static final String TABLE_NAME = "issues_impacts"; - - protected DropUuidColumnInIssuesImpactsTable(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DropUuidColumnInRulesDefaultImpactsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DropUuidColumnInRulesDefaultImpactsTable.java deleted file mode 100644 index 1069cb68d45..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/DropUuidColumnInRulesDefaultImpactsTable.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropUuidColumnInRulesDefaultImpactsTable extends DropColumnChange { - private static final String COLUMN_NAME = "uuid"; - private static final String TABLE_NAME = "rules_default_impacts"; - - protected DropUuidColumnInRulesDefaultImpactsTable(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/package-info.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/package-info.java deleted file mode 100644 index 3491e99a7a1..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v105/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.server.platform.db.migration.version.v105; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/AddPrioritizedRuleColumnToActiveRulesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/AddPrioritizedRuleColumnToActiveRulesTable.java deleted file mode 100644 index 36b09b4eabf..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/AddPrioritizedRuleColumnToActiveRulesTable.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v106; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.BooleanColumnDef; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AddPrioritizedRuleColumnToActiveRulesTable extends DdlChange { - - public static final String ACTIVE_RULES_TABLE_NAME = "active_rules"; - public static final String PRIORITIZED_RULE_COLUMN_NAME = "prioritized_rule"; - - public AddPrioritizedRuleColumnToActiveRulesTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, ACTIVE_RULES_TABLE_NAME, PRIORITIZED_RULE_COLUMN_NAME)) { - ColumnDef columnDef = BooleanColumnDef.newBooleanColumnDefBuilder() - .setColumnName(PRIORITIZED_RULE_COLUMN_NAME) - .setIsNullable(true) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), ACTIVE_RULES_TABLE_NAME) - .addColumn(columnDef) - .build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/AddPrioritizedRuleColumnToIssuesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/AddPrioritizedRuleColumnToIssuesTable.java deleted file mode 100644 index afb2585ba3a..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/AddPrioritizedRuleColumnToIssuesTable.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v106; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.BooleanColumnDef; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AddPrioritizedRuleColumnToIssuesTable extends DdlChange { - - public static final String ISSUES_TABLE_NAME = "issues"; - public static final String PRIORITIZED_RULE_COLUMN_NAME = "prioritized_rule"; - - public AddPrioritizedRuleColumnToIssuesTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, ISSUES_TABLE_NAME, PRIORITIZED_RULE_COLUMN_NAME)) { - ColumnDef columnDef = BooleanColumnDef.newBooleanColumnDefBuilder() - .setColumnName(PRIORITIZED_RULE_COLUMN_NAME) - .setIsNullable(true) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), ISSUES_TABLE_NAME) - .addColumn(columnDef) - .build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/DbVersion106.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/DbVersion106.java deleted file mode 100644 index b532c9478ed..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/DbVersion106.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v106; - -import org.sonar.server.platform.db.migration.step.MigrationStepRegistry; -import org.sonar.server.platform.db.migration.version.DbVersion; - -// ignoring bad number formatting, as it's indented that we align the migration numbers to SQ versions -@SuppressWarnings("java:S3937") -public class DbVersion106 implements DbVersion { - - /** - * We use the start of the 10.X cycle as an opportunity to align migration numbers with the SQ version number. - * Please follow this pattern: - * 10_0_000 - * 10_0_001 - * 10_0_002 - * 10_1_000 - * 10_1_001 - * 10_1_002 - * 10_2_000 - */ - - @Override - public void addSteps(MigrationStepRegistry registry) { - registry - .add(10_6_000, "Add 'prioritized_rule' column to 'issues' table", AddPrioritizedRuleColumnToIssuesTable.class) - .add(10_6_001, "Add 'prioritized_rule' column to 'active_rules' table", AddPrioritizedRuleColumnToActiveRulesTable.class) - .add(10_6_002, "Ensure 'value' column is resized to 400 in 'rule_tags' table", ResizeValueColumnInRuleTagsTable.class); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/ResizeValueColumnInRuleTagsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/ResizeValueColumnInRuleTagsTable.java deleted file mode 100644 index 8f971188e3d..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/ResizeValueColumnInRuleTagsTable.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v106; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class ResizeValueColumnInRuleTagsTable extends DdlChange { - - private static final VarcharColumnDef columnDefinition = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName("value") - .setIsNullable(false) - .setLimit(400) - .build(); - - public ResizeValueColumnInRuleTagsTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - context.execute(new AlterColumnsBuilder(getDialect(), "rule_tags") - .updateColumn(columnDefinition) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/package-info.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/package-info.java deleted file mode 100644 index ced70eace78..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v106/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.server.platform.db.migration.version.v106; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/AddAiCodeAssuranceColumnInProjectsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/AddAiCodeAssuranceColumnInProjectsTable.java deleted file mode 100644 index f1b9c78baf5..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/AddAiCodeAssuranceColumnInProjectsTable.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.BooleanColumnDef; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AddAiCodeAssuranceColumnInProjectsTable extends DdlChange { - static final String PROJECTS_TABLE_NAME = "projects"; - static final String AI_CODE_ASSURANCE = "ai_code_assurance"; - @VisibleForTesting - static final Boolean DEFAULT_COLUMN_VALUE = false; - - public AddAiCodeAssuranceColumnInProjectsTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, PROJECTS_TABLE_NAME, AI_CODE_ASSURANCE)) { - ColumnDef columnDef = BooleanColumnDef.newBooleanColumnDefBuilder() - .setColumnName(AI_CODE_ASSURANCE) - .setIsNullable(false) - .setDefaultValue(DEFAULT_COLUMN_VALUE) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), PROJECTS_TABLE_NAME) - .addColumn(columnDef) - .build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/AddDevopsPlatformColumnInDevopsPermsMapping.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/AddDevopsPlatformColumnInDevopsPermsMapping.java deleted file mode 100644 index 22d35c835e4..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/AddDevopsPlatformColumnInDevopsPermsMapping.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; - -public class AddDevopsPlatformColumnInDevopsPermsMapping extends DdlChange { - - static final String DEVOPS_PLATFORM_COLUMN_NAME = "devops_platform"; - @VisibleForTesting - static final String DEFAULT_COLUMN_VALUE = "github"; - - public AddDevopsPlatformColumnInDevopsPermsMapping(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, DEVOPS_PERMS_MAPPING_TABLE_NAME, DEVOPS_PLATFORM_COLUMN_NAME)) { - ColumnDef columnDef = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(DEVOPS_PLATFORM_COLUMN_NAME) - .setLimit(40) - .setIsNullable(false) - .setDefaultValue(DEFAULT_COLUMN_VALUE) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), DEVOPS_PERMS_MAPPING_TABLE_NAME) - .addColumn(columnDef) - .build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/AddUserConsentRequiredIfGitlabAutoProvisioningEnabled.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/AddUserConsentRequiredIfGitlabAutoProvisioningEnabled.java deleted file mode 100644 index b7a5acfdb73..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/AddUserConsentRequiredIfGitlabAutoProvisioningEnabled.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import java.util.Optional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.utils.System2; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.Upsert; - -public class AddUserConsentRequiredIfGitlabAutoProvisioningEnabled extends DataChange { - - private static final Logger LOGGER = LoggerFactory.getLogger(AddUserConsentRequiredIfGitlabAutoProvisioningEnabled.class.getName()); - - @VisibleForTesting - static final String PROVISIONING_GITLAB_ENABLED_PROP_KEY = "provisioning.gitlab.enabled"; - - @VisibleForTesting - static final String PROP_KEY = "sonar.auth.gitlab.userConsentForPermissionProvisioningRequired"; - - private static final String INSERT_QUERY = """ - insert into properties (uuid, prop_key, is_empty, created_at) - values (?, ?, ?, ?) - """; - - private final System2 system2; - private final UuidFactory uuidFactory; - - public AddUserConsentRequiredIfGitlabAutoProvisioningEnabled(Database db, System2 system2, UuidFactory uuidFactory) { - super(db); - this.system2 = system2; - this.uuidFactory = uuidFactory; - } - - @Override - protected void execute(DataChange.Context context) throws SQLException { - if (!isGitlabAutoProvisioningEnabled(context)) { - return; - } - if (isUserConsentAlreadyRequired(context)) { - return; - } - LOGGER.warn("Automatic synchronization was previously activated for Gitlab. It requires user consent to continue working as new" + - " features were added with the synchronization. Please read the upgrade notes."); - Upsert upsert = context.prepareUpsert(INSERT_QUERY); - upsert - .setString(1, uuidFactory.create()) - .setString(2, PROP_KEY) - .setBoolean(3, true) - .setLong(4, system2.now()) - .execute() - .commit(); - } - - private static boolean isUserConsentAlreadyRequired(Context context) throws SQLException { - return Optional.ofNullable(context.prepareSelect("select count(*) from properties where prop_key = ?") - .setString(1, PROP_KEY) - .get(t -> 1 == t.getInt(1))) - .orElseThrow(); - } - - private static boolean isGitlabAutoProvisioningEnabled(Context context) throws SQLException { - return Optional.ofNullable(context.prepareSelect("select count(*) from properties where prop_key = ? and text_value = ?") - .setString(1, PROVISIONING_GITLAB_ENABLED_PROP_KEY) - .setString(2, "true") - .get(t -> 1 == t.getInt(1))) - .orElseThrow(); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateCveCweTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateCveCweTable.java deleted file mode 100644 index 49e09da2250..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateCveCweTable.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.DESCRIPTION_SECTION_KEY_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateCveCweTable extends CreateTableChange { - - private static final String TABLE_NAME = "cve_cwe"; - - public static final VarcharColumnDef CVE_UUID_COLUMN = newVarcharColumnDefBuilder().setColumnName("cve_uuid").setIsNullable(false).setLimit(UUID_SIZE).build(); - public static final VarcharColumnDef CWE_COLUMN = newVarcharColumnDefBuilder().setColumnName("cwe").setIsNullable(false).setLimit(DESCRIPTION_SECTION_KEY_SIZE).build(); - - protected CreateCveCweTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(CVE_UUID_COLUMN) - .addPkColumn(CWE_COLUMN) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateCvesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateCvesTable.java deleted file mode 100644 index ddb5d81a3a2..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateCvesTable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.BigIntegerColumnDef; -import org.sonar.server.platform.db.migration.def.DecimalColumnDef; -import org.sonar.server.platform.db.migration.def.VarcharColumnDef; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder; -import static org.sonar.server.platform.db.migration.def.DecimalColumnDef.newDecimalColumnDefBuilder; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.DESCRIPTION_SECTION_KEY_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.MAX_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateCvesTable extends CreateTableChange { - - private static final String TABLE_NAME = "cves"; - - private static final VarcharColumnDef UUID_COLUMN = newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build(); - private static final VarcharColumnDef ID_COLUMN = newVarcharColumnDefBuilder().setColumnName("id").setIsNullable(false).setLimit(DESCRIPTION_SECTION_KEY_SIZE).build(); - private static final VarcharColumnDef DESCRIPTION_COLUMN = newVarcharColumnDefBuilder().setColumnName("description").setIsNullable(false).setLimit(MAX_SIZE).build(); - public static final BigIntegerColumnDef UPDATED_AT_COLUMN = newBigIntegerColumnDefBuilder().setColumnName("updated_at").setIsNullable(false).build(); - public static final BigIntegerColumnDef CREATED_AT_COLUMN = newBigIntegerColumnDefBuilder().setColumnName("created_at").setIsNullable(false).build(); - public static final BigIntegerColumnDef LAST_MODIFIED_COLUMN = newBigIntegerColumnDefBuilder().setColumnName("last_modified_at").setIsNullable(false).build(); - public static final BigIntegerColumnDef PUBLISHED_COLUMN = newBigIntegerColumnDefBuilder().setColumnName("published_at").setIsNullable(false).build(); - public static final DecimalColumnDef CVSS_SCORE_COLUMN = newDecimalColumnDefBuilder().setColumnName("cvss_score").setIsNullable(true).build(); - public static final DecimalColumnDef EPSS_SCORE_COLUMN = newDecimalColumnDefBuilder().setColumnName("epss_score").setIsNullable(true).build(); - public static final DecimalColumnDef EPSS_PERCENTILE_COLUMN = newDecimalColumnDefBuilder().setColumnName("epss_percentile").setIsNullable(true).build(); - - protected CreateCvesTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(UUID_COLUMN) - .addColumn(ID_COLUMN) - .addColumn(DESCRIPTION_COLUMN) - .addColumn(CVSS_SCORE_COLUMN) - .addColumn(EPSS_SCORE_COLUMN) - .addColumn(EPSS_PERCENTILE_COLUMN) - .addColumn(PUBLISHED_COLUMN) - .addColumn(LAST_MODIFIED_COLUMN) - .addColumn(CREATED_AT_COLUMN) - .addColumn(UPDATED_AT_COLUMN) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateIssuesDependencyTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateIssuesDependencyTable.java deleted file mode 100644 index db662abfd8a..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateIssuesDependencyTable.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateIssuesDependencyTable extends CreateTableChange { - - private static final String TABLE_NAME = "issues_dependency"; - - protected CreateIssuesDependencyTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName("issue_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("cve_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreatePrimaryKeyConstraintOnDevopsPermsMappingTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreatePrimaryKeyConstraintOnDevopsPermsMappingTable.java deleted file mode 100644 index a2b2c3e4491..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreatePrimaryKeyConstraintOnDevopsPermsMappingTable.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.AddPrimaryKeyBuilder; -import org.sonar.server.platform.db.migration.sql.DbPrimaryKeyConstraintFinder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; - -public class CreatePrimaryKeyConstraintOnDevopsPermsMappingTable extends DdlChange { - - @VisibleForTesting - static final String UUID_COLUMN_NAME = "uuid"; - - public CreatePrimaryKeyConstraintOnDevopsPermsMappingTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - createPrimaryKey(context); - } - - private void createPrimaryKey(Context context) throws SQLException { - boolean pkExists = new DbPrimaryKeyConstraintFinder(getDatabase()).findConstraintName(DEVOPS_PERMS_MAPPING_TABLE_NAME).isPresent(); - if (!pkExists) { - context.execute(new AddPrimaryKeyBuilder(DEVOPS_PERMS_MAPPING_TABLE_NAME, UUID_COLUMN_NAME).build()); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateTelemetryMetricsSentTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateTelemetryMetricsSentTable.java deleted file mode 100644 index b6c2864e32d..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateTelemetryMetricsSentTable.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; -import org.sonar.server.platform.db.migration.step.CreateTableChange; - -import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class CreateTelemetryMetricsSentTable extends CreateTableChange { - - private static final String TABLE_NAME = "telemetry_metrics_sent"; - private static final int LENGTH_OF_METRIC_KEY_AND_DIMENSION = 40; - - protected CreateTelemetryMetricsSentTable(Database db) { - super(db, TABLE_NAME); - } - - @Override - public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName("metric_key").setIsNullable(false) - .setLimit(LENGTH_OF_METRIC_KEY_AND_DIMENSION).build()) - .addPkColumn(newVarcharColumnDefBuilder().setColumnName("dimension").setIsNullable(false) - .setLimit(LENGTH_OF_METRIC_KEY_AND_DIMENSION).build()) - .addColumn(newBigIntegerColumnDefBuilder().setColumnName("last_sent").setIsNullable(false).build()) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateUniqueIndexOnDevopsPermsMappingTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateUniqueIndexOnDevopsPermsMappingTable.java deleted file mode 100644 index 00ca39d0757..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/CreateUniqueIndexOnDevopsPermsMappingTable.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v107.AddDevopsPlatformColumnInDevopsPermsMapping.DEVOPS_PLATFORM_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; - -public class CreateUniqueIndexOnDevopsPermsMappingTable extends DdlChange { - - @VisibleForTesting - static final String DEVOPS_ROLE_COLUMN_NAME = "devops_platform_role"; - @VisibleForTesting - static final String SONARQUBE_PERMISSION_COLUMN_NAME = "sonarqube_permission"; - @VisibleForTesting - static final String INDEX_NAME = "uniq_devops_perms_mapping"; - - public CreateUniqueIndexOnDevopsPermsMappingTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - createUserUuidUniqueIndex(context, connection); - } - } - - private void createUserUuidUniqueIndex(DdlChange.Context context, Connection connection) { - if (!DatabaseUtils.indexExistsIgnoreCase(DEVOPS_PERMS_MAPPING_TABLE_NAME, INDEX_NAME, connection)) { - context.execute(new CreateIndexBuilder(getDialect()) - .setTable(DEVOPS_PERMS_MAPPING_TABLE_NAME) - .setName(INDEX_NAME) - .addColumn(DEVOPS_PLATFORM_COLUMN_NAME, false) - .addColumn(DEVOPS_ROLE_COLUMN_NAME, false) - .addColumn(SONARQUBE_PERMISSION_COLUMN_NAME, false) - .setUnique(true) - .build()); - } - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/DbVersion107.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/DbVersion107.java deleted file mode 100644 index 43f0d7253d6..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/DbVersion107.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import org.sonar.server.platform.db.migration.step.MigrationStepRegistry; -import org.sonar.server.platform.db.migration.version.DbVersion; - -// ignoring bad number formatting, as it's indented that we align the migration numbers to SQ versions -@SuppressWarnings("java:S3937") -public class DbVersion107 implements DbVersion { - - /** - * We use the start of the 10.X cycle as an opportunity to align migration numbers with the SQ version number. - * Please follow this pattern: - * 10_0_000 - * 10_0_001 - * 10_0_002 - * 10_1_000 - * 10_1_001 - * 10_1_002 - * 10_2_000 - */ - @Override - public void addSteps(MigrationStepRegistry registry) { - registry - .add(10_7_000, "Create 'telemetry_metrics_sent' table", CreateTelemetryMetricsSentTable.class) - .add(10_7_001, "sonar.auth.gitlab.userConsentForPermissionProvisioningRequired", AddUserConsentRequiredIfGitlabAutoProvisioningEnabled.class) - .add(10_7_002, "Migrate SMTP configuration into internal_properties", MigrateSmtpConfiguration.class) - .add(10_7_003, "Drop 'github_perms_mapping' table if exists and 'devops_perms_mapping' table exists", DropGithubPermsMappingTableIfDevopsPermsMappingTableExists.class) - .add(10_7_004, "Rename 'github_perms_mapping' table to 'devops_perms_mapping'", RenameGithubPermsMappingTable.class) - .add(10_7_005, "Rename 'github_role' column to 'devops_platform_role' in devops_perms_mapping", RenameGithubRoleInDevopsPermsMapping.class) - .add(10_7_006, "Add 'devops_platform' column to 'devops_perms_mapping' table", AddDevopsPlatformColumnInDevopsPermsMapping.class) - .add(10_7_007, "Drop constraint on 'uuid' for 'devops_perms_mapping' table", DropPrimaryKeyOnDevopsPermsMappingTable.class) - .add(10_7_008, "Create primary key on 'devops_perms_mapping.uuid'", CreatePrimaryKeyConstraintOnDevopsPermsMappingTable.class) - .add(10_7_009, "Drop index 'uniq_github_perm_mappings' in the 'devops_perms_mapping' table", DropIndexUniqGithubPermsMappingInDevopsPermsMappingTable.class) - .add(10_7_010, "Create uniq index on 'devops_perms_mapping' table for columns 'devops_platform_role', 'sonarqube_permission' and 'devops_platform'", - CreateUniqueIndexOnDevopsPermsMappingTable.class) - .add(10_7_011, "Add default permissions for GitLab in 'devops_perms_mapping'", PopulateGitlabDevOpsPermissionsMapping.class) - .add(10_7_012, "Create 'cves' table", CreateCvesTable.class) - .add(10_7_013, "Create 'cve_cwe' table", CreateCveCweTable.class) - .add(10_7_014, "Create 'issues_dependency' table", CreateIssuesDependencyTable.class) - .add(10_7_015, "Add 'ai_code_assurance' column to 'projects' table", AddAiCodeAssuranceColumnInProjectsTable.class); - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/DropGithubPermsMappingTableIfDevopsPermsMappingTableExists.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/DropGithubPermsMappingTableIfDevopsPermsMappingTableExists.java deleted file mode 100644 index 43296d8bf8e..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/DropGithubPermsMappingTableIfDevopsPermsMappingTableExists.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.DropTableBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.GITHUB_PERMS_MAPPING_TABLE_NAME; - -/** - * Migration should be reentrant. - * If migration is rerun from version 103, a new table github_perms_mapping will be created while the table devops_perms_mapping will exist, - * the rename from github_perms_mapping to devops_perms_mapping will fail and we will be in an inconstant state with the two tables. - * To avoid this state, we need to drop the table github_perms_mapping if the table devops_perms_mapping exists. - */ -public class DropGithubPermsMappingTableIfDevopsPermsMappingTableExists extends DdlChange { - - public DropGithubPermsMappingTableIfDevopsPermsMappingTableExists(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (var connection = getDatabase().getDataSource().getConnection()) { - boolean devopsPermsMappingTableExists = DatabaseUtils.tableExists(DEVOPS_PERMS_MAPPING_TABLE_NAME, connection); - boolean githubPermsMappingTableExists = DatabaseUtils.tableExists(GITHUB_PERMS_MAPPING_TABLE_NAME, connection); - if (devopsPermsMappingTableExists && githubPermsMappingTableExists) { - context.execute(new DropTableBuilder(getDialect(), GITHUB_PERMS_MAPPING_TABLE_NAME).build()); - } - } - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/DropIndexUniqGithubPermsMappingInDevopsPermsMappingTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/DropIndexUniqGithubPermsMappingInDevopsPermsMappingTable.java deleted file mode 100644 index 4ac2eb5c1fd..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/DropIndexUniqGithubPermsMappingInDevopsPermsMappingTable.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import com.google.common.annotations.VisibleForTesting; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; - -public class DropIndexUniqGithubPermsMappingInDevopsPermsMappingTable extends DropIndexChange { - - @VisibleForTesting - static final String UNIQ_GITHUB_PERM_MAPPINGS_INDEX_NAME = "uniq_github_perm_mappings"; - - public DropIndexUniqGithubPermsMappingInDevopsPermsMappingTable(Database db) { - super(db, UNIQ_GITHUB_PERM_MAPPINGS_INDEX_NAME, DEVOPS_PERMS_MAPPING_TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/DropPrimaryKeyOnDevopsPermsMappingTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/DropPrimaryKeyOnDevopsPermsMappingTable.java deleted file mode 100644 index 665d2e3168d..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/DropPrimaryKeyOnDevopsPermsMappingTable.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import java.util.List; -import java.util.Optional; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.DbPrimaryKeyConstraintFinder; -import org.sonar.server.platform.db.migration.sql.DropPrimaryKeySqlGenerator; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; - -public class DropPrimaryKeyOnDevopsPermsMappingTable extends DdlChange { - - @VisibleForTesting - static final String UUID_COLUMN_NAME = "uuid"; - @VisibleForTesting - static final String CONSTRAINT_NAME = "pk_github_perms_mapping"; - - private final DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator; - private final DbPrimaryKeyConstraintFinder dbConstraintFinder; - - public DropPrimaryKeyOnDevopsPermsMappingTable(Database db, DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator, DbPrimaryKeyConstraintFinder dbConstraintFinder) { - super(db); - this.dropPrimaryKeySqlGenerator = dropPrimaryKeySqlGenerator; - this.dbConstraintFinder = dbConstraintFinder; - } - - @Override - public void execute(Context context) throws SQLException { - Optional<String> constraintName = dbConstraintFinder.findConstraintName(DEVOPS_PERMS_MAPPING_TABLE_NAME); - if (constraintName.isPresent() && constraintName.get().equalsIgnoreCase(CONSTRAINT_NAME)) { - List<String> statements = dropPrimaryKeySqlGenerator.generate(DEVOPS_PERMS_MAPPING_TABLE_NAME, UUID_COLUMN_NAME, false); - context.execute(statements); - } - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/MigrateSmtpConfiguration.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/MigrateSmtpConfiguration.java deleted file mode 100644 index 7a2f2f15db8..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/MigrateSmtpConfiguration.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import com.google.common.annotations.VisibleForTesting; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.utils.System2; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.Select; -import org.sonar.server.platform.db.migration.step.Upsert; - -import static java.util.stream.Collectors.joining; - -public class MigrateSmtpConfiguration extends DataChange { - - private static final Logger LOGGER = LoggerFactory.getLogger(MigrateSmtpConfiguration.class.getName()); - - @VisibleForTesting - static final String EMAIL_SMTP_HOST_SECURED = "email.smtp_host.secured"; - static final String EMAIL_SMTP_PORT_SECURED = "email.smtp_port.secured"; - static final String EMAIL_SMTP_SECURE_CONNECTION_SECURED = "email.smtp_secure_connection.secured"; - static final String EMAIL_SMTP_USERNAME_SECURED = "email.smtp_username.secured"; - static final String EMAIL_SMTP_PASSWORD_SECURED = "email.smtp_password.secured"; - static final String EMAIL_FROM = "email.from"; - static final String EMAIL_FROM_NAME = "email.fromName"; - static final String EMAIL_PREFIX = "email.prefix"; - static final String EMAIL_AUTH_METHOD = "email.smtp.auth.method"; - - @VisibleForTesting - static final List<String> SMTP_LEGACY_CONFIG_PROP_KEYS = List.of( - EMAIL_SMTP_HOST_SECURED, - EMAIL_SMTP_PORT_SECURED, - EMAIL_SMTP_SECURE_CONNECTION_SECURED, - EMAIL_SMTP_USERNAME_SECURED, - EMAIL_SMTP_PASSWORD_SECURED, - EMAIL_FROM, - EMAIL_FROM_NAME, - EMAIL_PREFIX, - EMAIL_AUTH_METHOD - ); - - private static final Map<String, String> defaultPropertyValues = Map.of( - EMAIL_SMTP_SECURE_CONNECTION_SECURED, "NONE", - EMAIL_FROM, "noreply@nowhere", - EMAIL_FROM_NAME, "SonarQube", - EMAIL_PREFIX, "[SONARQUBE]", - EMAIL_AUTH_METHOD, "BASIC" - ); - - private static final String PLACEHOLDER = "LIST_PLACEHOLDER"; - private static final String SELECT_PROPERTIES_QUERY = """ - select prop_key, is_empty, text_value, created_at from properties - where prop_key in (LIST_PLACEHOLDER) - """; - private static final String DELETE_PROPERTIES_QUERY = """ - delete from properties - where prop_key in (LIST_PLACEHOLDER) - """; - - private static final String INSERT_INTERNAL_PROPERTIES_QUERY = """ - insert into internal_properties (kee, is_empty, text_value, created_at) - values (?, ?, ?, ?) - """; - - private final System2 system2; - - public MigrateSmtpConfiguration(Database db, System2 system2) { - super(db); - this.system2 = system2; - } - - @Override - protected void execute(Context context) throws SQLException { - Map<String, PropertyDb> keyToProperties = new HashMap<>(); - String selectQuery = getQueryWithResolvedPlaceholder(SELECT_PROPERTIES_QUERY); - context.prepareSelect(selectQuery).scroll(row -> keyToProperties.put(row.getString(1), getPropertyFromRow(row))); - if (!keyToProperties.isEmpty()) { - insertPropertiesIntoInternal(context, keyToProperties); - deleteOriginalProperties(context); - LOGGER.info("SMTP configuration properties successfully migrated into internal_properties"); - } - } - - private static PropertyDb getPropertyFromRow(Select.Row row) throws SQLException { - return new PropertyDb( - row.getString(1), - row.getBoolean(2), - row.getString(3), - row.getLong(4) - ); - } - - private void insertPropertiesIntoInternal(Context context, Map<String, PropertyDb> properties) throws SQLException { - addDefaultPropertiesIfNeeded(properties); - properties.put(EMAIL_SMTP_SECURE_CONNECTION_SECURED, getSecureConnectionWithNewValues(properties.get(EMAIL_SMTP_SECURE_CONNECTION_SECURED))); - Upsert insertInternalProperties = context.prepareUpsert(INSERT_INTERNAL_PROPERTIES_QUERY); - for (PropertyDb property : properties.values()) { - insertInternalProperties - .setString(1, property.key) - .setBoolean(2, property.isEmpty) - .setString(3, property.value) - .setLong(4, property.createdAt) - .addBatch(); - LOGGER.debug("Migrated property: {}", property.key); - } - insertInternalProperties.execute().commit(); - } - - private void addDefaultPropertiesIfNeeded(Map<String, PropertyDb> keyToProperties) { - defaultPropertyValues.forEach((key, value) -> { - if (!keyToProperties.containsKey(key)) { - keyToProperties.put(key, new PropertyDb(key, false, value, system2.now())); - } - }); - } - - private static PropertyDb getSecureConnectionWithNewValues(PropertyDb currentProperty) { - String newValue = switch (currentProperty.value == null ? "" : currentProperty.value) { - case "ssl" -> "SSLTLS"; - case "starttls" -> "STARTTLS"; - default -> "NONE"; - }; - return new PropertyDb(currentProperty.key, currentProperty.isEmpty, newValue, currentProperty.createdAt); - } - - private static void deleteOriginalProperties(Context context) throws SQLException { - context.prepareUpsert(getQueryWithResolvedPlaceholder(DELETE_PROPERTIES_QUERY)) - .execute() - .commit(); - } - - private static String getQueryWithResolvedPlaceholder(String query) { - return query.replace(PLACEHOLDER, SMTP_LEGACY_CONFIG_PROP_KEYS.stream().map(key -> "'" + key + "'").collect(joining(","))); - } - - private record PropertyDb( - String key, - boolean isEmpty, - String value, - long createdAt - ) {} -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/PopulateGitlabDevOpsPermissionsMapping.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/PopulateGitlabDevOpsPermissionsMapping.java deleted file mode 100644 index 8d124b8c03a..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/PopulateGitlabDevOpsPermissionsMapping.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import java.sql.SQLException; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.Select; -import org.sonar.server.platform.db.migration.step.Upsert; - -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.api.web.UserRole.SCAN; -import static org.sonar.api.web.UserRole.SECURITYHOTSPOT_ADMIN; -import static org.sonar.api.web.UserRole.USER; - -public class PopulateGitlabDevOpsPermissionsMapping extends DataChange { - - private static final Map<String, Set<String>> GITLAB_ROLE_TO_SQ_PERMISSIONS = Map.of( - "guest", Set.of(USER), - "reporter", Set.of(USER, CODEVIEWER), - "developer", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN), - "maintainer", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN, ADMIN), - "owner", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN, ADMIN) - ); - - private static final String INSERT_QUERY = """ - insert into devops_perms_mapping (uuid, devops_platform, devops_platform_role, sonarqube_permission) - values (?, ?, ?, ?) - """; - - private final UuidFactory uuidFactory; - - public PopulateGitlabDevOpsPermissionsMapping(Database db, UuidFactory uuidFactory) { - super(db); - this.uuidFactory = uuidFactory; - } - - @Override - protected void execute(Context context) throws SQLException { - if (isDefaultMappingAlreadyDefined(context)) { - return; - } - try (Upsert upsert = context.prepareUpsert(INSERT_QUERY)) { - GITLAB_ROLE_TO_SQ_PERMISSIONS.forEach((role, permissions) -> insertGitlabRoleToSonarqubePermissionMapping(upsert, role, permissions)); - upsert.commit(); - } - } - - private void insertGitlabRoleToSonarqubePermissionMapping(Upsert upsert, String role, Set<String> sonarqubePermissions) { - sonarqubePermissions.forEach(permission -> insertGitlabRoleToSonarqubePermissionMapping(upsert, role, permission)); - } - - private void insertGitlabRoleToSonarqubePermissionMapping(Upsert upsert, String role, String sonarqubePermission) { - try { - upsert - .setString(1, uuidFactory.create()) - .setString(2, "gitlab") - .setString(3, role) - .setString(4, sonarqubePermission) - .execute(); - } catch (SQLException e) { - throw new IllegalStateException(e); - } - } - - private static boolean isDefaultMappingAlreadyDefined(Context context) throws SQLException { - try (Select select = context.prepareSelect("select count(*) from devops_perms_mapping where devops_platform='gitlab'")) { - return Optional.ofNullable(select.get(t -> t.getInt(1) > 0)) - .orElseThrow(); - } - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/RenameGithubPermsMappingTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/RenameGithubPermsMappingTable.java deleted file mode 100644 index 585e9119ebb..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/RenameGithubPermsMappingTable.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.RenameTableChange; - -public class RenameGithubPermsMappingTable extends RenameTableChange { - - static final String DEVOPS_PERMS_MAPPING_TABLE_NAME = "devops_perms_mapping"; - - static final String GITHUB_PERMS_MAPPING_TABLE_NAME = "github_perms_mapping"; - - protected RenameGithubPermsMappingTable(Database db) { - super(db, GITHUB_PERMS_MAPPING_TABLE_NAME, DEVOPS_PERMS_MAPPING_TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/RenameGithubRoleInDevopsPermsMapping.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/RenameGithubRoleInDevopsPermsMapping.java deleted file mode 100644 index 292fd2e6cad..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/RenameGithubRoleInDevopsPermsMapping.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v107; - -import com.google.common.annotations.VisibleForTesting; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.RenameVarcharColumnChange; - -import static org.sonar.server.platform.db.migration.version.v107.RenameGithubPermsMappingTable.DEVOPS_PERMS_MAPPING_TABLE_NAME; - -public class RenameGithubRoleInDevopsPermsMapping extends RenameVarcharColumnChange { - - @VisibleForTesting - static final String OLD_COLUMN_NAME = "github_role"; - @VisibleForTesting - static final String NEW_COLUMN_NAME = "devops_platform_role"; - - public RenameGithubRoleInDevopsPermsMapping(Database db) { - super(db, DEVOPS_PERMS_MAPPING_TABLE_NAME, OLD_COLUMN_NAME, NEW_COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/package-info.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/package-info.java deleted file mode 100644 index 126cd906600..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v107/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.server.platform.db.migration.version.v107; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AbstractAddMeasuresMigratedColumnToTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AbstractAddMeasuresMigratedColumnToTable.java deleted file mode 100644 index c1be035ec7e..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AbstractAddMeasuresMigratedColumnToTable.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.BooleanColumnDef; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AbstractAddMeasuresMigratedColumnToTable extends DdlChange { - - public static final String MIGRATION_FLAG_COLUMN_NAME = "measures_migrated"; - private final String tableName; - - public AbstractAddMeasuresMigratedColumnToTable(Database db, String tableName) { - super(db); - this.tableName = tableName; - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.tableColumnExists(connection, tableName, MIGRATION_FLAG_COLUMN_NAME)) { - ColumnDef columnDef = BooleanColumnDef.newBooleanColumnDefBuilder() - .setColumnName(MIGRATION_FLAG_COLUMN_NAME) - .setIsNullable(false) - .setDefaultValue(false) - .build(); - context.execute(new AddColumnsBuilder(getDialect(), tableName) - .addColumn(columnDef) - .build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AbstractCreateIndexOnMeasuresMigrated.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AbstractCreateIndexOnMeasuresMigrated.java deleted file mode 100644 index f51c0aef8a7..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AbstractCreateIndexOnMeasuresMigrated.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class AbstractCreateIndexOnMeasuresMigrated extends DdlChange { - - static final String COLUMN_NAME = "measures_migrated"; - private final String tableName; - private final String indexName; - - public AbstractCreateIndexOnMeasuresMigrated(Database db, String tableName, String indexName) { - super(db); - this.tableName = tableName; - this.indexName = indexName; - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!DatabaseUtils.indexExistsIgnoreCase(tableName, indexName, connection)) { - context.execute(new CreateIndexBuilder(getDialect()) - .setTable(tableName) - .setName(indexName) - .addColumn(COLUMN_NAME, false) - .build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AbstractMigrateLiveMeasuresToMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AbstractMigrateLiveMeasuresToMeasures.java deleted file mode 100644 index e1cac143632..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AbstractMigrateLiveMeasuresToMeasures.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import com.google.gson.Gson; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; -import javax.annotation.Nullable; -import org.apache.commons.codec.digest.MurmurHash3; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.utils.System2; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.db.dialect.H2; -import org.sonar.db.dialect.MsSql; -import org.sonar.db.dialect.Oracle; -import org.sonar.db.dialect.PostgreSql; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; -import org.sonar.server.platform.db.migration.step.Select; -import org.sonar.server.platform.db.migration.step.Upsert; - -import static java.lang.String.format; -import static java.nio.charset.StandardCharsets.UTF_8; - -public abstract class AbstractMigrateLiveMeasuresToMeasures extends DataChange { - private static final Logger LOGGER = LoggerFactory.getLogger(AbstractMigrateLiveMeasuresToMeasures.class); - - private static final Set<String> TEXT_VALUE_TYPES = Set.of("STRING", "LEVEL", "DATA", "DISTRIB"); - private static final Gson GSON = new Gson(); - - private static final String SELECT_QUERY = """ - SELECT lm.component_uuid, - m.name, - m.val_type, - lm.value, - lm.text_value, - lm.measure_data - FROM live_measures lm - INNER JOIN metrics m ON m.uuid = lm.metric_uuid - WHERE lm.project_uuid = ? - AND (lm.measure_data is null OR %s(lm.measure_data) < 1000000) - AND m.name NOT IN ('executable_lines_data', 'ncloc_data') - ORDER BY lm.component_uuid - """; - - private static final String INSERT_QUERY = """ - insert into measures (component_uuid, branch_uuid, json_value, json_value_hash, created_at, updated_at) - values ( ?, ?, ?, ?, ?, ?) - """; - - private final String tableName; - private final String item; - private final System2 system2; - - protected AbstractMigrateLiveMeasuresToMeasures(Database db, System2 system2, String tableName, String item) { - super(db); - this.system2 = system2; - this.tableName = tableName; - this.item = item; - } - - private String getSelectUuidQuery() { - return format(""" - SELECT uuid - FROM %s - WHERE measures_migrated = ? - """, tableName); - } - - private String getCountQuery() { - return format(""" - SELECT count(uuid) - FROM %s - """, tableName); - } - - private String getUpdateFlagQuery() { - return format(""" - UPDATE %s - SET measures_migrated = ? - WHERE uuid = ? - """, tableName); - } - - @Override - protected void execute(Context context) throws SQLException { - try (Connection c = getDatabase().getDataSource().getConnection()) { - // the table is later deleted, this check ensures the migration re-entrance - if (!DatabaseUtils.tableExists("live_measures", c)) { - return; - } - } - - List<String> uuids = context.prepareSelect(getSelectUuidQuery()) - .setBoolean(1, false) - .list(row -> row.getString(1)); - - Long total = context.prepareSelect(getCountQuery()) - .get(row -> row.getLong(1)); - - LOGGER.info("Starting the migration of {} {}s (total number of {}s: {})", uuids.size(), item, item, total); - int migrated = 0; - - String selectQuery = String.format(SELECT_QUERY, getByteLengthFunction()); - - for (String uuid : uuids) { - try { - migrateItem(uuid, context, selectQuery); - } catch (Exception e) { - LOGGER.error(format("Migration of %s %s failed", item, uuid)); - throw e; - } - - migrated++; - if (migrated % 100 == 0) { - LOGGER.info("{} {}s migrated", migrated, item); - } - } - } - - private String getByteLengthFunction() { - return switch (getDialect().getId()) { - case PostgreSql.ID -> "OCTET_LENGTH"; - case MsSql.ID -> "DATALENGTH"; - case Oracle.ID -> "DBMS_LOB.GETLENGTH"; - case H2.ID -> "LENGTH"; - default -> throw new IllegalStateException("Unsupported dialect: " + getDialect().getId()); - }; - } - - private void migrateItem(String uuid, Context context, String selectQuery) throws SQLException { - LOGGER.debug("Migrating {} {}...", item, uuid); - - Map<String, Object> measureValues = new HashMap<>(); - AtomicReference<String> componentUuid = new AtomicReference<>(null); - - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(selectQuery).setString(1, uuid); - massUpdate.update(INSERT_QUERY); - massUpdate.execute((row, update) -> { - boolean shouldUpdate = false; - String rowComponentUuid = row.getString(1); - if (componentUuid.get() == null || !rowComponentUuid.equals(componentUuid.get())) { - if (!measureValues.isEmpty()) { - preparePersistMeasure(uuid, update, componentUuid, measureValues); - shouldUpdate = true; - } - - LOGGER.debug("Starting processing of component {}...", rowComponentUuid); - componentUuid.set(rowComponentUuid); - measureValues.clear(); - readMeasureValue(row, measureValues); - } else { - readMeasureValue(row, measureValues); - } - return shouldUpdate; - }); - // insert the last component - if (!measureValues.isEmpty()) { - try (Upsert measureInsert = context.prepareUpsert(INSERT_QUERY)) { - preparePersistMeasure(uuid, measureInsert, componentUuid, measureValues); - measureInsert - .execute() - .commit(); - } - } - - LOGGER.debug("Flagging migration done for {} {}...", item, uuid); - - try (Upsert flagUpdate = context.prepareUpsert(getUpdateFlagQuery())) { - flagUpdate - .setBoolean(1, true) - .setString(2, uuid) - .execute() - .commit(); - } - - LOGGER.debug("Migration finished for {} {}", item, uuid); - } - - private void preparePersistMeasure(String uuid, Upsert update, AtomicReference<String> componentUuid, Map<String, Object> measureValues) throws SQLException { - LOGGER.debug("Persisting measures for component {}...", componentUuid.get()); - String jsonValue = GSON.toJson(measureValues); - - long jsonHash = MurmurHash3.hash128(jsonValue.getBytes(UTF_8))[0]; - - update.setString(1, componentUuid.get()); - update.setString(2, uuid); - update.setString(3, jsonValue); - update.setLong(4, jsonHash); - update.setLong(5, system2.now()); - update.setLong(6, system2.now()); - } - - private static void readMeasureValue(Select.Row row, Map<String, Object> measureValues) throws SQLException { - String metricName = row.getString(2); - String valueType = row.getString(3); - Double numericValue = row.getDouble(4); - String textValue = row.getString(5); - byte[] data = row.getBytes(6); - - Object metricValue = getMetricValue(data, textValue, valueType, numericValue); - if (metricValue != null - && !MeasureMigration.isMetricPlannedForDeletion(metricName)) { - measureValues.put(metricName, metricValue); - migrateMeasureIfNeeded(measureValues, metricName, metricValue); - } - } - - private static void migrateMeasureIfNeeded(Map<String, Object> measureValues, String metricName, Object metricValue) { - String migratedMetricKey = MeasureMigration.getMigrationMetricKey(metricName); - if (migratedMetricKey != null) { - try { - Long migratedValue = MeasureMigration.migrate(metricValue); - if (migratedValue != null) { - measureValues.put(migratedMetricKey, migratedValue); - } - } catch (Exception e) { - LOGGER.debug("Failed to migrate metric {} with value {}", metricName, metricValue); - } - } - } - - private static Object getMetricValue(@Nullable byte[] data, @Nullable String textValue, String valueType, Double numericValue) { - return TEXT_VALUE_TYPES.contains(valueType) ? getTextValue(data, textValue) : numericValue; - } - - private static String getTextValue(@Nullable byte[] data, @Nullable String textValue) { - return data != null ? new String(data, UTF_8) : textValue; - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddMeasuresMigratedColumnToProjectBranchesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddMeasuresMigratedColumnToProjectBranchesTable.java deleted file mode 100644 index cd7758356c9..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddMeasuresMigratedColumnToProjectBranchesTable.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import org.sonar.db.Database; - -public class AddMeasuresMigratedColumnToProjectBranchesTable extends AbstractAddMeasuresMigratedColumnToTable { - - public static final String PROJECT_BRANCHES_TABLE_NAME = "project_branches"; - - public AddMeasuresMigratedColumnToProjectBranchesTable(Database db) { - super(db, PROJECT_BRANCHES_TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AlterCveColumnsToNullable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AlterCveColumnsToNullable.java deleted file mode 100644 index 2611e917f53..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AlterCveColumnsToNullable.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.def.BigIntegerColumnDef; -import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder; - -public class AlterCveColumnsToNullable extends DdlChange { - - public static final BigIntegerColumnDef LAST_MODIFIED_COLUMN = newBigIntegerColumnDefBuilder().setColumnName("last_modified_at").setIsNullable(true).build(); - public static final BigIntegerColumnDef PUBLISHED_COLUMN = newBigIntegerColumnDefBuilder().setColumnName("published_at").setIsNullable(true).build(); - - - public AlterCveColumnsToNullable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - context.execute(new AlterColumnsBuilder(getDialect(), "cves") - .updateColumn(LAST_MODIFIED_COLUMN) - .build()); - context.execute(new AlterColumnsBuilder(getDialect(), "cves") - .updateColumn(PUBLISHED_COLUMN) - .build()); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnMeasuresTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnMeasuresTable.java deleted file mode 100644 index f2b3c1ae115..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnMeasuresTable.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.COLUMN_BRANCH_UUID; -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.MEASURES_TABLE_NAME; - -public class CreateIndexOnMeasuresTable extends DdlChange { - - static final String INDEX_NAME = "measures_branch_uuid"; - - public CreateIndexOnMeasuresTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - createUniqueIndex(context, connection); - } - } - - private void createUniqueIndex(Context context, Connection connection) { - if (!DatabaseUtils.indexExistsIgnoreCase(MEASURES_TABLE_NAME, INDEX_NAME, connection)) { - context.execute(new CreateIndexBuilder(getDialect()) - .setTable(MEASURES_TABLE_NAME) - .setName(INDEX_NAME) - .addColumn(COLUMN_BRANCH_UUID, false) - .setUnique(false) - .build()); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnPortfoliosMeasuresMigrated.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnPortfoliosMeasuresMigrated.java deleted file mode 100644 index 086a24abd5e..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnPortfoliosMeasuresMigrated.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import org.sonar.db.Database; - -public class CreateIndexOnPortfoliosMeasuresMigrated extends AbstractCreateIndexOnMeasuresMigrated { - - static final String TABLE_NAME = "portfolios"; - static final String INDEX_NAME = "portfolios_measures_migrated"; - - public CreateIndexOnPortfoliosMeasuresMigrated(Database db) { - super(db, TABLE_NAME, INDEX_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnProjectBranchesMeasuresMigrated.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnProjectBranchesMeasuresMigrated.java deleted file mode 100644 index 6fba6d297ec..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateIndexOnProjectBranchesMeasuresMigrated.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import org.sonar.db.Database; - -public class CreateIndexOnProjectBranchesMeasuresMigrated extends AbstractCreateIndexOnMeasuresMigrated { - - static final String TABLE_NAME = "project_branches"; - static final String INDEX_NAME = "pb_measures_migrated"; - - public CreateIndexOnProjectBranchesMeasuresMigrated(Database db) { - super(db, TABLE_NAME, INDEX_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateNewSoftwareQualityMetrics.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateNewSoftwareQualityMetrics.java deleted file mode 100644 index 413107b6b34..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateNewSoftwareQualityMetrics.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.Upsert; -import org.sonar.server.platform.db.migration.version.v00.PopulateInitialSchema; - -public class CreateNewSoftwareQualityMetrics extends DataChange { - private final UuidFactory uuidFactory; - - public CreateNewSoftwareQualityMetrics(Database db, UuidFactory uuidFactory) { - super(db); - this.uuidFactory = uuidFactory; - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - for (String metric : MeasureMigration.MIGRATION_MAP.values()) { - if (!metricExists(connection, metric)) { - Upsert upsert = context.prepareUpsert(PopulateInitialSchema.createInsertStatement("metrics", - "name", - "direction", - "qualitative", - "enabled", - "best_value", - "optimized_best_value", - "delete_historical_data", - "uuid" - )); - upsert - .setString(1, metric) - .setInt(2, -1) - .setBoolean(3, metric.startsWith("new_")) - .setBoolean(4, true) - .setDouble(5, 0.0) - .setBoolean(6, true) - .setBoolean(7, metric.startsWith("new_")) - .setString(8, uuidFactory.create()); - upsert.execute().commit(); - } - } - } - } - - private static boolean metricExists(Connection connection, String metric) throws SQLException { - String sql = "SELECT count(1) FROM metrics WHERE name = ?"; - try (PreparedStatement statement = connection.prepareStatement(sql)) { - statement.setString(1, metric); - ResultSet result = statement.executeQuery(); - return result.next() && result.getInt(1) > 0; - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreatePrimaryKeyOnMeasuresTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreatePrimaryKeyOnMeasuresTable.java deleted file mode 100644 index 8ded1b39336..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreatePrimaryKeyOnMeasuresTable.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.AddPrimaryKeyBuilder; -import org.sonar.server.platform.db.migration.sql.DbPrimaryKeyConstraintFinder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.COLUMN_COMPONENT_UUID; -import static org.sonar.server.platform.db.migration.version.v108.CreateMeasuresTable.MEASURES_TABLE_NAME; - -public class CreatePrimaryKeyOnMeasuresTable extends DdlChange { - - public CreatePrimaryKeyOnMeasuresTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - createPrimaryKey(context); - } - - private void createPrimaryKey(Context context) throws SQLException { - boolean pkExists = new DbPrimaryKeyConstraintFinder(getDatabase()).findConstraintName(MEASURES_TABLE_NAME).isPresent(); - if (!pkExists) { - context.execute(new AddPrimaryKeyBuilder(MEASURES_TABLE_NAME, COLUMN_COMPONENT_UUID).build()); - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DbVersion108.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DbVersion108.java deleted file mode 100644 index 8ea4cbc1d2f..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DbVersion108.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import org.sonar.server.platform.db.migration.step.MigrationStepRegistry; -import org.sonar.server.platform.db.migration.version.DbVersion; - -// ignoring bad number formatting, as it's indented that we align the migration numbers to SQ versions -@SuppressWarnings("java:S3937") -public class DbVersion108 implements DbVersion { - - /** - * We use the start of the 10.X cycle as an opportunity to align migration numbers with the SQ version number. - * Please follow this pattern: - * 10_0_000 - * 10_0_001 - * 10_0_002 - * 10_1_000 - * 10_1_001 - * 10_1_002 - * 10_2_000 - */ - @Override - public void addSteps(MigrationStepRegistry registry) { - registry - .add(10_8_000, "Create 'measures' table", CreateMeasuresTable.class) - .add(10_8_001, "Add 'measures_migrated' column on 'project_branches' table", AddMeasuresMigratedColumnToProjectBranchesTable.class) - .add(10_8_002, "Create index on 'project_branches.measures_migrated'", CreateIndexOnProjectBranchesMeasuresMigrated.class) - .add(10_8_003, "Migrate the content of 'live_measures' to 'measures' for branches", MigrateBranchesLiveMeasuresToMeasures.class) - .add(10_8_004, "Add 'measures_migrated' column on 'portfolios' table", AddMeasuresMigratedColumnToPortfoliosTable.class) - .add(10_8_005, "Create index on 'portfolios.measures_migrated'", CreateIndexOnPortfoliosMeasuresMigrated.class) - .add(10_8_006, "Migrate the content of 'live_measures' to 'measures' for portfolios", MigratePortfoliosLiveMeasuresToMeasures.class) - .add(10_8_007, "Create primary key on 'measures' table", CreatePrimaryKeyOnMeasuresTable.class) - .add(10_8_008, "Create index on column 'branch_uuid' in 'measures' table", CreateIndexOnMeasuresTable.class) - .add(10_8_009, "Drop column 'from_hotspot' in the 'issues' table", DropColumnFromHotspotInIssues.class) - .add(10_8_010, "Drop 'live_measures' table", DropLiveMeasuresTable.class) - .add(10_8_011, "Drop index on 'portfolios.measures_migrated'", DropIndexOnPortfoliosMeasuresMigrated.class) - .add(10_8_012, "Drop 'measures_migrated' column on 'portfolios' table", DropMeasuresMigratedColumnInPortfoliosTable.class) - .add(10_8_013, "Drop index on 'project_branches.measures_migrated'", DropIndexOnProjectBranchesMeasuresMigrated.class) - .add(10_8_014, "Drop 'measures_migrated' column on 'project_branches' table", DropMeasuresMigratedColumnInProjectBranchesTable.class) - .add(10_8_015, "Add column 'impacts' in 'active_rules' table", AddImpactsColumnInActiveRulesTable.class) - .add(10_8_016, "Create 'project_dependencies' table", CreateProjectDependenciesTable.class) - .add(10_8_017, "Enable specific MQR mode", EnableSpecificMqrMode.class) - .add(10_8_018, "Make columns 'published_at' and 'last_modified_at' nullable on the 'cves' table", AlterCveColumnsToNullable.class) - .add(10_8_019, "Delete Software Quality ratings from project_measures", DeleteSoftwareQualityRatingFromProjectMeasures.class) - .add(10_8_020, "Create new software quality metrics", CreateNewSoftwareQualityMetrics.class) - .add(10_8_021, "Migrate deprecated project_measures to replacement metrics", MigrateProjectMeasuresDeprecatedMetrics.class) - .add(10_8_022, "Add 'manual_severity' column in 'issues_impacts' table", AddManualSeverityColumnInIssuesImpactsTable.class) - .add(10_8_023, "Add 'ai_code_fix_enabled' column to 'projects' table", AddAICodeFixEnabledColumnToProjectsTable.class) - .add(10_8_024, "Migrate boolean values of 'sonar.ai.suggestions.enabled' property to new enum values", MigrateAiSuggestionEnabledValues.class) - .add(10_8_025, "Add 'ai_code_supported' column in 'quality_gates' table", AddAICodeSupportedColumnToQualityGatesTable.class) - .add(10_8_026, "Rename 'ai_code_assurance' column in 'projects' table to 'contains_ai_code", RenameAiCodeAssuranceColumnInProjects.class) - ; - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DeleteSoftwareQualityRatingFromProjectMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DeleteSoftwareQualityRatingFromProjectMeasures.java deleted file mode 100644 index 6d4fd1ddf52..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DeleteSoftwareQualityRatingFromProjectMeasures.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import java.util.Set; -import java.util.stream.Collectors; -import org.sonar.core.metric.SoftwareQualitiesMetrics; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.es.MigrationEsClient; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class DeleteSoftwareQualityRatingFromProjectMeasures extends DataChange { - - public static final Set<String> SOFTWARE_QUALITY_METRICS_TO_DELETE = Set.of( - SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, - SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_KEY, - SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, - SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_RATING_KEY, - SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_RATING_KEY, - SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_RATING_KEY, - SoftwareQualitiesMetrics.EFFORT_TO_REACH_SOFTWARE_QUALITY_MAINTAINABILITY_RATING_A_KEY, - SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, - SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_REMEDIATION_EFFORT_KEY, - SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, - SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_REMEDIATION_EFFORT_KEY, - SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, - SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_REMEDIATION_EFFORT_KEY, - SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO_KEY, - SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_DEBT_RATIO_KEY, - - // Portfolios - "software_quality_reliability_rating_distribution", - "software_quality_security_rating_distribution", - "software_quality_maintainability_rating_distribution", - "new_software_quality_maintainability_rating_distribution", - "new_software_quality_reliability_rating_distribution", - "new_software_quality_security_rating_distribution", - - // Views - "last_change_on_software_quality_security_rating", - "last_change_on_software_quality_reliability_rating", - "last_change_on_software_quality_maintainability_rating", - "software_quality_security_rating_effort", - "software_quality_reliability_rating_effort", - "software_quality_maintainability_rating_effort"); - - private static final String SELECT_QUERY = """ - select pm.uuid from project_measures pm - inner join metrics m on pm.metric_uuid = m.uuid - where m.name in (%s) - """.formatted(SOFTWARE_QUALITY_METRICS_TO_DELETE.stream().map(s -> "'" + s + "'").collect(Collectors.joining(","))); - - private final MigrationEsClient migrationEsClient; - - public DeleteSoftwareQualityRatingFromProjectMeasures(Database db, MigrationEsClient migrationEsClient) { - super(db); - this.migrationEsClient = migrationEsClient; - } - - @Override - protected void execute(Context context) throws SQLException { - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update("delete from project_measures where uuid = ?"); - - massUpdate.execute((row, update, index) -> { - update.setString(1, row.getString(1)); - return true; - }); - - // Reindexation of project measures is required to align with removed values - migrationEsClient.deleteIndexes("projectmeasures"); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropColumnFromHotspotInIssues.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropColumnFromHotspotInIssues.java deleted file mode 100644 index f5a92f8d092..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropColumnFromHotspotInIssues.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropColumnFromHotspotInIssues extends DropColumnChange { - private static final String COLUMN_NAME = "from_hotspot"; - private static final String TABLE_NAME = "issues"; - - public DropColumnFromHotspotInIssues(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropIndexOnPortfoliosMeasuresMigrated.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropIndexOnPortfoliosMeasuresMigrated.java deleted file mode 100644 index 817e8f7639b..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropIndexOnPortfoliosMeasuresMigrated.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -public class DropIndexOnPortfoliosMeasuresMigrated extends DropIndexChange { - - private static final String TABLE_NAME = "portfolios"; - private static final String INDEX_NAME = "portfolios_measures_migrated"; - - public DropIndexOnPortfoliosMeasuresMigrated(Database db) { - super(db, INDEX_NAME, TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropIndexOnProjectBranchesMeasuresMigrated.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropIndexOnProjectBranchesMeasuresMigrated.java deleted file mode 100644 index ccea53e9711..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropIndexOnProjectBranchesMeasuresMigrated.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropIndexChange; - -public class DropIndexOnProjectBranchesMeasuresMigrated extends DropIndexChange { - - private static final String TABLE_NAME = "project_branches"; - private static final String INDEX_NAME = "pb_measures_migrated"; - - public DropIndexOnProjectBranchesMeasuresMigrated(Database db) { - super(db, INDEX_NAME, TABLE_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropLiveMeasuresTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropLiveMeasuresTable.java deleted file mode 100644 index 80c9ec52a99..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropLiveMeasuresTable.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.sql.DropTableBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class DropLiveMeasuresTable extends DdlChange { - - private static final String TABLE_NAME = "live_measures"; - - public DropLiveMeasuresTable(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection c = getDatabase().getDataSource().getConnection()) { - if (DatabaseUtils.tableExists(TABLE_NAME, c)) { - context.execute(new DropTableBuilder(getDialect(), TABLE_NAME).build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropMeasuresMigratedColumnInPortfoliosTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropMeasuresMigratedColumnInPortfoliosTable.java deleted file mode 100644 index 8983a3c0fa1..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropMeasuresMigratedColumnInPortfoliosTable.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import com.google.common.annotations.VisibleForTesting; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropMeasuresMigratedColumnInPortfoliosTable extends DropColumnChange { - @VisibleForTesting - static final String COLUMN_NAME = "measures_migrated"; - @VisibleForTesting - static final String TABLE_NAME = "portfolios"; - - protected DropMeasuresMigratedColumnInPortfoliosTable(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropMeasuresMigratedColumnInProjectBranchesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropMeasuresMigratedColumnInProjectBranchesTable.java deleted file mode 100644 index 95450311d91..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/DropMeasuresMigratedColumnInProjectBranchesTable.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import com.google.common.annotations.VisibleForTesting; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DropColumnChange; - -public class DropMeasuresMigratedColumnInProjectBranchesTable extends DropColumnChange { - @VisibleForTesting - static final String COLUMN_NAME = "measures_migrated"; - @VisibleForTesting - static final String TABLE_NAME = "project_branches"; - - protected DropMeasuresMigratedColumnInProjectBranchesTable(Database db) { - super(db, TABLE_NAME, COLUMN_NAME); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/EnableSpecificMqrMode.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/EnableSpecificMqrMode.java deleted file mode 100644 index 44927c7c6dd..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/EnableSpecificMqrMode.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import org.sonar.api.utils.System2; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.history.MigrationHistory; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.Upsert; - -import static org.sonar.core.config.MQRModeConstants.MULTI_QUALITY_MODE_ENABLED; -import static org.sonar.server.platform.db.migration.version.v00.PopulateInitialSchema.createInsertStatement; - -public class EnableSpecificMqrMode extends DataChange { - private final MigrationHistory migrationHistory; - private final UuidFactory uuidFactory; - private final System2 system2; - - public EnableSpecificMqrMode(Database db, MigrationHistory migrationHistory, UuidFactory uuidFactory, System2 system2) { - super(db); - this.migrationHistory = migrationHistory; - this.uuidFactory = uuidFactory; - this.system2 = system2; - } - - @Override - public void execute(Context context) throws SQLException { - try (Connection connection = getDatabase().getDataSource().getConnection()) { - if (!paramExists(connection)) { - long version = migrationHistory.getInitialDbVersion(); - boolean mqrModeEnabled = version >= 102_000L || version == -1L; - Upsert upsert = context.prepareUpsert( - createInsertStatement("properties", - "uuid", - "prop_key", - "is_empty", - "text_value", - "created_at")); - upsert.setString(1, uuidFactory.create()) - .setString(2, MULTI_QUALITY_MODE_ENABLED) - .setBoolean(3, false) - .setString(4, String.valueOf(mqrModeEnabled)) - .setLong(5, system2.now()); - upsert.execute().commit(); - } - } - } - - private static boolean paramExists(Connection connection) throws SQLException { - String sql = "SELECT count(1) FROM properties WHERE prop_key = '" + MULTI_QUALITY_MODE_ENABLED + "'"; - try (PreparedStatement statement = connection.prepareStatement(sql)) { - ResultSet result = statement.executeQuery(); - return result.next() && result.getInt(1) > 0; - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MeasureMigration.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MeasureMigration.java deleted file mode 100644 index 2815f0331c0..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MeasureMigration.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.annotation.CheckForNull; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.core.metric.SoftwareQualitiesMetrics; - -public class MeasureMigration { - - static final Pattern VALUE_EXTRACTION_PATTERN = Pattern.compile("\"total\":(\\d+)"); - - static final Map<String, String> MIGRATION_MAP = Map.of( - CoreMetrics.MAINTAINABILITY_ISSUES_KEY, SoftwareQualitiesMetrics.SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY, - CoreMetrics.NEW_MAINTAINABILITY_ISSUES_KEY, SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_MAINTAINABILITY_ISSUES_KEY, - CoreMetrics.RELIABILITY_ISSUES_KEY, SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY, - CoreMetrics.NEW_RELIABILITY_ISSUES_KEY, SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY, - CoreMetrics.SECURITY_ISSUES_KEY, SoftwareQualitiesMetrics.SOFTWARE_QUALITY_SECURITY_ISSUES_KEY, - CoreMetrics.NEW_SECURITY_ISSUES_KEY, SoftwareQualitiesMetrics.NEW_SOFTWARE_QUALITY_SECURITY_ISSUES_KEY); - - private MeasureMigration() { - //Only static methods - } - - @CheckForNull - public static String getMigrationMetricKey(String metricKey) { - return MIGRATION_MAP.get(metricKey); - } - - @CheckForNull - public static Long migrate(Object value) { - Matcher matcher = VALUE_EXTRACTION_PATTERN.matcher(value.toString()); - if (matcher.find()) { - return Long.valueOf(matcher.group(1)); - } - return null; - } - - public static boolean isMetricPlannedForDeletion(String metricKey) { - return DeleteSoftwareQualityRatingFromProjectMeasures.SOFTWARE_QUALITY_METRICS_TO_DELETE.contains(metricKey); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MigrateAiSuggestionEnabledValues.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MigrateAiSuggestionEnabledValues.java deleted file mode 100644 index 98fe4cef1e0..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MigrateAiSuggestionEnabledValues.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import java.util.Optional; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; - -public class MigrateAiSuggestionEnabledValues extends DataChange { - - static final String AI_CODEFIX_ENABLED_PROP_KEY = "sonar.ai.suggestions.enabled"; - static final String ENABLED_FOR_ALL_PROJECTS = "ENABLED_FOR_ALL_PROJECTS"; - static final String DISABLED = "DISABLED"; - - public MigrateAiSuggestionEnabledValues(Database db) { - super(db); - } - - @Override - protected void execute(Context context) throws SQLException { - var isAiCodeFixEnabledOptional = Optional.ofNullable(context.prepareSelect("select text_value from properties where prop_key=?") - .setString(1, AI_CODEFIX_ENABLED_PROP_KEY) - .get(r -> r.getBoolean(1))); - - if (isAiCodeFixEnabledOptional.isPresent()) { - boolean isAiCodeFixEnabled = isAiCodeFixEnabledOptional.get(); - context.prepareUpsert("update properties set text_value=? where prop_key=?") - .setString(1, isAiCodeFixEnabled ? ENABLED_FOR_ALL_PROJECTS : DISABLED) - .setString(2, AI_CODEFIX_ENABLED_PROP_KEY) - .execute() - .commit(); - if (isAiCodeFixEnabled) { - context.prepareUpsert("update projects set ai_code_fix_enabled = ?") - .setBoolean(1, true) - .execute() - .commit(); - } - } - } - -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MigratePortfoliosLiveMeasuresToMeasures.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MigratePortfoliosLiveMeasuresToMeasures.java deleted file mode 100644 index 326a515e2bb..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MigratePortfoliosLiveMeasuresToMeasures.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import org.sonar.api.utils.System2; -import org.sonar.db.Database; - -public class MigratePortfoliosLiveMeasuresToMeasures extends AbstractMigrateLiveMeasuresToMeasures { - - protected MigratePortfoliosLiveMeasuresToMeasures(Database db, System2 system2) { - super(db, system2, "portfolios", "portfolio"); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MigrateProjectMeasuresDeprecatedMetrics.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MigrateProjectMeasuresDeprecatedMetrics.java deleted file mode 100644 index fdb83f908ff..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/MigrateProjectMeasuresDeprecatedMetrics.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Collectors; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; - -public class MigrateProjectMeasuresDeprecatedMetrics extends DataChange { - - private static final String SELECT_QUERY = """ - select m.name, pm.component_uuid , pm.analysis_uuid, pm.text_value - from project_measures pm - join metrics m - on pm.metric_uuid = m.uuid - and m.name in (%s) - and not exists ( - select 1 - from project_measures pm2 - join metrics m2 - on pm2.metric_uuid = m2.uuid - and pm.analysis_uuid = pm2.analysis_uuid - and m2.name in ('software_quality_maintainability_issues') - ) - order by pm.analysis_uuid - """.formatted(MeasureMigration.MIGRATION_MAP.keySet().stream().map(s -> "'" + s + "'").collect(Collectors.joining(","))); - - private static final String SELECT_NEW_METRICS_UUID = """ - select m.name, m.uuid - from metrics m - where m.name in (%s) - """.formatted(MeasureMigration.MIGRATION_MAP.values().stream().map(s -> "'" + s + "'").collect(Collectors.joining(","))); - - private final UuidFactory uuidFactory; - - public MigrateProjectMeasuresDeprecatedMetrics(Database db, UuidFactory uuidFactory) { - super(db); - this.uuidFactory = uuidFactory; - } - - @Override - protected void execute(Context context) throws SQLException { - - Map<String, String> newMetricsUuid = getNewMetricsUuid(); - - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select(SELECT_QUERY); - massUpdate.update("INSERT INTO project_measures (value, component_uuid, analysis_uuid, uuid, metric_uuid) VALUES (?, ?, ?, ?, ?)"); - - massUpdate.execute((row, update, index) -> { - String metricName = row.getString(1); - String componentUuid = row.getString(2); - String analysisUuid = row.getString(3); - String textValue = row.getString(4); - - Long migratedValue = MeasureMigration.migrate(textValue); - if (migratedValue != null) { - update.setDouble(1, migratedValue.doubleValue()); - update.setString(2, componentUuid); - update.setString(3, analysisUuid); - update.setString(4, uuidFactory.create()); - String newMetricName = MeasureMigration.MIGRATION_MAP.get(metricName); - update.setString(5, newMetricsUuid.get(newMetricName)); - return true; - } else { - return false; - } - }); - } - - private Map<String, String> getNewMetricsUuid() throws SQLException{ - Map<String, String> map = new HashMap<>(); - try (Connection connection = getDatabase().getDataSource().getConnection()) { - try (PreparedStatement statement = connection.prepareStatement(SELECT_NEW_METRICS_UUID)) { - ResultSet result = statement.executeQuery(); - while (result.next()) { - map.put(result.getString(1), result.getString(2)); - } - return map; - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/RenameAiCodeAssuranceColumnInProjects.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/RenameAiCodeAssuranceColumnInProjects.java deleted file mode 100644 index e66fe3c0caa..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/RenameAiCodeAssuranceColumnInProjects.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.Connection; -import java.sql.SQLException; -import org.sonar.db.ColumnMetadata; -import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.server.platform.db.migration.def.BooleanColumnDef; -import org.sonar.server.platform.db.migration.def.ColumnDef; -import org.sonar.server.platform.db.migration.sql.RenameColumnsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; - -public class RenameAiCodeAssuranceColumnInProjects extends DdlChange { - - private static final String TABLE_NAME = "projects"; - private static final String OLD_COLUMN_NAME = "ai_code_assurance"; - private static final String NEW_COLUMN_NAME = "contains_ai_code"; - - public RenameAiCodeAssuranceColumnInProjects(Database db) { - super(db); - } - - @Override - public void execute(Context context) throws SQLException { - try ( - Connection c = getDatabase().getDataSource().getConnection()) { - ColumnMetadata oldColumnMetadata = DatabaseUtils.getColumnMetadata(c, TABLE_NAME, OLD_COLUMN_NAME); - if (!DatabaseUtils.tableColumnExists(c, TABLE_NAME, NEW_COLUMN_NAME) && oldColumnMetadata != null) { - ColumnDef newColumnDef = BooleanColumnDef.newBooleanColumnDefBuilder() - .setColumnName(NEW_COLUMN_NAME) - .build(); - - context.execute(new RenameColumnsBuilder(getDialect(), TABLE_NAME).renameColumn(OLD_COLUMN_NAME, newColumnDef).build()); - } - } - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/package-info.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/package-info.java deleted file mode 100644 index ae9847707cb..00000000000 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.server.platform.db.migration.version.v108; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java index 0912bde27ee..3aa3e0fc7c9 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java @@ -49,7 +49,6 @@ public class DbVersion202501 implements DbVersion { .add(2025_01_009, "Add 'inline_annotations_enabled' column to 'project_alm_settings' table", AddInlineAnnotationsEnabledColumnToProjectAlmSettingsTable.class) .add(2025_01_010, "Populate 'inline_annotations_enabled' column for Azure", PopulateInlineAnnotationsEnabledColumnForAzure.class) .add(2025_01_011, "Update default admin password if still hashed with BCRYPT", UpdateDefaultAdminPasswordIfInvalidHashMechanism.class) - .add(2025_01_012, "Log message if users are still relying on BCRYPT hashed passwords", LogMessageIfInvalidHashMechanismUsed.class) - ; + .add(2025_01_012, "Log message if users are still relying on BCRYPT hashed passwords", LogMessageIfInvalidHashMechanismUsed.class); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddImpactsColumnInActiveRulesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/AddDeclaredLicenseExpressionToScaReleasesTable.java index f4655a2b9b1..c44a3dc006c 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddImpactsColumnInActiveRulesTable.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/AddDeclaredLicenseExpressionToScaReleasesTable.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v108; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.sonar.db.Database; @@ -27,24 +27,28 @@ import org.sonar.server.platform.db.migration.step.DdlChange; import static org.sonar.db.DatabaseUtils.tableColumnExists; -public class AddImpactsColumnInActiveRulesTable extends DdlChange { - static final String ACTIVE_RULES_TABLE_NAME = "active_rules"; - static final String IMPACTS = "impacts"; +public class AddDeclaredLicenseExpressionToScaReleasesTable extends DdlChange { + static final String TABLE_NAME = "sca_releases"; + static final String COLUMN_NAME = "declared_license_expression"; + private static final String NOASSERTION = "NOASSERTION"; + private static final int COLUMN_SIZE = 400; - public AddImpactsColumnInActiveRulesTable(Database db) { + public AddDeclaredLicenseExpressionToScaReleasesTable(Database db) { super(db); } @Override public void execute(Context context) throws SQLException { try (var connection = getDatabase().getDataSource().getConnection()) { - if (!tableColumnExists(connection, ACTIVE_RULES_TABLE_NAME, IMPACTS)) { + if (!tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { var columnDef = VarcharColumnDef.newVarcharColumnDefBuilder() - .setColumnName(IMPACTS) - .setIsNullable(true) - .setLimit(500) + .setDefaultValue(NOASSERTION) + .setColumnName(COLUMN_NAME) + .setLimit(COLUMN_SIZE) + .setIsNullable(false) .build(); - context.execute(new AddColumnsBuilder(getDialect(), ACTIVE_RULES_TABLE_NAME) + + context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME) .addColumn(columnDef) .build()); } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddAICodeFixEnabledColumnToProjectsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/AddNewInPullRequestToScaDependenciesTable.java index 95611cc2700..38ec297c269 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddAICodeFixEnabledColumnToProjectsTable.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/AddNewInPullRequestToScaDependenciesTable.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v108; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.sonar.db.Database; @@ -27,24 +27,24 @@ import org.sonar.server.platform.db.migration.step.DdlChange; import static org.sonar.db.DatabaseUtils.tableColumnExists; -public class AddAICodeFixEnabledColumnToProjectsTable extends DdlChange { - static final String PROJECTS_TABLE_NAME = "projects"; - static final String AI_CODE_FIX_ENABLED_COLUMN_NAME = "ai_code_fix_enabled"; +public class AddNewInPullRequestToScaDependenciesTable extends DdlChange { + static final String TABLE_NAME = "sca_dependencies"; + static final String COLUMN_NAME = "new_in_pull_request"; - public AddAICodeFixEnabledColumnToProjectsTable(Database db) { + public AddNewInPullRequestToScaDependenciesTable(Database db) { super(db); } @Override public void execute(Context context) throws SQLException { try (var connection = getDatabase().getDataSource().getConnection()) { - if (!tableColumnExists(connection, PROJECTS_TABLE_NAME, AI_CODE_FIX_ENABLED_COLUMN_NAME)) { + if (!tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { var columnDef = BooleanColumnDef.newBooleanColumnDefBuilder() - .setColumnName(AI_CODE_FIX_ENABLED_COLUMN_NAME) + .setColumnName(COLUMN_NAME) .setIsNullable(false) .setDefaultValue(false) .build(); - context.execute(new AddColumnsBuilder(getDialect(), PROJECTS_TABLE_NAME) + context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME) .addColumn(columnDef) .build()); } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddManualSeverityColumnInIssuesImpactsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/AddNewInPullRequestToScaReleasesTable.java index cda1af8103d..f5fbee42a66 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddManualSeverityColumnInIssuesImpactsTable.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/AddNewInPullRequestToScaReleasesTable.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v108; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.sonar.db.Database; @@ -27,28 +27,25 @@ import org.sonar.server.platform.db.migration.step.DdlChange; import static org.sonar.db.DatabaseUtils.tableColumnExists; -public class AddManualSeverityColumnInIssuesImpactsTable extends DdlChange { +public class AddNewInPullRequestToScaReleasesTable extends DdlChange { + static final String TABLE_NAME = "sca_releases"; + static final String COLUMN_NAME = "new_in_pull_request"; - public static final String TABLE_NAME = "issues_impacts"; - public static final String MANUAL_SEVERITY = "manual_severity"; - - - public AddManualSeverityColumnInIssuesImpactsTable(Database db) { + public AddNewInPullRequestToScaReleasesTable(Database db) { super(db); } @Override public void execute(Context context) throws SQLException { try (var connection = getDatabase().getDataSource().getConnection()) { - if (!tableColumnExists(connection, TABLE_NAME, MANUAL_SEVERITY)) { - var manualSeverity = BooleanColumnDef.newBooleanColumnDefBuilder() - .setColumnName(MANUAL_SEVERITY) + if (!tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { + var columnDef = BooleanColumnDef.newBooleanColumnDefBuilder() + .setColumnName(COLUMN_NAME) .setIsNullable(false) .setDefaultValue(false) .build(); - context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME) - .addColumn(manualSeverity) + .addColumn(columnDef) .build()); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddAICodeSupportedColumnToQualityGatesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/AddProductionScopeToScaDependenciesTable.java index 7af09037f59..bf2aab43019 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/AddAICodeSupportedColumnToQualityGatesTable.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/AddProductionScopeToScaDependenciesTable.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v108; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.sonar.db.Database; @@ -27,24 +27,24 @@ import org.sonar.server.platform.db.migration.step.DdlChange; import static org.sonar.db.DatabaseUtils.tableColumnExists; -public class AddAICodeSupportedColumnToQualityGatesTable extends DdlChange { - private static final String QUALITY_GATE_TABLE_NAME = "quality_gates"; - private static final String SUPPORTS_AI_CODE_COLUMN_NAME = "ai_code_supported"; +public class AddProductionScopeToScaDependenciesTable extends DdlChange { + static final String TABLE_NAME = "sca_dependencies"; + static final String COLUMN_NAME = "production_scope"; - public AddAICodeSupportedColumnToQualityGatesTable(Database db) { + public AddProductionScopeToScaDependenciesTable(Database db) { super(db); } @Override public void execute(Context context) throws SQLException { try (var connection = getDatabase().getDataSource().getConnection()) { - if (!tableColumnExists(connection, QUALITY_GATE_TABLE_NAME, SUPPORTS_AI_CODE_COLUMN_NAME)) { + if (!tableColumnExists(connection, TABLE_NAME, COLUMN_NAME)) { var columnDef = BooleanColumnDef.newBooleanColumnDefBuilder() - .setColumnName(SUPPORTS_AI_CODE_COLUMN_NAME) + .setColumnName(COLUMN_NAME) .setIsNullable(false) - .setDefaultValue(false) + .setDefaultValue(true) .build(); - context.execute(new AddColumnsBuilder(getDialect(), QUALITY_GATE_TABLE_NAME) + context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME) .addColumn(columnDef) .build()); } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddReportSchedulesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateArchitectureGraphsTable.java index d9f852f18fc..72a984fcd85 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/AddReportSchedulesTable.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateArchitectureGraphsTable.java @@ -17,32 +17,36 @@ * 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.platform.db.migration.version.v101; +package org.sonar.server.platform.db.migration.version.v202502; + +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; import java.sql.SQLException; +import java.util.List; import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.def.ClobColumnDef; import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; import org.sonar.server.platform.db.migration.step.CreateTableChange; -import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; -import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; - -public class AddReportSchedulesTable extends CreateTableChange { +public class CreateArchitectureGraphsTable extends CreateTableChange { + public static final String TABLE_NAME = "architecture_graphs"; - static final String TABLE_NAME = "report_schedules"; - public AddReportSchedulesTable(Database db) { + protected CreateArchitectureGraphsTable(Database db) { super(db, TABLE_NAME); } @Override public void execute(Context context, String tableName) throws SQLException { - context.execute(new CreateTableBuilder(getDialect(), tableName) + List<String> createQueries = new CreateTableBuilder(getDialect(), tableName) .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("portfolio_uuid").setIsNullable(true).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName("branch_uuid").setIsNullable(true).setLimit(UUID_SIZE).build()) - .addColumn(newBigIntegerColumnDefBuilder().setColumnName("last_send_time_in_ms").setIsNullable(false).build()) - .build()); + .addColumn(newVarcharColumnDefBuilder().setColumnName("branch_uuid").setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("source").setIsNullable(false).setLimit(255).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName("type").setIsNullable(false).setLimit(255).build()) + .addColumn(ClobColumnDef.newClobColumnDefBuilder().setColumnName("graph_data").setIsNullable(false).build()) + .build(); + + context.execute(createQueries); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateUniqueConstraintOnIssuesImpacts.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaDependenciesRelease.java index 59775043799..5e05d8e84c3 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateUniqueConstraintOnIssuesImpacts.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaDependenciesRelease.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v102; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.Connection; import java.sql.SQLException; @@ -26,11 +26,13 @@ import org.sonar.db.DatabaseUtils; import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; import org.sonar.server.platform.db.migration.step.DdlChange; -public class CreateUniqueConstraintOnIssuesImpacts extends DdlChange { - private static final String TABLE_NAME = "issues_impacts"; - private static final String INDEX_NAME = "uniq_iss_key_sof_qual"; +public class CreateIndexOnScaDependenciesRelease extends DdlChange { - public CreateUniqueConstraintOnIssuesImpacts(Database db) { + static final String TABLE_NAME = "sca_dependencies"; + static final String INDEX_NAME = "sca_dependencies_release_uuid"; + static final String COLUMN_NAME_SCA_RELEASE_UUID = "sca_release_uuid"; + + public CreateIndexOnScaDependenciesRelease(Database db) { super(db); } @@ -46,9 +48,7 @@ public class CreateUniqueConstraintOnIssuesImpacts extends DdlChange { context.execute(new CreateIndexBuilder(getDialect()) .setTable(TABLE_NAME) .setName(INDEX_NAME) - .addColumn("issue_key", false) - .addColumn("software_quality", false) - .setUnique(true) + .addColumn(COLUMN_NAME_SCA_RELEASE_UUID, false) .build()); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateUniqueConstraintOnRulesDefaultImpacts.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaIssuesReleasesScaIssueUuid.java index 17f265dd8af..391e7e23cee 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/CreateUniqueConstraintOnRulesDefaultImpacts.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaIssuesReleasesScaIssueUuid.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v102; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.Connection; import java.sql.SQLException; @@ -26,11 +26,13 @@ import org.sonar.db.DatabaseUtils; import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; import org.sonar.server.platform.db.migration.step.DdlChange; -public class CreateUniqueConstraintOnRulesDefaultImpacts extends DdlChange { - private static final String TABLE_NAME = "rules_default_impacts"; - private static final String INDEX_NAME = "uniq_rul_uuid_sof_qual"; +public class CreateIndexOnScaIssuesReleasesScaIssueUuid extends DdlChange { - public CreateUniqueConstraintOnRulesDefaultImpacts(Database db) { + static final String TABLE_NAME = "sca_issues_releases"; + static final String INDEX_NAME = "sca_issues_releases_sca_issue"; + static final String COLUMN_NAME_SCA_ISSUE_UUID = "sca_issue_uuid"; + + public CreateIndexOnScaIssuesReleasesScaIssueUuid(Database db) { super(db); } @@ -46,9 +48,7 @@ public class CreateUniqueConstraintOnRulesDefaultImpacts extends DdlChange { context.execute(new CreateIndexBuilder(getDialect()) .setTable(TABLE_NAME) .setName(INDEX_NAME) - .addColumn("rule_uuid", false) - .addColumn("software_quality", false) - .setUnique(true) + .addColumn(COLUMN_NAME_SCA_ISSUE_UUID, false) .build()); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexForEmailOnUsersTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaIssuesReleasesScaReleaseUuid.java index bacb55e7455..342a8a1966c 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexForEmailOnUsersTable.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaIssuesReleasesScaReleaseUuid.java @@ -17,9 +17,8 @@ * 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.platform.db.migration.version.v101; +package org.sonar.server.platform.db.migration.version.v202502; -import com.google.common.annotations.VisibleForTesting; import java.sql.Connection; import java.sql.SQLException; import org.sonar.db.Database; @@ -27,16 +26,13 @@ import org.sonar.db.DatabaseUtils; import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; import org.sonar.server.platform.db.migration.step.DdlChange; -class CreateIndexForEmailOnUsersTable extends DdlChange { +public class CreateIndexOnScaIssuesReleasesScaReleaseUuid extends DdlChange { - @VisibleForTesting - static final String INDEX_NAME = "users_email"; - @VisibleForTesting - static final String TABLE_NAME = "users"; - @VisibleForTesting - static final String COLUMN_NAME = "email"; + static final String TABLE_NAME = "sca_issues_releases"; + static final String INDEX_NAME = "sca_issues_releases_sca_releas"; + static final String COLUMN_NAME_SCA_RELEASE_UUID = "sca_release_uuid"; - public CreateIndexForEmailOnUsersTable(Database db) { + public CreateIndexOnScaIssuesReleasesScaReleaseUuid(Database db) { super(db); } @@ -52,8 +48,7 @@ class CreateIndexForEmailOnUsersTable extends DdlChange { context.execute(new CreateIndexBuilder(getDialect()) .setTable(TABLE_NAME) .setName(INDEX_NAME) - .addColumn(COLUMN_NAME) - .setUnique(false) + .addColumn(COLUMN_NAME_SCA_RELEASE_UUID, false) .build()); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateIndexForRuleImpactChangesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaReleasesComponent.java index 41ac645d795..5175333bd92 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateIndexForRuleImpactChangesTable.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaReleasesComponent.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v103; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.Connection; import java.sql.SQLException; @@ -26,29 +26,30 @@ import org.sonar.db.DatabaseUtils; import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; import org.sonar.server.platform.db.migration.step.DdlChange; -public class CreateIndexForRuleImpactChangesTable extends DdlChange { +public class CreateIndexOnScaReleasesComponent extends DdlChange { - static final String INDEX_NAME = "rule_impact_changes_r_c_uuid"; - static final String TABLE_NAME = "rule_impact_changes"; + static final String TABLE_NAME = "sca_releases"; + // abbreviated for 30 char limit + static final String INDEX_NAME = "sca_releases_comp_uuid"; + static final String COLUMN_NAME_COMPONENT_UUID = "component_uuid"; - public CreateIndexForRuleImpactChangesTable(Database db) { + public CreateIndexOnScaReleasesComponent(Database db) { super(db); } @Override public void execute(Context context) throws SQLException { try (Connection connection = getDatabase().getDataSource().getConnection()) { - createUniqueIndex(context, connection); + createIndex(context, connection); } } - private void createUniqueIndex(Context context, Connection connection) { + private void createIndex(Context context, Connection connection) { if (!DatabaseUtils.indexExistsIgnoreCase(TABLE_NAME, INDEX_NAME, connection)) { context.execute(new CreateIndexBuilder(getDialect()) .setTable(TABLE_NAME) .setName(INDEX_NAME) - .addColumn("rule_change_uuid", false) - .setUnique(false) + .addColumn(COLUMN_NAME_COMPONENT_UUID, false) .build()); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaReleasesComponentUuid.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaReleasesComponentUuid.java new file mode 100644 index 00000000000..848d5925a9e --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateIndexOnScaReleasesComponentUuid.java @@ -0,0 +1,58 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.db.migration.version.v202502; + +import java.sql.Connection; +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.DatabaseUtils; +import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; +import org.sonar.server.platform.db.migration.step.DdlChange; + +public class CreateIndexOnScaReleasesComponentUuid extends DdlChange { + + static final String TABLE_NAME = "sca_releases"; + // abbreviated for 30 char limit + static final String INDEX_NAME = "sca_releases_comp_uuid_uuid"; + static final String COLUMN_NAME_COMPONENT_UUID = "component_uuid"; + static final String COLUMN_NAME_UUID = "uuid"; + + public CreateIndexOnScaReleasesComponentUuid(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + try (Connection connection = getDatabase().getDataSource().getConnection()) { + createIndex(context, connection); + } + } + + private void createIndex(Context context, Connection connection) { + if (!DatabaseUtils.indexExistsIgnoreCase(TABLE_NAME, INDEX_NAME, connection)) { + context.execute(new CreateIndexBuilder(getDialect()) + .setTable(TABLE_NAME) + .setName(INDEX_NAME) + .addColumn(COLUMN_NAME_COMPONENT_UUID, false) + .addColumn(COLUMN_NAME_UUID, false) + .build()); + } + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaDependenciesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaDependenciesTable.java new file mode 100644 index 00000000000..c88c2be3f79 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaDependenciesTable.java @@ -0,0 +1,66 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.db.migration.version.v202502; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; +import org.sonar.server.platform.db.migration.step.CreateTableChange; + +import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder; +import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder; +import static org.sonar.server.platform.db.migration.def.ClobColumnDef.newClobColumnDefBuilder; +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; + +public class CreateScaDependenciesTable extends CreateTableChange { + + private static final String TABLE_NAME = "sca_dependencies"; + private static final String COLUMN_UUID_NAME = "uuid"; + private static final String COLUMN_SCA_RELEASE_UUID_NAME = "sca_release_uuid"; + private static final String COLUMN_DIRECT_NAME = "direct"; + private static final String COLUMN_SCOPE_NAME = "scope"; + private static final int COLUMN_SCOPE_SIZE = 100; + private static final String COLUMN_USER_DEPENDENCY_FILE_PATH_NAME = "user_dependency_file_path"; + private static final String COLUMN_LOCKFILE_DEPENDENCY_FILE_PATH_NAME = "lockfile_dependency_file_path"; + private static final int COLUMN_DEPENDENCY_FILE_PATH_SIZE = 1000; + private static final String COLUMN_CHAINS_NAME = "chains"; + private static final String COLUMN_CREATED_AT_NAME = "created_at"; + private static final String COLUMN_UPDATED_AT_NAME = "updated_at"; + + protected CreateScaDependenciesTable(Database db) { + super(db, TABLE_NAME); + } + + @Override + public void execute(Context context, String tableName) throws SQLException { + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_UUID_NAME).setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_SCA_RELEASE_UUID_NAME).setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newBooleanColumnDefBuilder().setColumnName(COLUMN_DIRECT_NAME).setIsNullable(false).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_SCOPE_NAME).setIsNullable(false).setLimit(COLUMN_SCOPE_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_USER_DEPENDENCY_FILE_PATH_NAME).setIsNullable(true).setLimit(COLUMN_DEPENDENCY_FILE_PATH_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_LOCKFILE_DEPENDENCY_FILE_PATH_NAME).setIsNullable(true).setLimit(COLUMN_DEPENDENCY_FILE_PATH_SIZE).build()) + .addColumn(newClobColumnDefBuilder().setColumnName(COLUMN_CHAINS_NAME).setIsNullable(true).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_CREATED_AT_NAME).setIsNullable(false).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_UPDATED_AT_NAME).setIsNullable(false).build()) + .build()); + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateProjectDependenciesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaIssuesReleasesTable.java index 3420f3edc80..099b40d16ac 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateProjectDependenciesTable.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaIssuesReleasesTable.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v108; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.sonar.db.Database; @@ -25,22 +25,23 @@ import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; import org.sonar.server.platform.db.migration.step.CreateTableChange; import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder; -import static org.sonar.server.platform.db.migration.def.ClobColumnDef.newClobColumnDefBuilder; +import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder; import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; -public class CreateProjectDependenciesTable extends CreateTableChange { +public class CreateScaIssuesReleasesTable extends CreateTableChange { - private static final String TABLE_NAME = "project_dependencies"; + static final String COLUMN_SCA_ISSUE_UUID_NAME = "sca_issue_uuid"; + static final String COLUMN_SCA_RELEASE_UUID_NAME = "sca_release_uuid"; + static final String COLUMN_SEVERITY_NAME = "severity"; + static final int COLUMN_SEVERITY_SIZE = 15; + static final String COLUMN_SEVERITY_SORT_KEY_NAME = "severity_sort_key"; + private static final String TABLE_NAME = "sca_issues_releases"; private static final String COLUMN_UUID_NAME = "uuid"; - private static final String COLUMN_VERSION_NAME = "version"; - private static final String COLUMN_INCLUDE_PATHS_NAME = "include_paths"; - private static final String COLUMN_PACKAGE_MANAGER_NAME = "package_manager"; - private static final int COLUMN_PACKAGE_MANAGER_SIZE = 50; private static final String COLUMN_CREATED_AT_NAME = "created_at"; private static final String COLUMN_UPDATED_AT_NAME = "updated_at"; - protected CreateProjectDependenciesTable(Database db) { + protected CreateScaIssuesReleasesTable(Database db) { super(db, TABLE_NAME); } @@ -48,9 +49,10 @@ public class CreateProjectDependenciesTable extends CreateTableChange { public void execute(Context context, String tableName) throws SQLException { context.execute(new CreateTableBuilder(getDialect(), tableName) .addPkColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_UUID_NAME).setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newClobColumnDefBuilder().setColumnName(COLUMN_VERSION_NAME).setIsNullable(true).build()) - .addColumn(newClobColumnDefBuilder().setColumnName(COLUMN_INCLUDE_PATHS_NAME).setIsNullable(true).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_PACKAGE_MANAGER_NAME).setIsNullable(true).setLimit(COLUMN_PACKAGE_MANAGER_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_SCA_ISSUE_UUID_NAME).setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_SCA_RELEASE_UUID_NAME).setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_SEVERITY_NAME).setIsNullable(false).setLimit(COLUMN_SEVERITY_SIZE).build()) + .addColumn(newIntegerColumnDefBuilder().setColumnName(COLUMN_SEVERITY_SORT_KEY_NAME).setIsNullable(false).build()) .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_CREATED_AT_NAME).setIsNullable(false).build()) .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_UPDATED_AT_NAME).setIsNullable(false).build()) .build()); diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaIssuesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaIssuesTable.java new file mode 100644 index 00000000000..4924fbbc0fd --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaIssuesTable.java @@ -0,0 +1,65 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.db.migration.version.v202502; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; +import org.sonar.server.platform.db.migration.step.CreateTableChange; + +import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder; +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; + +public class CreateScaIssuesTable extends CreateTableChange { + + private static final String TABLE_NAME = "sca_issues"; + private static final String COLUMN_UUID_NAME = "uuid"; + private static final String COLUMN_SCA_ISSUE_TYPE = "sca_issue_type"; + private static final int COLUMN_SCA_ISSUE_TYPE_SIZE = 40; + private static final String COLUMN_PACKAGE_URL = "package_url"; + private static final int COLUMN_PACKAGE_URL_SIZE = 400; + private static final String COLUMN_VULNERABILITY_ID = "vulnerability_id"; + // the max we have seen in the past as of 2025-02 is 35, though no spec guarantees that + private static final int COLUMN_VULNERABILITY_ID_SIZE = 63; + private static final String COLUMN_SPDX_LICENSE_ID = "spdx_license_id"; + // the max we have seen in the past as of 2025-02 is 68, though customers can type custom LicenseRef- names, + // and we'll probably need to restrict the length of those to this. + private static final int COLUMN_SPDX_LICENSE_ID_SIZE = 127; + private static final String COLUMN_CREATED_AT_NAME = "created_at"; + private static final String COLUMN_UPDATED_AT_NAME = "updated_at"; + + protected CreateScaIssuesTable(Database db) { + super(db, TABLE_NAME); + } + + @Override + public void execute(Context context, String tableName) throws SQLException { + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_UUID_NAME).setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_SCA_ISSUE_TYPE).setIsNullable(false).setLimit(COLUMN_SCA_ISSUE_TYPE_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_PACKAGE_URL).setIsNullable(false).setLimit(COLUMN_PACKAGE_URL_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_VULNERABILITY_ID).setIsNullable(false).setLimit(COLUMN_VULNERABILITY_ID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_SPDX_LICENSE_ID).setIsNullable(false).setLimit(COLUMN_SPDX_LICENSE_ID_SIZE).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_CREATED_AT_NAME).setIsNullable(false).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_UPDATED_AT_NAME).setIsNullable(false).build()) + .build()); + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaReleasesTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaReleasesTable.java new file mode 100644 index 00000000000..39111e8de9c --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaReleasesTable.java @@ -0,0 +1,70 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.db.migration.version.v202502; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; +import org.sonar.server.platform.db.migration.step.CreateTableChange; + +import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder; +import static org.sonar.server.platform.db.migration.def.BooleanColumnDef.newBooleanColumnDefBuilder; +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; + +public class CreateScaReleasesTable extends CreateTableChange { + + private static final String TABLE_NAME = "sca_releases"; + private static final String COLUMN_UUID_NAME = "uuid"; + private static final String COLUMN_COMPONENT_UUID_NAME = "component_uuid"; + private static final String COLUMN_PACKAGE_URL_NAME = "package_url"; + private static final int COLUMN_PACKAGE_URL_SIZE = 400; + private static final String COLUMN_PACKAGE_MANAGER_NAME = "package_manager"; + private static final int COLUMN_PACKAGE_MANAGER_SIZE = 20; + private static final String COLUMN_PACKAGE_NAME_NAME = "package_name"; + private static final int COLUMN_PACKAGE_NAME_SIZE = 400; + private static final String COLUMN_VERSION_NAME = "version"; + private static final int COLUMN_VERSION_SIZE = 400; + private static final String COLUMN_LICENSE_EXPRESSION_NAME = "license_expression"; + private static final int COLUMN_LICENSE_EXPRESSION_SIZE = 400; + private static final String COLUMN_KNOWN_NAME = "known"; + private static final String COLUMN_CREATED_AT_NAME = "created_at"; + private static final String COLUMN_UPDATED_AT_NAME = "updated_at"; + + protected CreateScaReleasesTable(Database db) { + super(db, TABLE_NAME); + } + + @Override + public void execute(Context context, String tableName) throws SQLException { + context.execute(new CreateTableBuilder(getDialect(), tableName) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_UUID_NAME).setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_COMPONENT_UUID_NAME).setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_PACKAGE_URL_NAME).setIsNullable(false).setLimit(COLUMN_PACKAGE_URL_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_PACKAGE_MANAGER_NAME).setIsNullable(false).setLimit(COLUMN_PACKAGE_MANAGER_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_PACKAGE_NAME_NAME).setIsNullable(false).setLimit(COLUMN_PACKAGE_NAME_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_VERSION_NAME).setIsNullable(false).setLimit(COLUMN_VERSION_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_LICENSE_EXPRESSION_NAME).setIsNullable(false).setLimit(COLUMN_LICENSE_EXPRESSION_SIZE).build()) + .addColumn(newBooleanColumnDefBuilder().setColumnName(COLUMN_KNOWN_NAME).setIsNullable(false).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_CREATED_AT_NAME).setIsNullable(false).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_UPDATED_AT_NAME).setIsNullable(false).build()) + .build()); + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateMeasuresTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaVulnerabilityIssuesTable.java index db7154b72a4..ccb335717ef 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v108/CreateMeasuresTable.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateScaVulnerabilityIssuesTable.java @@ -17,7 +17,7 @@ * 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.platform.db.migration.version.v108; +package org.sonar.server.platform.db.migration.version.v202502; import java.sql.SQLException; import org.sonar.db.Database; @@ -25,33 +25,36 @@ import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; import org.sonar.server.platform.db.migration.step.CreateTableChange; import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder; -import static org.sonar.server.platform.db.migration.def.ClobColumnDef.newClobColumnDefBuilder; +import static org.sonar.server.platform.db.migration.def.DecimalColumnDef.newDecimalColumnDefBuilder; import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; -public class CreateMeasuresTable extends CreateTableChange { +public class CreateScaVulnerabilityIssuesTable extends CreateTableChange { - static final String MEASURES_TABLE_NAME = "measures"; - static final String COLUMN_COMPONENT_UUID = "component_uuid"; - static final String COLUMN_BRANCH_UUID = "branch_uuid"; - static final String COLUMN_JSON_VALUE = "json_value"; - static final String COLUMN_JSON_VALUE_HASH = "json_value_hash"; - static final String COLUMN_CREATED_AT = "created_at"; - static final String COLUMN_UPDATED_AT = "updated_at"; + private static final String TABLE_NAME = "sca_vulnerability_issues"; + private static final String COLUMN_UUID_NAME = "uuid"; + private static final String COLUMN_BASE_SEVERITY = "base_severity"; + private static final int COLUMN_BASE_SEVERITY_SIZE = 15; + private static final String COLUMN_CWE_IDS = "cwe_ids"; + private static final int COLUMN_CWE_IDS_SIZE = 255; + private static final String COLUMN_CVSS_SCORE = "cvss_score"; + private static final String COLUMN_CREATED_AT_NAME = "created_at"; + private static final String COLUMN_UPDATED_AT_NAME = "updated_at"; - protected CreateMeasuresTable(Database db) { - super(db, MEASURES_TABLE_NAME); + protected CreateScaVulnerabilityIssuesTable(Database db) { + super(db, TABLE_NAME); } @Override public void execute(Context context, String tableName) throws SQLException { context.execute(new CreateTableBuilder(getDialect(), tableName) - .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_COMPONENT_UUID).setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_BRANCH_UUID).setIsNullable(false).setLimit(UUID_SIZE).build()) - .addColumn(newClobColumnDefBuilder().setColumnName(COLUMN_JSON_VALUE).setIsNullable(false).build()) - .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_JSON_VALUE_HASH).setIsNullable(false).build()) - .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_CREATED_AT).setIsNullable(false).build()) - .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_UPDATED_AT).setIsNullable(false).build()) + .addPkColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_UUID_NAME).setIsNullable(false).setLimit(UUID_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_BASE_SEVERITY).setIsNullable(false).setLimit(COLUMN_BASE_SEVERITY_SIZE).build()) + .addColumn(newVarcharColumnDefBuilder().setColumnName(COLUMN_CWE_IDS).setIsNullable(false).setLimit(COLUMN_CWE_IDS_SIZE).build()) + // precision 3 gives 3 digits total, and scale 1 is 1 digits after the decimal point. CVSS scores are 0-10 with 1 decimal point. + .addColumn(newDecimalColumnDefBuilder().setColumnName(COLUMN_CVSS_SCORE).setIsNullable(true).setPrecision(3).setScale(1).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_CREATED_AT_NAME).setIsNullable(false).build()) + .addColumn(newBigIntegerColumnDefBuilder().setColumnName(COLUMN_UPDATED_AT_NAME).setIsNullable(false).build()) .build()); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnArchitectureGraphs.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnArchitectureGraphs.java new file mode 100644 index 00000000000..802396d18b1 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnArchitectureGraphs.java @@ -0,0 +1,60 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.db.migration.version.v202502; + +import java.sql.Connection; +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.DatabaseUtils; +import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; +import org.sonar.server.platform.db.migration.step.DdlChange; + +public class CreateUniqueIndexOnArchitectureGraphs extends DdlChange { + + static final String TABLE_NAME = "architecture_graphs"; + static final String INDEX_NAME = "uq_idx_ag_branch_type_source"; + static final String COLUMN_NAME_BRANCH_UUID = "branch_uuid"; + static final String COLUMN_NAME_TYPE = "type"; + static final String COLUMN_NAME_SOURCE = "source"; + + public CreateUniqueIndexOnArchitectureGraphs(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + try (Connection connection = getDatabase().getDataSource().getConnection()) { + createIndex(context, connection); + } + } + + private void createIndex(Context context, Connection connection) { + if (!DatabaseUtils.indexExistsIgnoreCase(TABLE_NAME, INDEX_NAME, connection)) { + context.execute(new CreateIndexBuilder(getDialect()) + .setTable(TABLE_NAME) + .setName(INDEX_NAME) + .setUnique(true) + .addColumn(COLUMN_NAME_BRANCH_UUID, false) + .addColumn(COLUMN_NAME_TYPE, false) + .addColumn(COLUMN_NAME_SOURCE, false) + .build()); + } + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexOnExternalIdAndIdentityOnExternalGroupsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnScaIssues.java index 61a49e3143c..277071739e1 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v101/CreateIndexOnExternalIdAndIdentityOnExternalGroupsTable.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnScaIssues.java @@ -17,9 +17,8 @@ * 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.platform.db.migration.version.v101; +package org.sonar.server.platform.db.migration.version.v202502; -import com.google.common.annotations.VisibleForTesting; import java.sql.Connection; import java.sql.SQLException; import org.sonar.db.Database; @@ -27,16 +26,16 @@ import org.sonar.db.DatabaseUtils; import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; import org.sonar.server.platform.db.migration.step.DdlChange; -import static org.sonar.server.platform.db.migration.version.v101.CreateExternalGroupsTable.EXTERNAL_GROUP_ID_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateExternalGroupsTable.EXTERNAL_IDENTITY_PROVIDER_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v101.CreateExternalGroupsTable.TABLE_NAME; +public class CreateUniqueIndexOnScaIssues extends DdlChange { -public class CreateIndexOnExternalIdAndIdentityOnExternalGroupsTable extends DdlChange { + static final String TABLE_NAME = "sca_issues"; + static final String INDEX_NAME = "sca_issues_unique"; + static final String COLUMN_NAME_SCA_ISSUE_TYPE = "sca_issue_type"; + static final String COLUMN_NAME_PACKAGE_URL = "package_url"; + static final String COLUMN_NAME_VULNERABILITY_ID = "vulnerability_id"; + static final String COLUMN_NAME_SPDX_LICENSE_ID = "spdx_license_id"; - @VisibleForTesting - static final String INDEX_NAME = "uniq_ext_grp_ext_id_provider"; - - public CreateIndexOnExternalIdAndIdentityOnExternalGroupsTable(Database db) { + public CreateUniqueIndexOnScaIssues(Database db) { super(db); } @@ -52,11 +51,15 @@ public class CreateIndexOnExternalIdAndIdentityOnExternalGroupsTable extends Ddl context.execute(new CreateIndexBuilder(getDialect()) .setTable(TABLE_NAME) .setName(INDEX_NAME) - .addColumn(EXTERNAL_IDENTITY_PROVIDER_COLUMN_NAME, false) - .addColumn(EXTERNAL_GROUP_ID_COLUMN_NAME, false) .setUnique(true) + .addColumn(COLUMN_NAME_SCA_ISSUE_TYPE, false) + .addColumn(COLUMN_NAME_VULNERABILITY_ID, false) + // we specifically want this to be after vulnerability ID, so we can + // do an indexed lookup by vulnerability ID without having to know the + // package URL + .addColumn(COLUMN_NAME_PACKAGE_URL, false) + .addColumn(COLUMN_NAME_SPDX_LICENSE_ID, false) .build()); } - } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/CreateUniqueIndexForScimGroupsUuid.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnScaIssuesReleases.java index 5613db0d398..dae1d218e97 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v100/CreateUniqueIndexForScimGroupsUuid.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/CreateUniqueIndexOnScaIssuesReleases.java @@ -17,9 +17,8 @@ * 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.platform.db.migration.version.v100; +package org.sonar.server.platform.db.migration.version.v202502; -import com.google.common.annotations.VisibleForTesting; import java.sql.Connection; import java.sql.SQLException; import org.sonar.db.Database; @@ -27,34 +26,32 @@ import org.sonar.db.DatabaseUtils; import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; import org.sonar.server.platform.db.migration.step.DdlChange; -import static org.sonar.server.platform.db.migration.version.v100.CreateScimGroupsTable.TABLE_NAME; +public class CreateUniqueIndexOnScaIssuesReleases extends DdlChange { -public class CreateUniqueIndexForScimGroupsUuid extends DdlChange { + static final String TABLE_NAME = "sca_issues_releases"; + static final String INDEX_NAME = "sca_issues_releases_unique"; + static final String COLUMN_NAME_SCA_ISSUE_UUID = "sca_issue_uuid"; + static final String COLUMN_NAME_SCA_RELEASE_UUID = "sca_release_uuid"; - @VisibleForTesting - static final String COLUMN_NAME = "group_uuid"; - - @VisibleForTesting - static final String INDEX_NAME = "uniq_scim_group_uuid"; - - public CreateUniqueIndexForScimGroupsUuid(Database db) { + public CreateUniqueIndexOnScaIssuesReleases(Database db) { super(db); } @Override public void execute(Context context) throws SQLException { try (Connection connection = getDatabase().getDataSource().getConnection()) { - createUserUuidUniqueIndex(context, connection); + createIndex(context, connection); } } - private void createUserUuidUniqueIndex(Context context, Connection connection) { + private void createIndex(Context context, Connection connection) { if (!DatabaseUtils.indexExistsIgnoreCase(TABLE_NAME, INDEX_NAME, connection)) { context.execute(new CreateIndexBuilder(getDialect()) .setTable(TABLE_NAME) .setName(INDEX_NAME) - .addColumn(COLUMN_NAME, false) .setUnique(true) + .addColumn(COLUMN_NAME_SCA_ISSUE_UUID, false) + .addColumn(COLUMN_NAME_SCA_RELEASE_UUID, false) .build()); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/DbVersion202502.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/DbVersion202502.java index cd2431cefb5..8bbbe17ee01 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/DbVersion202502.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/DbVersion202502.java @@ -38,6 +38,26 @@ public class DbVersion202502 implements DbVersion { registry .add(2025_02_000, "Drop 'issues_dependency' table", DropIssuesDependencyTable.class) .add(2025_02_001, "Drop 'cve_cwe' table", DropCveCweTable.class) - .add(2025_02_002, "Drop 'cves' table", DropCvesTable.class); + .add(2025_02_002, "Drop 'cves' table", DropCvesTable.class) + .add(2025_02_003, "Create table for SCA releases", CreateScaReleasesTable.class) + .add(2025_02_004, "Create index for SCA releases component", CreateIndexOnScaReleasesComponent.class) + .add(2025_02_005, "Create table for SCA dependencies", CreateScaDependenciesTable.class) + .add(2025_02_006, "Create index for SCA dependencies to releases", CreateIndexOnScaDependenciesRelease.class) + .add(2025_02_007, "Create table for SCA issues", CreateScaIssuesTable.class) + .add(2025_02_008, "Create unique index on SCA issues", CreateUniqueIndexOnScaIssues.class) + .add(2025_02_009, "Create table for vulnerability subtype of SCA issues", CreateScaVulnerabilityIssuesTable.class) + .add(2025_02_010, "Create table for SCA issues to releases", CreateScaIssuesReleasesTable.class) + .add(2025_02_011, "Create index for SCA issues to releases to SCA issues", CreateIndexOnScaIssuesReleasesScaIssueUuid.class) + .add(2025_02_012, "Create index for SCA issues to releases to SCA releases", CreateIndexOnScaIssuesReleasesScaReleaseUuid.class) + .add(2025_02_013, "Create unique index for SCA issues to releases", CreateUniqueIndexOnScaIssuesReleases.class) + .add(2025_02_014, "Add new_in_pull_request column to SCA releases", AddNewInPullRequestToScaReleasesTable.class) + .add(2025_02_015, "Add new_in_pull_request column to SCA dependencies", AddNewInPullRequestToScaDependenciesTable.class) + .add(2025_02_016, "Insert default AI Codefix provider key and modelKey properties", InsertDefaultAiSuggestionProviderKeyAndModelKeyProperties.class) + .add(2025_02_017, "Add table 'architecture_graphs'", CreateArchitectureGraphsTable.class) + .add(2025_02_018, "Drop 'sca_releases_comp_uuid' index", DropIndexOnScaReleasesComponent.class) + .add(2025_02_019, "Create 'sca_releases_comp_uuid_uuid' index", CreateIndexOnScaReleasesComponentUuid.class) + .add(2025_02_020, "Add 'sca_dependencies.production_scope' column", AddProductionScopeToScaDependenciesTable.class) + .add(2025_02_021, "Add declared_license_expression to SCA releases", AddDeclaredLicenseExpressionToScaReleasesTable.class) + .add(2025_02_022, "Create 'uq_idx_ag_branch_type_source' for architecture graphs", CreateUniqueIndexOnArchitectureGraphs.class); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexOnMainBranchProjectUuid.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/DropIndexOnScaReleasesComponent.java index daa15db5691..5cec4743767 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v102/DropIndexOnMainBranchProjectUuid.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/DropIndexOnScaReleasesComponent.java @@ -17,16 +17,17 @@ * 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.platform.db.migration.version.v102; +package org.sonar.server.platform.db.migration.version.v202502; import org.sonar.db.Database; import org.sonar.server.platform.db.migration.step.DropIndexChange; -public class DropIndexOnMainBranchProjectUuid extends DropIndexChange { - private static final String INDEX_NAME = "idx_main_branch_prj_uuid"; - private static final String TABLE_NAME = "components"; +public class DropIndexOnScaReleasesComponent extends DropIndexChange { - public DropIndexOnMainBranchProjectUuid(Database db) { + private static final String TABLE_NAME = "sca_releases"; + private static final String INDEX_NAME = "sca_releases_comp_uuid"; + + public DropIndexOnScaReleasesComponent(Database db) { super(db, INDEX_NAME, TABLE_NAME); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/InsertDefaultAiSuggestionProviderKeyAndModelKeyProperties.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/InsertDefaultAiSuggestionProviderKeyAndModelKeyProperties.java new file mode 100644 index 00000000000..17eb9f23a70 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202502/InsertDefaultAiSuggestionProviderKeyAndModelKeyProperties.java @@ -0,0 +1,76 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.db.migration.version.v202502; + +import java.sql.SQLException; +import java.util.Optional; +import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactory; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.step.DataChange; + +import static org.sonar.core.config.AiCodeFixEnablementConstants.SUGGESTION_FEATURE_ENABLED_PROPERTY; +import static org.sonar.core.config.AiCodeFixEnablementConstants.SUGGESTION_PROVIDER_KEY_PROPERTY; +import static org.sonar.core.config.AiCodeFixEnablementConstants.SUGGESTION_PROVIDER_MODEL_KEY_PROPERTY; + +public class InsertDefaultAiSuggestionProviderKeyAndModelKeyProperties extends DataChange { + + static final String DISABLED = "DISABLED"; + static final String DEFAULT_PROVIDER_KEY = "OPENAI"; + static final String DEFAULT_PROVIDER_MODEL_KEY = "OPENAI_GPT_4O"; + private final System2 system2; + private final UuidFactory uuidFactory; + + public InsertDefaultAiSuggestionProviderKeyAndModelKeyProperties(Database db, System2 system2, UuidFactory uuidFactory) { + super(db); + this.system2 = system2; + this.uuidFactory = uuidFactory; + } + + @Override + protected void execute(Context context) throws SQLException { + boolean isAiCodeFixEnabled = Optional.ofNullable(context.prepareSelect("select text_value from properties where prop_key=?") + .setString(1, SUGGESTION_FEATURE_ENABLED_PROPERTY) + .get(r -> r.getString(1))) + .map(value -> !DISABLED.equals(value)) + .orElse(false); + + if (isAiCodeFixEnabled) { + insertProperty(context, SUGGESTION_PROVIDER_KEY_PROPERTY, DEFAULT_PROVIDER_KEY); + insertProperty(context, SUGGESTION_PROVIDER_MODEL_KEY_PROPERTY, DEFAULT_PROVIDER_MODEL_KEY); + } + } + + private void insertProperty(Context context, String key, String value) throws SQLException { + context.prepareUpsert(""" + INSERT INTO properties + (prop_key, is_empty, text_value, created_at, uuid) + VALUES(?, ?, ?, ?, ?) + """) + .setString(1, key) + .setBoolean(2, false) + .setString(3, value) + .setLong(4, system2.now()) + .setString(5, uuidFactory.create()) + .execute() + .commit(); + } + +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v102/DbVersion102Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v102/DbVersion102Test.java deleted file mode 100644 index 428e48b9273..00000000000 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v102/DbVersion102Test.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v102; - -import org.junit.Test; - -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationNotEmpty; -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber; - -public class DbVersion102Test { - private final DbVersion102 underTest = new DbVersion102(); - - @Test - public void migrationNumber_starts_at_10_2_000() { - verifyMinimumMigrationNumber(underTest, 10_2_000); - } - - @Test - public void verify_migration_is_not_empty() { - verifyMigrationNotEmpty(underTest); - } - -} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v103/DbVersion103Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v103/DbVersion103Test.java deleted file mode 100644 index 0e2f1b08088..00000000000 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v103/DbVersion103Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v103; - -import org.junit.Test; - -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationNotEmpty; -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber; - -public class DbVersion103Test { - - private final DbVersion103 underTest = new DbVersion103(); - - @Test - public void migrationNumber_starts_at_10_3_000() { - verifyMinimumMigrationNumber(underTest, 10_3_000); - } - - @Test - public void verify_migration_is_not_empty() { - verifyMigrationNotEmpty(underTest); - } - -} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v104/DbVersion104Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v104/DbVersion104Test.java deleted file mode 100644 index 206323283e3..00000000000 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v104/DbVersion104Test.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v104; - -import org.junit.Test; - -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationNotEmpty; -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber; - -public class DbVersion104Test { - - private final DbVersion104 underTest = new DbVersion104(); - - @Test - public void migrationNumber_starts_at_10_4_000() { - verifyMinimumMigrationNumber(underTest, 10_4_000); - } - - @Test - public void verify_migration_is_not_empty() { - verifyMigrationNotEmpty(underTest); - } -} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v105/DbVersion105Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v105/DbVersion105Test.java deleted file mode 100644 index dff7dfeef1b..00000000000 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v105/DbVersion105Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v105; - -import org.junit.Test; - -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationNotEmpty; -import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber; - -public class DbVersion105Test { - - private final DbVersion105 underTest = new DbVersion105(); - - @Test - public void migrationNumber_starts_at_10_5_000() { - verifyMinimumMigrationNumber(underTest, 10_5_000); - } - - @Test - public void verify_migration_is_not_empty() { - verifyMigrationNotEmpty(underTest); - } - -} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/AddAICodeFixEnabledColumnToProjectsTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/AddAICodeFixEnabledColumnToProjectsTableTest.java deleted file mode 100644 index 2ffb4b56396..00000000000 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/AddAICodeFixEnabledColumnToProjectsTableTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.BOOLEAN; -import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; -import static org.sonar.server.platform.db.migration.version.v108.AddAICodeFixEnabledColumnToProjectsTable.AI_CODE_FIX_ENABLED_COLUMN_NAME; -import static org.sonar.server.platform.db.migration.version.v108.AddAICodeFixEnabledColumnToProjectsTable.PROJECTS_TABLE_NAME; - -class AddAICodeFixEnabledColumnToProjectsTableTest { - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddImpactsColumnInActiveRulesTable.class); - - private final AddAICodeFixEnabledColumnToProjectsTable underTest = new AddAICodeFixEnabledColumnToProjectsTable(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(PROJECTS_TABLE_NAME, AI_CODE_FIX_ENABLED_COLUMN_NAME); - underTest.execute(); - assertColumnExists(); - } - - @Test - void execute_whenColumnsAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertColumnExists(); - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } - - private void assertColumnExists() { - db.assertColumnDefinition(PROJECTS_TABLE_NAME, AI_CODE_FIX_ENABLED_COLUMN_NAME, BOOLEAN, null, false); - } - -} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/AddAICodeSupportedColumnToQualityGatesTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/AddAICodeSupportedColumnToQualityGatesTableTest.java deleted file mode 100644 index cf8b79a99f7..00000000000 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/AddAICodeSupportedColumnToQualityGatesTableTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.BOOLEAN; -import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; - -class AddAICodeSupportedColumnToQualityGatesTableTest { - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddAICodeSupportedColumnToQualityGatesTable.class); - - private final AddAICodeSupportedColumnToQualityGatesTable underTest = new AddAICodeSupportedColumnToQualityGatesTable(db.database()); - - @Test - void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist("quality_gates", "ai_code_supported"); - underTest.execute(); - assertColumnExists(); - } - - @Test - void execute_whenColumnsAlreadyExists_shouldNotFail() throws SQLException { - underTest.execute(); - assertColumnExists(); - assertThatCode(underTest::execute).doesNotThrowAnyException(); - } - - private void assertColumnExists() { - db.assertColumnDefinition("quality_gates", "ai_code_supported", BOOLEAN, null, false); - } - -} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/RenameAiCodeAssuranceColumnInProjectsTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/RenameAiCodeAssuranceColumnInProjectsTest.java deleted file mode 100644 index 3536a135eab..00000000000 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/RenameAiCodeAssuranceColumnInProjectsTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.platform.db.migration.version.v108; - -import java.sql.SQLException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.db.MigrationDbTester; - -import static java.sql.Types.BOOLEAN; - -public class RenameAiCodeAssuranceColumnInProjectsTest { - public static final String TABLE_NAME = "projects"; - public static final String NEW_COLUMN_NAME = "contains_ai_code"; - - @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(RenameAiCodeAssuranceColumnInProjects.class); - private final RenameAiCodeAssuranceColumnInProjects underTest = new RenameAiCodeAssuranceColumnInProjects(db.database()); - - @Test - void columnIsRenamed() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, BOOLEAN, 1, false); - } - - @Test - void migration_is_reentrant() throws SQLException { - db.assertColumnDoesNotExist(TABLE_NAME, NEW_COLUMN_NAME); - underTest.execute(); - underTest.execute(); - db.assertColumnDefinition(TABLE_NAME, NEW_COLUMN_NAME, BOOLEAN, 1, false); - } -} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/AddImpactsColumnInActiveRulesTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v202502/AddDeclaredLicenseExpressionToScaReleasesTableTest.java index 27edad2832b..182fcf41ecb 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v108/AddImpactsColumnInActiveRulesTableTest.java +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v202502/AddDeclaredLicenseExpressionToScaReleasesTableTest.java @@ -17,28 +17,30 @@ * 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.platform.db.migration.version.v108; +package org.sonar.server.platform.db.migration.version.v202502; -import java.sql.SQLException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.MigrationDbTester; +import java.sql.SQLException; + import static java.sql.Types.VARCHAR; import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; -import static org.sonar.server.platform.db.migration.version.v108.AddImpactsColumnInActiveRulesTable.ACTIVE_RULES_TABLE_NAME; -import static org.sonar.server.platform.db.migration.version.v108.AddImpactsColumnInActiveRulesTable.IMPACTS; -class AddImpactsColumnInActiveRulesTableTest { +class AddDeclaredLicenseExpressionToScaReleasesTableTest { + static final String TABLE_NAME = "sca_releases"; + static final String COLUMN_NAME = "declared_license_expression"; + private static final int COLUMN_SIZE = 400; @RegisterExtension - public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddImpactsColumnInActiveRulesTable.class); + public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(AddDeclaredLicenseExpressionToScaReleasesTable.class); - private final AddImpactsColumnInActiveRulesTable underTest = new AddImpactsColumnInActiveRulesTable(db.database()); + private final AddDeclaredLicenseExpressionToScaReleasesTable underTest = new AddDeclaredLicenseExpressionToScaReleasesTable(db.database()); @Test void execute_whenColumnDoesNotExist_shouldCreateColumn() throws SQLException { - db.assertColumnDoesNotExist(ACTIVE_RULES_TABLE_NAME, IMPACTS); + db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); underTest.execute(); assertColumnExists(); } @@ -51,7 +53,6 @@ class AddImpactsColumnInActiveRulesTableTest { } private void assertColumnExists() { - db.assertColumnDefinition(ACTIVE_RULES_TABLE_NAME, IMPACTS, VARCHAR, 500, true); + db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, VARCHAR, COLUMN_SIZE, false); } - } diff --git a/server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java b/server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java index 0c5ae857700..a641ae20c57 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java +++ b/server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java @@ -138,6 +138,11 @@ public class EsConnectorImpl implements EsConnector { private HttpHost toHttpHost(HostAndPort host) { try { String scheme = keyStorePath != null ? "https" : HttpHost.DEFAULT_SCHEME_NAME; + if ("true".equalsIgnoreCase(System.getProperty("java.net.preferIPv6Addresses"))) { + // host.getHost() returns IP address. This is required for HttpHost to work as we need to use IP address in the RestClient to + // correctly resolve the host. Otherwise, RestClient will try to find the ip using hostname, and it might fail in case of IPv6. + return new HttpHost(InetAddress.getByName(host.getHost()), host.getHost(), host.getPortOrDefault(9001), scheme); + } return new HttpHost(InetAddress.getByName(host.getHost()), host.getPortOrDefault(9001), scheme); } catch (UnknownHostException e) { throw new IllegalStateException("Can not resolve host [" + host + "]", e); diff --git a/server/sonar-process/build.gradle b/server/sonar-process/build.gradle index 613083e5d6e..543bca3f05b 100644 --- a/server/sonar-process/build.gradle +++ b/server/sonar-process/build.gradle @@ -30,6 +30,7 @@ dependencies { testImplementation 'org.assertj:assertj-core' testImplementation 'org.hamcrest:hamcrest' testImplementation 'org.junit.jupiter:junit-jupiter-api' + testImplementation 'org.junit.jupiter:junit-jupiter-params' testImplementation 'org.mockito:mockito-core' testImplementation 'org.awaitility:awaitility' testImplementation project(':sonar-testing-harness') diff --git a/server/sonar-process/src/it/java/org/sonar/process/cluster/hz/HazelcastMemberBuilderIT.java b/server/sonar-process/src/it/java/org/sonar/process/cluster/hz/HazelcastMemberBuilderIT.java new file mode 100644 index 00000000000..2109ef4d3b0 --- /dev/null +++ b/server/sonar-process/src/it/java/org/sonar/process/cluster/hz/HazelcastMemberBuilderIT.java @@ -0,0 +1,124 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.process.cluster.hz; + +import java.net.InetAddress; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; +import org.sonar.process.NetworkUtilsImpl; +import org.sonar.process.ProcessId; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + + +@Timeout(60) +class HazelcastMemberBuilderIT { + + // use loopback for support of offline builds + private final InetAddress loopback = InetAddress.getLoopbackAddress(); + + @Test + void build_tcp_ip_member_hostaddress() { + HazelcastMember member = new HazelcastMemberBuilder(JoinConfigurationType.TCP_IP) + .setMembers(loopback.getHostAddress()) + .setProcessId(ProcessId.COMPUTE_ENGINE) + .setNodeName("bar") + .setPort(NetworkUtilsImpl.INSTANCE.getNextLoopbackAvailablePort()) + .setNetworkInterface(loopback.getHostAddress()) + .build(); + + assertThat(member.getUuid()).isNotNull(); + assertThat(member.getClusterTime()).isPositive(); + assertThat(member.getCluster().getMembers()).hasSize(1); + assertThat(member.getMemberUuids()).containsOnlyOnce(member.getUuid()); + + assertThat(member.getAtomicReference("baz")).isNotNull(); + assertThat(member.getLock("baz")).isNotNull(); + assertThat(member.getReplicatedMap("baz")).isNotNull(); + + member.close(); + } + + @Test + void strip_square_brackets_from_ipv6_address_when_building_a_member() { + HazelcastMemberBuilder memberBuilder = new HazelcastMemberBuilder(JoinConfigurationType.TCP_IP) + .setMembers(loopback.getHostAddress()) + .setProcessId(ProcessId.COMPUTE_ENGINE) + .setNodeName("bar") + .setPort(NetworkUtilsImpl.INSTANCE.getNextLoopbackAvailablePort()) + .setNetworkInterface("[" + loopback.getHostAddress() + "]"); + + assertThatCode(memberBuilder::build).doesNotThrowAnyException(); + } + + @Test + void build_tcp_ip_member_hostname() { + HazelcastMember member = new HazelcastMemberBuilder(JoinConfigurationType.TCP_IP) + .setMembers(loopback.getHostName()) + .setProcessId(ProcessId.COMPUTE_ENGINE) + .setNodeName("bar") + .setPort(NetworkUtilsImpl.INSTANCE.getNextLoopbackAvailablePort()) + .setNetworkInterface(loopback.getHostAddress()) + .build(); + + assertThat(member.getUuid()).isNotNull(); + assertThat(member.getClusterTime()).isPositive(); + assertThat(member.getCluster().getMembers()).hasSize(1); + assertThat(member.getMemberUuids()).containsOnlyOnce(member.getUuid()); + + assertThat(member.getAtomicReference("baz")).isNotNull(); + assertThat(member.getLock("baz")).isNotNull(); + assertThat(member.getReplicatedMap("baz")).isNotNull(); + + member.close(); + } + + @Test + void build_kubernetes_member() { + HazelcastMember member = new HazelcastMemberBuilder(JoinConfigurationType.KUBERNETES) + .setMembers(loopback.getHostAddress()) + .setProcessId(ProcessId.COMPUTE_ENGINE) + .setNodeName("bar") + .setPort(NetworkUtilsImpl.INSTANCE.getNextLoopbackAvailablePort()) + .setNetworkInterface(loopback.getHostAddress()) + .build(); + + assertThat(member.getUuid()).isNotNull(); + assertThat(member.getClusterTime()).isPositive(); + assertThat(member.getCluster().getMembers()).hasSize(1); + assertThat(member.getMemberUuids()).containsOnlyOnce(member.getUuid()); + + assertThat(member.getAtomicReference("baz")).isNotNull(); + assertThat(member.getLock("baz")).isNotNull(); + assertThat(member.getReplicatedMap("baz")).isNotNull(); + + member.close(); + } + + @Test + void fail_if_elasticsearch_process() { + var builder = new HazelcastMemberBuilder(JoinConfigurationType.TCP_IP); + assertThatThrownBy(() -> builder.setProcessId(ProcessId.ELASTICSEARCH)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Hazelcast must not be enabled on Elasticsearch node"); + } +} diff --git a/server/sonar-process/src/main/java/org/sonar/process/NetworkUtils.java b/server/sonar-process/src/main/java/org/sonar/process/NetworkUtils.java index e1bb4f91938..056c8978407 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/NetworkUtils.java +++ b/server/sonar-process/src/main/java/org/sonar/process/NetworkUtils.java @@ -20,6 +20,7 @@ package org.sonar.process; import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.InetAddress; import java.util.Optional; import java.util.OptionalInt; @@ -51,6 +52,8 @@ public interface NetworkUtils { boolean isLoopback(String hostOrAddress); + boolean isIpv6Address(String hostOrAddress); + /** * Returns the machine {@link InetAddress} that matches the specified * predicate. If multiple addresses match then a single one @@ -66,4 +69,13 @@ public interface NetworkUtils { default Optional<InetAddress> getLocalNonLoopbackIpv4Address() { return getLocalInetAddress(a -> !a.isLoopbackAddress() && a instanceof Inet4Address); } + + /** + * Returns a local {@link InetAddress} that is IPv6 and not + * loopback. If multiple addresses match then a single one + * is picked in a non deterministic way. + */ + default Optional<InetAddress> getLocalNonLoopbackIpv6Address() { + return getLocalInetAddress(a -> !a.isLoopbackAddress() && a instanceof Inet6Address); + } } diff --git a/server/sonar-process/src/main/java/org/sonar/process/NetworkUtilsImpl.java b/server/sonar-process/src/main/java/org/sonar/process/NetworkUtilsImpl.java index 6bc1237d9de..d40a63969ac 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/NetworkUtilsImpl.java +++ b/server/sonar-process/src/main/java/org/sonar/process/NetworkUtilsImpl.java @@ -22,6 +22,7 @@ package org.sonar.process; import com.google.common.annotations.VisibleForTesting; import com.google.common.net.InetAddresses; import java.io.IOException; +import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.ServerSocket; @@ -102,7 +103,7 @@ public class NetworkUtilsImpl implements NetworkUtils { return InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { LOG.trace("Failed to get hostname", e); - return "unresolved hostname"; + return "unresolved hostname"; } } @@ -145,6 +146,17 @@ public class NetworkUtilsImpl implements NetworkUtils { } @Override + public boolean isIpv6Address(String hostOrAddress) { + Optional<InetAddress> inetAddress = toInetAddress(hostOrAddress); + boolean ipv6Preferred = Boolean.parseBoolean(System.getProperty("java.net.preferIPv6Addresses")); + + if (inetAddress.isEmpty() || inetAddress.get().isLoopbackAddress()) { + return ipv6Preferred; + } + return inetAddress.get() instanceof Inet6Address; + } + + @Override public Optional<InetAddress> getLocalInetAddress(Predicate<InetAddress> predicate) { try { return Collections.list(NetworkInterface.getNetworkInterfaces()).stream() diff --git a/server/sonar-process/src/main/java/org/sonar/process/cluster/hz/HazelcastMemberBuilder.java b/server/sonar-process/src/main/java/org/sonar/process/cluster/hz/HazelcastMemberBuilder.java index 2d0edcef910..8627327ac64 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/cluster/hz/HazelcastMemberBuilder.java +++ b/server/sonar-process/src/main/java/org/sonar/process/cluster/hz/HazelcastMemberBuilder.java @@ -19,6 +19,7 @@ */ package org.sonar.process.cluster.hz; +import com.google.common.net.HostAndPort; import com.hazelcast.config.Config; import com.hazelcast.config.JoinConfig; import com.hazelcast.config.MemberAttributeConfig; @@ -26,10 +27,10 @@ import com.hazelcast.config.NetworkConfig; import com.hazelcast.core.Hazelcast; import java.util.List; import java.util.stream.Stream; +import org.jetbrains.annotations.NotNull; import org.sonar.process.ProcessId; import org.sonar.process.cluster.hz.HazelcastMember.Attribute; -import static java.lang.String.format; import static java.util.Collections.singletonList; import static java.util.Objects.requireNonNull; import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HZ_PORT; @@ -94,22 +95,25 @@ public class HazelcastMemberBuilder { .setReuseAddress(true); netConfig.getInterfaces() .setEnabled(true) - .setInterfaces(singletonList(requireNonNull(networkInterface, "Network interface is missing"))); + .setInterfaces(provideNetworkInterfaceForHazelcastConfig()); JoinConfig joinConfig = netConfig.getJoin(); joinConfig.getAwsConfig().setEnabled(false); joinConfig.getMulticastConfig().setEnabled(false); + final int defaultHzNodePort = Integer.parseInt(CLUSTER_NODE_HZ_PORT.getDefaultValue()); if (KUBERNETES.equals(type)) { joinConfig.getKubernetesConfig().setEnabled(true) .setProperty("service-dns", requireNonNull(members, "Service DNS is missing")) - .setProperty("service-port", CLUSTER_NODE_HZ_PORT.getDefaultValue()); + .setProperty("service-port", String.valueOf(defaultHzNodePort)); } else { List<String> addressesWithDefaultPorts = Stream.of(this.members.split(",")) - .filter(host -> !host.isBlank()) - .map(String::trim) - .map(HazelcastMemberBuilder::applyDefaultPortToHost) - .toList(); + .filter(host -> !host.isBlank()) + .map(String::trim) + .map(HostAndPort::fromString) + .map(parsedHost -> parsedHost.withDefaultPort(defaultHzNodePort)) + .map(HostAndPort::toString) + .toList(); joinConfig.getTcpIpConfig().setEnabled(true); joinConfig.getTcpIpConfig().setMembers(requireNonNull(addressesWithDefaultPorts, "Members are missing")); } @@ -127,8 +131,9 @@ public class HazelcastMemberBuilder { .setProperty("hazelcast.phone.home.enabled", "false") // Use slf4j for logging .setProperty("hazelcast.logging.type", "slf4j") - .setProperty("hazelcast.partial.member.disconnection.resolution.heartbeat.count", "5") - ; + // support ip v6 + .setProperty("hazelcast.prefer.ipv4.stack", "false") + .setProperty("hazelcast.partial.member.disconnection.resolution.heartbeat.count", "5"); MemberAttributeConfig attributes = config.getMemberAttributeConfig(); attributes.setAttribute(Attribute.NODE_NAME.getKey(), requireNonNull(nodeName, "Node name is missing")); @@ -137,8 +142,15 @@ public class HazelcastMemberBuilder { return new HazelcastMemberImpl(Hazelcast.newHazelcastInstance(config)); } - private static String applyDefaultPortToHost(String host) { - return host.contains(":") ? host : format("%s:%s", host, CLUSTER_NODE_HZ_PORT.getDefaultValue()); + /** + * Hazelcast doesn't recognize IPv6 address in the square brackets so we remove in case user provided us with the IP with square brackets + */ + @NotNull + private List<String> provideNetworkInterfaceForHazelcastConfig() { + String hazelcastNetworkInterface = requireNonNull(networkInterface, "Network interface is missing"); + if (hazelcastNetworkInterface.startsWith("[") && hazelcastNetworkInterface.endsWith("]")) { + hazelcastNetworkInterface = hazelcastNetworkInterface.replace("[", "").replace("]", ""); + } + return singletonList(hazelcastNetworkInterface); } - } diff --git a/server/sonar-process/src/test/java/org/sonar/process/NetworkUtilsImplTest.java b/server/sonar-process/src/test/java/org/sonar/process/NetworkUtilsImplTest.java index 639fc720ff8..f68604a5cfc 100644 --- a/server/sonar-process/src/test/java/org/sonar/process/NetworkUtilsImplTest.java +++ b/server/sonar-process/src/test/java/org/sonar/process/NetworkUtilsImplTest.java @@ -27,19 +27,20 @@ import java.util.HashSet; import java.util.Optional; import java.util.Set; import org.hamcrest.CoreMatchers; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.apache.commons.lang3.RandomStringUtils.secure; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assume.assumeThat; -public class NetworkUtilsImplTest { +class NetworkUtilsImplTest { + public static final String PREFER_IPV_6_ADDRESSES = "java.net.preferIPv6Addresses"; - private NetworkUtilsImpl underTest = new NetworkUtilsImpl(); + private final NetworkUtilsImpl underTest = new NetworkUtilsImpl(); @Test - public void getNextAvailablePort_returns_a_port() throws Exception { + void getNextAvailablePort_returns_a_port() throws Exception { String localhost = InetAddress.getLocalHost().getHostName(); int port = underTest.getNextAvailablePort(localhost).getAsInt(); assertThat(port) @@ -48,7 +49,7 @@ public class NetworkUtilsImplTest { } @Test - public void getNextAvailablePort_does_not_return_twice_the_same_port() throws Exception { + void getNextAvailablePort_does_not_return_twice_the_same_port() throws Exception { String localhost = InetAddress.getLocalHost().getHostName(); Set<Integer> ports = new HashSet<>(Arrays.asList( underTest.getNextAvailablePort(localhost).getAsInt(), @@ -58,7 +59,7 @@ public class NetworkUtilsImplTest { } @Test - public void getLocalNonLoopbackIpv4Address_returns_a_valid_local_and_non_loopback_ipv4() { + void getLocalNonLoopbackIpv4Address_returns_a_valid_local_and_non_loopback_ipv4() { Optional<InetAddress> address = underTest.getLocalNonLoopbackIpv4Address(); // address is empty on offline builds @@ -69,7 +70,7 @@ public class NetworkUtilsImplTest { } @Test - public void getHostname_returns_hostname_of_localhost_otherwise_a_constant() { + void getHostname_returns_hostname_of_localhost_otherwise_a_constant() { try { InetAddress localHost = InetAddress.getLocalHost(); assertThat(underTest.getHostname()).isEqualTo(localHost.getHostName()); @@ -80,41 +81,41 @@ public class NetworkUtilsImplTest { } @Test - public void getLocalInetAddress_filters_local_addresses() { + void getLocalInetAddress_filters_local_addresses() { InetAddress address = underTest.getLocalInetAddress(InetAddress::isLoopbackAddress).get(); assertThat(address.isLoopbackAddress()).isTrue(); } @Test - public void getLocalInetAddress_returns_empty_if_no_local_addresses_match() { + void getLocalInetAddress_returns_empty_if_no_local_addresses_match() { Optional<InetAddress> address = underTest.getLocalInetAddress(a -> false); assertThat(address).isEmpty(); } @Test - public void toInetAddress_supports_host_names() { + void toInetAddress_supports_host_names() { assertThat(underTest.toInetAddress("localhost")).isNotEmpty(); // do not test values that require DNS calls. Build must support offline mode. } @Test - public void toInetAddress_supports_ipv4() { + void toInetAddress_supports_ipv4() { assertThat(underTest.toInetAddress("1.2.3.4")).isNotEmpty(); } @Test - public void toInetAddress_supports_ipv6() { + void toInetAddress_supports_ipv6() { assertThat(underTest.toInetAddress("2a01:e34:ef1f:dbb0:c2f6:a978:c5c0:9ccb")).isNotEmpty(); assertThat(underTest.toInetAddress("[2a01:e34:ef1f:dbb0:c2f6:a978:c5c0:9ccb]")).isNotEmpty(); } @Test - public void toInetAddress_returns_empty_on_unvalid_IP_and_hostname() { + void toInetAddress_returns_empty_on_unvalid_IP_and_hostname() { assertThat(underTest.toInetAddress(secure().nextAlphabetic(32))).isEmpty(); } @Test - public void isLoopback_returns_true_on_loopback_address_or_host() { + void isLoopback_returns_true_on_loopback_address_or_host() { InetAddress loopback = InetAddress.getLoopbackAddress(); assertThat(underTest.isLoopback(loopback.getHostAddress())).isTrue(); @@ -122,7 +123,7 @@ public class NetworkUtilsImplTest { } @Test - public void isLoopback_returns_true_on_localhost_address_or_host_if_loopback() { + void isLoopback_returns_true_on_localhost_address_or_host_if_loopback() { try { InetAddress localHost = InetAddress.getLocalHost(); boolean isLoopback = localHost.isLoopbackAddress(); @@ -134,7 +135,7 @@ public class NetworkUtilsImplTest { } @Test - public void isLocal_returns_true_on_loopback_address_or_host() { + void isLocal_returns_true_on_loopback_address_or_host() { InetAddress loopback = InetAddress.getLoopbackAddress(); assertThat(underTest.isLocal(loopback.getHostAddress())).isTrue(); @@ -142,7 +143,7 @@ public class NetworkUtilsImplTest { } @Test - public void isLocal_returns_true_on_localhost_address_or_host() { + void isLocal_returns_true_on_localhost_address_or_host() { try { InetAddress localHost = InetAddress.getLocalHost(); @@ -152,4 +153,18 @@ public class NetworkUtilsImplTest { // ignore, host running the test has no localhost } } + + @Test + void isIpv6Address_returnsAccordingToAddressAndIPv6Preference() { + System.setProperty(PREFER_IPV_6_ADDRESSES, "false"); + assertThat(underTest.isIpv6Address("2001:db8:3::91")).isTrue(); + assertThat(underTest.isIpv6Address("192.168.1.1")).isFalse(); + assertThat(underTest.isIpv6Address("")).isFalse(); + + System.setProperty(PREFER_IPV_6_ADDRESSES, "true"); + assertThat(underTest.isIpv6Address("2001:db8:3::91")).isTrue(); + assertThat(underTest.isIpv6Address("192.168.1.1")).isFalse(); + assertThat(underTest.isIpv6Address("")).isTrue(); + } + } diff --git a/server/sonar-process/src/test/java/org/sonar/process/cluster/hz/HazelcastMemberBuilderTest.java b/server/sonar-process/src/test/java/org/sonar/process/cluster/hz/HazelcastMemberBuilderTest.java index b76089729c9..fd2e6395866 100644 --- a/server/sonar-process/src/test/java/org/sonar/process/cluster/hz/HazelcastMemberBuilderTest.java +++ b/server/sonar-process/src/test/java/org/sonar/process/cluster/hz/HazelcastMemberBuilderTest.java @@ -19,97 +19,74 @@ */ package org.sonar.process.cluster.hz; -import java.net.InetAddress; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.DisableOnDebug; -import org.junit.rules.TestRule; -import org.junit.rules.Timeout; -import org.sonar.process.NetworkUtilsImpl; +import com.hazelcast.config.Config; +import com.hazelcast.config.InterfacesConfig; +import com.hazelcast.config.JoinConfig; +import com.hazelcast.config.NetworkConfig; +import com.hazelcast.config.TcpIpConfig; +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import org.assertj.core.api.InstanceOfAssertFactories; +import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.ArgumentCaptor; +import org.mockito.MockedStatic; import org.sonar.process.ProcessId; +import org.sonar.process.ProcessProperties; +import static org.assertj.core.api.Assertions.as; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class HazelcastMemberBuilderTest { - - @Rule - public TestRule safeguardTimeout = new DisableOnDebug(Timeout.seconds(60)); - - // use loopback for support of offline builds - private final InetAddress loopback = InetAddress.getLoopbackAddress(); - - @Test - public void build_tcp_ip_member_hostaddress() { - HazelcastMember member = new HazelcastMemberBuilder(JoinConfigurationType.TCP_IP) - .setMembers(loopback.getHostAddress()) - .setProcessId(ProcessId.COMPUTE_ENGINE) - .setNodeName("bar") - .setPort(NetworkUtilsImpl.INSTANCE.getNextLoopbackAvailablePort()) - .setNetworkInterface(loopback.getHostAddress()) - .build(); - - assertThat(member.getUuid()).isNotNull(); - assertThat(member.getClusterTime()).isPositive(); - assertThat(member.getCluster().getMembers()).hasSize(1); - assertThat(member.getMemberUuids()).containsOnlyOnce(member.getUuid()); - - assertThat(member.getAtomicReference("baz")).isNotNull(); - assertThat(member.getLock("baz")).isNotNull(); - assertThat(member.getReplicatedMap("baz")).isNotNull(); - - member.close(); - } - - @Test - public void build_tcp_ip_member_hostname() { - HazelcastMember member = new HazelcastMemberBuilder(JoinConfigurationType.TCP_IP) - .setMembers(loopback.getHostName()) +import static org.mockito.ArgumentCaptor.forClass; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; + + +@Timeout(60) +class HazelcastMemberBuilderTest { + + @CsvSource({ + "::1,[::1]:9003", + "[::1],[::1]:9003", + "[::1]:5000,[::1]:5000", + "127.0.0.1,127.0.0.1:9003", + "127.0.0.1:5000,127.0.0.1:5000" + }) + @ParameterizedTest + void add_default_port_to_member(String memberParam, String memberAddress) { + try (MockedStatic<Hazelcast> mockedHazelcast = mockStatic(Hazelcast.class)) { + ArgumentCaptor<Config> configCaptor = forClass(Config.class); + mockedHazelcast.when(() -> Hazelcast.newHazelcastInstance(configCaptor.capture())) + .thenReturn(mock(HazelcastInstance.class)); + + int defaultPort = Integer.parseInt(ProcessProperties.Property.CLUSTER_NODE_HZ_PORT.getDefaultValue()); + new HazelcastMemberBuilder(JoinConfigurationType.TCP_IP) + .setMembers(memberParam) .setProcessId(ProcessId.COMPUTE_ENGINE) .setNodeName("bar") - .setPort(NetworkUtilsImpl.INSTANCE.getNextLoopbackAvailablePort()) - .setNetworkInterface(loopback.getHostAddress()) + .setPort(defaultPort) + .setNetworkInterface("127.0.0.1") .build(); - assertThat(member.getUuid()).isNotNull(); - assertThat(member.getClusterTime()).isPositive(); - assertThat(member.getCluster().getMembers()).hasSize(1); - assertThat(member.getMemberUuids()).containsOnlyOnce(member.getUuid()); - - assertThat(member.getAtomicReference("baz")).isNotNull(); - assertThat(member.getLock("baz")).isNotNull(); - assertThat(member.getReplicatedMap("baz")).isNotNull(); - - member.close(); - } - - @Test - public void build_kubernetes_member() { - HazelcastMember member = new HazelcastMemberBuilder(JoinConfigurationType.KUBERNETES) - .setMembers(loopback.getHostAddress()) - .setProcessId(ProcessId.COMPUTE_ENGINE) - .setNodeName("bar") - .setPort(NetworkUtilsImpl.INSTANCE.getNextLoopbackAvailablePort()) - .setNetworkInterface(loopback.getHostAddress()) - .build(); - - assertThat(member.getUuid()).isNotNull(); - assertThat(member.getClusterTime()).isPositive(); - assertThat(member.getCluster().getMembers()).hasSize(1); - assertThat(member.getMemberUuids()).containsOnlyOnce(member.getUuid()); - - assertThat(member.getAtomicReference("baz")).isNotNull(); - assertThat(member.getLock("baz")).isNotNull(); - assertThat(member.getReplicatedMap("baz")).isNotNull(); - - member.close(); - } - - @Test - public void fail_if_elasticsearch_process() { - var builder = new HazelcastMemberBuilder(JoinConfigurationType.TCP_IP); - assertThatThrownBy(() -> builder.setProcessId(ProcessId.ELASTICSEARCH)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Hazelcast must not be enabled on Elasticsearch node"); + Config config = configCaptor.getValue(); + + assertThat(config.getNetworkConfig()) + .extracting(NetworkConfig::getPort) + .isEqualTo(defaultPort); + + assertThat(config.getNetworkConfig()) + .extracting(NetworkConfig::getInterfaces) + .extracting(InterfacesConfig::getInterfaces, as(InstanceOfAssertFactories.COLLECTION)) + .hasSize(1).element(0) + .isEqualTo("127.0.0.1"); + + assertThat(config.getNetworkConfig()) + .extracting(NetworkConfig::getJoin) + .extracting(JoinConfig::getTcpIpConfig) + .extracting(TcpIpConfig::getMembers) + .asInstanceOf(InstanceOfAssertFactories.LIST) + .hasSize(1).element(0) + .isEqualTo(memberAddress); + } } } diff --git a/server/sonar-server-common/src/it/java/org/sonar/server/issue/notification/NewIssuesNotificationIT.java b/server/sonar-server-common/src/it/java/org/sonar/server/issue/notification/NewIssuesNotificationIT.java index 5ff60803404..aa69e44aa0d 100644 --- a/server/sonar-server-common/src/it/java/org/sonar/server/issue/notification/NewIssuesNotificationIT.java +++ b/server/sonar-server-common/src/it/java/org/sonar/server/issue/notification/NewIssuesNotificationIT.java @@ -39,8 +39,8 @@ import static org.apache.commons.lang3.RandomStringUtils.secure; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.ASSIGNEE; diff --git a/server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexIT.java b/server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexIT.java index 20f90793e08..c218b8759d7 100644 --- a/server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexIT.java +++ b/server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexIT.java @@ -74,10 +74,10 @@ import static org.sonar.api.rule.Severity.BLOCKER; import static org.sonar.api.rule.Severity.CRITICAL; import static org.sonar.api.rule.Severity.MAJOR; import static org.sonar.api.rule.Severity.MINOR; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.core.config.MQRModeConstants.MULTI_QUALITY_MODE_ENABLED; import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection; import static org.sonar.db.rule.RuleTesting.newRule; diff --git a/server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexerIT.java b/server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexerIT.java index 29660645356..fc405598bf8 100644 --- a/server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexerIT.java +++ b/server/sonar-server-common/src/it/java/org/sonar/server/rule/index/RuleIndexerIT.java @@ -34,7 +34,7 @@ import org.junit.runner.RunWith; import org.slf4j.event.Level; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.testfixtures.log.LogTester; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSmtpConfiguration.java b/server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSmtpConfiguration.java index fdb82e52af1..b69faf6ea80 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSmtpConfiguration.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSmtpConfiguration.java @@ -20,10 +20,14 @@ package org.sonar.server.email; import org.sonar.api.ce.ComputeEngineSide; +import org.sonar.api.config.internal.Encryption; +import org.sonar.api.config.internal.Settings; import org.sonar.api.server.ServerSide; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import static org.sonar.api.CoreProperties.ENCRYPTION_SECRET_KEY_PATH; + @ServerSide @ComputeEngineSide public class EmailSmtpConfiguration { @@ -62,9 +66,11 @@ public class EmailSmtpConfiguration { public static final String EMAIL_CONFIG_SMTP_OAUTH_GRANT_DEFAULT = "client_credentials"; private final DbClient dbClient; + private final Encryption encryption; - public EmailSmtpConfiguration(DbClient dbClient) { + public EmailSmtpConfiguration(DbClient dbClient, Settings settings) { this.dbClient = dbClient; + this.encryption = new Encryption(settings.getRawString(ENCRYPTION_SECRET_KEY_PATH).orElse(null)); } public String getSmtpHost() { @@ -129,8 +135,20 @@ public class EmailSmtpConfiguration { private String get(String key, String defaultValue) { try (DbSession dbSession = dbClient.openSession(false)) { - return dbClient.internalPropertiesDao().selectByKey(dbSession, key).orElse(defaultValue); + return dbClient.internalPropertiesDao().selectByKey(dbSession, key) + .map(value -> decryptIfNeeded(key, value)) + .orElse(defaultValue); } } + private String decryptIfNeeded(String key, String value) { + if (!encryption.isEncrypted(value)) { + return value; + } + try { + return encryption.decrypt(value); + } catch (Exception e) { + throw new IllegalStateException("Fail to decrypt the property %s. Please check your secret key.".formatted(key), e); + } + } } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/es/EsClientProvider.java b/server/sonar-server-common/src/main/java/org/sonar/server/es/EsClientProvider.java index e3b59850d56..0040303b83b 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/es/EsClientProvider.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/es/EsClientProvider.java @@ -95,6 +95,9 @@ public class EsClientProvider { private static HttpHost toHttpHost(HostAndPort host, Configuration config) { try { String scheme = config.get(CLUSTER_ES_HTTP_KEYSTORE.getKey()).isPresent() ? "https" : HttpHost.DEFAULT_SCHEME_NAME; + if ("true".equalsIgnoreCase(System.getProperty("java.net.preferIPv6Addresses"))) { + return new HttpHost(InetAddress.getByName(host.getHost()), host.getHost(), host.getPortOrDefault(9001), scheme); + } return new HttpHost(InetAddress.getByName(host.getHost()), host.getPortOrDefault(9001), scheme); } catch (UnknownHostException e) { throw new IllegalStateException("Can not resolve host [" + host + "]", e); diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/IssueFieldsSetter.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/IssueFieldsSetter.java index a6a78237d8c..3e126f4cfdc 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/IssueFieldsSetter.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/IssueFieldsSetter.java @@ -34,7 +34,6 @@ import org.sonar.api.issue.IssueStatus; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; import org.sonar.api.server.ServerSide; import org.sonar.api.server.rule.RuleTagFormat; import org.sonar.api.utils.Duration; @@ -43,6 +42,7 @@ import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.DefaultIssueComment; import org.sonar.core.issue.IssueChangeContext; import org.sonar.core.rule.ImpactSeverityMapper; +import org.sonar.core.rule.RuleType; import org.sonar.db.protobuf.DbIssues; import org.sonar.db.user.UserDto; import org.sonar.db.user.UserIdDto; @@ -51,6 +51,7 @@ import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Strings.isNullOrEmpty; import static java.util.Objects.requireNonNull; import static org.sonar.api.server.rule.internal.ImpactMapper.convertToSoftwareQuality; +import static org.sonar.core.rule.RuleTypeMapper.toApiRuleType; /** * Updates issue fields and chooses if changes must be kept in history. @@ -505,7 +506,7 @@ public class IssueFieldsSetter { && issue.getImpacts().stream().noneMatch(DefaultImpact::manualSeverity)) { issue.getImpacts() .stream() - .filter(i -> convertToSoftwareQuality(issue.type()).equals(i.softwareQuality())) + .filter(i -> convertToSoftwareQuality(toApiRuleType(issue.type())).equals(i.softwareQuality())) .forEach(i -> { Severity newSeverity = ImpactSeverityMapper.mapImpactSeverity(issue.severity()); issue.addImpact(i.softwareQuality(), newSeverity, true); diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/TaintChecker.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/TaintChecker.java index d30043dfc8c..972f06e0366 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/TaintChecker.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/TaintChecker.java @@ -27,7 +27,7 @@ import java.util.Map; import java.util.function.Predicate; import org.jetbrains.annotations.NotNull; import org.sonar.api.config.Configuration; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssue; import org.sonar.db.issue.IssueDto; diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java index 732cf909e76..4f044ecc2e0 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java @@ -28,7 +28,7 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.server.es.BaseDoc; import org.sonar.server.permission.index.AuthorizationDoc; diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java index 13753a919e4..676a6284b61 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java @@ -32,7 +32,7 @@ import org.apache.ibatis.cursor.Cursor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RulesDefinition.StigVersion; import org.sonar.db.DatabaseUtils; import org.sonar.db.DbClient; @@ -126,7 +126,7 @@ class IssueIteratorForSingleChunk implements IssueIterator { doc.setProjectUuid(projectUuid); String tags = indexedIssueDto.getTags(); doc.setTags(STRING_LIST_SPLITTER.splitToList(tags == null ? "" : tags)); - doc.setType(RuleType.valueOf(indexedIssueDto.getIssueType())); + doc.setType(RuleType.fromDbConstant(indexedIssueDto.getIssueType())); doc.setImpacts(indexedIssueDto.getEffectiveImpacts()); SecurityStandards securityStandards = fromSecurityStandards(deserializeSecurityStandardsString(indexedIssueDto.getSecurityStandards())); SecurityStandards.SQCategory sqCategory = securityStandards.getSqCategory(); diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/PrStatistics.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/PrStatistics.java index ffb6621ce11..4ff2e9439ac 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/PrStatistics.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/PrStatistics.java @@ -20,11 +20,11 @@ package org.sonar.server.issue.index; import java.util.Map; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.VULNERABILITY; public class PrStatistics { diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssueChangesEmailTemplate.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssueChangesEmailTemplate.java index 45dd3cf054e..4fa964f5a83 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssueChangesEmailTemplate.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssueChangesEmailTemplate.java @@ -37,7 +37,7 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import javax.annotation.Nullable; import org.sonar.api.platform.Server; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.i18n.I18n; import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.ChangedIssue; import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.Project; diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssuesChangesNotificationBuilder.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssuesChangesNotificationBuilder.java index c0abb5da858..5976c611b8e 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssuesChangesNotificationBuilder.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssuesChangesNotificationBuilder.java @@ -28,7 +28,7 @@ import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; import org.sonar.api.issue.IssueStatus; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/RuleGroup.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/RuleGroup.java index 2727b76d224..9eb28474e79 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/RuleGroup.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/RuleGroup.java @@ -21,9 +21,9 @@ package org.sonar.server.issue.notification; import java.util.Collection; import javax.annotation.Nullable; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; enum RuleGroup { SECURITY_HOTSPOTS, diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/Function.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/Function.java index 36ce293b74a..7db3488f20e 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/Function.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/Function.java @@ -21,7 +21,7 @@ package org.sonar.server.issue.workflow; import javax.annotation.Nullable; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.user.UserDto; @FunctionalInterface diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/FunctionExecutor.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/FunctionExecutor.java index 6f9aad9e28a..bfd542fcb76 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/FunctionExecutor.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/FunctionExecutor.java @@ -22,7 +22,7 @@ package org.sonar.server.issue.workflow; import javax.annotation.Nullable; import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ServerSide; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.IssueChangeContext; diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/HasType.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/HasType.java index bd8b985dd32..89984133395 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/HasType.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/HasType.java @@ -22,7 +22,7 @@ package org.sonar.server.issue.workflow; import java.util.EnumSet; import java.util.Set; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssue; import static java.util.Arrays.asList; diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IsHotspot.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IsHotspot.java index c9e9e1dca4b..c7f35c31532 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IsHotspot.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IsHotspot.java @@ -20,7 +20,7 @@ package org.sonar.server.issue.workflow; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssue; enum IsHotspot implements Condition { diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IsNotHotspot.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IsNotHotspot.java index ca8245cfbb5..a0eed3b6aad 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IsNotHotspot.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IsNotHotspot.java @@ -20,7 +20,7 @@ package org.sonar.server.issue.workflow; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssue; enum IsNotHotspot implements Condition { diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java index 11716fb7196..5252e2b422c 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java @@ -25,9 +25,9 @@ import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.issue.DefaultTransitions; import org.sonar.api.issue.Issue; import org.sonar.api.issue.IssueStatus; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ServerSide; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.DefaultIssueComment; import org.sonar.core.issue.IssueChangeContext; @@ -84,19 +84,19 @@ public class IssueWorkflow implements Startable { .from(STATUS_OPEN).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) .functions(new SetResolution(RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build()) .transition(Transition.builder(DefaultTransitions.ACCEPT) .from(STATUS_REOPENED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) .functions(new SetResolution(RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build()) .transition(Transition.builder(DefaultTransitions.ACCEPT) .from(STATUS_CONFIRMED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) .functions(new SetResolution(RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build()) // resolve as false-positive @@ -104,19 +104,19 @@ public class IssueWorkflow implements Startable { .from(STATUS_OPEN).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) .functions(new SetResolution(RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build()) .transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE) .from(STATUS_REOPENED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) .functions(new SetResolution(RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build()) .transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE) .from(STATUS_CONFIRMED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) .functions(new SetResolution(RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build()) // reopen @@ -148,19 +148,19 @@ public class IssueWorkflow implements Startable { .from(STATUS_OPEN).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) .functions(new SetResolution(RESOLUTION_FIXED)) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build()) .transition(Transition.builder(DefaultTransitions.RESOLVE) .from(STATUS_REOPENED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) .functions(new SetResolution(RESOLUTION_FIXED)) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build()) .transition(Transition.builder(DefaultTransitions.RESOLVE) .from(STATUS_CONFIRMED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) .functions(new SetResolution(RESOLUTION_FIXED)) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build()) // resolve as won't fix, deprecated @@ -168,19 +168,19 @@ public class IssueWorkflow implements Startable { .from(STATUS_OPEN).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) .functions(new SetResolution(RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build()) .transition(Transition.builder(DefaultTransitions.WONT_FIX) .from(STATUS_REOPENED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) .functions(new SetResolution(RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build()) .transition(Transition.builder(DefaultTransitions.WONT_FIX) .from(STATUS_CONFIRMED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) .functions(new SetResolution(RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build()); } @@ -191,7 +191,7 @@ public class IssueWorkflow implements Startable { .to(STATUS_REVIEWED) .conditions(new HasType(RuleType.SECURITY_HOTSPOT)) .functions(new SetResolution(RESOLUTION_FIXED)) - .requiredProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN); + .requiredProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN); builder .transition(reviewedAsFixedBuilder .from(STATUS_TO_REVIEW) @@ -206,7 +206,7 @@ public class IssueWorkflow implements Startable { Transition.TransitionBuilder resolveAsSafeTransitionBuilder = Transition.builder(DefaultTransitions.RESOLVE_AS_SAFE) .to(STATUS_REVIEWED) .functions(new SetResolution(RESOLUTION_SAFE)) - .requiredProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN); + .requiredProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN); builder .transition(resolveAsSafeTransitionBuilder .from(STATUS_TO_REVIEW) @@ -221,7 +221,7 @@ public class IssueWorkflow implements Startable { Transition.TransitionBuilder resolveAsAcknowledgedTransitionBuilder = Transition.builder(DefaultTransitions.RESOLVE_AS_ACKNOWLEDGED) .to(STATUS_REVIEWED) .functions(new SetResolution(RESOLUTION_ACKNOWLEDGED)) - .requiredProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN); + .requiredProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN); builder .transition(resolveAsAcknowledgedTransitionBuilder .from(STATUS_TO_REVIEW) @@ -238,7 +238,7 @@ public class IssueWorkflow implements Startable { .from(STATUS_REVIEWED).to(STATUS_TO_REVIEW) .conditions(new HasType(RuleType.SECURITY_HOTSPOT), new HasResolution(RESOLUTION_FIXED, RESOLUTION_SAFE, RESOLUTION_ACKNOWLEDGED)) .functions(new SetResolution(null)) - .requiredProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN) + .requiredProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN) .build()); } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/SetType.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/SetType.java index bbfb1440182..865fe452ffb 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/SetType.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/SetType.java @@ -20,7 +20,7 @@ package org.sonar.server.issue.workflow; import javax.annotation.Nullable; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; public class SetType implements Function { private final RuleType type; diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/Transition.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/Transition.java index e1c50f7a15a..5489fb88fdf 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/Transition.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/Transition.java @@ -26,6 +26,7 @@ import java.util.List; import javax.annotation.CheckForNull; import org.apache.commons.lang3.StringUtils; import org.sonar.api.issue.Issue; +import org.sonar.db.permission.ProjectPermission; import static com.google.common.base.Preconditions.checkArgument; @@ -36,7 +37,7 @@ public class Transition { private final Condition[] conditions; private final Function[] functions; private final boolean automatic; - private String requiredProjectPermission; + private ProjectPermission requiredProjectPermission; private Transition(TransitionBuilder builder) { key = builder.key; @@ -82,7 +83,7 @@ public class Transition { } @CheckForNull - public String requiredProjectPermission() { + public ProjectPermission requiredProjectPermission() { return requiredProjectPermission; } @@ -132,7 +133,7 @@ public class Transition { private List<Condition> conditions = Lists.newArrayList(); private List<Function> functions = Lists.newArrayList(); private boolean automatic = false; - private String requiredProjectPermission; + private ProjectPermission requiredProjectPermission; private TransitionBuilder(String key) { this.key = key; @@ -163,7 +164,7 @@ public class Transition { return this; } - public TransitionBuilder requiredProjectPermission(String requiredProjectPermission) { + public TransitionBuilder requiredProjectPermission(ProjectPermission requiredProjectPermission) { this.requiredProjectPermission = requiredProjectPermission; return this; } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/log/DistributedServerLogging.java b/server/sonar-server-common/src/main/java/org/sonar/server/log/DistributedServerLogging.java index a4dcaccefc8..2dd1bf3c8e3 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/log/DistributedServerLogging.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/log/DistributedServerLogging.java @@ -185,12 +185,14 @@ public class DistributedServerLogging extends ServerLogging { String oneTimeToken, ZipOutputStream out) throws IOException { WebAddress addressAndPort = retrieveWebAddressOfAMember(member); String address = addressAndPort.address; + + String context = addressAndPort.context; int port = addressAndPort.port; if (address.equals(localWebAPIAddress.address) && port == localWebAPIAddress.port) { return; } - String url = String.format("http://%s:%d/api/system/logs?name=%s", address, port, logName); + String url = String.format("http://%s:%d%s/api/system/logs?name=%s", address, port, context, logName); Request request = new Request.Builder().url(url) .addHeader(NODE_TO_NODE_SECRET, oneTimeToken) .build(); @@ -228,9 +230,10 @@ public class DistributedServerLogging extends ServerLogging { } private static DistributedCall<WebAddress> askForWebAPIAddress() { - return () -> new WebAddress(ServerLogging.getWebAPIAddressFromHazelcastQuery(), ServerLogging.getWebAPIPortFromHazelcastQuery()); + return () -> new WebAddress(ServerLogging.getWebAPIAddressFromHazelcastQuery(), ServerLogging.getWebAPIContextFromHazelcastQuery(), + ServerLogging.getWebAPIPortFromHazelcastQuery()); } - public record WebAddress(String address, int port) implements Serializable { + public record WebAddress(String address, String context, int port) implements Serializable { } } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/log/ServerLogging.java b/server/sonar-server-common/src/main/java/org/sonar/server/log/ServerLogging.java index 21efc145238..2f3ab7d8899 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/log/ServerLogging.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/log/ServerLogging.java @@ -95,6 +95,10 @@ public class ServerLogging implements Startable { .orElseThrow(() -> new IllegalStateException("No web host found in configuration"))); } + public static String getWebAPIContextFromHazelcastQuery() { + return instance.config.get(ProcessProperties.Property.WEB_CONTEXT.getKey()).orElse(""); + } + public void changeLevel(LoggerLevel level) { Level logbackLevel = Level.toLevel(level.name()); database.enableSqlLogging(level == TRACE); diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java b/server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java index 0c376c2c622..699310a3ec0 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/notification/NotificationManager.java @@ -22,7 +22,7 @@ package org.sonar.server.notification; import java.util.Objects; import java.util.Set; import org.sonar.api.notifications.Notification; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import static java.util.Objects.requireNonNull; @@ -83,15 +83,19 @@ public interface NotificationManager { Set<EmailRecipient> findSubscribedEmailRecipients(String dispatcherKey, String projectKey, Set<String> logins, SubscriberPermissionsOnProject subscriberPermissionsOnProject); final class SubscriberPermissionsOnProject { - public static final SubscriberPermissionsOnProject ALL_MUST_HAVE_ROLE_USER = new SubscriberPermissionsOnProject(UserRole.USER); + public static final SubscriberPermissionsOnProject ALL_MUST_HAVE_ROLE_USER = new SubscriberPermissionsOnProject(ProjectPermission.USER); private final String globalSubscribers; private final String projectSubscribers; - public SubscriberPermissionsOnProject(String globalAndProjectSubscribers) { + public SubscriberPermissionsOnProject(ProjectPermission globalAndProjectSubscribers) { this(globalAndProjectSubscribers, globalAndProjectSubscribers); } + public SubscriberPermissionsOnProject(ProjectPermission globalSubscribers, ProjectPermission projectSubscribers) { + this(globalSubscribers.getKey(), projectSubscribers.getKey()); + } + public SubscriberPermissionsOnProject(String globalSubscribers, String projectSubscribers) { this.globalSubscribers = requireNonNull(globalSubscribers, "global subscribers's required permission can't be null"); this.projectSubscribers = requireNonNull(projectSubscribers, "project subscribers's required permission can't be null"); diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/permission/PermissionService.java b/server/sonar-server-common/src/main/java/org/sonar/server/permission/PermissionService.java index dc6d5731029..28f8b14dd64 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/permission/PermissionService.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/permission/PermissionService.java @@ -21,10 +21,12 @@ package org.sonar.server.permission; import java.util.List; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; public interface PermissionService { List<GlobalPermission> getGlobalPermissions(); - List<String> getAllProjectPermissions(); + + List<ProjectPermission> getAllProjectPermissions(); } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/permission/PermissionServiceImpl.java b/server/sonar-server-common/src/main/java/org/sonar/server/permission/PermissionServiceImpl.java index 230683acec3..cb418c3f213 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/permission/PermissionServiceImpl.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/permission/PermissionServiceImpl.java @@ -19,41 +19,37 @@ */ package org.sonar.server.permission; -import java.util.Collections; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Set; import javax.annotation.concurrent.Immutable; import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentTypes; -import org.sonar.api.web.UserRole; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; +import org.sonar.server.component.ComponentTypes; @Immutable public class PermissionServiceImpl implements PermissionService { - public static final Set<String> ALL_PROJECT_PERMISSIONS = Collections.unmodifiableSet(new LinkedHashSet<>(List.of( - UserRole.ADMIN, - UserRole.CODEVIEWER, - UserRole.ISSUE_ADMIN, - UserRole.SECURITYHOTSPOT_ADMIN, - UserRole.SCAN, - UserRole.USER - ))); + /** + * This particular order seems to be important for some web services. + * Maybe the UI is relying on it? + * That's why we are not relying on {@link ProjectPermission#values()}. + */ + private static final List<ProjectPermission> ALL_PROJECT_PERMISSIONS = List.of( + ProjectPermission.ADMIN, + ProjectPermission.CODEVIEWER, + ProjectPermission.ISSUE_ADMIN, + ProjectPermission.SECURITYHOTSPOT_ADMIN, + ProjectPermission.SCAN, + ProjectPermission.USER); private static final List<GlobalPermission> ALL_GLOBAL_PERMISSIONS = List.of(GlobalPermission.values()); private final List<GlobalPermission> globalPermissions; - private final List<String> projectPermissions; public PermissionServiceImpl(ComponentTypes componentTypes) { globalPermissions = List.copyOf(ALL_GLOBAL_PERMISSIONS.stream() .filter(s -> !s.equals(GlobalPermission.APPLICATION_CREATOR) || componentTypes.isQualifierPresent(ComponentQualifiers.APP)) .filter(s -> !s.equals(GlobalPermission.PORTFOLIO_CREATOR) || componentTypes.isQualifierPresent(ComponentQualifiers.VIEW)) .toList()); - projectPermissions = List.copyOf(ALL_PROJECT_PERMISSIONS.stream() - .filter(s -> !s.equals(GlobalPermission.APPLICATION_CREATOR.getKey()) || componentTypes.isQualifierPresent(ComponentQualifiers.APP)) - .filter(s -> !s.equals(GlobalPermission.PORTFOLIO_CREATOR.getKey()) || componentTypes.isQualifierPresent(ComponentQualifiers.VIEW)) - .toList()); } /** @@ -68,7 +64,7 @@ public class PermissionServiceImpl implements PermissionService { * Return an immutable Set of all project permissions */ @Override - public List<String> getAllProjectPermissions() { - return projectPermissions; + public List<ProjectPermission> getAllProjectPermissions() { + return ALL_PROJECT_PERMISSIONS; } } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/project/VisibilityService.java b/server/sonar-server-common/src/main/java/org/sonar/server/project/VisibilityService.java index 3fe64754141..dbaa63f2496 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/project/VisibilityService.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/project/VisibilityService.java @@ -39,7 +39,7 @@ import org.sonar.server.es.Indexers; import static java.util.Collections.singletonList; import static java.util.Optional.ofNullable; import static org.sonar.api.utils.Preconditions.checkState; -import static org.sonar.api.web.UserRole.PUBLIC_PERMISSIONS; +import static org.sonar.db.permission.ProjectPermission.PUBLIC_PERMISSIONS; import static org.sonar.db.ce.CeTaskTypes.GITHUB_PROJECT_PERMISSIONS_PROVISIONING; import static org.sonar.db.ce.CeTaskTypes.GITLAB_PROJECT_PERMISSIONS_PROVISIONING; @@ -110,10 +110,10 @@ public class VisibilityService { dbClient.groupPermissionDao().deleteByEntityUuidForAnyOne(dbSession, entity); // grant UserRole.CODEVIEWER and UserRole.USER to any group or user with at least one permission on project PUBLIC_PERMISSIONS.forEach(permission -> { - dbClient.groupPermissionDao().selectGroupUuidsWithPermissionOnEntityBut(dbSession, entity.getUuid(), permission) - .forEach(group -> insertProjectPermissionOnGroup(dbSession, entity, permission, group)); - dbClient.userPermissionDao().selectUserIdsWithPermissionOnEntityBut(dbSession, entity.getUuid(), permission) - .forEach(userUuid -> insertProjectPermissionOnUser(dbSession, entity, permission, userUuid)); + dbClient.groupPermissionDao().selectGroupUuidsWithPermissionOnEntityBut(dbSession, entity.getUuid(), permission.getKey()) + .forEach(group -> insertProjectPermissionOnGroup(dbSession, entity, permission.getKey(), group)); + dbClient.userPermissionDao().selectUserIdsWithPermissionOnEntityBut(dbSession, entity.getUuid(), permission.getKey()) + .forEach(userUuid -> insertProjectPermissionOnUser(dbSession, entity, permission.getKey(), userUuid)); }); } @@ -136,9 +136,9 @@ public class VisibilityService { private void updatePermissionsToPublic(DbSession dbSession, EntityDto entity) { PUBLIC_PERMISSIONS.forEach(permission -> { // delete project group permission for UserRole.CODEVIEWER and UserRole.USER - dbClient.groupPermissionDao().deleteByEntityAndPermission(dbSession, permission, entity); + dbClient.groupPermissionDao().deleteByEntityAndPermission(dbSession, permission.getKey(), entity); // delete project user permission for UserRole.CODEVIEWER and UserRole.USER - dbClient.userPermissionDao().deleteEntityPermissionOfAnyUser(dbSession, permission, entity); + dbClient.userPermissionDao().deleteEntityPermissionOfAnyUser(dbSession, permission.getKey(), entity); }); } } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java index 15d352a81b2..ae66aec98a8 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java @@ -35,7 +35,7 @@ import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.issue.ImpactDto; import org.sonar.db.rule.RuleDescriptionSectionDto; import org.sonar.db.rule.RuleDto; @@ -349,7 +349,7 @@ public class RuleDoc extends BaseDoc { @CheckForNull private static RuleType getType(RuleForIndexingDto dto) { if (dto.isAdHoc() && dto.getAdHocType() != null) { - return RuleType.valueOf(dto.getAdHocType()); + return RuleType.fromDbConstant(dto.getAdHocType()); } return dto.getTypeAsRuleType(); } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java index 89cd15fe4f8..3f443234135 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java @@ -57,7 +57,7 @@ import org.sonar.api.config.Configuration; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.db.qualityprofile.QProfileDto; import org.sonar.server.es.EsClient; @@ -82,8 +82,8 @@ import static org.elasticsearch.index.query.QueryBuilders.nestedQuery; import static org.elasticsearch.index.query.QueryBuilders.termsQuery; import static org.elasticsearch.search.aggregations.AggregationBuilders.filters; import static org.elasticsearch.search.aggregations.AggregationBuilders.reverseNested; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.core.config.MQRModeConstants.MULTI_QUALITY_MODE_DEFAULT_VALUE; import static org.sonar.core.config.MQRModeConstants.MULTI_QUALITY_MODE_ENABLED; import static org.sonar.server.es.EsUtils.SCROLL_TIME_IN_MINUTES; diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java index d949c2aaf9f..d0904071684 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java @@ -25,7 +25,7 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.qualityprofile.QProfileDto; import static java.util.Arrays.asList; diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/setting/ThreadLocalSettings.java b/server/sonar-server-common/src/main/java/org/sonar/server/setting/ThreadLocalSettings.java index 92ffa498023..1786a62e90f 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/setting/ThreadLocalSettings.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/setting/ThreadLocalSettings.java @@ -20,13 +20,13 @@ package org.sonar.server.setting; import com.google.common.annotations.VisibleForTesting; +import jakarta.inject.Inject; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Properties; -import jakarta.inject.Inject; import org.apache.ibatis.exceptions.PersistenceException; import org.sonar.api.CoreProperties; import org.sonar.api.ce.ComputeEngineSide; diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/email/EmailSmtpConfigurationTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/email/EmailSmtpConfigurationTest.java new file mode 100644 index 00000000000..94a47b844b7 --- /dev/null +++ b/server/sonar-server-common/src/test/java/org/sonar/server/email/EmailSmtpConfigurationTest.java @@ -0,0 +1,82 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.email; + + +import java.io.File; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.sonar.api.config.internal.Encryption; +import org.sonar.api.config.internal.Settings; +import org.sonar.db.DbClient; +import org.sonar.db.property.InternalPropertiesDao; + +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.api.CoreProperties.ENCRYPTION_SECRET_KEY_PATH; +import static org.sonar.server.email.EmailSmtpConfiguration.EMAIL_CONFIG_FROM; +import static org.sonar.server.email.EmailSmtpConfiguration.EMAIL_CONFIG_SMTP_PASSWORD; + +class EmailSmtpConfigurationTest { + + DbClient dbClientMock = mock(DbClient.class); + InternalPropertiesDao internalPropertiesDaoMock = mock(InternalPropertiesDao.class); + Settings settings = mock(Settings.class); + EmailSmtpConfiguration smtpConfiguration; + + @BeforeEach + void beforeEach() { + when(dbClientMock.internalPropertiesDao()).thenReturn(internalPropertiesDaoMock); + when(settings.getRawString(ENCRYPTION_SECRET_KEY_PATH)).thenReturn(Optional.of(pathToSecretKey())); + smtpConfiguration = new EmailSmtpConfiguration(dbClientMock, settings); + } + + @Test + void getValue_whenNoEncryption_shouldReturnOriginalValue() { + when(internalPropertiesDaoMock.selectByKey(any(), eq(EMAIL_CONFIG_FROM))).thenReturn(Optional.of("email-from-value")); + var value = smtpConfiguration.getFrom(); + + assertThat(value).isEqualTo("email-from-value"); + } + + @Test + void getValue_whenStoredInEncryptedFormat_shouldReturnDecryptedValue() { + var encryptedValue = new Encryption(pathToSecretKey()).encrypt("password123"); + + when(internalPropertiesDaoMock.selectByKey(any(), eq(EMAIL_CONFIG_SMTP_PASSWORD))).thenReturn(Optional.of(encryptedValue)); + var value = smtpConfiguration.getSmtpPassword(); + + assertThat(encryptedValue).startsWith("{aes-gcm}"); + assertThat(value).isEqualTo("password123"); + } + + String pathToSecretKey() { + try { + var resource = getClass().getResource("/org/sonar/encryption/aes_secret_key.txt"); + return new File(resource.toURI()).getCanonicalPath(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/IssueFieldsSetterTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/IssueFieldsSetterTest.java index f715b858cf1..7f32d659ffd 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/IssueFieldsSetterTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/IssueFieldsSetterTest.java @@ -35,7 +35,7 @@ import org.sonar.api.issue.IssueStatus; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.core.issue.DefaultImpact; import org.sonar.core.issue.DefaultIssue; diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/IssueStorageTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/IssueStorageTest.java index 99c2131ba70..cdbf30c57cf 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/IssueStorageTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/IssueStorageTest.java @@ -23,7 +23,7 @@ import java.util.Date; import org.junit.Test; import org.mockito.MockedStatic; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.Duration; import org.sonar.core.issue.DefaultIssue; diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/TaintCheckerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/TaintCheckerTest.java index fcf18eba925..8e5073080ad 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/TaintCheckerTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/TaintCheckerTest.java @@ -25,7 +25,7 @@ import java.util.Map; import javax.annotation.Nullable; import org.junit.Test; import org.sonar.api.config.Configuration; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssue; import org.sonar.db.issue.IssueDto; import org.sonar.db.protobuf.DbCommons; diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplateTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplateTest.java index aff59c99a83..53e21adbfb9 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplateTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplateTest.java @@ -37,7 +37,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.sonar.api.notifications.Notification; import org.sonar.api.platform.Server; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.i18n.I18n; import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.AnalysisChange; import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.Change; @@ -65,7 +65,7 @@ import static org.sonar.api.issue.Issue.STATUS_REOPENED; import static org.sonar.api.issue.Issue.STATUS_RESOLVED; import static org.sonar.api.issue.Issue.STATUS_REVIEWED; import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.server.issue.notification.IssuesChangesNotificationBuilderTesting.newAnalysisChange; import static org.sonar.server.issue.notification.IssuesChangesNotificationBuilderTesting.newBranch; import static org.sonar.server.issue.notification.IssuesChangesNotificationBuilderTesting.newChangedIssue; diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/FpPrAcceptedEmailTemplateTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/FpPrAcceptedEmailTemplateTest.java index 1d01ff0ad4f..20e1d04c1f3 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/FpPrAcceptedEmailTemplateTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/FpPrAcceptedEmailTemplateTest.java @@ -35,7 +35,7 @@ import org.junit.runner.RunWith; import org.sonar.api.notifications.Notification; import org.sonar.api.platform.Server; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.i18n.I18n; import org.sonar.server.issue.notification.FPOrAcceptedNotification.FpPrAccepted; import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.AnalysisChange; @@ -53,7 +53,7 @@ import static org.apache.commons.lang3.RandomStringUtils.secure; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.server.issue.notification.FPOrAcceptedNotification.FpPrAccepted.ACCEPTED; import static org.sonar.server.issue.notification.FPOrAcceptedNotification.FpPrAccepted.FP; import static org.sonar.server.issue.notification.IssuesChangesNotificationBuilderTesting.newRandomNotAHotspotRule; diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/IssuesChangesNotificationBuilderTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/IssuesChangesNotificationBuilderTest.java index 8eb787b42f9..6d6513ec151 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/IssuesChangesNotificationBuilderTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/IssuesChangesNotificationBuilderTest.java @@ -30,7 +30,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.sonar.api.issue.IssueStatus; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.AnalysisChange; import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.ChangedIssue; diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/IssuesChangesNotificationSerializerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/IssuesChangesNotificationSerializerTest.java index fa26db55f80..fde3169cd39 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/IssuesChangesNotificationSerializerTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/IssuesChangesNotificationSerializerTest.java @@ -24,7 +24,7 @@ import java.util.Set; import java.util.stream.IntStream; import org.junit.Test; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import static java.util.stream.Collectors.toSet; @@ -43,7 +43,7 @@ public class IssuesChangesNotificationSerializerTest { .mapToObj(i -> new IssuesChangesNotificationBuilder.ChangedIssue.Builder("issue_key_" + i) .setNewStatus("foo") .setAssignee(null) - .setRule(newRule("repository", "key" + i, RuleType.valueOf(i), "name" + i)) + .setRule(newRule("repository", "key" + i, RuleType.fromDbConstant(i), "name" + i)) .setProject(newProject(i + "")) .build()) .collect(toSet()); @@ -62,7 +62,7 @@ public class IssuesChangesNotificationSerializerTest { .mapToObj(i -> new IssuesChangesNotificationBuilder.ChangedIssue.Builder("issue_key_" + i) .setNewStatus("foo") .setAssignee(null) - .setRule(newRule("repository", "key" + i, RuleType.valueOf(i), "name" + i)) + .setRule(newRule("repository", "key" + i, RuleType.fromDbConstant(i), "name" + i)) .setProject(newProject(i + "")) .build()) .collect(toSet()); diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewIssuesStatisticsTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewIssuesStatisticsTest.java index 64f503059d7..c0f8565260a 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewIssuesStatisticsTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewIssuesStatisticsTest.java @@ -31,7 +31,7 @@ import javax.annotation.CheckForNull; import org.junit.jupiter.api.Test; import org.sonar.api.issue.Issue; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.core.issue.DefaultIssue; import org.sonar.server.issue.notification.NewIssuesStatistics.Metric; diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java index 0848e232b67..9cc73ebf555 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java @@ -53,7 +53,7 @@ import static org.sonar.api.issue.Issue.RESOLUTION_SAFE; import static org.sonar.api.issue.Issue.STATUS_CLOSED; import static org.sonar.api.issue.Issue.STATUS_REVIEWED; import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.core.issue.IssueChangeContext.issueChangeContextByScanBuilder; import static org.sonar.core.issue.IssueChangeContext.issueChangeContextByUserBuilder; import static org.sonar.db.rule.RuleTesting.XOO_X1; diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/TransitionTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/TransitionTest.java index bd5a2621ab2..702f906f96b 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/TransitionTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/TransitionTest.java @@ -20,7 +20,7 @@ package org.sonar.server.issue.workflow; import org.junit.Test; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.issue.DefaultIssue; import static org.assertj.core.api.Assertions.assertThat; @@ -41,7 +41,7 @@ public class TransitionTest { .from("OPEN").to("CLOSED") .conditions(condition1, condition2) .functions(function1, function2) - .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .requiredProjectPermission(ProjectPermission.ISSUE_ADMIN) .build(); assertThat(transition.key()).isEqualTo("close"); assertThat(transition.from()).isEqualTo("OPEN"); @@ -49,7 +49,7 @@ public class TransitionTest { assertThat(transition.conditions()).containsOnly(condition1, condition2); assertThat(transition.functions()).containsOnly(function1, function2); assertThat(transition.automatic()).isFalse(); - assertThat(transition.requiredProjectPermission()).isEqualTo(UserRole.ISSUE_ADMIN); + assertThat(transition.requiredProjectPermission()).isEqualTo(ProjectPermission.ISSUE_ADMIN); } @Test diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/log/DistributedServerLoggingTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/log/DistributedServerLoggingTest.java index 40658ad7e2d..bbb21ea871a 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/log/DistributedServerLoggingTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/log/DistributedServerLoggingTest.java @@ -86,7 +86,7 @@ public class DistributedServerLoggingTest { DistributedAnswer<Object> answer = mock(); when(hazelcastMember.call(any(), any(), anyLong())).thenReturn(answer); - when(answer.getSingleAnswer()).thenReturn(Optional.of(new DistributedServerLogging.WebAddress("anyhost", 9000))); + when(answer.getSingleAnswer()).thenReturn(Optional.of(new DistributedServerLogging.WebAddress("anyhost", "", 9000))); when(hazelcastMember.getUuid()).thenReturn(UUID.fromString("00000000-0000-0000-0000-000000000000")); when(member1.getUuid()).thenReturn(UUID.fromString("00000000-0000-0000-0000-000000000001")); when(member2.getUuid()).thenReturn(UUID.fromString("00000000-0000-0000-0000-000000000002")); diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/log/ServerLoggingTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/log/ServerLoggingTest.java index 65cfdcb6c4c..fc9df7940a0 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/log/ServerLoggingTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/log/ServerLoggingTest.java @@ -231,4 +231,12 @@ public class ServerLoggingTest { assertThat(ServerLogging.getWebAPIAddressFromHazelcastQuery()).isEqualTo("anyhost"); } + + @Test + public void getWebAPIAddressFromHazelcastQuery_whenSpecified_shouldReturnContext() { + underTest.start(); + settings.setProperty(ProcessProperties.Property.WEB_CONTEXT.getKey(), "any_context"); + + assertThat(ServerLogging.getWebAPIContextFromHazelcastQuery()).isEqualTo("any_context"); + } } diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/permission/PermissionServiceImplTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/permission/PermissionServiceImplTest.java index 4c4221e3c52..d3da292bb12 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/permission/PermissionServiceImplTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/permission/PermissionServiceImplTest.java @@ -20,26 +20,28 @@ package org.sonar.server.permission; import org.junit.Test; -import org.sonar.server.component.ComponentTypesRule; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; +import org.sonar.server.component.ComponentTypesRule; import static org.assertj.core.api.Assertions.assertThat; public class PermissionServiceImplTest { - private ComponentTypesRule resourceTypesRule = new ComponentTypesRule().setRootQualifiers("APP", "VW"); - private PermissionServiceImpl underTest = new PermissionServiceImpl(resourceTypesRule); + private final ComponentTypesRule resourceTypesRule = new ComponentTypesRule().setRootQualifiers("APP", "VW"); + private final PermissionServiceImpl underTest = new PermissionServiceImpl(resourceTypesRule); @Test public void globalPermissions_must_be_ordered() { assertThat(underTest.getGlobalPermissions()) .extracting(GlobalPermission::getKey) - .containsExactly("admin", "gateadmin", "profileadmin", "provisioning", "scan", "applicationcreator", "portfoliocreator"); + .containsExactlyInAnyOrder("admin", "gateadmin", "profileadmin", "provisioning", "scan", "applicationcreator", "portfoliocreator"); } @Test public void projectPermissions_must_be_ordered() { assertThat(underTest.getAllProjectPermissions()) - .containsExactly("admin", "codeviewer", "issueadmin", "securityhotspotadmin", "scan", "user"); + .extracting(ProjectPermission::getKey) + .containsExactlyInAnyOrder("admin", "codeviewer", "issueadmin", "securityhotspotadmin", "scan", "user"); } } diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/permission/index/PermissionIndexerDaoIT.java b/server/sonar-server-common/src/test/java/org/sonar/server/permission/index/PermissionIndexerDaoIT.java index d51e582eb6c..29e248263c1 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/permission/index/PermissionIndexerDaoIT.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/permission/index/PermissionIndexerDaoIT.java @@ -48,8 +48,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.db.component.ComponentQualifiers.APP; import static org.sonar.db.component.ComponentQualifiers.PROJECT; import static org.sonar.db.component.ComponentQualifiers.VIEW; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; public class PermissionIndexerDaoIT { diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/permission/index/PermissionIndexerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/permission/index/PermissionIndexerTest.java index 7f706879735..e5cd24dd872 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/permission/index/PermissionIndexerTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/permission/index/PermissionIndexerTest.java @@ -43,8 +43,8 @@ import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.db.component.ComponentQualifiers.PROJECT; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.es.Indexers.EntityEvent.PERMISSION_CHANGE; import static org.sonar.server.permission.index.IndexAuthorizationConstants.TYPE_AUTHORIZATION; diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java index a4cb48a9fce..fb26dd5cc1e 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java @@ -20,7 +20,7 @@ package org.sonar.server.rule; import org.junit.Test; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.rule.RuleDescriptionSectionDto; import org.sonar.db.rule.RuleDto; diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleDocTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleDocTest.java index a176360b748..21eff8259fc 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleDocTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleDocTest.java @@ -22,7 +22,7 @@ package org.sonar.server.rule.index; import java.util.Set; import org.junit.Test; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.rule.RuleDescriptionSectionContextDto; import org.sonar.db.rule.RuleDescriptionSectionDto; import org.sonar.db.rule.RuleDto; diff --git a/server/sonar-server-common/src/test/resources/org/sonar/encryption/aes_secret_key.txt b/server/sonar-server-common/src/test/resources/org/sonar/encryption/aes_secret_key.txt new file mode 100644 index 00000000000..65b98c522da --- /dev/null +++ b/server/sonar-server-common/src/test/resources/org/sonar/encryption/aes_secret_key.txt @@ -0,0 +1 @@ +0PZz+G+f8mjr3sPn4+AhHg==
\ No newline at end of file diff --git a/server/sonar-server-common/src/testFixtures/java/org/sonar/server/extension/TestCoreExtension.java b/server/sonar-server-common/src/testFixtures/java/org/sonar/server/extension/TestCoreExtension.java new file mode 100644 index 00000000000..70d2db15815 --- /dev/null +++ b/server/sonar-server-common/src/testFixtures/java/org/sonar/server/extension/TestCoreExtension.java @@ -0,0 +1,75 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.extension; + +import java.util.stream.Stream; +import org.sonar.api.ce.ComputeEngineSide; +import org.sonar.api.server.ServerSide; +import org.sonar.core.extension.CoreExtension; +import org.sonar.core.extension.PlatformLevel; +import org.sonar.db.MyBatisConfExtension; + +public class TestCoreExtension implements CoreExtension { + @Override + public String getName() { + return "mockCoreExtension"; + } + + @Override + public void load(Context context) { + context.addExtensions( + TestBean1.class, + TestBean2.class, + TestBean3.class, + TestBean4.class + ); + } + + @PlatformLevel(1) + @ComputeEngineSide + @ServerSide + public static class TestBean1 implements MyBatisConfExtension { + public boolean called = false; + + @Override + public Stream<Class<?>> getMapperClasses() { + called = true; + return Stream.empty(); + } + } + + @PlatformLevel(2) + @ComputeEngineSide + @ServerSide + public static class TestBean2 { + } + + @PlatformLevel(3) + @ComputeEngineSide + @ServerSide + public static class TestBean3 { + } + + @PlatformLevel(4) + @ComputeEngineSide + @ServerSide + public static class TestBean4 { + } +} diff --git a/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java b/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java index 02cf7e1351b..2118e6f4ef5 100644 --- a/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java +++ b/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/IssueDocTesting.java @@ -27,7 +27,7 @@ import java.util.HashMap; import java.util.Random; import org.sonar.db.component.ComponentScopes; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.util.Uuids; import org.sonar.db.component.ComponentDto; import org.sonar.server.issue.index.IssueDoc; diff --git a/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/notification/IssuesChangesNotificationBuilderTesting.java b/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/notification/IssuesChangesNotificationBuilderTesting.java index ef76560d70f..8e54f6f16f9 100644 --- a/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/notification/IssuesChangesNotificationBuilderTesting.java +++ b/server/sonar-server-common/src/testFixtures/java/org/sonar/server/issue/notification/IssuesChangesNotificationBuilderTesting.java @@ -21,7 +21,7 @@ package org.sonar.server.issue.notification; import java.util.Random; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.DbTester; import org.sonar.db.component.BranchDto; import org.sonar.db.component.ComponentDto; @@ -36,10 +36,10 @@ import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.User import static com.google.common.base.Preconditions.checkArgument; import static org.apache.commons.lang3.RandomStringUtils.secure; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.VULNERABILITY; public class IssuesChangesNotificationBuilderTesting { diff --git a/server/sonar-server-common/src/testFixtures/resources/META-INF/services/org.sonar.core.extension.CoreExtension b/server/sonar-server-common/src/testFixtures/resources/META-INF/services/org.sonar.core.extension.CoreExtension new file mode 100644 index 00000000000..10f22a0a33a --- /dev/null +++ b/server/sonar-server-common/src/testFixtures/resources/META-INF/services/org.sonar.core.extension.CoreExtension @@ -0,0 +1 @@ +org.sonar.server.extension.TestCoreExtension diff --git a/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/Dimension.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/Dimension.java index f3479858bff..4b136272f6c 100644 --- a/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/Dimension.java +++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/Dimension.java @@ -31,7 +31,8 @@ public enum Dimension { USER("user"), PROJECT("project"), LANGUAGE("language"), - ANALYSIS("analysis"); + ANALYSIS("analysis"), + FIX_SUGGESTION("fixsuggestion"); private final String value; diff --git a/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/FixSuggestionMetric.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/FixSuggestionMetric.java new file mode 100644 index 00000000000..e7b079a0b6d --- /dev/null +++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/FixSuggestionMetric.java @@ -0,0 +1,56 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.telemetry.core.schema; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.sonar.telemetry.core.TelemetryDataType; + +import static org.sonar.telemetry.core.Granularity.ADHOC; + +public class FixSuggestionMetric extends InstallationMetric { + + @JsonProperty("fix_suggestion_uuid") + private String fixSuggestionUuid; + + @JsonProperty("project_uuid") + private String projectUuid; + + public FixSuggestionMetric(String key, Object value, TelemetryDataType type, String projectUuid, String fixSuggestionUuid) { + super(key, value, type, ADHOC); + this.projectUuid = projectUuid; + this.fixSuggestionUuid = fixSuggestionUuid; + } + + public String getProjectUuid() { + return projectUuid; + } + + public void setProjectUuid(String projectUuid) { + this.projectUuid = projectUuid; + } + + public String getFixSuggestionUuid() { + return fixSuggestionUuid; + } + + public void setFixSuggestionUuid(String fixSuggestionUuid) { + this.fixSuggestionUuid = fixSuggestionUuid; + } +} diff --git a/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/DimensionTest.java b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/DimensionTest.java index f80c2a971bb..69d77f3716f 100644 --- a/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/DimensionTest.java +++ b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/DimensionTest.java @@ -39,11 +39,13 @@ class DimensionTest { assertEquals(Dimension.USER, Dimension.fromValue("user")); assertEquals(Dimension.PROJECT, Dimension.fromValue("project")); assertEquals(Dimension.LANGUAGE, Dimension.fromValue("language")); + assertEquals(Dimension.FIX_SUGGESTION, Dimension.fromValue("fixsuggestion")); assertEquals(Dimension.INSTALLATION, Dimension.fromValue("INSTALLATION")); assertEquals(Dimension.USER, Dimension.fromValue("USER")); assertEquals(Dimension.PROJECT, Dimension.fromValue("PROJECT")); assertEquals(Dimension.LANGUAGE, Dimension.fromValue("LANGUAGE")); + assertEquals(Dimension.FIX_SUGGESTION, Dimension.fromValue("FIXSUGGESTION")); } @Test diff --git a/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/FixSuggestionMetricTest.java b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/FixSuggestionMetricTest.java new file mode 100644 index 00000000000..4169ca95089 --- /dev/null +++ b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/FixSuggestionMetricTest.java @@ -0,0 +1,51 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.telemetry.core.schema; + +import org.junit.jupiter.api.Test; +import org.sonar.telemetry.core.Granularity; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.telemetry.core.TelemetryDataType.STRING; + +class FixSuggestionMetricTest { + + @Test + void getters() { + FixSuggestionMetric metric = new FixSuggestionMetric("ai_codefix.suggestion_rule_key", "rule:key", STRING, "projectUuid", "fixSuggestionUuid"); + + assertThat(metric.getKey()).isEqualTo("ai_codefix.suggestion_rule_key"); + assertThat(metric.getValue()).isEqualTo("rule:key"); + assertThat(metric.getProjectUuid()).isEqualTo("projectUuid"); + assertThat(metric.getGranularity()).isEqualTo(Granularity.ADHOC); + assertThat(metric.getType()).isEqualTo(STRING); + assertThat(metric.getFixSuggestionUuid()).isEqualTo("fixSuggestionUuid"); + } + + @Test + void setters() { + FixSuggestionMetric metric = new FixSuggestionMetric("ai_codefix.suggestion_rule_key", "rule:key", STRING, "projectUuid", "fixSuggestionUuid"); + metric.setProjectUuid("newProjectUuid"); + metric.setFixSuggestionUuid("newFixSuggestionUuid"); + + assertThat(metric.getProjectUuid()).isEqualTo("newProjectUuid"); + assertThat(metric.getFixSuggestionUuid()).isEqualTo("newFixSuggestionUuid"); + } +} diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/TelemetryDaemon.java b/server/sonar-telemetry/src/main/java/org/sonar/telemetry/TelemetryDaemon.java index 8d6ac35d955..8969fd3d675 100644 --- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/TelemetryDaemon.java +++ b/server/sonar-telemetry/src/main/java/org/sonar/telemetry/TelemetryDaemon.java @@ -116,27 +116,28 @@ public class TelemetryDaemon extends AbstractStoppableScheduledExecutorServiceIm private Runnable telemetryCommand() { return () -> { - if (!lockManager.tryLock(LOCK_NAME, lockDuration())) { - return; - } - - long now = system2.now(); try { + if (!lockManager.tryLock(LOCK_NAME, lockDuration())) { + return; + } + + long now = system2.now(); if (shouldUploadStatistics(now)) { uploadLegacyTelemetry(); uploadMetrics(); - writeTelemetrySequence(); + + updateTelemetryProps(now); } } catch (Exception e) { LOG.debug("Error while checking SonarQube statistics: {}", e.getMessage(), e); - } finally { - writeLastPing(now); } // do not check at start up to exclude test instance which are not up for a long time }; } - private void writeTelemetrySequence() { + private void updateTelemetryProps(long now) { + writeLastPing(now); + Optional<String> currentSequence = internalProperties.read(I_PROP_MESSAGE_SEQUENCE); if (currentSequence.isEmpty()) { internalProperties.write(I_PROP_MESSAGE_SEQUENCE, String.valueOf(1)); diff --git a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryDaemonTest.java b/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryDaemonTest.java index 816eaea18b7..8a1b9471019 100644 --- a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryDaemonTest.java +++ b/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryDaemonTest.java @@ -49,6 +49,7 @@ import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.after; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.timeout; @@ -115,32 +116,23 @@ class TelemetryDaemonTest { void start_whenLastPingEarlierThanOneDayAgo_shouldNotSendData() throws IOException { initTelemetrySettingsToDefaultValues(); when(lockManager.tryLock(any(), anyInt())).thenReturn(true); - settings.setProperty("sonar.telemetry.frequencyInSeconds", "1"); long now = system2.now(); long twentyHoursAgo = now - (ONE_HOUR * 20L); - mockDataJsonWriterDoingSomething(); - + long moreThanOneDayAgo = now - ONE_DAY - ONE_HOUR; internalProperties.write("telemetry.lastPing", String.valueOf(twentyHoursAgo)); - underTest.start(); - - verify(client, after(2_000).never()).upload(anyString()); - } - - @Test - void start_whenExceptionThrown_shouldNotRepeatedlySendDataAndLastPingPropIsStillSet() throws IOException { - initTelemetrySettingsToDefaultValues(); - when(lockManager.tryLock(any(), anyInt())).thenReturn(true); settings.setProperty("sonar.telemetry.frequencyInSeconds", "1"); - long today = parseDate("2017-08-01").getTime(); - system2.setNow(today); - settings.removeProperty("telemetry.lastPing"); + when(dataLoader.load()).thenReturn(SOME_TELEMETRY_DATA); mockDataJsonWriterDoingSomething(); - when(dataLoader.load()).thenThrow(new IllegalStateException("Some error was thrown.")); underTest.start(); - verify(client, after(2_000).never()).upload(anyString()); - verify(internalProperties, timeout(4_000)).write("telemetry.lastPing", String.valueOf(today)); + verify(dataJsonWriter, after(2_000).never()).writeTelemetryData(any(JsonWriter.class), same(SOME_TELEMETRY_DATA)); + verify(client, never()).upload(anyString()); + + internalProperties.write("telemetry.lastPing", String.valueOf(moreThanOneDayAgo)); + + verify(client, timeout(2_000)).upload(anyString()); + verify(dataJsonWriter).writeTelemetryData(any(JsonWriter.class), same(SOME_TELEMETRY_DATA)); } @Test @@ -208,6 +200,12 @@ class TelemetryDaemonTest { verify(internalProperties, timeout(4_000)).write("telemetry.messageSeq", "11"); } + private void initTelemetrySettingsToDefaultValues() { + settings.setProperty(SONAR_TELEMETRY_ENABLE.getKey(), SONAR_TELEMETRY_ENABLE.getDefaultValue()); + settings.setProperty(SONAR_TELEMETRY_URL.getKey(), SONAR_TELEMETRY_URL.getDefaultValue()); + settings.setProperty(SONAR_TELEMETRY_FREQUENCY_IN_SECONDS.getKey(), SONAR_TELEMETRY_FREQUENCY_IN_SECONDS.getDefaultValue()); + } + private void mockDataJsonWriterDoingSomething() { doAnswer(t -> { JsonWriter json = t.getArgument(0); @@ -218,10 +216,4 @@ class TelemetryDaemonTest { .writeTelemetryData(any(), any()); } - private void initTelemetrySettingsToDefaultValues() { - settings.setProperty(SONAR_TELEMETRY_ENABLE.getKey(), SONAR_TELEMETRY_ENABLE.getDefaultValue()); - settings.setProperty(SONAR_TELEMETRY_URL.getKey(), SONAR_TELEMETRY_URL.getDefaultValue()); - settings.setProperty(SONAR_TELEMETRY_FREQUENCY_IN_SECONDS.getKey(), SONAR_TELEMETRY_FREQUENCY_IN_SECONDS.getDefaultValue()); - } - } diff --git a/server/sonar-webserver-api/src/it/java/org/sonar/server/plugins/DetectPluginChangeIT.java b/server/sonar-webserver-api/src/it/java/org/sonar/server/plugins/DetectPluginChangeIT.java index 174537211d5..51745d15781 100644 --- a/server/sonar-webserver-api/src/it/java/org/sonar/server/plugins/DetectPluginChangeIT.java +++ b/server/sonar-webserver-api/src/it/java/org/sonar/server/plugins/DetectPluginChangeIT.java @@ -19,6 +19,8 @@ */ package org.sonar.server.plugins; +import java.util.List; +import java.util.Map; import org.junit.Rule; import org.junit.Test; import org.sonar.api.Plugin; @@ -96,6 +98,35 @@ public class DetectPluginChangeIT { } @Test + public void detect_changes_when_forced_refresh() { + addPluginToDb("plugin1", "hash1", PluginDto.Type.BUNDLED); + addPluginToFs("plugin1", "hash1", PluginType.BUNDLED); + addPluginToDb("plugin2", "hash2", PluginDto.Type.EXTERNAL); + addPluginToFs("plugin2", "hash2", PluginType.EXTERNAL); + + dbTester.executeDdl("insert into internal_properties (kee, is_empty, text_value, created_at) values ('plugin.refresh.forced', false, 'true', 12345)"); + + detectPluginChange.start(); + assertThat(detectPluginChange.anyPluginChanged()).isTrue(); + + // Ensure the force refresh flag has been deleted + assertThat(getInternalProperty("plugin.refresh.forced")).isEmpty(); + } + + @Test + public void detect_changes_when_internal_propertiy_has_false_value_should_not_refresh() { + addPluginToDb("plugin1", "hash1", PluginDto.Type.BUNDLED); + addPluginToFs("plugin1", "hash1", PluginType.BUNDLED); + addPluginToDb("plugin2", "hash2", PluginDto.Type.EXTERNAL); + addPluginToFs("plugin2", "hash2", PluginType.EXTERNAL); + + dbTester.executeDdl("insert into internal_properties (kee, is_empty, text_value, created_at) values ('plugin.refresh.forced', false, 'false', 12345)"); + + detectPluginChange.start(); + assertThat(detectPluginChange.anyPluginChanged()).isFalse(); + } + + @Test public void fail_if_start_twice() { detectPluginChange.start(); assertThrows(IllegalStateException.class, detectPluginChange::start); @@ -123,4 +154,7 @@ public class DetectPluginChangeIT { pluginRepository.addPlugin(serverPlugin); } + private List<Map<String, Object>> getInternalProperty(String key) { + return dbTester.select("select * from internal_properties where kee='" + key + "'"); + } } diff --git a/server/sonar-webserver-api/src/main/java/org/sonar/server/exceptions/BadRequestException.java b/server/sonar-webserver-api/src/main/java/org/sonar/server/exceptions/BadRequestException.java index 7e6d7c1cc7c..7c7a1ed8173 100644 --- a/server/sonar-webserver-api/src/main/java/org/sonar/server/exceptions/BadRequestException.java +++ b/server/sonar-webserver-api/src/main/java/org/sonar/server/exceptions/BadRequestException.java @@ -21,6 +21,8 @@ package org.sonar.server.exceptions; import com.google.common.base.MoreObjects; import java.util.List; +import java.util.Optional; +import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; @@ -33,10 +35,16 @@ import static java.util.Arrays.asList; public class BadRequestException extends ServerException { private final transient List<String> errors; + private final transient String relatedField; - BadRequestException(List<String> errors) { + BadRequestException(List<String> errors, @Nullable String relatedField) { super(HTTP_BAD_REQUEST, errors.get(0)); this.errors = errors; + this.relatedField = relatedField; + } + + BadRequestException(List<String> errors) { + this(errors, null); } public static void checkRequest(boolean expression, String message, Object... messageArguments) { @@ -65,14 +73,26 @@ public class BadRequestException extends ServerException { return new BadRequestException(errorMessages); } + public static BadRequestException createWithRelatedField(String message, String relatedField) { + checkArgument(!message.isEmpty(), "Message cannot be empty"); + checkArgument(!relatedField.isEmpty(), "Related field cannot be empty"); + return new BadRequestException(List.of(message), relatedField); + } + public List<String> errors() { return errors; } + public Optional<String> getRelatedField() { + return Optional.ofNullable(relatedField); + } + @Override public String toString() { return MoreObjects.toStringHelper(this) .add("errors", errors) + .add("relatedField", relatedField) + .omitNullValues() .toString(); } diff --git a/server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/DetectPluginChange.java b/server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/DetectPluginChange.java index 40f8f8036d7..af1972430f9 100644 --- a/server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/DetectPluginChange.java +++ b/server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/DetectPluginChange.java @@ -34,6 +34,7 @@ import org.sonar.db.plugin.PluginDto; import static java.util.function.Function.identity; public class DetectPluginChange implements Startable { + public static final String FORCE_PLUGIN_RELOAD_PROPERTY = "plugin.refresh.forced"; private static final Logger LOG = Loggers.get(DetectPluginChange.class); private final ServerPluginRepository serverPluginRepository; @@ -49,7 +50,7 @@ public class DetectPluginChange implements Startable { public void start() { Preconditions.checkState(changesDetected == null, "Can only call #start() once"); Profiler profiler = Profiler.create(LOG).startInfo("Detect plugin changes"); - changesDetected = anyChange(); + changesDetected = isForcedReload() || anyChange(); if (changesDetected) { LOG.debug("Plugin changes detected"); } else { @@ -65,6 +66,17 @@ public class DetectPluginChange implements Startable { return changesDetected; } + private boolean isForcedReload() { + try (DbSession dbSession = dbClient.openSession(false)) { + boolean forceRefresh = Boolean.parseBoolean(dbClient.internalPropertiesDao().selectByKey(dbSession, FORCE_PLUGIN_RELOAD_PROPERTY).orElse("false")); + if (forceRefresh) { + dbClient.internalPropertiesDao().delete(dbSession, FORCE_PLUGIN_RELOAD_PROPERTY); + dbSession.commit(); + } + return forceRefresh; + } + } + private boolean anyChange() { try (DbSession dbSession = dbClient.openSession(false)) { Map<String, PluginDto> dbPluginsByKey = dbClient.pluginDao().selectAll(dbSession).stream() diff --git a/server/sonar-webserver-api/src/main/java/org/sonar/server/qualitygate/changeevent/ChangedIssueImpl.java b/server/sonar-webserver-api/src/main/java/org/sonar/server/qualitygate/changeevent/ChangedIssueImpl.java index 2b91499368e..02c0424da06 100644 --- a/server/sonar-webserver-api/src/main/java/org/sonar/server/qualitygate/changeevent/ChangedIssueImpl.java +++ b/server/sonar-webserver-api/src/main/java/org/sonar/server/qualitygate/changeevent/ChangedIssueImpl.java @@ -24,7 +24,7 @@ import java.util.Objects; import org.sonar.api.issue.Issue; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssue; class ChangedIssueImpl implements QGChangeEventListener.ChangedIssue { diff --git a/server/sonar-webserver-api/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListener.java b/server/sonar-webserver-api/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListener.java index c5ffd4d58b7..bf9feea1763 100644 --- a/server/sonar-webserver-api/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListener.java +++ b/server/sonar-webserver-api/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListener.java @@ -24,10 +24,10 @@ import java.util.Map; import java.util.Set; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ServerSide; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.VULNERABILITY; @ServerSide public interface QGChangeEventListener { diff --git a/server/sonar-webserver-api/src/test/java/org/sonar/server/exceptions/BadRequestExceptionTest.java b/server/sonar-webserver-api/src/test/java/org/sonar/server/exceptions/BadRequestExceptionTest.java index 623a5d6ac89..e46efc445d6 100644 --- a/server/sonar-webserver-api/src/test/java/org/sonar/server/exceptions/BadRequestExceptionTest.java +++ b/server/sonar-webserver-api/src/test/java/org/sonar/server/exceptions/BadRequestExceptionTest.java @@ -69,6 +69,28 @@ public class BadRequestExceptionTest { } @Test + public void fail_when_creating_exception_with_empty_message() { + assertThatThrownBy(() -> BadRequestException.createWithRelatedField("", "relatedField")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Message cannot be empty"); + } + + @Test + public void fail_when_creating_exception_with_empty_relatedField() { + assertThatThrownBy(() -> BadRequestException.createWithRelatedField("message", "")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Related field cannot be empty"); + } + + @Test + public void create_exception_with_relatedField() { + BadRequestException underTest = BadRequestException.createWithRelatedField("error message", "related field"); + + assertThat(underTest.getRelatedField()).contains("related field"); + assertThat(underTest).hasToString("BadRequestException{errors=[error message], relatedField=related field}"); + } + + @Test public void fail_when_creating_exception_with_one_null_element() { assertThatThrownBy(() -> BadRequestException.create(asList("error", null))) .isInstanceOf(IllegalArgumentException.class) diff --git a/server/sonar-webserver-api/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImplTest.java b/server/sonar-webserver-api/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImplTest.java index 51c4d332b60..4303a88bfe9 100644 --- a/server/sonar-webserver-api/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImplTest.java +++ b/server/sonar-webserver-api/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImplTest.java @@ -39,7 +39,7 @@ import org.mockito.InOrder; import org.mockito.Mockito; import org.slf4j.event.Level; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.testfixtures.log.LogTester; import org.sonar.core.issue.DefaultIssue; import org.sonar.db.component.BranchDto; diff --git a/server/sonar-webserver-auth/src/it/java/org/sonar/server/user/ServerUserSessionIT.java b/server/sonar-webserver-auth/src/it/java/org/sonar/server/user/ServerUserSessionIT.java index 293a331651a..1e6a60e9594 100644 --- a/server/sonar-webserver-auth/src/it/java/org/sonar/server/user/ServerUserSessionIT.java +++ b/server/sonar-webserver-auth/src/it/java/org/sonar/server/user/ServerUserSessionIT.java @@ -27,12 +27,12 @@ import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.junit.Rule; import org.junit.Test; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ProjectData; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; @@ -136,23 +136,23 @@ public class ServerUserSessionIT { public void checkComponentUuidPermission_fails_with_FE_when_user_has_not_permission_for_specified_uuid_in_db() { UserDto user = db.users().insertUser(); ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project); UserSession session = newUserSession(user); - assertThatForbiddenExceptionIsThrown(() -> session.checkComponentUuidPermission(UserRole.USER, "another-uuid")); + assertThatForbiddenExceptionIsThrown(() -> session.checkComponentUuidPermission(ProjectPermission.USER, "another-uuid")); } @Test public void checkChildProjectsPermission_succeeds_if_user_has_permissions_on_all_application_child_projects() { UserDto user = db.users().insertUser(); ProjectData project = db.components().insertPrivateProject(); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project.getProjectDto()); ProjectData application = db.components().insertPrivateApplication(); db.components().addApplicationProject(application, project); UserSession underTest = newUserSession(user); - assertThat(underTest.checkChildProjectsPermission(UserRole.USER, application.getMainBranchComponent())).isSameAs(underTest); + assertThat(underTest.checkChildProjectsPermission(ProjectPermission.USER, application.getMainBranchComponent())).isSameAs(underTest); } @Test @@ -162,7 +162,7 @@ public class ServerUserSessionIT { UserSession underTest = newUserSession(user); - assertThat(underTest.checkChildProjectsPermission(UserRole.USER, project)).isSameAs(underTest); + assertThat(underTest.checkChildProjectsPermission(ProjectPermission.USER, project)).isSameAs(underTest); } @Test @@ -176,7 +176,7 @@ public class ServerUserSessionIT { UserSession underTest = newUserSession(user); - assertThatForbiddenExceptionIsThrown(() -> underTest.checkChildProjectsPermission(UserRole.USER, application.getMainBranchComponent())); + assertThatForbiddenExceptionIsThrown(() -> underTest.checkChildProjectsPermission(ProjectPermission.USER, application.getMainBranchComponent())); } @Test @@ -199,7 +199,7 @@ public class ServerUserSessionIT { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); UserDto user = db.users().insertUser(); db.users().insertGlobalPermissionOnUser(user, GlobalPermission.PROVISION_PROJECTS); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, project); UserSession session = newUserSession(user); assertThat(session.hasPermission(GlobalPermission.PROVISION_PROJECTS)).isTrue(); @@ -253,7 +253,7 @@ public class ServerUserSessionIT { ProjectData project1 = db.components().insertPrivateProject(); ProjectData project2 = db.components().insertPrivateProject(); UserDto user = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project1.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project1.getProjectDto()); ProjectData application = db.components().insertPrivateApplication(); db.components().addApplicationProject(application, project1); @@ -261,30 +261,30 @@ public class ServerUserSessionIT { db.components().insertComponent(newProjectCopy(project1.getMainBranchComponent(), application.getMainBranchComponent())); UserSession session = newUserSession(user); - assertThat(session.hasChildProjectsPermission(UserRole.USER, application.getMainBranchComponent())).isTrue(); + assertThat(session.hasChildProjectsPermission(ProjectPermission.USER, application.getMainBranchComponent())).isTrue(); db.components().addApplicationProject(application, project2); db.components().insertComponent(newProjectCopy(project2.getMainBranchComponent(), application.getMainBranchComponent())); - assertThat(session.hasChildProjectsPermission(UserRole.USER, application.getMainBranchComponent())).isFalse(); + assertThat(session.hasChildProjectsPermission(ProjectPermission.USER, application.getMainBranchComponent())).isFalse(); } @Test public void test_hasChildProjectsPermission_for_anonymous_user() { ProjectData project = db.components().insertPrivateProject(); - db.users().insertPermissionOnAnyone(UserRole.USER); + db.users().insertPermissionOnAnyone(ProjectPermission.USER); ProjectData application = db.components().insertPrivateApplication(); db.components().addApplicationProject(application.getProjectDto(), project.getProjectDto()); // add computed project db.components().insertComponent(newProjectCopy(project.getMainBranchComponent(), application.getMainBranchComponent())); UserSession session = newAnonymousSession(); - assertThat(session.hasChildProjectsPermission(UserRole.USER, application.getProjectDto())).isFalse(); + assertThat(session.hasChildProjectsPermission(ProjectPermission.USER, application.getProjectDto())).isFalse(); } @Test public void hasChildProjectsPermission_keeps_cache_of_permissions_of_anonymous_user() { - db.users().insertPermissionOnAnyone(UserRole.USER); + db.users().insertPermissionOnAnyone(ProjectPermission.USER); ProjectDto project = db.components().insertPublicProject().getProjectDto(); ProjectDto application = db.components().insertPublicApplication().getProjectDto(); @@ -293,11 +293,11 @@ public class ServerUserSessionIT { UserSession session = newAnonymousSession(); // feed the cache - assertThat(session.hasChildProjectsPermission(UserRole.USER, application)).isTrue(); + assertThat(session.hasChildProjectsPermission(ProjectPermission.USER, application)).isTrue(); // change privacy of the project without updating the cache db.getDbClient().componentDao().setPrivateForBranchUuidWithoutAudit(db.getSession(), project.getUuid(), true); - assertThat(session.hasChildProjectsPermission(UserRole.USER, application)).isTrue(); + assertThat(session.hasChildProjectsPermission(ProjectPermission.USER, application)).isTrue(); } @Test @@ -318,44 +318,44 @@ public class ServerUserSessionIT { db.components().addPortfolioProject(portfolio, project1.getProjectDto().getUuid()); db.components().insertComponent(newProjectCopy(project1.getMainBranchComponent(), portfolio)); - assertThat(session.hasPortfolioChildProjectsPermission(UserRole.USER, portfolio)).isTrue(); + assertThat(session.hasPortfolioChildProjectsPermission(ProjectPermission.USER, portfolio)).isTrue(); // Add private project2 with USER permissions to private portfolio - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project2.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project2.getProjectDto()); db.components().addPortfolioProject(portfolio, project2.getProjectDto().getUuid()); db.components().insertComponent(newProjectCopy(project2.getMainBranchComponent(), portfolio)); - assertThat(session.hasPortfolioChildProjectsPermission(UserRole.USER, portfolio)).isTrue(); + assertThat(session.hasPortfolioChildProjectsPermission(ProjectPermission.USER, portfolio)).isTrue(); // Add private project4 with USER permissions to sub-portfolio - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project4.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project4.getProjectDto()); db.components().addPortfolioProject(subPortfolio, project4.getProjectDto().getUuid()); db.components().insertComponent(newProjectCopy(project4.getMainBranchComponent(), subPortfolio)); db.components().addPortfolioReference(portfolio, subPortfolio.uuid()); // The predicate should work both on view and subview components - assertThat(session.hasPortfolioChildProjectsPermission(UserRole.USER, portfolio)).isTrue(); - assertThat(session.hasPortfolioChildProjectsPermission(UserRole.USER, subPortfolio)).isTrue(); + assertThat(session.hasPortfolioChildProjectsPermission(ProjectPermission.USER, portfolio)).isTrue(); + assertThat(session.hasPortfolioChildProjectsPermission(ProjectPermission.USER, subPortfolio)).isTrue(); // Add private project3 without permissions to private portfolio db.components().addPortfolioProject(portfolio, project3.getProjectDto().getUuid()); db.components().insertComponent(newProjectCopy(project3.getMainBranchComponent(), portfolio)); - assertThat(session.hasPortfolioChildProjectsPermission(UserRole.USER, portfolio)).isFalse(); + assertThat(session.hasPortfolioChildProjectsPermission(ProjectPermission.USER, portfolio)).isFalse(); // Add private project5 without permissions to sub-portfolio db.components().addPortfolioProject(subPortfolio, project5.getProjectDto().getUuid()); db.components().insertComponent(newProjectCopy(project5.getMainBranchComponent(), subPortfolio)); - assertThat(session.hasPortfolioChildProjectsPermission(UserRole.USER, portfolio)).isFalse(); - assertThat(session.hasPortfolioChildProjectsPermission(UserRole.USER, subPortfolio)).isFalse(); + assertThat(session.hasPortfolioChildProjectsPermission(ProjectPermission.USER, portfolio)).isFalse(); + assertThat(session.hasPortfolioChildProjectsPermission(ProjectPermission.USER, subPortfolio)).isFalse(); } @Test public void test_hasPortfolioChildProjectsPermission_for_anonymous_user() { ProjectData project = db.components().insertPrivateProject(); - db.users().insertPermissionOnAnyone(UserRole.USER); + db.users().insertPermissionOnAnyone(ProjectPermission.USER); ComponentDto portfolio = db.components().insertPrivatePortfolio(); @@ -364,12 +364,12 @@ public class ServerUserSessionIT { db.components().insertComponent(newProjectCopy(project.getMainBranchComponent(), portfolio)); UserSession session = newAnonymousSession(); - assertThat(session.hasPortfolioChildProjectsPermission(UserRole.USER, portfolio)).isFalse(); + assertThat(session.hasPortfolioChildProjectsPermission(ProjectPermission.USER, portfolio)).isFalse(); } @Test public void hasPortfolioChildProjectsPermission_keeps_cache_of_permissions_of_anonymous_user() { - db.users().insertPermissionOnAnyone(UserRole.USER); + db.users().insertPermissionOnAnyone(ProjectPermission.USER); ProjectDto project = db.components().insertPublicProject().getProjectDto(); ComponentDto portfolio = db.components().insertPublicPortfolio(); @@ -378,11 +378,11 @@ public class ServerUserSessionIT { UserSession session = newAnonymousSession(); // feed the cache - assertThat(session.hasPortfolioChildProjectsPermission(UserRole.USER, portfolio)).isTrue(); + assertThat(session.hasPortfolioChildProjectsPermission(ProjectPermission.USER, portfolio)).isTrue(); // change privacy of the project without updating the cache db.getDbClient().componentDao().setPrivateForBranchUuidWithoutAudit(db.getSession(), project.getUuid(), true); - assertThat(session.hasPortfolioChildProjectsPermission(UserRole.USER, portfolio)).isTrue(); + assertThat(session.hasPortfolioChildProjectsPermission(ProjectPermission.USER, portfolio)).isTrue(); } @Test @@ -391,8 +391,8 @@ public class ServerUserSessionIT { ServerUserSession underTest = newAnonymousSession(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, publicProject.getMainBranchComponent())).isTrue(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.USER, publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.CODEVIEWER, publicProject.getMainBranchComponent())).isTrue(); } @Test @@ -402,8 +402,8 @@ public class ServerUserSessionIT { ServerUserSession underTest = newAnonymousSession(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, publicProject.getMainBranchComponent())).isTrue(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.USER, publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.CODEVIEWER, publicProject.getMainBranchComponent())).isTrue(); } @Test @@ -413,8 +413,8 @@ public class ServerUserSessionIT { ServerUserSession underTest = newAnonymousSession(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, publicProject.getMainBranchComponent())).isTrue(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.USER, publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.CODEVIEWER, publicProject.getMainBranchComponent())).isTrue(); } @Test @@ -424,8 +424,8 @@ public class ServerUserSessionIT { ServerUserSession underTest = newAnonymousSession(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, publicProject.getMainBranchComponent())).isTrue(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.USER, publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.CODEVIEWER, publicProject.getMainBranchComponent())).isTrue(); } @Test @@ -435,8 +435,8 @@ public class ServerUserSessionIT { ServerUserSession underTest = newUserSession(user); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, privateProject.getMainBranchComponent())).isFalse(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, privateProject.getMainBranchComponent())).isFalse(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.USER, privateProject.getMainBranchComponent())).isFalse(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.CODEVIEWER, privateProject.getMainBranchComponent())).isFalse(); } @Test @@ -447,8 +447,8 @@ public class ServerUserSessionIT { ServerUserSession underTest = newUserSession(user); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, privateProject.getMainBranchComponent())).isFalse(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, privateProject.getMainBranchComponent())).isFalse(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.USER, privateProject.getMainBranchComponent())).isFalse(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.CODEVIEWER, privateProject.getMainBranchComponent())).isFalse(); } @Test @@ -459,100 +459,100 @@ public class ServerUserSessionIT { ServerUserSession underTest = newUserSession(user); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, privateProject.getMainBranchComponent())).isFalse(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, privateProject.getMainBranchComponent())).isFalse(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.USER, privateProject.getMainBranchComponent())).isFalse(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.CODEVIEWER, privateProject.getMainBranchComponent())).isFalse(); } @Test public void hasComponentPermissionByDtoOrUuid_returns_true_for_anonymous_user_for_inserted_permissions_on_group_AnyOne_on_public_projects() { ProjectData publicProject = db.components().insertPublicProject(); - db.users().insertEntityPermissionOnAnyone("p1", publicProject.getProjectDto()); + db.users().insertEntityPermissionOnAnyone(ProjectPermission.SCAN, publicProject.getProjectDto()); ServerUserSession underTest = newAnonymousSession(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.SCAN, publicProject.getMainBranchComponent())).isTrue(); } @Test public void hasComponentPermissionByDtoOrUuid_returns_false_for_anonymous_user_for_inserted_permissions_on_group_on_public_projects() { ProjectData publicProject = db.components().insertPublicProject(); GroupDto group = db.users().insertGroup(); - db.users().insertEntityPermissionOnGroup(group, "p1", publicProject.getProjectDto()); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.SCAN, publicProject.getProjectDto()); ServerUserSession underTest = newAnonymousSession(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", publicProject.getMainBranchComponent())).isFalse(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.SCAN, publicProject.getMainBranchComponent())).isFalse(); } @Test public void hasComponentPermissionByDtoOrUuid_returns_false_for_anonymous_user_for_inserted_permissions_on_group_on_private_projects() { ProjectData privateProject = db.components().insertPrivateProject(); GroupDto group = db.users().insertGroup(); - db.users().insertEntityPermissionOnGroup(group, "p1", privateProject.getProjectDto()); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.SCAN, privateProject.getProjectDto()); ServerUserSession underTest = newAnonymousSession(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", privateProject.getMainBranchComponent())).isFalse(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.SCAN, privateProject.getMainBranchComponent())).isFalse(); } @Test public void hasComponentPermissionByDtoOrUuid_returns_false_for_anonymous_user_for_inserted_permissions_on_user_on_public_projects() { UserDto user = db.users().insertUser(); ProjectData publicProject = db.components().insertPublicProject(); - db.users().insertProjectPermissionOnUser(user, "p1", publicProject.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.SCAN, publicProject.getProjectDto()); ServerUserSession underTest = newAnonymousSession(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", publicProject.getMainBranchComponent())).isFalse(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.SCAN, publicProject.getMainBranchComponent())).isFalse(); } @Test public void hasComponentPermissionByDtoOrUuid_returns_false_for_anonymous_user_for_inserted_permissions_on_user_on_private_projects() { UserDto user = db.users().insertUser(); ProjectData project = db.components().insertPrivateProject(); - db.users().insertProjectPermissionOnUser(user, "p1", project.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.SCAN, project.getProjectDto()); ServerUserSession underTest = newAnonymousSession(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", project.getMainBranchComponent())).isFalse(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.SCAN, project.getMainBranchComponent())).isFalse(); } @Test public void hasComponentPermissionByDtoOrUuid_keeps_cache_of_permissions_of_logged_in_user() { UserDto user = db.users().insertUser(); ProjectData publicProject = db.components().insertPublicProject(); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, publicProject.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, publicProject.getProjectDto()); UserSession underTest = newUserSession(user); // feed the cache - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.ADMIN, publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.ADMIN, publicProject.getMainBranchComponent())).isTrue(); // change permissions without updating the cache - db.users().deletePermissionFromUser(publicProject.getProjectDto(), user, UserRole.ADMIN); - db.users().insertProjectPermissionOnUser(user, UserRole.ISSUE_ADMIN, publicProject.getProjectDto()); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.ADMIN, publicProject.getMainBranchComponent())).isTrue(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.ISSUE_ADMIN, publicProject.getMainBranchComponent())).isFalse(); + db.users().deletePermissionFromUser(publicProject.getProjectDto(), user, ProjectPermission.ADMIN); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ISSUE_ADMIN, publicProject.getProjectDto()); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.ADMIN, publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.ISSUE_ADMIN, publicProject.getMainBranchComponent())).isFalse(); } @Test public void hasComponentPermissionByDtoOrUuid_keeps_cache_of_permissions_of_anonymous_user() { ProjectData publicProject = db.components().insertPublicProject(); - db.users().insertEntityPermissionOnAnyone(UserRole.ADMIN, publicProject.getProjectDto()); + db.users().insertEntityPermissionOnAnyone(ProjectPermission.ADMIN, publicProject.getProjectDto()); UserSession underTest = newAnonymousSession(); // feed the cache - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.ADMIN, publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.ADMIN, publicProject.getMainBranchComponent())).isTrue(); // change permissions without updating the cache - db.users().deleteProjectPermissionFromAnyone(publicProject.getProjectDto(), UserRole.ADMIN); - db.users().insertEntityPermissionOnAnyone(UserRole.ISSUE_ADMIN, publicProject.getProjectDto()); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.ADMIN, publicProject.getMainBranchComponent())).isTrue(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.ISSUE_ADMIN, publicProject.getMainBranchComponent())).isFalse(); + db.users().deleteProjectPermissionFromAnyone(publicProject.getProjectDto(), ProjectPermission.ADMIN); + db.users().insertEntityPermissionOnAnyone(ProjectPermission.ISSUE_ADMIN, publicProject.getProjectDto()); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.ADMIN, publicProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.ISSUE_ADMIN, publicProject.getMainBranchComponent())).isFalse(); } - private boolean hasComponentPermissionByDtoOrUuid(UserSession underTest, String permission, ComponentDto component) { + private boolean hasComponentPermissionByDtoOrUuid(UserSession underTest, ProjectPermission permission, ComponentDto component) { boolean b1 = underTest.hasComponentPermission(permission, component); boolean b2 = underTest.hasComponentUuidPermission(permission, component.uuid()); checkState(b1 == b2, "Different behaviors"); @@ -566,19 +566,19 @@ public class ServerUserSessionIT { UserSession underTest = newAnonymousSession(); - assertThat(underTest.keepAuthorizedComponents(UserRole.ADMIN, Arrays.asList(privateProject.getMainBranchComponent(), publicProject.getMainBranchComponent()))).isEmpty(); + assertThat(underTest.keepAuthorizedComponents(ProjectPermission.ADMIN, Arrays.asList(privateProject.getMainBranchComponent(), publicProject.getMainBranchComponent()))).isEmpty(); } @Test public void keepAuthorizedComponents_filters_components_with_granted_permissions_for_anonymous() { ProjectData publicProject = db.components().insertPublicProject(); ProjectData privateProject = db.components().insertPrivateProject(); - db.users().insertEntityPermissionOnAnyone(UserRole.ISSUE_ADMIN, publicProject.getProjectDto()); + db.users().insertEntityPermissionOnAnyone(ProjectPermission.ISSUE_ADMIN, publicProject.getProjectDto()); UserSession underTest = newAnonymousSession(); - assertThat(underTest.keepAuthorizedComponents(UserRole.ADMIN, Arrays.asList(privateProject.getMainBranchComponent(), publicProject.getMainBranchComponent()))).isEmpty(); - assertThat(underTest.keepAuthorizedComponents(UserRole.ISSUE_ADMIN, Arrays.asList(privateProject.getMainBranchComponent(), publicProject.getMainBranchComponent()))) + assertThat(underTest.keepAuthorizedComponents(ProjectPermission.ADMIN, Arrays.asList(privateProject.getMainBranchComponent(), publicProject.getMainBranchComponent()))).isEmpty(); + assertThat(underTest.keepAuthorizedComponents(ProjectPermission.ISSUE_ADMIN, Arrays.asList(privateProject.getMainBranchComponent(), publicProject.getMainBranchComponent()))) .containsExactly(publicProject.getMainBranchComponent()); } @@ -586,12 +586,12 @@ public class ServerUserSessionIT { public void keepAuthorizedComponents_on_branches() { UserDto user = db.users().insertUser(); ProjectData privateProject = db.components().insertPrivateProject(); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, privateProject.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, privateProject.getProjectDto()); ComponentDto privateBranchProject = db.components().insertProjectBranch(privateProject.getMainBranchComponent()); UserSession underTest = newUserSession(user); - assertThat(underTest.keepAuthorizedComponents(UserRole.ADMIN, asList(privateProject.getMainBranchComponent(), privateBranchProject))) + assertThat(underTest.keepAuthorizedComponents(ProjectPermission.ADMIN, asList(privateProject.getMainBranchComponent(), privateBranchProject))) .containsExactlyInAnyOrder(privateProject.getMainBranchComponent(), privateBranchProject); } @@ -608,13 +608,13 @@ public class ServerUserSessionIT { UserSession underTest = newUserSession(user); ComponentDto portfolio = db.components().insertPrivatePortfolio(); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, portfolio); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, portfolio); ComponentDto subPortfolio = db.components().insertSubportfolio(portfolio); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, subPortfolio); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, subPortfolio); ProjectData app = db.components().insertPrivateApplication(); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, app.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, app.getProjectDto()); ProjectData app2 = db.components().insertPrivateApplication(); @@ -623,12 +623,12 @@ public class ServerUserSessionIT { var copyProject1 = db.components().insertComponent(newProjectCopy(project1, portfolio)); // Add private project2 with USER permissions to private portfolio - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project2); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project2); db.components().addPortfolioProject(portfolio, project2); var copyProject2 = db.components().insertComponent(newProjectCopy(project2, portfolio)); // Add private project4 with USER permissions to sub-portfolio - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project4); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project4); db.components().addPortfolioProject(subPortfolio, project4); var copyProject4 = db.components().insertComponent(newProjectCopy(project4, subPortfolio)); db.components().addPortfolioReference(portfolio, subPortfolio.uuid()); @@ -638,7 +638,7 @@ public class ServerUserSessionIT { var copyProject3 = db.components().insertComponent(newProjectCopy(project3, portfolio)); // Add private project5 with USER permissions to app - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project5.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project5.getProjectDto()); db.components().addApplicationProject(app, project5); var copyProject5 = db.components().insertComponent(newProjectCopy(project5, app)); db.components().addPortfolioReference(portfolio, app.getProjectDto().getUuid()); @@ -648,16 +648,16 @@ public class ServerUserSessionIT { var copyProject6 = db.components().insertComponent(newProjectCopy(project6, app2)); db.components().addPortfolioReference(portfolio, app2.getProjectDto().getUuid()); - assertThat(underTest.keepAuthorizedComponents(UserRole.ADMIN, List.of(portfolio))).isEmpty(); - assertThat(underTest.keepAuthorizedComponents(UserRole.USER, List.of(portfolio))).containsExactly(portfolio); + assertThat(underTest.keepAuthorizedComponents(ProjectPermission.ADMIN, List.of(portfolio))).isEmpty(); + assertThat(underTest.keepAuthorizedComponents(ProjectPermission.USER, List.of(portfolio))).containsExactly(portfolio); - assertThat(underTest.keepAuthorizedComponents(UserRole.ADMIN, Arrays.asList(app.getMainBranchComponent(), subPortfolio, app2.getMainBranchComponent()))).isEmpty(); - assertThat(underTest.keepAuthorizedComponents(UserRole.USER, Arrays.asList(app.getMainBranchComponent(), subPortfolio, app2.getMainBranchComponent()))).containsExactly(app.getMainBranchComponent(), subPortfolio); + assertThat(underTest.keepAuthorizedComponents(ProjectPermission.ADMIN, Arrays.asList(app.getMainBranchComponent(), subPortfolio, app2.getMainBranchComponent()))).isEmpty(); + assertThat(underTest.keepAuthorizedComponents(ProjectPermission.USER, Arrays.asList(app.getMainBranchComponent(), subPortfolio, app2.getMainBranchComponent()))).containsExactly(app.getMainBranchComponent(), subPortfolio); - assertThat(underTest.keepAuthorizedComponents(UserRole.ADMIN, Arrays.asList(project1, project2, project3, project4, project5.getMainBranchComponent(), project6.getMainBranchComponent()))).isEmpty(); - assertThat(underTest.keepAuthorizedComponents(UserRole.USER, Arrays.asList(project1, project2, project3, project4, project5.getMainBranchComponent(), project6.getMainBranchComponent()))) + assertThat(underTest.keepAuthorizedComponents(ProjectPermission.ADMIN, Arrays.asList(project1, project2, project3, project4, project5.getMainBranchComponent(), project6.getMainBranchComponent()))).isEmpty(); + assertThat(underTest.keepAuthorizedComponents(ProjectPermission.USER, Arrays.asList(project1, project2, project3, project4, project5.getMainBranchComponent(), project6.getMainBranchComponent()))) .containsExactly(project1, project2, project4, project5.getMainBranchComponent()); - assertThat(underTest.keepAuthorizedComponents(UserRole.USER, Arrays.asList(copyProject1, copyProject2, copyProject3, copyProject4, copyProject5, copyProject6))) + assertThat(underTest.keepAuthorizedComponents(ProjectPermission.USER, Arrays.asList(copyProject1, copyProject2, copyProject3, copyProject4, copyProject5, copyProject6))) .containsExactly(copyProject1, copyProject2, copyProject4, copyProject5); } @@ -669,13 +669,13 @@ public class ServerUserSessionIT { UserDto user = db.users().insertUser(); UserSession underTest = newUserSession(user); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project1.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project1.getProjectDto()); ComponentDto file1Project1 = db.components().insertFile(project1.getMainBranchDto()); ComponentDto file2Project1 = db.components().insertFile(project1.getMainBranchDto()); ComponentDto file1Project2 = db.components().insertFile(project2.getMainBranchDto()); - assertThat(underTest.keepAuthorizedComponents(UserRole.USER, List.of(file1Project1, file2Project1, file1Project2))).containsExactly(file1Project1, file2Project1); + assertThat(underTest.keepAuthorizedComponents(ProjectPermission.USER, List.of(file1Project1, file2Project1, file1Project2))).containsExactly(file1Project1, file2Project1); } @Test @@ -742,13 +742,13 @@ public class ServerUserSessionIT { ComponentDto fileInBranch = db.components().insertComponent(newChildComponent("fileUuid", branch, branch)); // permissions are defined on the project, not on the branch - db.users().insertProjectPermissionOnUser(user, "p1", privateProject.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, privateProject.getProjectDto()); UserSession underTest = newUserSession(user); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", privateProject.getMainBranchComponent())).isTrue(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", branch)).isTrue(); - assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", fileInBranch)).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.CODEVIEWER, privateProject.getMainBranchComponent())).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.CODEVIEWER, branch)).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, ProjectPermission.CODEVIEWER, fileInBranch)).isTrue(); } @Test @@ -757,7 +757,7 @@ public class ServerUserSessionIT { ProjectData privateProject = db.components().insertPrivateProject(); Set<ProjectDto> projectDto = Set.of(publicProject.getProjectDto(), privateProject.getProjectDto()); - List<ProjectDto> projectDtos = newUserSession(null).keepAuthorizedEntities(UserRole.USER, projectDto); + List<ProjectDto> projectDtos = newUserSession(null).keepAuthorizedEntities(ProjectPermission.USER, projectDto); assertThat(projectDtos).containsExactly(publicProject.getProjectDto()); } @@ -769,37 +769,35 @@ public class ServerUserSessionIT { ProjectData privateProject = db.components().insertPrivateProject(); Set<ProjectDto> projectDto = Set.of(publicProject.getProjectDto(), privateProject.getProjectDto()); - List<ProjectDto> projectDtos = newUserSession(userDto).keepAuthorizedEntities(UserRole.USER, projectDto); + List<ProjectDto> projectDtos = newUserSession(userDto).keepAuthorizedEntities(ProjectPermission.USER, projectDto); assertThat(projectDtos).containsExactly(publicProject.getProjectDto()); } @Test public void keepAuthorizedProjects_shouldAcceptsOnlyPrivateProject_whenCalledWithGoodPermissionAndAnUser() { - String permission = "aNewPermission"; UserDto userDto = db.users().insertUser(); ProjectDto publicProject = db.components().insertPublicProject().getProjectDto(); ProjectDto privateProject = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(userDto, permission, privateProject); + db.users().insertProjectPermissionOnUser(userDto, ProjectPermission.SCAN, privateProject); ProjectDto privateProjectWithoutPermission = db.components().insertPrivateProject().getProjectDto(); Set<ProjectDto> projectDto = Set.of(publicProject, privateProject, privateProjectWithoutPermission); - List<ProjectDto> projectDtos = newUserSession(userDto).keepAuthorizedEntities(permission, projectDto); + List<ProjectDto> projectDtos = newUserSession(userDto).keepAuthorizedEntities(ProjectPermission.SCAN, projectDto); assertThat(projectDtos).containsExactly(privateProject); } @Test public void keepAuthorizedProjects_shouldRejectPrivateAndPublicProject_whenCalledWithWrongPermissionAndNoUser() { - String permission = "aNewPermission"; UserDto userDto = db.users().insertUser(); ProjectDto publicProject = db.components().insertPublicProject().getProjectDto(); ProjectDto privateProject = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(userDto, permission, privateProject); + db.users().insertProjectPermissionOnUser(userDto, ProjectPermission.SCAN, privateProject); ProjectDto privateProjectWithoutPermission = db.components().insertPrivateProject().getProjectDto(); Set<ProjectDto> projectDto = Set.of(publicProject, privateProject, privateProjectWithoutPermission); - List<ProjectDto> projectDtos = newUserSession(null).keepAuthorizedEntities(permission, projectDto); + List<ProjectDto> projectDtos = newUserSession(null).keepAuthorizedEntities(ProjectPermission.SCAN, projectDto); assertThat(projectDtos).isEmpty(); } diff --git a/server/sonar-webserver-auth/src/it/java/org/sonar/server/user/TokenUserSessionIT.java b/server/sonar-webserver-auth/src/it/java/org/sonar/server/user/TokenUserSessionIT.java index 15206a15a46..3a42636fe26 100644 --- a/server/sonar-webserver-auth/src/it/java/org/sonar/server/user/TokenUserSessionIT.java +++ b/server/sonar-webserver-auth/src/it/java/org/sonar/server/user/TokenUserSessionIT.java @@ -28,7 +28,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; @@ -40,9 +40,9 @@ import org.sonar.db.user.UserTokenDto; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.SCAN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.SCAN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.user.TokenType.GLOBAL_ANALYSIS_TOKEN; import static org.sonar.db.user.TokenType.PROJECT_ANALYSIS_TOKEN; import static org.sonar.db.user.TokenType.PROJECT_BADGE_TOKEN; @@ -212,7 +212,7 @@ public class TokenUserSessionIT { @Test @UseDataProvider("validPermissions") - public void keepAuthorizedEntities_shouldFilterPrivateProjects_whenProjectAnalysisToken(String permission) { + public void keepAuthorizedEntities_shouldFilterPrivateProjects_whenProjectAnalysisToken(ProjectPermission permission) { UserDto user = db.users().insertUser(); ProjectData publicProject = db.components().insertPublicProject(); @@ -296,7 +296,7 @@ public class TokenUserSessionIT { @Test @UseDataProvider("validPermissions") - public void keepAuthorizedComponents_shouldFilterPrivateProjects_whenProjectAnalysisToken(String permission) { + public void keepAuthorizedComponents_shouldFilterPrivateProjects_whenProjectAnalysisToken(ProjectPermission permission) { UserDto user = db.users().insertUser(); ProjectData publicProject = db.components().insertPublicProject(); @@ -337,11 +337,11 @@ public class TokenUserSessionIT { ProjectData publicProject = db.components().insertPublicProject(); ProjectData privateProject = db.components().insertPrivateProject(); - db.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, privateProject.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, privateProject.getProjectDto()); Set<ComponentDto> componentDtos = Set.of(publicProject.getMainBranchComponent(), privateProject.getMainBranchComponent()); List<ComponentDto> authorizedComponents = mockProjectAnalysisTokenUserSession(user, privateProject.getProjectDto()) - .keepAuthorizedComponents(UserRole.CODEVIEWER, componentDtos); + .keepAuthorizedComponents(ProjectPermission.CODEVIEWER, componentDtos); assertThat(authorizedComponents).isEmpty(); } diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/SafeModeUserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/SafeModeUserSession.java index 6b872dbbe1c..7a29912c32f 100644 --- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/SafeModeUserSession.java +++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/SafeModeUserSession.java @@ -25,6 +25,7 @@ import java.util.Optional; import javax.annotation.CheckForNull; import javax.annotation.concurrent.Immutable; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; import org.sonar.server.user.AbstractUserSession; @@ -42,17 +43,17 @@ public class SafeModeUserSession extends AbstractUserSession { } @Override - protected boolean hasEntityUuidPermission(String permission, String entityUuid) { + protected boolean hasEntityUuidPermission(ProjectPermission permission, String entityUuid) { return false; } @Override - protected boolean hasChildProjectsPermission(String permission, String applicationUuid) { + protected boolean hasChildProjectsPermission(ProjectPermission permission, String applicationUuid) { return false; } @Override - protected boolean hasPortfolioChildProjectsPermission(String permission, String portfolioUuid) { + protected boolean hasPortfolioChildProjectsPermission(ProjectPermission permission, String portfolioUuid) { return false; } diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/AbstractUserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/AbstractUserSession.java index 3bb350d7649..193e260da4a 100644 --- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/AbstractUserSession.java +++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/AbstractUserSession.java @@ -25,7 +25,7 @@ import java.util.Optional; import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.component.ComponentDto; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; @@ -38,7 +38,6 @@ import static org.sonar.db.component.ComponentQualifiers.APP; import static org.sonar.server.user.UserSession.IdentityProvider.SONARQUBE; public abstract class AbstractUserSession implements UserSession { - private static final Set<String> PUBLIC_PERMISSIONS = Set.of(UserRole.USER, UserRole.CODEVIEWER); private static final String INSUFFICIENT_PRIVILEGES_MESSAGE = "Insufficient privileges"; private static final String AUTHENTICATION_IS_REQUIRED_MESSAGE = "Authentication is required"; @@ -87,7 +86,7 @@ public abstract class AbstractUserSession implements UserSession { protected abstract boolean hasPermissionImpl(GlobalPermission permission); @Override - public boolean hasComponentPermission(String permission, ComponentDto component) { + public boolean hasComponentPermission(ProjectPermission permission, ComponentDto component) { Optional<String> projectUuid1 = componentUuidToEntityUuid(component.uuid()); return projectUuid1 @@ -96,33 +95,33 @@ public abstract class AbstractUserSession implements UserSession { } @Override - public final boolean hasEntityPermission(String permission, EntityDto entity) { + public final boolean hasEntityPermission(ProjectPermission permission, EntityDto entity) { return hasEntityUuidPermission(permission, entity.getAuthUuid()); } @Override - public final boolean hasEntityPermission(String permission, String entityUuid) { + public final boolean hasEntityPermission(ProjectPermission permission, String entityUuid) { return hasEntityUuidPermission(permission, entityUuid); } @Override - public final boolean hasChildProjectsPermission(String permission, ComponentDto component) { + public final boolean hasChildProjectsPermission(ProjectPermission permission, ComponentDto component) { return componentUuidToEntityUuid(component.uuid()) .map(applicationUuid -> hasChildProjectsPermission(permission, applicationUuid)).orElse(false); } @Override - public final boolean hasChildProjectsPermission(String permission, EntityDto application) { + public final boolean hasChildProjectsPermission(ProjectPermission permission, EntityDto application) { return hasChildProjectsPermission(permission, application.getUuid()); } @Override - public final boolean hasPortfolioChildProjectsPermission(String permission, ComponentDto portfolio) { + public final boolean hasPortfolioChildProjectsPermission(ProjectPermission permission, ComponentDto portfolio) { return hasPortfolioChildProjectsPermission(permission, portfolio.uuid()); } @Override - public boolean hasComponentUuidPermission(String permission, String componentUuid) { + public boolean hasComponentUuidPermission(ProjectPermission permission, String componentUuid) { Optional<String> entityUuid = componentUuidToEntityUuid(componentUuid); return entityUuid .map(s -> hasEntityUuidPermission(permission, s)) @@ -131,27 +130,27 @@ public abstract class AbstractUserSession implements UserSession { protected abstract Optional<String> componentUuidToEntityUuid(String componentUuid); - protected abstract boolean hasEntityUuidPermission(String permission, String entityUuid); + protected abstract boolean hasEntityUuidPermission(ProjectPermission permission, String entityUuid); - protected abstract boolean hasChildProjectsPermission(String permission, String applicationUuid); + protected abstract boolean hasChildProjectsPermission(ProjectPermission permission, String applicationUuid); - protected abstract boolean hasPortfolioChildProjectsPermission(String permission, String portfolioUuid); + protected abstract boolean hasPortfolioChildProjectsPermission(ProjectPermission permission, String portfolioUuid); @Override - public final List<ComponentDto> keepAuthorizedComponents(String permission, Collection<ComponentDto> components) { + public final List<ComponentDto> keepAuthorizedComponents(ProjectPermission permission, Collection<ComponentDto> components) { return doKeepAuthorizedComponents(permission, components); } @Override - public final <T extends EntityDto> List<T> keepAuthorizedEntities(String permission, Collection<T> projects) { + public final <T extends EntityDto> List<T> keepAuthorizedEntities(ProjectPermission permission, Collection<T> projects) { return doKeepAuthorizedEntities(permission, projects); } /** * Naive implementation, to be overridden if needed */ - protected <T extends EntityDto> List<T> doKeepAuthorizedEntities(String permission, Collection<T> entities) { - boolean allowPublicComponent = PUBLIC_PERMISSIONS.contains(permission); + protected <T extends EntityDto> List<T> doKeepAuthorizedEntities(ProjectPermission permission, Collection<T> entities) { + boolean allowPublicComponent = ProjectPermission.PUBLIC_PERMISSIONS.contains(permission); return entities.stream() .filter(c -> (allowPublicComponent && !c.isPrivate()) || hasEntityPermission(permission, c.getUuid())) .toList(); @@ -160,8 +159,8 @@ public abstract class AbstractUserSession implements UserSession { /** * Naive implementation, to be overridden if needed */ - protected List<ComponentDto> doKeepAuthorizedComponents(String permission, Collection<ComponentDto> components) { - boolean allowPublicComponent = PUBLIC_PERMISSIONS.contains(permission); + protected List<ComponentDto> doKeepAuthorizedComponents(ProjectPermission permission, Collection<ComponentDto> components) { + boolean allowPublicComponent = ProjectPermission.PUBLIC_PERMISSIONS.contains(permission); return components.stream() .filter(c -> (allowPublicComponent && !c.isPrivate()) || hasComponentPermission(permission, c)) .toList(); @@ -184,7 +183,7 @@ public abstract class AbstractUserSession implements UserSession { } @Override - public final UserSession checkComponentPermission(String projectPermission, ComponentDto component) { + public final UserSession checkComponentPermission(ProjectPermission projectPermission, ComponentDto component) { if (!hasComponentPermission(projectPermission, component)) { throw new ForbiddenException(INSUFFICIENT_PRIVILEGES_MESSAGE); } @@ -192,7 +191,7 @@ public abstract class AbstractUserSession implements UserSession { } @Override - public UserSession checkEntityPermission(String projectPermission, EntityDto entity) { + public UserSession checkEntityPermission(ProjectPermission projectPermission, EntityDto entity) { if (hasEntityPermission(projectPermission, entity)) { return this; } @@ -201,7 +200,7 @@ public abstract class AbstractUserSession implements UserSession { } @Override - public UserSession checkEntityPermissionOrElseThrowResourceForbiddenException(String projectPermission, EntityDto entity) { + public UserSession checkEntityPermissionOrElseThrowResourceForbiddenException(ProjectPermission projectPermission, EntityDto entity) { if (hasEntityPermission(projectPermission, entity)) { return this; } @@ -210,7 +209,7 @@ public abstract class AbstractUserSession implements UserSession { } @Override - public UserSession checkChildProjectsPermission(String projectPermission, ComponentDto component) { + public UserSession checkChildProjectsPermission(ProjectPermission projectPermission, ComponentDto component) { if (!APP.equals(component.qualifier()) || hasChildProjectsPermission(projectPermission, component)) { return this; } @@ -219,7 +218,7 @@ public abstract class AbstractUserSession implements UserSession { } @Override - public UserSession checkChildProjectsPermission(String projectPermission, EntityDto application) { + public UserSession checkChildProjectsPermission(ProjectPermission projectPermission, EntityDto application) { if (!APP.equals(application.getQualifier()) || hasChildProjectsPermission(projectPermission, application)) { return this; } @@ -228,7 +227,7 @@ public abstract class AbstractUserSession implements UserSession { } @Override - public final UserSession checkComponentUuidPermission(String permission, String componentUuid) { + public final UserSession checkComponentUuidPermission(ProjectPermission permission, String componentUuid) { if (!hasComponentUuidPermission(permission, componentUuid)) { throw new ForbiddenException(INSUFFICIENT_PRIVILEGES_MESSAGE); } diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/DoPrivileged.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/DoPrivileged.java index 213df3158bd..da6d5db5405 100644 --- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/DoPrivileged.java +++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/DoPrivileged.java @@ -24,6 +24,7 @@ import java.util.Collections; import java.util.Optional; import org.sonar.db.component.ComponentDto; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; /** @@ -113,7 +114,7 @@ public final class DoPrivileged { } @Override - public boolean hasComponentPermission(String permission, ComponentDto component) { + public boolean hasComponentPermission(ProjectPermission permission, ComponentDto component) { return true; } @@ -124,17 +125,17 @@ public final class DoPrivileged { } @Override - protected boolean hasEntityUuidPermission(String permission, String entityUuid) { + protected boolean hasEntityUuidPermission(ProjectPermission permission, String entityUuid) { return true; } @Override - protected boolean hasChildProjectsPermission(String permission, String applicationUuid) { + protected boolean hasChildProjectsPermission(ProjectPermission permission, String applicationUuid) { return true; } @Override - protected boolean hasPortfolioChildProjectsPermission(String permission, String applicationUuid) { + protected boolean hasPortfolioChildProjectsPermission(ProjectPermission permission, String applicationUuid) { return true; } diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/GithubWebhookUserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/GithubWebhookUserSession.java index 4effdb77e2e..d42c505441f 100644 --- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/GithubWebhookUserSession.java +++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/GithubWebhookUserSession.java @@ -22,6 +22,7 @@ package org.sonar.server.user; import java.util.Collection; import java.util.Optional; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; import static java.util.Collections.emptySet; @@ -96,22 +97,22 @@ public class GithubWebhookUserSession extends AbstractUserSession { } @Override - protected boolean hasEntityUuidPermission(String permission, String entityUuid) { + protected boolean hasEntityUuidPermission(ProjectPermission permission, String entityUuid) { return false; } @Override - protected boolean hasChildProjectsPermission(String permission, String applicationUuid) { + protected boolean hasChildProjectsPermission(ProjectPermission permission, String applicationUuid) { return false; } @Override - protected boolean hasPortfolioChildProjectsPermission(String permission, String portfolioUuid) { + protected boolean hasPortfolioChildProjectsPermission(ProjectPermission permission, String portfolioUuid) { return false; } @Override - public boolean hasComponentUuidPermission(String permission, String componentUuid) { + public boolean hasComponentUuidPermission(ProjectPermission permission, String componentUuid) { return true; } diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ServerUserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ServerUserSession.java index d20f6b1ce23..db27d951e02 100644 --- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ServerUserSession.java +++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ServerUserSession.java @@ -41,6 +41,7 @@ import org.sonar.db.component.ComponentTreeQuery; import org.sonar.db.component.ComponentTreeQuery.Strategy; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; @@ -49,9 +50,9 @@ import static java.util.Optional.of; import static java.util.Optional.ofNullable; import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toSet; -import static org.sonar.api.web.UserRole.PUBLIC_PERMISSIONS; import static org.sonar.db.component.ComponentQualifiers.SUBVIEW; import static org.sonar.db.component.ComponentQualifiers.VIEW; +import static org.sonar.db.permission.ProjectPermission.PUBLIC_PERMISSIONS; /** * Implementation of {@link UserSession} used in web server @@ -165,19 +166,19 @@ public class ServerUserSession extends AbstractUserSession { } @Override - protected boolean hasEntityUuidPermission(String permission, String entityUuid) { + protected boolean hasEntityUuidPermission(ProjectPermission permission, String entityUuid) { return hasPermission(permission, entityUuid); } @Override - protected boolean hasChildProjectsPermission(String permission, String applicationUuid) { + protected boolean hasChildProjectsPermission(ProjectPermission permission, String applicationUuid) { Set<String> childProjectUuids = loadChildProjectUuids(applicationUuid); Set<String> projectsWithPermission = keepEntitiesUuidsByPermission(permission, childProjectUuids); return projectsWithPermission.containsAll(childProjectUuids); } @Override - protected boolean hasPortfolioChildProjectsPermission(String permission, String portfolioUuid) { + protected boolean hasPortfolioChildProjectsPermission(ProjectPermission permission, String portfolioUuid) { // portfolioUuid might be the UUID of a sub portfolio Set<String> projectUuids = findProjectUuids(portfolioUuid); @@ -186,7 +187,7 @@ public class ServerUserSession extends AbstractUserSession { } @Override - protected <T extends EntityDto> List<T> doKeepAuthorizedEntities(String permission, Collection<T> entities) { + protected <T extends EntityDto> List<T> doKeepAuthorizedEntities(ProjectPermission permission, Collection<T> entities) { Set<String> projectsUuids = entities.stream().map(EntityDto::getUuid).collect(Collectors.toSet()); // TODO in SONAR-19445 Set<String> authorizedEntitiesUuids = keepEntitiesUuidsByPermission(permission, projectsUuids); @@ -196,7 +197,7 @@ public class ServerUserSession extends AbstractUserSession { .toList(); } - private Set<String> keepEntitiesUuidsByPermission(String permission, Collection<String> entityUuids) { + private Set<String> keepEntitiesUuidsByPermission(ProjectPermission permission, Collection<String> entityUuids) { try (DbSession dbSession = dbClient.openSession(false)) { String userUuid = userDto == null ? null : userDto.getUuid(); return dbClient.authorizationDao().keepAuthorizedEntityUuids(dbSession, entityUuids, userUuid, permission); @@ -266,9 +267,9 @@ public class ServerUserSession extends AbstractUserSession { return !Objects.isNull(componentDto.qualifier()) && QUALIFIERS.contains(componentDto.qualifier()); } - private boolean hasPermission(String permission, String entityUuid) { + private boolean hasPermission(ProjectPermission permission, String entityUuid) { Set<String> entityPermissions = permissionsByEntityUuid.computeIfAbsent(entityUuid, this::loadEntityPermissions); - return entityPermissions.contains(permission); + return permission != null && entityPermissions.contains(permission.getKey()); } private Set<String> loadEntityPermissions(String entityUuid) { @@ -281,7 +282,7 @@ public class ServerUserSession extends AbstractUserSession { return loadDbPermissions(dbSession, entityUuid); } Set<String> projectPermissions = new HashSet<>(); - projectPermissions.addAll(PUBLIC_PERMISSIONS); + projectPermissions.addAll(PUBLIC_PERMISSIONS.stream().map(ProjectPermission::getKey).collect(toSet())); projectPermissions.addAll(loadDbPermissions(dbSession, entityUuid)); return Collections.unmodifiableSet(projectPermissions); } @@ -330,7 +331,7 @@ public class ServerUserSession extends AbstractUserSession { } @Override - protected List<ComponentDto> doKeepAuthorizedComponents(String permission, Collection<ComponentDto> components) { + protected List<ComponentDto> doKeepAuthorizedComponents(ProjectPermission permission, Collection<ComponentDto> components) { try (DbSession dbSession = dbClient.openSession(false)) { Map<String, String> entityUuidsByComponentUuid = new HashMap<>(getEntityUuidsByComponentUuid(dbSession, components)); Map<String, ComponentDto> originalComponents = findComponentsByCopyComponentUuid(components, dbSession); @@ -353,7 +354,7 @@ public class ServerUserSession extends AbstractUserSession { } } - protected Set<String> keepAuthorizedProjectsUuids(DbSession dbSession, String permission, Collection<String> entityUuids) { + protected Set<String> keepAuthorizedProjectsUuids(DbSession dbSession, ProjectPermission permission, Collection<String> entityUuids) { return dbClient.authorizationDao().keepAuthorizedEntityUuids(dbSession, entityUuids, getUuid(), permission); } diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java index d637ad08ee9..48033a0d609 100644 --- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java +++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java @@ -26,6 +26,7 @@ import javax.annotation.CheckForNull; import org.sonar.db.component.ComponentDto; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; import org.sonar.server.exceptions.UnauthorizedException; @@ -123,37 +124,37 @@ public class ThreadLocalUserSession implements UserSession { } @Override - public UserSession checkComponentPermission(String projectPermission, ComponentDto component) { + public UserSession checkComponentPermission(ProjectPermission projectPermission, ComponentDto component) { get().checkComponentPermission(projectPermission, component); return this; } @Override - public UserSession checkEntityPermission(String projectPermission, EntityDto entity) { + public UserSession checkEntityPermission(ProjectPermission projectPermission, EntityDto entity) { get().checkEntityPermission(projectPermission, entity); return this; } @Override - public UserSession checkEntityPermissionOrElseThrowResourceForbiddenException(String projectPermission, EntityDto entity) { + public UserSession checkEntityPermissionOrElseThrowResourceForbiddenException(ProjectPermission projectPermission, EntityDto entity) { get().checkEntityPermissionOrElseThrowResourceForbiddenException(projectPermission, entity); return this; } @Override - public UserSession checkChildProjectsPermission(String projectPermission, ComponentDto component) { + public UserSession checkChildProjectsPermission(ProjectPermission projectPermission, ComponentDto component) { get().checkChildProjectsPermission(projectPermission, component); return this; } @Override - public UserSession checkChildProjectsPermission(String projectPermission, EntityDto application) { + public UserSession checkChildProjectsPermission(ProjectPermission projectPermission, EntityDto application) { get().checkChildProjectsPermission(projectPermission, application); return this; } @Override - public UserSession checkComponentUuidPermission(String permission, String componentUuid) { + public UserSession checkComponentUuidPermission(ProjectPermission permission, String componentUuid) { get().checkComponentUuidPermission(permission, componentUuid); return this; } @@ -180,47 +181,47 @@ public class ThreadLocalUserSession implements UserSession { } @Override - public boolean hasComponentPermission(String permission, ComponentDto component) { + public boolean hasComponentPermission(ProjectPermission permission, ComponentDto component) { return get().hasComponentPermission(permission, component); } @Override - public boolean hasEntityPermission(String permission, EntityDto entity) { + public boolean hasEntityPermission(ProjectPermission permission, EntityDto entity) { return get().hasEntityPermission(permission, entity); } @Override - public boolean hasEntityPermission(String permission, String entityUuid) { + public boolean hasEntityPermission(ProjectPermission permission, String entityUuid) { return get().hasEntityPermission(permission, entityUuid); } @Override - public boolean hasChildProjectsPermission(String permission, ComponentDto component) { + public boolean hasChildProjectsPermission(ProjectPermission permission, ComponentDto component) { return get().hasChildProjectsPermission(permission, component); } @Override - public boolean hasChildProjectsPermission(String permission, EntityDto application) { + public boolean hasChildProjectsPermission(ProjectPermission permission, EntityDto application) { return get().hasChildProjectsPermission(permission, application); } @Override - public boolean hasPortfolioChildProjectsPermission(String permission, ComponentDto portfolio) { + public boolean hasPortfolioChildProjectsPermission(ProjectPermission permission, ComponentDto portfolio) { return get().hasPortfolioChildProjectsPermission(permission, portfolio); } @Override - public boolean hasComponentUuidPermission(String permission, String componentUuid) { + public boolean hasComponentUuidPermission(ProjectPermission permission, String componentUuid) { return get().hasComponentUuidPermission(permission, componentUuid); } @Override - public List<ComponentDto> keepAuthorizedComponents(String permission, Collection<ComponentDto> components) { + public List<ComponentDto> keepAuthorizedComponents(ProjectPermission permission, Collection<ComponentDto> components) { return get().keepAuthorizedComponents(permission, components); } @Override - public <T extends EntityDto> List<T> keepAuthorizedEntities(String permission, Collection<T> entities) { + public <T extends EntityDto> List<T> keepAuthorizedEntities(ProjectPermission permission, Collection<T> entities) { return get().keepAuthorizedEntities(permission, entities); } } diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/TokenUserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/TokenUserSession.java index bc4a31241db..9cbdd782874 100644 --- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/TokenUserSession.java +++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/TokenUserSession.java @@ -28,17 +28,18 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.TokenType; import org.sonar.db.user.UserDto; import org.sonar.db.user.UserTokenDto; import static java.lang.String.format; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.SCAN; +import static org.sonar.db.permission.ProjectPermission.USER; public class TokenUserSession extends ServerUserSession { private static final String TOKEN_ASSERTION_ERROR_MESSAGE = "Unsupported token type %s"; - private static final String SCAN = "scan"; private static final Set<GlobalPermission> GLOBAL_ANALYSIS_TOKEN_SUPPORTED_PERMISSIONS = EnumSet.of(GlobalPermission.SCAN, GlobalPermission.PROVISION_PROJECTS); private final UserTokenDto userToken; @@ -48,7 +49,7 @@ public class TokenUserSession extends ServerUserSession { } @Override - protected boolean hasEntityUuidPermission(String permission, String entityUuid) { + protected boolean hasEntityUuidPermission(ProjectPermission permission, String entityUuid) { TokenType tokenType = TokenType.valueOf(userToken.getType()); return switch (tokenType) { case USER_TOKEN -> super.hasEntityUuidPermission(permission, entityUuid); @@ -80,7 +81,7 @@ public class TokenUserSession extends ServerUserSession { } @Override - protected <T extends EntityDto> List<T> doKeepAuthorizedEntities(String permission, Collection<T> entities) { + protected <T extends EntityDto> List<T> doKeepAuthorizedEntities(ProjectPermission permission, Collection<T> entities) { TokenType tokenType = TokenType.valueOf(userToken.getType()); return switch (tokenType) { case USER_TOKEN, GLOBAL_ANALYSIS_TOKEN -> super.doKeepAuthorizedEntities(permission, entities); @@ -96,7 +97,7 @@ public class TokenUserSession extends ServerUserSession { * Required to override doKeepAuthorizedComponents to handle the case of a project analysis token */ @Override - protected Set<String> keepAuthorizedProjectsUuids(DbSession dbSession, String permission, Collection<String> entityUuids) { + protected Set<String> keepAuthorizedProjectsUuids(DbSession dbSession, ProjectPermission permission, Collection<String> entityUuids) { TokenType tokenType = TokenType.valueOf(userToken.getType()); return switch (tokenType) { case USER_TOKEN, GLOBAL_ANALYSIS_TOKEN -> super.keepAuthorizedProjectsUuids(dbSession, permission, entityUuids); diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/UserSession.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/UserSession.java index c5aaa7f866e..52f3966ed1e 100644 --- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/UserSession.java +++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/user/UserSession.java @@ -27,6 +27,7 @@ import javax.annotation.CheckForNull; import org.sonar.db.component.ComponentDto; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; import static java.util.Objects.requireNonNull; @@ -144,27 +145,27 @@ public interface UserSession { * @param component non-null component. * @param permission project permission as defined by {@link org.sonar.server.permission.PermissionService} */ - boolean hasComponentPermission(String permission, ComponentDto component); + boolean hasComponentPermission(ProjectPermission permission, ComponentDto component); - boolean hasEntityPermission(String permission, EntityDto entity); + boolean hasEntityPermission(ProjectPermission permission, EntityDto entity); - boolean hasEntityPermission(String permission, String entityUuid); + boolean hasEntityPermission(ProjectPermission permission, String entityUuid); - boolean hasChildProjectsPermission(String permission, ComponentDto component); + boolean hasChildProjectsPermission(ProjectPermission permission, ComponentDto component); - boolean hasChildProjectsPermission(String permission, EntityDto application); + boolean hasChildProjectsPermission(ProjectPermission permission, EntityDto application); - boolean hasPortfolioChildProjectsPermission(String permission, ComponentDto component); + boolean hasPortfolioChildProjectsPermission(ProjectPermission permission, ComponentDto component); /** - * Using {@link #hasComponentPermission(String, ComponentDto)} is recommended + * Using {@link #hasComponentPermission(ProjectPermission, ComponentDto)} is recommended * because it does not have to load project if the referenced component * is not a project. * - * @deprecated use {@link #hasComponentPermission(String, ComponentDto)} instead + * @deprecated use {@link #hasComponentPermission(ProjectPermission, ComponentDto)} instead */ @Deprecated - boolean hasComponentUuidPermission(String permission, String componentUuid); + boolean hasComponentUuidPermission(ProjectPermission permission, String componentUuid); /** * Return the subset of specified components which the user has granted permission. @@ -173,50 +174,50 @@ public interface UserSession { * If the input is ordered, then the returned components are in the same order. * The duplicated components are returned duplicated too. */ - List<ComponentDto> keepAuthorizedComponents(String permission, Collection<ComponentDto> components); + List<ComponentDto> keepAuthorizedComponents(ProjectPermission permission, Collection<ComponentDto> components); - <T extends EntityDto> List<T> keepAuthorizedEntities(String permission, Collection<T> components); + <T extends EntityDto> List<T> keepAuthorizedEntities(ProjectPermission permission, Collection<T> components); /** - * Ensures that {@link #hasComponentPermission(String, ComponentDto)} is {@code true}, + * Ensures that {@link #hasComponentPermission(ProjectPermission, ComponentDto)} is {@code true}, * otherwise throws a {@link org.sonar.server.exceptions.ForbiddenException}. */ - UserSession checkComponentPermission(String projectPermission, ComponentDto component); + UserSession checkComponentPermission(ProjectPermission projectPermission, ComponentDto component); /** * Ensures that {@link #hasEntityPermission(String, EntityDto)} is {@code true}, * otherwise throws a {@link org.sonar.server.exceptions.ForbiddenException}. */ - UserSession checkEntityPermission(String projectPermission, EntityDto entity); + UserSession checkEntityPermission(ProjectPermission projectPermission, EntityDto entity); /** * Ensures that {@link #hasEntityPermission(String, EntityDto)} is {@code true}, * otherwise throws a {@link org.sonar.server.exceptions.ResourceForbiddenException}. * <p> - * Differs from {@link #checkEntityPermission(String, EntityDto)} by throwing a different exception (ensuring no resource listing is possible). + * Differs from {@link #checkEntityPermission(ProjectPermission, EntityDto)} by throwing a different exception (ensuring no resource listing is possible). */ - UserSession checkEntityPermissionOrElseThrowResourceForbiddenException(String projectPermission, EntityDto entity); + UserSession checkEntityPermissionOrElseThrowResourceForbiddenException(ProjectPermission projectPermission, EntityDto entity); /** - * Ensures that {@link #hasChildProjectsPermission(String, ComponentDto)} is {@code true} + * Ensures that {@link #hasChildProjectsPermission(ProjectPermission, ComponentDto)} is {@code true} * otherwise throws a {@link org.sonar.server.exceptions.ForbiddenException}. */ - UserSession checkChildProjectsPermission(String projectPermission, ComponentDto project); + UserSession checkChildProjectsPermission(ProjectPermission projectPermission, ComponentDto project); /** - * Ensures that {@link #hasChildProjectsPermission(String, EntityDto)} is {@code true} + * Ensures that {@link #hasChildProjectsPermission(ProjectPermission, EntityDto)} is {@code true} * otherwise throws a {@link org.sonar.server.exceptions.ForbiddenException}. */ - UserSession checkChildProjectsPermission(String projectPermission, EntityDto application); + UserSession checkChildProjectsPermission(ProjectPermission projectPermission, EntityDto application); /** - * Ensures that {@link #hasComponentUuidPermission(String, String)} is {@code true}, + * Ensures that {@link #hasComponentUuidPermission(ProjectPermission, String)} is {@code true}, * otherwise throws a {@link org.sonar.server.exceptions.ForbiddenException}. * - * @deprecated use {@link #checkComponentPermission(String, ComponentDto)} instead + * @deprecated use {@link #checkComponentPermission(ProjectPermission, ComponentDto)} instead */ @Deprecated - UserSession checkComponentUuidPermission(String permission, String componentUuid); + UserSession checkComponentUuidPermission(ProjectPermission permission, String componentUuid); /** * Whether user can administrate system, for example for using cross-organizations services diff --git a/server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/SafeModeUserSessionTest.java b/server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/SafeModeUserSessionTest.java index ea5fd3085dc..00e158af1c7 100644 --- a/server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/SafeModeUserSessionTest.java +++ b/server/sonar-webserver-auth/src/test/java/org/sonar/server/authentication/SafeModeUserSessionTest.java @@ -20,7 +20,7 @@ package org.sonar.server.authentication; import org.junit.Test; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.GlobalPermission; import static org.assertj.core.api.Assertions.assertThat; @@ -46,8 +46,8 @@ public class SafeModeUserSessionTest { assertThat(underTest.shouldResetPassword()).isFalse(); assertThat(underTest.isSystemAdministrator()).isFalse(); assertThat(underTest.hasPermissionImpl(GlobalPermission.ADMINISTER)).isFalse(); - assertThat(underTest.hasEntityUuidPermission(UserRole.USER, "foo")).isFalse(); - assertThat(underTest.hasChildProjectsPermission(UserRole.USER, "foo")).isFalse(); - assertThat(underTest.hasPortfolioChildProjectsPermission(UserRole.USER, "foo")).isFalse(); + assertThat(underTest.hasEntityUuidPermission(ProjectPermission.USER, "foo")).isFalse(); + assertThat(underTest.hasChildProjectsPermission(ProjectPermission.USER, "foo")).isFalse(); + assertThat(underTest.hasPortfolioChildProjectsPermission(ProjectPermission.USER, "foo")).isFalse(); } } diff --git a/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/DoPrivilegedTest.java b/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/DoPrivilegedTest.java index b4b7041236f..03355eaa833 100644 --- a/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/DoPrivilegedTest.java +++ b/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/DoPrivilegedTest.java @@ -19,14 +19,16 @@ */ package org.sonar.server.user; +import java.util.Arrays; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.sonar.db.component.ComponentDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.server.tester.MockUserSession; import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; public class DoPrivilegedTest { @@ -48,7 +50,8 @@ public class DoPrivilegedTest { // verify the session used inside Privileged task assertThat(catcher.userSession.isLoggedIn()).isFalse(); - assertThat(catcher.userSession.hasComponentPermission("any permission", new ComponentDto())).isTrue(); + Arrays.stream(ProjectPermission.values()) + .forEach(permission -> assertThat(catcher.userSession.hasComponentPermission(permission, new ComponentDto())).isTrue()); assertThat(catcher.userSession.isSystemAdministrator()).isTrue(); assertThat(catcher.userSession.shouldResetPassword()).isFalse(); assertThat(catcher.userSession.isActive()).isTrue(); @@ -77,7 +80,8 @@ public class DoPrivilegedTest { // verify the session used inside Privileged task assertThat(catcher.userSession.isLoggedIn()).isFalse(); - assertThat(catcher.userSession.hasComponentPermission("any permission", new ComponentDto())).isTrue(); + Arrays.stream(ProjectPermission.values()) + .forEach(permission -> assertThat(catcher.userSession.hasComponentPermission(permission, new ComponentDto())).isTrue()); } private class UserSessionCatcherTask extends DoPrivileged.Task { diff --git a/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/GithubWebhookUserSessionTest.java b/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/GithubWebhookUserSessionTest.java index a43f159cd11..960f56c83ff 100644 --- a/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/GithubWebhookUserSessionTest.java +++ b/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/GithubWebhookUserSessionTest.java @@ -22,6 +22,7 @@ package org.sonar.server.user; import java.util.Arrays; import org.junit.Test; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; @@ -96,22 +97,26 @@ public class GithubWebhookUserSessionTest { @Test public void hasProjectUuidPermission() { - assertThat(githubWebhookUserSession.hasEntityUuidPermission("perm", "project")).isFalse(); + Arrays.stream(ProjectPermission.values()).forEach(projectPermission -> + assertThat(githubWebhookUserSession.hasEntityUuidPermission(projectPermission, "project")).isFalse()); } @Test public void hasChildProjectsPermission() { - assertThat(githubWebhookUserSession.hasChildProjectsPermission("perm", "project")).isFalse(); + Arrays.stream(ProjectPermission.values()).forEach(projectPermission -> + assertThat(githubWebhookUserSession.hasChildProjectsPermission(projectPermission, "project")).isFalse()); } @Test public void hasPortfolioChildProjectsPermission() { - assertThat(githubWebhookUserSession.hasPortfolioChildProjectsPermission("perm", "project")).isFalse(); + Arrays.stream(ProjectPermission.values()).forEach(projectPermission -> + assertThat(githubWebhookUserSession.hasPortfolioChildProjectsPermission(projectPermission, "project")).isFalse()); } @Test public void hasComponentUuidPermission_returnsAlwaysTrue() { - assertThat(githubWebhookUserSession.hasComponentUuidPermission("perm", "project")).isTrue(); + Arrays.stream(ProjectPermission.values()).forEach(projectPermission -> + assertThat(githubWebhookUserSession.hasComponentUuidPermission(projectPermission, "project")).isTrue()); } @Test diff --git a/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/ThreadLocalUserSessionTest.java b/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/ThreadLocalUserSessionTest.java index 489cb81bae5..91a9a3ab728 100644 --- a/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/ThreadLocalUserSessionTest.java +++ b/server/sonar-webserver-auth/src/test/java/org/sonar/server/user/ThreadLocalUserSessionTest.java @@ -36,7 +36,7 @@ import org.sonar.server.tester.MockUserSession; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; public class ThreadLocalUserSessionTest { diff --git a/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/AbstractMockUserSession.java b/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/AbstractMockUserSession.java index fc5447032fd..1c0484de527 100644 --- a/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/AbstractMockUserSession.java +++ b/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/AbstractMockUserSession.java @@ -30,7 +30,7 @@ import java.util.Set; import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.component.BranchDto; import org.sonar.db.component.ComponentDto; import org.sonar.db.permission.GlobalPermission; @@ -39,20 +39,20 @@ import org.sonar.db.project.ProjectDto; import org.sonar.server.user.AbstractUserSession; import static com.google.common.base.Preconditions.checkArgument; +import static org.sonar.db.permission.ProjectPermission.PUBLIC_PERMISSIONS; public abstract class AbstractMockUserSession<T extends AbstractMockUserSession> extends AbstractUserSession { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractMockUserSession.class); - private static final Set<String> PUBLIC_PERMISSIONS = ImmutableSet.of(UserRole.USER, UserRole.CODEVIEWER); // FIXME to check with Simon private final Class<T> clazz; - private final HashMultimap<String, String> projectUuidByPermission = HashMultimap.create(); + private final HashMultimap<ProjectPermission, String> projectUuidByPermission = HashMultimap.create(); private final Set<GlobalPermission> permissions = new HashSet<>(); private final Map<String, String> projectUuidByComponentUuid = new HashMap<>(); private final Map<String, String> projectUuidByBranchUuid = new HashMap<>(); private final Map<String, Set<String>> applicationProjects = new HashMap<>(); private final Map<String, Set<String>> portfolioProjects = new HashMap<>(); - private final Set<String> projectPermissions = new HashSet<>(); + private final Set<ProjectPermission> projectPermissions = new HashSet<>(); private boolean systemAdministrator = false; private boolean resetPassword = false; @@ -78,10 +78,10 @@ public abstract class AbstractMockUserSession<T extends AbstractMockUserSession> Arrays.stream(components) .forEach(component -> { if (component.branchUuid().equals(component.uuid()) && !component.isPrivate()) { - this.projectUuidByPermission.put(UserRole.USER, component.uuid()); - this.projectUuidByPermission.put(UserRole.CODEVIEWER, component.uuid()); - this.projectPermissions.add(UserRole.USER); - this.projectPermissions.add(UserRole.CODEVIEWER); + this.projectUuidByPermission.put(ProjectPermission.USER, component.uuid()); + this.projectUuidByPermission.put(ProjectPermission.CODEVIEWER, component.uuid()); + this.projectPermissions.add(ProjectPermission.USER); + this.projectPermissions.add(ProjectPermission.CODEVIEWER); } this.projectUuidByComponentUuid.put(component.uuid(), component.branchUuid()); }); @@ -92,10 +92,10 @@ public abstract class AbstractMockUserSession<T extends AbstractMockUserSession> Arrays.stream(projects) .forEach(project -> { if (!project.isPrivate()) { - this.projectUuidByPermission.put(UserRole.USER, project.getUuid()); - this.projectUuidByPermission.put(UserRole.CODEVIEWER, project.getUuid()); - this.projectPermissions.add(UserRole.USER); - this.projectPermissions.add(UserRole.CODEVIEWER); + this.projectUuidByPermission.put(ProjectPermission.USER, project.getUuid()); + this.projectUuidByPermission.put(ProjectPermission.CODEVIEWER, project.getUuid()); + this.projectPermissions.add(ProjectPermission.USER); + this.projectPermissions.add(ProjectPermission.CODEVIEWER); } this.projectUuidByComponentUuid.put(project.getUuid(), project.getUuid()); }); @@ -118,10 +118,10 @@ public abstract class AbstractMockUserSession<T extends AbstractMockUserSession> Arrays.stream(portfolios) .forEach(portfolio -> { if (!portfolio.isPrivate()) { - this.projectUuidByPermission.put(UserRole.USER, portfolio.getUuid()); - this.projectUuidByPermission.put(UserRole.CODEVIEWER, portfolio.getUuid()); - this.projectPermissions.add(UserRole.USER); - this.projectPermissions.add(UserRole.CODEVIEWER); + this.projectUuidByPermission.put(ProjectPermission.USER, portfolio.getUuid()); + this.projectUuidByPermission.put(ProjectPermission.CODEVIEWER, portfolio.getUuid()); + this.projectPermissions.add(ProjectPermission.USER); + this.projectPermissions.add(ProjectPermission.CODEVIEWER); } this.projectUuidByComponentUuid.put(portfolio.getUuid(), portfolio.getUuid()); }); @@ -143,7 +143,7 @@ public abstract class AbstractMockUserSession<T extends AbstractMockUserSession> return clazz.cast(this); } - public T addProjectPermission(String permission, ComponentDto... components) { + public T addProjectPermission(ProjectPermission permission, ComponentDto... components) { Arrays.stream(components).forEach(component -> { checkArgument( component.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission), @@ -156,7 +156,7 @@ public abstract class AbstractMockUserSession<T extends AbstractMockUserSession> return clazz.cast(this); } - public T addProjectPermission(String permission, ProjectDto... projects) { + public T addProjectPermission(ProjectPermission permission, ProjectDto... projects) { Arrays.stream(projects).forEach(component -> { checkArgument( component.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission), @@ -169,7 +169,7 @@ public abstract class AbstractMockUserSession<T extends AbstractMockUserSession> return clazz.cast(this); } - public T addPortfolioPermission(String permission, PortfolioDto... portfolios) { + public T addPortfolioPermission(ProjectPermission permission, PortfolioDto... portfolios) { Arrays.stream(portfolios).forEach(component -> { checkArgument( component.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission), @@ -189,7 +189,7 @@ public abstract class AbstractMockUserSession<T extends AbstractMockUserSession> } @Override - public boolean hasComponentPermission(String permission, ComponentDto component) { + public boolean hasComponentPermission(ProjectPermission permission, ComponentDto component) { return componentUuidToEntityUuid(component.uuid()) .or(() -> componentUuidToEntityUuid(component.branchUuid())) .map(projectUuid -> hasEntityUuidPermission(permission, projectUuid)).orElseGet(() -> { @@ -199,19 +199,19 @@ public abstract class AbstractMockUserSession<T extends AbstractMockUserSession> } @Override - protected boolean hasEntityUuidPermission(String permission, String entityUuid) { + protected boolean hasEntityUuidPermission(ProjectPermission permission, String entityUuid) { return projectPermissions.contains(permission) && projectUuidByPermission.get(permission).contains(entityUuid); } @Override - protected boolean hasChildProjectsPermission(String permission, String applicationUuid) { + protected boolean hasChildProjectsPermission(ProjectPermission permission, String applicationUuid) { return applicationProjects.containsKey(applicationUuid) && applicationProjects.get(applicationUuid) .stream() .allMatch(projectUuid -> projectPermissions.contains(permission) && projectUuidByPermission.get(permission).contains(projectUuid)); } @Override - protected boolean hasPortfolioChildProjectsPermission(String permission, String portfolioUuid) { + protected boolean hasPortfolioChildProjectsPermission(ProjectPermission permission, String portfolioUuid) { return portfolioProjects.containsKey(portfolioUuid) && portfolioProjects.get(portfolioUuid) .stream() .allMatch(projectUuid -> projectPermissions.contains(permission) && projectUuidByPermission.get(permission).contains(projectUuid)); diff --git a/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/UserSessionRule.java b/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/UserSessionRule.java index 6940ed20fae..1d77dc6b2f8 100644 --- a/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/UserSessionRule.java +++ b/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/UserSessionRule.java @@ -35,6 +35,7 @@ import org.sonar.db.component.BranchDto; import org.sonar.db.component.ComponentDto; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.portfolio.PortfolioDto; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.GroupDto; @@ -208,12 +209,12 @@ public class UserSessionRule implements TestRule, UserSession, BeforeTestExecuti return this; } - public UserSessionRule addProjectPermission(String projectPermission, ComponentDto... components) { + public UserSessionRule addProjectPermission(ProjectPermission projectPermission, ComponentDto... components) { ensureAbstractMockUserSession().addProjectPermission(projectPermission, components); return this; } - public UserSessionRule addPortfolioPermission(String projectPermission, ComponentDto... components) { + public UserSessionRule addPortfolioPermission(ProjectPermission projectPermission, ComponentDto... components) { ensureAbstractMockUserSession().addProjectPermission(projectPermission, components); return this; } @@ -228,12 +229,12 @@ public class UserSessionRule implements TestRule, UserSession, BeforeTestExecuti return this; } - public UserSessionRule addProjectPermission(String projectPermission, ProjectDto... projectDto) { + public UserSessionRule addProjectPermission(ProjectPermission projectPermission, ProjectDto... projectDto) { ensureAbstractMockUserSession().addProjectPermission(projectPermission, projectDto); return this; } - public UserSessionRule addPortfolioPermission(String portfolioPermission, PortfolioDto... portfolioDto) { + public UserSessionRule addPortfolioPermission(ProjectPermission portfolioPermission, PortfolioDto... portfolioDto) { ensureAbstractMockUserSession().addPortfolioPermission(portfolioPermission, portfolioDto); return this; } @@ -272,47 +273,47 @@ public class UserSessionRule implements TestRule, UserSession, BeforeTestExecuti } @Override - public boolean hasComponentPermission(String permission, ComponentDto component) { + public boolean hasComponentPermission(ProjectPermission permission, ComponentDto component) { return currentUserSession.hasComponentPermission(permission, component); } @Override - public boolean hasEntityPermission(String permission, EntityDto entity) { + public boolean hasEntityPermission(ProjectPermission permission, EntityDto entity) { return currentUserSession.hasEntityPermission(permission, entity.getUuid()); } @Override - public boolean hasEntityPermission(String permission, String entityUuid) { + public boolean hasEntityPermission(ProjectPermission permission, String entityUuid) { return currentUserSession.hasEntityPermission(permission, entityUuid); } @Override - public boolean hasChildProjectsPermission(String permission, ComponentDto component) { + public boolean hasChildProjectsPermission(ProjectPermission permission, ComponentDto component) { return currentUserSession.hasChildProjectsPermission(permission, component); } @Override - public boolean hasChildProjectsPermission(String permission, EntityDto application) { + public boolean hasChildProjectsPermission(ProjectPermission permission, EntityDto application) { return currentUserSession.hasChildProjectsPermission(permission, application); } @Override - public boolean hasPortfolioChildProjectsPermission(String permission, ComponentDto component) { + public boolean hasPortfolioChildProjectsPermission(ProjectPermission permission, ComponentDto component) { return currentUserSession.hasPortfolioChildProjectsPermission(permission, component); } @Override - public boolean hasComponentUuidPermission(String permission, String componentUuid) { + public boolean hasComponentUuidPermission(ProjectPermission permission, String componentUuid) { return currentUserSession.hasComponentUuidPermission(permission, componentUuid); } @Override - public List<ComponentDto> keepAuthorizedComponents(String permission, Collection<ComponentDto> components) { + public List<ComponentDto> keepAuthorizedComponents(ProjectPermission permission, Collection<ComponentDto> components) { return currentUserSession.keepAuthorizedComponents(permission, components); } @Override - public <T extends EntityDto> List<T> keepAuthorizedEntities(String permission, Collection<T> entities) { + public <T extends EntityDto> List<T> keepAuthorizedEntities(ProjectPermission permission, Collection<T> entities) { return currentUserSession.keepAuthorizedEntities(permission, entities); } @@ -383,37 +384,37 @@ public class UserSessionRule implements TestRule, UserSession, BeforeTestExecuti } @Override - public UserSession checkComponentPermission(String projectPermission, ComponentDto component) { + public UserSession checkComponentPermission(ProjectPermission projectPermission, ComponentDto component) { currentUserSession.checkComponentPermission(projectPermission, component); return this; } @Override - public UserSession checkEntityPermission(String projectPermission, EntityDto entity) { + public UserSession checkEntityPermission(ProjectPermission projectPermission, EntityDto entity) { currentUserSession.checkEntityPermission(projectPermission, entity); return this; } @Override - public UserSession checkEntityPermissionOrElseThrowResourceForbiddenException(String projectPermission, EntityDto entity) { + public UserSession checkEntityPermissionOrElseThrowResourceForbiddenException(ProjectPermission projectPermission, EntityDto entity) { currentUserSession.checkEntityPermissionOrElseThrowResourceForbiddenException(projectPermission, entity); return this; } @Override - public UserSession checkChildProjectsPermission(String projectPermission, ComponentDto component) { + public UserSession checkChildProjectsPermission(ProjectPermission projectPermission, ComponentDto component) { currentUserSession.checkChildProjectsPermission(projectPermission, component); return this; } @Override - public UserSession checkChildProjectsPermission(String projectPermission, EntityDto application) { + public UserSession checkChildProjectsPermission(ProjectPermission projectPermission, EntityDto application) { currentUserSession.checkChildProjectsPermission(projectPermission, application); return this; } @Override - public UserSession checkComponentUuidPermission(String permission, String componentUuid) { + public UserSession checkComponentUuidPermission(ProjectPermission permission, String componentUuid) { currentUserSession.checkComponentUuidPermission(permission, componentUuid); return this; } diff --git a/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/user/TestUserSessionFactory.java b/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/user/TestUserSessionFactory.java index 7431b18045e..c50bd10b04b 100644 --- a/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/user/TestUserSessionFactory.java +++ b/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/user/TestUserSessionFactory.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.Optional; import javax.annotation.Nullable; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; import org.sonar.db.user.UserTokenDto; @@ -123,17 +124,17 @@ public class TestUserSessionFactory implements UserSessionFactory { } @Override - protected boolean hasEntityUuidPermission(String permission, String entityUuid) { + protected boolean hasEntityUuidPermission(ProjectPermission permission, String entityUuid) { throw notImplemented(); } @Override - protected boolean hasChildProjectsPermission(String permission, String applicationUuid) { + protected boolean hasChildProjectsPermission(ProjectPermission permission, String applicationUuid) { throw notImplemented(); } @Override - protected boolean hasPortfolioChildProjectsPermission(String permission, String portfolioUuid) { throw notImplemented(); } + protected boolean hasPortfolioChildProjectsPermission(ProjectPermission permission, String portfolioUuid) { throw notImplemented(); } @Override public boolean isSystemAdministrator() { diff --git a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/component/ComponentUpdaterIT.java b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/component/ComponentUpdaterIT.java index 7b43b4e1079..809c680b6e2 100644 --- a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/component/ComponentUpdaterIT.java +++ b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/component/ComponentUpdaterIT.java @@ -30,7 +30,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.NullSource; import org.junit.jupiter.params.provider.ValueSource; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -525,7 +525,8 @@ public class ComponentUpdaterIT { List<String> permissions = db.getDbClient().userPermissionDao().selectEntityPermissionsOfUser(session, userDto.getUuid(), componentCreationData.projectDto().getUuid()); assertThat(permissions) - .containsExactlyInAnyOrder(UserRole.USER, UserRole.CODEVIEWER); + .map(ProjectPermission::fromKey) + .containsExactlyInAnyOrder(ProjectPermission.USER, ProjectPermission.CODEVIEWER); } @Test diff --git a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/permission/GroupPermissionChangerIT.java b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/permission/GroupPermissionChangerIT.java index 2c93b3ab581..d1bafecf5b2 100644 --- a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/permission/GroupPermissionChangerIT.java +++ b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/permission/GroupPermissionChangerIT.java @@ -24,20 +24,20 @@ import org.apache.commons.lang3.StringUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentTypes; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.core.util.Uuids; import org.sonar.db.DbSession; import org.sonar.db.DbTester; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.permission.GlobalPermission; import org.sonar.db.permission.GroupPermissionDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; @@ -107,93 +107,93 @@ public class GroupPermissionChangerIT { .forEach(perm -> { apply(new GroupPermissionChange(Operation.REMOVE, perm, privateProject, null, permissionService)); - assertThat(db.users().selectAnyonePermissions(privateProject.getUuid())).contains(perm); + assertThat(db.users().selectAnyonePermissions(privateProject.getUuid())).map(ProjectPermission::fromKey).contains(perm); }); } @Test public void apply_adds_permission_USER_to_group_on_private_project() { - applyAddsPermissionToGroupOnPrivateProject(UserRole.USER); + applyAddsPermissionToGroupOnPrivateProject(ProjectPermission.USER); } @Test public void apply_adds_permission_CODEVIEWER_to_group_on_private_project() { - applyAddsPermissionToGroupOnPrivateProject(UserRole.CODEVIEWER); + applyAddsPermissionToGroupOnPrivateProject(ProjectPermission.CODEVIEWER); } @Test public void apply_adds_permission_ADMIN_to_group_on_private_project() { - applyAddsPermissionToGroupOnPrivateProject(UserRole.ADMIN); + applyAddsPermissionToGroupOnPrivateProject(ProjectPermission.ADMIN); } @Test public void apply_adds_permission_ISSUE_ADMIN_to_group_on_private_project() { - applyAddsPermissionToGroupOnPrivateProject(UserRole.ISSUE_ADMIN); + applyAddsPermissionToGroupOnPrivateProject(ProjectPermission.ISSUE_ADMIN); } @Test public void apply_adds_permission_SCAN_EXECUTION_to_group_on_private_project() { - applyAddsPermissionToGroupOnPrivateProject(GlobalPermission.SCAN.getKey()); + applyAddsPermissionToGroupOnPrivateProject(ProjectPermission.SCAN); } - private void applyAddsPermissionToGroupOnPrivateProject(String permission) { + private void applyAddsPermissionToGroupOnPrivateProject(ProjectPermission permission) { apply(new GroupPermissionChange(Operation.ADD, permission, privateProject, group, permissionService)); assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); - assertThat(db.users().selectGroupPermissions(group, privateProject)).containsOnly(permission); + assertThat(db.users().selectGroupPermissions(group, privateProject)).containsOnly(permission.getKey()); } @Test public void apply_removes_permission_USER_from_group_on_private_project() { - applyRemovesPermissionFromGroupOnPrivateProject(UserRole.USER); + applyRemovesPermissionFromGroupOnPrivateProject(ProjectPermission.USER); } @Test public void apply_removes_permission_CODEVIEWER_from_group_on_private_project() { - applyRemovesPermissionFromGroupOnPrivateProject(UserRole.CODEVIEWER); + applyRemovesPermissionFromGroupOnPrivateProject(ProjectPermission.CODEVIEWER); } @Test public void apply_removes_permission_ADMIN_from_on_private_project() { - applyRemovesPermissionFromGroupOnPrivateProject(UserRole.ADMIN); + applyRemovesPermissionFromGroupOnPrivateProject(ProjectPermission.ADMIN); } @Test public void apply_removes_permission_ISSUE_ADMIN_from_on_private_project() { - applyRemovesPermissionFromGroupOnPrivateProject(UserRole.ISSUE_ADMIN); + applyRemovesPermissionFromGroupOnPrivateProject(ProjectPermission.ISSUE_ADMIN); } @Test public void apply_removes_permission_SCAN_EXECUTION_from_on_private_project() { - applyRemovesPermissionFromGroupOnPrivateProject(GlobalPermission.SCAN.getKey()); + applyRemovesPermissionFromGroupOnPrivateProject(ProjectPermission.SCAN); } - private void applyRemovesPermissionFromGroupOnPrivateProject(String permission) { + private void applyRemovesPermissionFromGroupOnPrivateProject(ProjectPermission permission) { db.users().insertEntityPermissionOnGroup(group, permission, privateProject); - apply(new GroupPermissionChange(Operation.ADD, permission, privateProject, group, permissionService), permission); + apply(new GroupPermissionChange(Operation.ADD, permission, privateProject, group, permissionService), permission.getKey()); - assertThat(db.users().selectGroupPermissions(group, privateProject)).containsOnly(permission); + assertThat(db.users().selectGroupPermissions(group, privateProject)).containsOnly(permission.getKey()); } @Test public void apply_has_no_effect_when_adding_USER_permission_to_group_AnyOne_on_a_public_project() { - apply(new GroupPermissionChange(Operation.ADD, UserRole.USER, publicProject, null, permissionService)); + apply(new GroupPermissionChange(Operation.ADD, ProjectPermission.USER, publicProject, null, permissionService)); assertThat(db.users().selectAnyonePermissions(publicProject.getUuid())).isEmpty(); } @Test public void apply_has_no_effect_when_adding_CODEVIEWER_permission_to_group_AnyOne_on_a_public_project() { - apply(new GroupPermissionChange(Operation.ADD, UserRole.CODEVIEWER, publicProject, null, permissionService)); + apply(new GroupPermissionChange(Operation.ADD, ProjectPermission.CODEVIEWER, publicProject, null, permissionService)); assertThat(db.users().selectAnyonePermissions(publicProject.getUuid())).isEmpty(); } @Test public void apply_fails_with_BadRequestException_when_adding_permission_ADMIN_to_group_AnyOne_on_a_public_project() { - GroupPermissionChange change = new GroupPermissionChange(Operation.ADD, UserRole.ADMIN, publicProject, null, permissionService); + GroupPermissionChange change = new GroupPermissionChange(Operation.ADD, ProjectPermission.ADMIN, publicProject, null, permissionService); assertThatThrownBy(() -> apply(change)) .isInstanceOf(BadRequestException.class) .hasMessage("It is not possible to add the 'admin' permission to group 'Anyone'."); @@ -201,9 +201,9 @@ public class GroupPermissionChangerIT { @Test public void apply_adds_permission_ISSUE_ADMIN_to_group_AnyOne_on_a_public_project() { - apply(new GroupPermissionChange(Operation.ADD, UserRole.ISSUE_ADMIN, publicProject, null, permissionService)); + apply(new GroupPermissionChange(Operation.ADD, ProjectPermission.ISSUE_ADMIN, publicProject, null, permissionService)); - assertThat(db.users().selectAnyonePermissions(publicProject.getUuid())).containsOnly(UserRole.ISSUE_ADMIN); + assertThat(db.users().selectAnyonePermissions(publicProject.getUuid())).containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); } @Test @@ -215,7 +215,7 @@ public class GroupPermissionChangerIT { @Test public void apply_fails_with_BadRequestException_when_removing_USER_permission_from_group_AnyOne_on_a_public_project() { - GroupPermissionChange change = new GroupPermissionChange(Operation.REMOVE, UserRole.USER, publicProject, null, permissionService); + GroupPermissionChange change = new GroupPermissionChange(Operation.REMOVE, ProjectPermission.USER, publicProject, null, permissionService); assertThatThrownBy(() -> apply(change)) .isInstanceOf(BadRequestException.class) .hasMessage("Permission user can't be removed from a public component"); @@ -223,7 +223,7 @@ public class GroupPermissionChangerIT { @Test public void apply_fails_with_BadRequestException_when_removing_CODEVIEWER_permission_from_group_AnyOne_on_a_public_project() { - GroupPermissionChange change = new GroupPermissionChange(Operation.REMOVE, UserRole.CODEVIEWER, publicProject, null, permissionService); + GroupPermissionChange change = new GroupPermissionChange(Operation.REMOVE, ProjectPermission.CODEVIEWER.getKey(), publicProject, null, permissionService); assertThatThrownBy(() -> apply(change)) .isInstanceOf(BadRequestException.class) .hasMessage("Permission codeviewer can't be removed from a public component"); @@ -231,12 +231,12 @@ public class GroupPermissionChangerIT { @Test public void apply_removes_ADMIN_permission_from_group_AnyOne_on_a_public_project() { - applyRemovesPermissionFromGroupAnyOneOnAPublicProject(UserRole.ADMIN); + applyRemovesPermissionFromGroupAnyOneOnAPublicProject(ProjectPermission.ADMIN.getKey()); } @Test public void apply_removes_ISSUE_ADMIN_permission_from_group_AnyOne_on_a_public_project() { - applyRemovesPermissionFromGroupAnyOneOnAPublicProject(UserRole.ISSUE_ADMIN); + applyRemovesPermissionFromGroupAnyOneOnAPublicProject(ProjectPermission.ISSUE_ADMIN.getKey()); } @Test @@ -254,7 +254,7 @@ public class GroupPermissionChangerIT { @Test public void apply_fails_with_BadRequestException_when_removing_USER_permission_from_a_group_on_a_public_project() { - GroupPermissionChange change = new GroupPermissionChange(Operation.REMOVE, UserRole.USER, publicProject, group, permissionService); + GroupPermissionChange change = new GroupPermissionChange(Operation.REMOVE, ProjectPermission.USER, publicProject, group, permissionService); assertThatThrownBy(() -> apply(change)) .isInstanceOf(BadRequestException.class) .hasMessage("Permission user can't be removed from a public component"); @@ -262,7 +262,7 @@ public class GroupPermissionChangerIT { @Test public void apply_fails_with_BadRequestException_when_removing_CODEVIEWER_permission_from_a_group_on_a_public_project() { - GroupPermissionChange change = new GroupPermissionChange(Operation.REMOVE, UserRole.CODEVIEWER, publicProject, group, permissionService); + GroupPermissionChange change = new GroupPermissionChange(Operation.REMOVE, ProjectPermission.CODEVIEWER, publicProject, group, permissionService); assertThatThrownBy(() -> apply(change)) .isInstanceOf(BadRequestException.class) .hasMessage("Permission codeviewer can't be removed from a public component"); @@ -270,7 +270,7 @@ public class GroupPermissionChangerIT { @Test public void add_permission_to_anyone() { - apply(new GroupPermissionChange(Operation.ADD, ADMINISTER_QUALITY_PROFILES.getKey(), null, null, permissionService)); + apply(new GroupPermissionChange(Operation.ADD, ADMINISTER_QUALITY_PROFILES, null, permissionService)); assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); assertThat(db.users().selectAnyonePermissions(null)).containsOnly(ADMINISTER_QUALITY_PROFILES.getKey()); @@ -280,7 +280,7 @@ public class GroupPermissionChangerIT { public void do_nothing_when_adding_permission_that_already_exists() { db.users().insertPermissionOnGroup(group, ADMINISTER_QUALITY_GATES); - apply(new GroupPermissionChange(Operation.ADD, ADMINISTER_QUALITY_GATES.getKey(), null, group, permissionService), ADMINISTER_QUALITY_GATES.getKey()); + apply(new GroupPermissionChange(Operation.ADD, ADMINISTER_QUALITY_GATES, group, permissionService), ADMINISTER_QUALITY_GATES.getKey()); assertThat(db.users().selectGroupPermissions(group, null)).containsExactly(ADMINISTER_QUALITY_GATES.getKey()); } @@ -288,32 +288,26 @@ public class GroupPermissionChangerIT { @Test public void fail_to_add_global_permission_but_SCAN_and_ADMIN_on_private_project() { permissionService.getGlobalPermissions().stream() - .map(GlobalPermission::getKey) - .filter(perm -> !UserRole.ADMIN.equals(perm) && !GlobalPermission.SCAN.getKey().equals(perm)) + .filter(perm -> !ADMINISTER.equals(perm) && !GlobalPermission.SCAN.equals(perm)) .forEach(perm -> { - try { - new GroupPermissionChange(Operation.ADD, perm, privateProject, group, permissionService); - fail("a BadRequestException should have been thrown for permission " + perm); - } catch (BadRequestException e) { - assertThat(e).hasMessage("Invalid project permission '" + perm + - "'. Valid values are [" + StringUtils.join(permissionService.getAllProjectPermissions(), ", ") + "]"); - } + var permissionKey = perm.getKey(); + assertThatThrownBy(() -> new GroupPermissionChange(Operation.ADD, permissionKey, privateProject, group, permissionService)) + .withFailMessage("a BadRequestException should have been thrown for permission " + perm) + .isInstanceOf(BadRequestException.class) + .hasMessage("Invalid project permission '" + perm + "'. Valid values are [" + StringUtils.join(permissionService.getAllProjectPermissions(), ", ") + "]"); }); } @Test public void fail_to_add_global_permission_but_SCAN_and_ADMIN_on_public_project() { permissionService.getGlobalPermissions().stream() - .map(GlobalPermission::getKey) - .filter(perm -> !UserRole.ADMIN.equals(perm) && !GlobalPermission.SCAN.getKey().equals(perm)) + .filter(perm -> !ADMINISTER.equals(perm) && !GlobalPermission.SCAN.equals(perm)) .forEach(perm -> { - try { - new GroupPermissionChange(Operation.ADD, perm, publicProject, group, permissionService); - fail("a BadRequestException should have been thrown for permission " + perm); - } catch (BadRequestException e) { - assertThat(e).hasMessage("Invalid project permission '" + perm + - "'. Valid values are [" + StringUtils.join(permissionService.getAllProjectPermissions(), ", ") + "]"); - } + var permissionKey = perm.getKey(); + assertThatThrownBy(() -> new GroupPermissionChange(Operation.ADD, permissionKey, publicProject, group, permissionService)) + .withFailMessage("a BadRequestException should have been thrown for permission " + perm) + .isInstanceOf(BadRequestException.class) + .hasMessage("Invalid project permission '" + perm + "'. Valid values are [" + StringUtils.join(permissionService.getAllProjectPermissions(), ", ") + "]"); }); } @@ -321,14 +315,13 @@ public class GroupPermissionChangerIT { public void fail_to_add_project_permission_but_SCAN_and_ADMIN_on_global_group() { permissionService.getAllProjectPermissions() .stream() - .filter(perm -> !GlobalPermission.SCAN.getKey().equals(perm) && !GlobalPermission.ADMINISTER.getKey().equals(perm)) + .filter(perm -> !ProjectPermission.SCAN.equals(perm) && !ProjectPermission.ADMIN.equals(perm)) .forEach(permission -> { - try { - new GroupPermissionChange(Operation.ADD, permission, null, group, permissionService); - fail("a BadRequestException should have been thrown for permission " + permission); - } catch (BadRequestException e) { - assertThat(e).hasMessage("Invalid global permission '" + permission + "'. Valid values are [admin, gateadmin, profileadmin, provisioning, scan]"); - } + var permissionKey = permission.getKey(); + assertThatThrownBy(() -> new GroupPermissionChange(Operation.ADD, permissionKey, null, group, permissionService)) + .withFailMessage("a BadRequestException should have been thrown for permission " + permission) + .isInstanceOf(BadRequestException.class) + .hasMessage("Invalid global permission '" + permission + "'. Valid values are [admin, gateadmin, profileadmin, provisioning, scan]"); }); } @@ -337,7 +330,7 @@ public class GroupPermissionChangerIT { db.users().insertPermissionOnGroup(group, ADMINISTER_QUALITY_GATES); db.users().insertPermissionOnGroup(group, PROVISION_PROJECTS); - apply(new GroupPermissionChange(Operation.REMOVE, ADMINISTER_QUALITY_GATES.getKey(), null, group, permissionService), ADMINISTER_QUALITY_GATES.getKey(), + apply(new GroupPermissionChange(Operation.REMOVE, ADMINISTER_QUALITY_GATES, group, permissionService), ADMINISTER_QUALITY_GATES.getKey(), PROVISION_PROJECTS.getKey()); assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(PROVISION_PROJECTS.getKey()); @@ -346,19 +339,19 @@ public class GroupPermissionChangerIT { @Test public void remove_project_permission_from_group() { db.users().insertPermissionOnGroup(group, ADMINISTER_QUALITY_GATES); - db.users().insertEntityPermissionOnGroup(group, UserRole.ISSUE_ADMIN, privateProject); - db.users().insertEntityPermissionOnGroup(group, UserRole.CODEVIEWER, privateProject); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.ISSUE_ADMIN, privateProject); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.CODEVIEWER, privateProject); - apply(new GroupPermissionChange(Operation.REMOVE, UserRole.ISSUE_ADMIN, privateProject, group, permissionService), UserRole.ISSUE_ADMIN, - UserRole.CODEVIEWER); + apply(new GroupPermissionChange(Operation.REMOVE, ProjectPermission.ISSUE_ADMIN.getKey(), privateProject, group, permissionService), ProjectPermission.ISSUE_ADMIN.getKey(), + ProjectPermission.CODEVIEWER.getKey()); assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(ADMINISTER_QUALITY_GATES.getKey()); - assertThat(db.users().selectGroupPermissions(group, privateProject)).containsOnly(UserRole.CODEVIEWER); + assertThat(db.users().selectGroupPermissions(group, privateProject)).containsOnly(ProjectPermission.CODEVIEWER.getKey()); } @Test public void do_not_fail_if_removing_a_permission_that_does_not_exist() { - apply(new GroupPermissionChange(Operation.REMOVE, UserRole.ISSUE_ADMIN, privateProject, group, permissionService)); + apply(new GroupPermissionChange(Operation.REMOVE, ProjectPermission.ISSUE_ADMIN.getKey(), privateProject, group, permissionService)); assertThat(db.users().selectGroupPermissions(group, null)).isEmpty(); assertThat(db.users().selectGroupPermissions(group, privateProject)).isEmpty(); @@ -392,7 +385,7 @@ public class GroupPermissionChangerIT { db.commit(); } - private void unsafeInsertProjectPermissionOnAnyone(String perm) { + private void unsafeInsertProjectPermissionOnAnyone(ProjectPermission perm) { GroupPermissionDto dto = new GroupPermissionDto() .setUuid(Uuids.createFast()) .setGroupUuid(null) diff --git a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/permission/PermissionTemplateServiceIT.java b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/permission/PermissionTemplateServiceIT.java index b362cc9a87b..4151521e7b5 100644 --- a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/permission/PermissionTemplateServiceIT.java +++ b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/permission/PermissionTemplateServiceIT.java @@ -25,18 +25,18 @@ import java.util.stream.Stream; import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; -import org.sonar.api.web.UserRole; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.db.DbSession; import org.sonar.db.DbTester; -import org.sonar.server.component.ComponentTypesRule; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.PermissionTemplateDbTester; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.portfolio.PortfolioDto; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.es.Indexers; import org.sonar.server.es.TestIndexers; import org.sonar.server.exceptions.TemplateMatchingKeyException; @@ -101,7 +101,7 @@ public class PermissionTemplateServiceIT { underTest.applyAndCommit(session, permissionTemplate, singletonList(publicProject)); assertThat(selectProjectPermissionsOfGroup(null, publicProject.getUuid())) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermission.SCAN.getKey()); + .containsOnly("p1", ProjectPermission.ADMIN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), ProjectPermission.SCAN.getKey()); } @Test @@ -116,7 +116,7 @@ public class PermissionTemplateServiceIT { underTest.applyDefaultToNewComponent(session, publicProject, null); assertThat(selectProjectPermissionsOfGroup(null, publicProject.getUuid())) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermission.SCAN.getKey()); + .containsOnly("p1", ProjectPermission.ADMIN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), ProjectPermission.SCAN.getKey()); } @Test @@ -131,7 +131,7 @@ public class PermissionTemplateServiceIT { underTest.applyAndCommit(session, permissionTemplate, singletonList(privateProject)); assertThat(selectProjectPermissionsOfGroup(group, privateProject.getUuid())) - .containsOnly("p1", UserRole.CODEVIEWER, UserRole.USER, UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermission.SCAN.getKey()); + .containsOnly("p1", ProjectPermission.CODEVIEWER.getKey(), ProjectPermission.USER.getKey(), ProjectPermission.ADMIN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), ProjectPermission.SCAN.getKey()); } @Test @@ -147,7 +147,7 @@ public class PermissionTemplateServiceIT { underTest.applyDefaultToNewComponent(session, privateProject, null); assertThat(selectProjectPermissionsOfGroup(group, privateProject.getUuid())) - .containsOnly("p1", UserRole.CODEVIEWER, UserRole.USER, UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermission.SCAN.getKey()); + .containsOnly("p1", ProjectPermission.CODEVIEWER.getKey(), ProjectPermission.USER.getKey(), ProjectPermission.ADMIN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), ProjectPermission.SCAN.getKey()); } @Test @@ -162,7 +162,7 @@ public class PermissionTemplateServiceIT { underTest.applyAndCommit(session, permissionTemplate, singletonList(publicProject)); assertThat(selectProjectPermissionsOfGroup(group, publicProject.getUuid())) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermission.SCAN.getKey()); + .containsOnly("p1", ProjectPermission.ADMIN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), ProjectPermission.SCAN.getKey()); } @Test @@ -178,7 +178,7 @@ public class PermissionTemplateServiceIT { underTest.applyDefaultToNewComponent(session, publicProject, null); assertThat(selectProjectPermissionsOfGroup(group, publicProject.getUuid())) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermission.SCAN.getKey()); + .containsOnly("p1", ProjectPermission.ADMIN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), ProjectPermission.SCAN.getKey()); } @Test @@ -193,7 +193,7 @@ public class PermissionTemplateServiceIT { underTest.applyAndCommit(session, permissionTemplate, singletonList(publicProject)); assertThat(selectProjectPermissionsOfUser(user, publicProject.getUuid())) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermission.SCAN.getKey()); + .containsOnly("p1", ProjectPermission.ADMIN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), ProjectPermission.SCAN.getKey()); } @Test @@ -209,7 +209,7 @@ public class PermissionTemplateServiceIT { underTest.applyDefaultToNewComponent(session, publicProject, null); assertThat(selectProjectPermissionsOfUser(user, publicProject.getUuid())) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermission.SCAN.getKey()); + .containsOnly("p1", ProjectPermission.ADMIN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), ProjectPermission.SCAN.getKey()); } @Test @@ -224,7 +224,7 @@ public class PermissionTemplateServiceIT { underTest.applyAndCommit(session, permissionTemplate, singletonList(privateProject)); assertThat(selectProjectPermissionsOfUser(user, privateProject.getUuid())) - .containsOnly("p1", UserRole.CODEVIEWER, UserRole.USER, UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermission.SCAN.getKey()); + .containsOnly("p1", ProjectPermission.CODEVIEWER.getKey(), ProjectPermission.USER.getKey(), ProjectPermission.ADMIN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), ProjectPermission.SCAN.getKey()); } @Test @@ -240,7 +240,7 @@ public class PermissionTemplateServiceIT { underTest.applyDefaultToNewComponent(session, privateProject, null); assertThat(selectProjectPermissionsOfUser(user, privateProject.getUuid())) - .containsOnly("p1", UserRole.CODEVIEWER, UserRole.USER, UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermission.SCAN.getKey()); + .containsOnly("p1", ProjectPermission.CODEVIEWER.getKey(), ProjectPermission.USER.getKey(), ProjectPermission.ADMIN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), ProjectPermission.SCAN.getKey()); } @Test @@ -256,7 +256,7 @@ public class PermissionTemplateServiceIT { underTest.applyDefaultToNewComponent(session, publicProject, user.getUuid()); assertThat(selectProjectPermissionsOfUser(user, publicProject.getUuid())) - .containsOnly("p1", UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermission.SCAN.getKey()); + .containsOnly("p1", ProjectPermission.ADMIN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), ProjectPermission.SCAN.getKey()); } @Test @@ -272,7 +272,7 @@ public class PermissionTemplateServiceIT { underTest.applyDefaultToNewComponent(session, privateProject, user.getUuid()); assertThat(selectProjectPermissionsOfUser(user, privateProject.getUuid())) - .containsOnly("p1", UserRole.CODEVIEWER, UserRole.USER, UserRole.ADMIN, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, GlobalPermission.SCAN.getKey()); + .containsOnly("p1", ProjectPermission.CODEVIEWER.getKey(), ProjectPermission.USER.getKey(), ProjectPermission.ADMIN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), GlobalPermission.SCAN.getKey()); } @Test @@ -386,16 +386,16 @@ public class PermissionTemplateServiceIT { ProjectDto project = dbTester.components().insertPrivateProject().getProjectDto(); GroupDto adminGroup = dbTester.users().insertGroup(); GroupDto userGroup = dbTester.users().insertGroup(); - dbTester.users().insertPermissionOnGroup(adminGroup, GlobalPermission.ADMINISTER.getKey()); - dbTester.users().insertPermissionOnGroup(userGroup, UserRole.USER); + dbTester.users().insertPermissionOnGroup(adminGroup, GlobalPermission.ADMINISTER); + dbTester.users().insertPermissionOnGroup(userGroup, ProjectPermission.USER); dbTester.users().insertGlobalPermissionOnUser(user, GlobalPermission.ADMINISTER); PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(); dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, adminGroup, GlobalPermission.ADMINISTER.getKey()); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, adminGroup, UserRole.ISSUE_ADMIN); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, userGroup, UserRole.USER); - dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, userGroup, UserRole.CODEVIEWER); - dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, UserRole.USER); - dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, UserRole.CODEVIEWER); + dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, adminGroup, ProjectPermission.ISSUE_ADMIN); + dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, userGroup, ProjectPermission.USER); + dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, userGroup, ProjectPermission.CODEVIEWER); + dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, ProjectPermission.USER); + dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, ProjectPermission.CODEVIEWER); dbTester.permissionTemplates().addUserToTemplate(permissionTemplate, user, GlobalPermission.ADMINISTER.getKey()); assertThat(selectProjectPermissionsOfGroup(adminGroup, project.getUuid())).isEmpty(); @@ -405,8 +405,8 @@ public class PermissionTemplateServiceIT { underTest.applyAndCommit(session, permissionTemplate, singletonList(project)); - assertThat(selectProjectPermissionsOfGroup(adminGroup, project.getUuid())).containsOnly(GlobalPermission.ADMINISTER.getKey(), UserRole.ISSUE_ADMIN); - assertThat(selectProjectPermissionsOfGroup(userGroup, project.getUuid())).containsOnly(UserRole.USER, UserRole.CODEVIEWER); + assertThat(selectProjectPermissionsOfGroup(adminGroup, project.getUuid())).containsOnly(GlobalPermission.ADMINISTER.getKey(), ProjectPermission.ISSUE_ADMIN.getKey()); + assertThat(selectProjectPermissionsOfGroup(userGroup, project.getUuid())).containsOnly(ProjectPermission.USER.getKey(), ProjectPermission.CODEVIEWER.getKey()); assertThat(selectProjectPermissionsOfGroup(null, project.getUuid())).isEmpty(); assertThat(selectProjectPermissionsOfUser(user, project.getUuid())).containsOnly(GlobalPermission.ADMINISTER.getKey()); } @@ -427,9 +427,9 @@ public class PermissionTemplateServiceIT { PermissionTemplateDto template = templateDb.insertTemplate(); dbTester.permissionTemplates().setDefaultTemplates(template, null, null); templateDb.addProjectCreatorToTemplate(template.getUuid(), GlobalPermission.SCAN.getKey(), template.getName()); - templateDb.addUserToTemplate(template.getUuid(), user.getUuid(), UserRole.USER, template.getName(), user.getLogin()); - templateDb.addGroupToTemplate(template.getUuid(), group.getUuid(), UserRole.CODEVIEWER, template.getName(), group.getName()); - templateDb.addGroupToTemplate(template.getUuid(), null, UserRole.ISSUE_ADMIN, template.getName(), null); + templateDb.addUserToTemplate(template.getUuid(), user.getUuid(), ProjectPermission.USER, template.getName(), user.getLogin()); + templateDb.addGroupToTemplate(template.getUuid(), group.getUuid(), ProjectPermission.CODEVIEWER, template.getName(), group.getName()); + templateDb.addGroupToTemplate(template.getUuid(), null, ProjectPermission.ISSUE_ADMIN, template.getName(), null); // authenticated user checkWouldUserHaveScanPermission(user.getUuid(), true); diff --git a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/permission/UserPermissionChangerIT.java b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/permission/UserPermissionChangerIT.java index ee06ae88bc3..87910895440 100644 --- a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/permission/UserPermissionChangerIT.java +++ b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/permission/UserPermissionChangerIT.java @@ -19,24 +19,25 @@ */ package org.sonar.server.common.permission; +import java.util.Arrays; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentTypes; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.db.DbSession; import org.sonar.db.DbTester; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; import org.sonar.db.user.UserIdDto; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; @@ -46,7 +47,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.sonar.server.common.permission.Operation.ADD; import static org.sonar.server.common.permission.Operation.REMOVE; -import static org.sonar.server.permission.PermissionServiceImpl.ALL_PROJECT_PERMISSIONS; public class UserPermissionChangerIT { @Rule @@ -101,48 +101,48 @@ public class UserPermissionChangerIT { @Test public void apply_has_no_effect_when_adding_permission_USER_on_a_public_project() { - UserPermissionChange change = new UserPermissionChange(ADD, UserRole.USER, publicProject, UserIdDto.from(user1), permissionService); + UserPermissionChange change = new UserPermissionChange(ADD, ProjectPermission.USER, publicProject, UserIdDto.from(user1), permissionService); apply(change); - assertThat(db.users().selectEntityPermissionOfUser(user1, publicProject.getUuid())).doesNotContain(UserRole.USER); + assertThat(db.users().selectEntityPermissionOfUser(user1, publicProject.getUuid())).map(ProjectPermission::fromKey).doesNotContain(ProjectPermission.USER); } @Test public void apply_has_no_effect_when_adding_permission_CODEVIEWER_on_a_public_project() { - UserPermissionChange change = new UserPermissionChange(ADD, UserRole.CODEVIEWER, publicProject, UserIdDto.from(user1), permissionService); + UserPermissionChange change = new UserPermissionChange(ADD, ProjectPermission.CODEVIEWER, publicProject, UserIdDto.from(user1), permissionService); apply(change); - assertThat(db.users().selectEntityPermissionOfUser(user1, publicProject.getUuid())).doesNotContain(UserRole.CODEVIEWER); + assertThat(db.users().selectEntityPermissionOfUser(user1, publicProject.getUuid())).map(ProjectPermission::fromKey).doesNotContain(ProjectPermission.CODEVIEWER); } @Test public void apply_adds_permission_ADMIN_on_a_public_project() { - applyAddsPermissionOnAPublicProject(UserRole.ADMIN); + applyAddsPermissionOnAPublicProject(ProjectPermission.ADMIN); } @Test public void apply_adds_permission_ISSUE_ADMIN_on_a_public_project() { - applyAddsPermissionOnAPublicProject(UserRole.ISSUE_ADMIN); + applyAddsPermissionOnAPublicProject(ProjectPermission.ISSUE_ADMIN); } @Test public void apply_adds_permission_SCAN_EXECUTION_on_a_public_project() { - applyAddsPermissionOnAPublicProject(GlobalPermission.SCAN.getKey()); + applyAddsPermissionOnAPublicProject(ProjectPermission.SCAN); } - private void applyAddsPermissionOnAPublicProject(String permission) { + private void applyAddsPermissionOnAPublicProject(ProjectPermission permission) { UserPermissionChange change = new UserPermissionChange(ADD, permission, publicProject, UserIdDto.from(user1), permissionService); apply(change); - assertThat(db.users().selectEntityPermissionOfUser(user1, publicProject.getUuid())).containsOnly(permission); + assertThat(db.users().selectEntityPermissionOfUser(user1, publicProject.getUuid())).map(ProjectPermission::fromKey).containsOnly(permission); } @Test public void apply_fails_with_BadRequestException_when_removing_permission_USER_from_a_public_project() { - UserPermissionChange change = new UserPermissionChange(REMOVE, UserRole.USER, publicProject, UserIdDto.from(user1), permissionService); + UserPermissionChange change = new UserPermissionChange(REMOVE, ProjectPermission.USER, publicProject, UserIdDto.from(user1), permissionService); assertThatThrownBy(() -> apply(change)) .isInstanceOf(BadRequestException.class) @@ -151,7 +151,7 @@ public class UserPermissionChangerIT { @Test public void apply_fails_with_BadRequestException_when_removing_permission_CODEVIEWER_from_a_public_project() { - UserPermissionChange change = new UserPermissionChange(REMOVE, UserRole.CODEVIEWER, publicProject, UserIdDto.from(user1), permissionService); + UserPermissionChange change = new UserPermissionChange(REMOVE, ProjectPermission.CODEVIEWER, publicProject, UserIdDto.from(user1), permissionService); assertThatThrownBy(() -> apply(change)) .isInstanceOf(BadRequestException.class) @@ -160,24 +160,24 @@ public class UserPermissionChangerIT { @Test public void apply_removes_permission_ADMIN_from_a_public_project() { - applyRemovesPermissionFromPublicProject(UserRole.ADMIN); + applyRemovesPermissionFromPublicProject(ProjectPermission.ADMIN); } @Test public void apply_removes_permission_ISSUE_ADMIN_from_a_public_project() { - applyRemovesPermissionFromPublicProject(UserRole.ISSUE_ADMIN); + applyRemovesPermissionFromPublicProject(ProjectPermission.ISSUE_ADMIN); } @Test public void apply_removes_permission_SCAN_EXECUTION_from_a_public_project() { - applyRemovesPermissionFromPublicProject(GlobalPermission.SCAN.getKey()); + applyRemovesPermissionFromPublicProject(ProjectPermission.SCAN); } - private void applyRemovesPermissionFromPublicProject(String permission) { + private void applyRemovesPermissionFromPublicProject(ProjectPermission permission) { db.users().insertProjectPermissionOnUser(user1, permission, publicProject); UserPermissionChange change = new UserPermissionChange(REMOVE, permission, publicProject, UserIdDto.from(user1), permissionService); - apply(change, Set.of(permission)); + apply(change, Set.of(permission.getKey())); assertThat(db.users().selectEntityPermissionOfUser(user1, publicProject.getUuid())).isEmpty(); } @@ -190,7 +190,7 @@ public class UserPermissionChangerIT { apply(change); - assertThat(db.users().selectEntityPermissionOfUser(user1, privateProject.getUuid())).contains(permission); + assertThat(db.users().selectEntityPermissionOfUser(user1, privateProject.getUuid())).contains(permission.getKey()); }); } @@ -203,9 +203,9 @@ public class UserPermissionChangerIT { .forEach(permission -> { UserPermissionChange change = new UserPermissionChange(REMOVE, permission, privateProject, UserIdDto.from(user1), permissionService); - apply(change, ALL_PROJECT_PERMISSIONS); + apply(change, Arrays.stream(ProjectPermission.values()).map(ProjectPermission::getKey).collect(toSet())); - assertThat(db.users().selectEntityPermissionOfUser(user1, privateProject.getUuid())).doesNotContain(permission); + assertThat(db.users().selectEntityPermissionOfUser(user1, privateProject.getUuid())).doesNotContain(permission.getKey()); }); } @@ -223,11 +223,11 @@ public class UserPermissionChangerIT { @Test public void add_project_permission_to_user() { - UserPermissionChange change = new UserPermissionChange(ADD, UserRole.ISSUE_ADMIN, privateProject, UserIdDto.from(user1), permissionService); + UserPermissionChange change = new UserPermissionChange(ADD, ProjectPermission.ISSUE_ADMIN, privateProject, UserIdDto.from(user1), permissionService); apply(change); assertThat(db.users().selectPermissionsOfUser(user1)).isEmpty(); - assertThat(db.users().selectEntityPermissionOfUser(user1, privateProject.getUuid())).contains(UserRole.ISSUE_ADMIN); + assertThat(db.users().selectEntityPermissionOfUser(user1, privateProject.getUuid())).contains(ProjectPermission.ISSUE_ADMIN.getKey()); assertThat(db.users().selectPermissionsOfUser(user2)).isEmpty(); assertThat(db.users().selectEntityPermissionOfUser(user2, privateProject.getUuid())).isEmpty(); } @@ -255,7 +255,7 @@ public class UserPermissionChangerIT { @Test public void fail_to_add_project_permission() { assertThatThrownBy(() -> { - UserPermissionChange change = new UserPermissionChange(ADD, UserRole.ISSUE_ADMIN, null, UserIdDto.from(user1), permissionService); + UserPermissionChange change = new UserPermissionChange(ADD, ProjectPermission.ISSUE_ADMIN, null, UserIdDto.from(user1), permissionService); apply(change); }) .isInstanceOf(BadRequestException.class) @@ -267,31 +267,31 @@ public class UserPermissionChangerIT { db.users().insertGlobalPermissionOnUser(user1, GlobalPermission.ADMINISTER_QUALITY_GATES); db.users().insertGlobalPermissionOnUser(user1, GlobalPermission.SCAN); db.users().insertGlobalPermissionOnUser(user2, GlobalPermission.ADMINISTER_QUALITY_GATES); - db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, privateProject); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.ISSUE_ADMIN, privateProject); UserPermissionChange change = new UserPermissionChange(REMOVE, GlobalPermission.ADMINISTER_QUALITY_GATES.getKey(), null, UserIdDto.from(user1), permissionService); - apply(change, Set.of(GlobalPermission.ADMINISTER_QUALITY_GATES.getKey(), GlobalPermission.SCAN.getKey(), UserRole.ISSUE_ADMIN)); + apply(change, Set.of(GlobalPermission.ADMINISTER_QUALITY_GATES.getKey(), GlobalPermission.SCAN.getKey(), ProjectPermission.ISSUE_ADMIN.getKey())); assertThat(db.users().selectPermissionsOfUser(user1)).containsOnly(GlobalPermission.SCAN); assertThat(db.users().selectPermissionsOfUser(user2)).containsOnly(GlobalPermission.ADMINISTER_QUALITY_GATES); - assertThat(db.users().selectEntityPermissionOfUser(user1, privateProject.getUuid())).containsOnly(UserRole.ISSUE_ADMIN); + assertThat(db.users().selectEntityPermissionOfUser(user1, privateProject.getUuid())).containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); } @Test public void remove_project_permission_from_user() { EntityDto project2 = db.components().insertPrivateProject().getProjectDto(); db.users().insertGlobalPermissionOnUser(user1, GlobalPermission.ADMINISTER_QUALITY_GATES); - db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, privateProject); - db.users().insertProjectPermissionOnUser(user1, UserRole.USER, privateProject); - db.users().insertProjectPermissionOnUser(user2, UserRole.ISSUE_ADMIN, privateProject); - db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, project2); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.ISSUE_ADMIN, privateProject); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.USER, privateProject); + db.users().insertProjectPermissionOnUser(user2, ProjectPermission.ISSUE_ADMIN, privateProject); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.ISSUE_ADMIN, project2); - UserPermissionChange change = new UserPermissionChange(REMOVE, UserRole.ISSUE_ADMIN, privateProject, UserIdDto.from(user1), permissionService); - apply(change, Set.of(GlobalPermission.ADMINISTER_QUALITY_GATES.getKey(), UserRole.ISSUE_ADMIN, UserRole.USER)); + UserPermissionChange change = new UserPermissionChange(REMOVE, ProjectPermission.ISSUE_ADMIN, privateProject, UserIdDto.from(user1), permissionService); + apply(change, Set.of(GlobalPermission.ADMINISTER_QUALITY_GATES.getKey(), ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.USER.getKey())); - assertThat(db.users().selectEntityPermissionOfUser(user1, privateProject.getUuid())).containsOnly(UserRole.USER); - assertThat(db.users().selectEntityPermissionOfUser(user2, privateProject.getUuid())).containsOnly(UserRole.ISSUE_ADMIN); - assertThat(db.users().selectEntityPermissionOfUser(user1, project2.getUuid())).containsOnly(UserRole.ISSUE_ADMIN); + assertThat(db.users().selectEntityPermissionOfUser(user1, privateProject.getUuid())).containsOnly(ProjectPermission.USER.getKey()); + assertThat(db.users().selectEntityPermissionOfUser(user2, privateProject.getUuid())).containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); + assertThat(db.users().selectEntityPermissionOfUser(user1, project2.getUuid())).containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); } @Test @@ -304,7 +304,7 @@ public class UserPermissionChangerIT { @Test public void do_not_fail_if_removing_a_project_permission_that_does_not_exist() { - UserPermissionChange change = new UserPermissionChange(REMOVE, UserRole.ISSUE_ADMIN, privateProject, UserIdDto.from(user1), permissionService); + UserPermissionChange change = new UserPermissionChange(REMOVE, ProjectPermission.ISSUE_ADMIN, privateProject, UserIdDto.from(user1), permissionService); apply(change); assertThat(db.users().selectEntityPermissionOfUser(user1, privateProject.getUuid())).isEmpty(); diff --git a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/rule/RuleCreatorIT.java b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/rule/RuleCreatorIT.java index de801eb4624..46bccd40d61 100644 --- a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/rule/RuleCreatorIT.java +++ b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/rule/RuleCreatorIT.java @@ -35,9 +35,9 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.utils.System2; +import org.sonar.core.rule.RuleType; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbSession; @@ -71,6 +71,7 @@ import static org.sonar.api.issue.impact.SoftwareQuality.RELIABILITY; import static org.sonar.api.issue.impact.SoftwareQuality.SECURITY; import static org.sonar.api.server.rule.internal.ImpactMapper.convertToImpactSeverity; import static org.sonar.api.server.rule.internal.ImpactMapper.convertToSoftwareQuality; +import static org.sonar.core.rule.RuleTypeMapper.toApiRuleType; import static org.sonar.db.rule.RuleTesting.newCustomRule; import static org.sonar.db.rule.RuleTesting.newRule; import static org.sonar.server.util.TypeValidationsTesting.newFullTypeValidations; @@ -197,7 +198,7 @@ public class RuleCreatorIT { assertThat(rule.getSeverityString()).isEqualTo(Severity.MAJOR); assertThat(rule.getCleanCodeAttribute()).isEqualTo(CleanCodeAttribute.CLEAR); assertThat(rule.getDefaultImpacts()).extracting(ImpactDto::getSoftwareQuality, ImpactDto::getSeverity).containsExactly(tuple( - convertToSoftwareQuality(RuleType.valueOf(templateRule.getType())), + convertToSoftwareQuality(toApiRuleType(RuleType.fromDbConstant(templateRule.getType()))), convertToImpactSeverity(requireNonNull(Severity.MAJOR)))); } diff --git a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/user/service/UserServiceIT.java b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/user/service/UserServiceIT.java index a997ae877ba..d187336783d 100644 --- a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/user/service/UserServiceIT.java +++ b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/user/service/UserServiceIT.java @@ -37,7 +37,7 @@ import org.junit.runner.RunWith; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.server.authentication.IdentityProvider; import org.sonar.api.utils.DateUtils; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -577,8 +577,8 @@ public class UserServiceIT { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); db.users().insertGlobalPermissionOnUser(user, GlobalPermission.SCAN); db.users().insertGlobalPermissionOnUser(user, GlobalPermission.ADMINISTER_QUALITY_PROFILES); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project); - db.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, project); userService.deactivate(user.getUuid(), false); @@ -592,8 +592,8 @@ public class UserServiceIT { UserDto user = db.users().insertUser(); PermissionTemplateDto template = db.permissionTemplates().insertTemplate(); PermissionTemplateDto anotherTemplate = db.permissionTemplates().insertTemplate(); - db.permissionTemplates().addUserToTemplate(template.getUuid(), user.getUuid(), UserRole.USER, template.getName(), user.getLogin()); - db.permissionTemplates().addUserToTemplate(anotherTemplate.getUuid(), user.getUuid(), UserRole.CODEVIEWER, anotherTemplate.getName(), user.getLogin()); + db.permissionTemplates().addUserToTemplate(template.getUuid(), user.getUuid(), ProjectPermission.USER, template.getName(), user.getLogin()); + db.permissionTemplates().addUserToTemplate(anotherTemplate.getUuid(), user.getUuid(), ProjectPermission.CODEVIEWER, anotherTemplate.getName(), user.getLogin()); userService.deactivate(user.getUuid(), false); diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/DefaultDevOpsProjectCreator.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/DefaultDevOpsProjectCreator.java index 01784ce8d3b..406bf840f48 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/DefaultDevOpsProjectCreator.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/DefaultDevOpsProjectCreator.java @@ -23,7 +23,7 @@ import java.util.Optional; import java.util.Set; import javax.annotation.CheckForNull; import org.jetbrains.annotations.Nullable; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.auth.DevOpsPlatformSettings; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -126,7 +126,7 @@ public class DefaultDevOpsProjectCreator implements DevOpsProjectCreator { private void addScanPermissionToCurrentUser(DbSession dbSession, ProjectDto projectDto) { UserSession userSession = devOpsProjectCreationContext.userSession(); UserIdDto userId = new UserIdDto(requireNonNull(userSession.getUuid()), requireNonNull(userSession.getLogin())); - UserPermissionChange scanPermission = new UserPermissionChange(Operation.ADD, UserRole.SCAN, projectDto, userId, permissionService); + UserPermissionChange scanPermission = new UserPermissionChange(Operation.ADD, ProjectPermission.SCAN.getKey(), projectDto, userId, permissionService); permissionUpdater.apply(dbSession, Set.of(scanPermission)); } diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/github/GithubProjectCreator.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/github/GithubProjectCreator.java index 79ca428c1fd..ab769024ac6 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/github/GithubProjectCreator.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/github/GithubProjectCreator.java @@ -22,7 +22,7 @@ package org.sonar.server.common.almsettings.github; import java.util.Set; import javax.annotation.CheckForNull; import org.sonar.alm.client.github.GithubPermissionConverter; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.auth.DevOpsPlatformSettings; import org.sonar.auth.github.AppInstallationToken; import org.sonar.auth.github.GsonRepositoryCollaborator; @@ -121,9 +121,9 @@ public class GithubProjectCreator extends DefaultDevOpsProjectCreator { } private boolean hasScanPermission(Set<DevOpsPermissionsMappingDto> permissionsMappingDtos, String role, GsonRepositoryPermissions permissions) { - Set<String> sonarqubePermissions = githubPermissionConverter.toSonarqubeRolesWithFallbackOnRepositoryPermissions(permissionsMappingDtos, + Set<ProjectPermission> sonarqubePermissions = githubPermissionConverter.toSonarqubeRolesWithFallbackOnRepositoryPermissions(permissionsMappingDtos, role, permissions); - return sonarqubePermissions.contains(UserRole.SCAN); + return sonarqubePermissions.contains(ProjectPermission.SCAN); } } diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/component/ComponentUpdater.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/component/ComponentUpdater.java index 80d533da292..10c39b9a7a4 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/component/ComponentUpdater.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/component/ComponentUpdater.java @@ -26,8 +26,6 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.db.component.ComponentScopes; import org.sonar.api.utils.System2; import org.sonar.core.i18n.I18n; import org.sonar.core.util.UuidFactory; @@ -36,6 +34,9 @@ import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; import org.sonar.db.component.BranchType; import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.ComponentQualifiers; +import org.sonar.db.component.ComponentScopes; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.portfolio.PortfolioDto; import org.sonar.db.portfolio.PortfolioDto.SelectionMode; import org.sonar.db.project.CreationMethod; @@ -54,9 +55,9 @@ import org.sonar.server.project.DefaultBranchNameResolver; import static com.google.common.base.Preconditions.checkState; import static java.util.Collections.singletonList; -import static org.sonar.api.web.UserRole.PUBLIC_PERMISSIONS; import static org.sonar.core.component.ComponentKeys.ALLOWED_CHARACTERS_MESSAGE; import static org.sonar.core.component.ComponentKeys.isValidProjectKey; +import static org.sonar.db.permission.ProjectPermission.PUBLIC_PERMISSIONS; import static org.sonar.server.exceptions.BadRequestException.checkRequest; import static org.sonar.server.exceptions.BadRequestException.throwBadRequestException; @@ -169,8 +170,8 @@ public class ComponentUpdater { } } - private UserPermissionChange toUserPermissionChange(String permission, ProjectDto projectDto, UserDto userDto) { - return new UserPermissionChange(Operation.ADD, permission, projectDto, userDto, permissionService); + private UserPermissionChange toUserPermissionChange(ProjectPermission permission, ProjectDto projectDto, UserDto userDto) { + return new UserPermissionChange(Operation.ADD, permission.getKey(), projectDto, userDto, permissionService); } private void addToFavourites(DbSession dbSession, ProjectDto projectDto, @Nullable String userUuid, @Nullable String userLogin) { diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/GroupPermissionChange.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/GroupPermissionChange.java index 6737eabd198..d1112bd2d06 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/GroupPermissionChange.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/GroupPermissionChange.java @@ -23,6 +23,8 @@ import java.util.Optional; import java.util.StringJoiner; import javax.annotation.Nullable; import org.sonar.db.entity.EntityDto; +import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; import org.sonar.server.permission.GroupUuidOrAnyone; import org.sonar.server.permission.PermissionService; @@ -37,6 +39,16 @@ public class GroupPermissionChange extends PermissionChange { this.groupDto = groupDto; } + public GroupPermissionChange(Operation operation, ProjectPermission permission, EntityDto entityDto, + @Nullable GroupDto groupDto, PermissionService permissionService) { + this(operation, permission.getKey(), entityDto, groupDto, permissionService); + } + + public GroupPermissionChange(Operation operation, GlobalPermission permission, + @Nullable GroupDto groupDto, PermissionService permissionService) { + this(operation, permission.getKey(), null, groupDto, permissionService); + } + public GroupUuidOrAnyone getGroupUuidOrAnyone() { return GroupUuidOrAnyone.from(groupDto); } diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/GroupPermissionChanger.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/GroupPermissionChanger.java index da682f62ff1..f8ff1170c87 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/GroupPermissionChanger.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/GroupPermissionChanger.java @@ -22,13 +22,13 @@ package org.sonar.server.common.permission; import java.util.HashSet; import java.util.Set; import javax.annotation.Nullable; -import org.sonar.api.web.UserRole; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; import org.sonar.db.permission.GroupPermissionDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.permission.GroupUuidOrAnyone; @@ -99,7 +99,7 @@ public class GroupPermissionChanger implements GranteeTypeSpecificPermissionUpda private static boolean isAttemptToAddPublicPermissionToPublicComponent(GroupPermissionChange change, EntityDto project) { return !project.isPrivate() && change.getOperation() == ADD - && UserRole.PUBLIC_PERMISSIONS.contains(change.getPermission()); + && ProjectPermission.isPublic(change.getPermission()); } private static boolean isAttemptToRemovePermissionFromAnyoneOnPrivateComponent(GroupPermissionChange change, EntityDto project) { @@ -129,7 +129,7 @@ public class GroupPermissionChanger implements GranteeTypeSpecificPermissionUpda private static boolean isAttemptToRemovePublicPermissionFromPublicComponent(GroupPermissionChange change, EntityDto project) { return !project.isPrivate() && change.getOperation() == REMOVE - && UserRole.PUBLIC_PERMISSIONS.contains(change.getPermission()); + && ProjectPermission.isPublic(change.getPermission()); } private boolean addPermission(DbSession dbSession, GroupPermissionChange change) { diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/PermissionChange.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/PermissionChange.java index b03aad134fa..ccd087bb019 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/PermissionChange.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/PermissionChange.java @@ -46,7 +46,8 @@ public abstract class PermissionChange { "Invalid global permission '%s'. Valid values are %s", permission, permissionService.getGlobalPermissions().stream().map(GlobalPermission::getKey).toList()); } else { - checkRequest(permissionService.getAllProjectPermissions().contains(permission), "Invalid project permission '%s'. Valid values are %s", permission, + checkRequest(permissionService.getAllProjectPermissions().stream().anyMatch(p -> p.getKey().equals(permission)), + "Invalid project permission '%s'. Valid values are %s", permission, permissionService.getAllProjectPermissions()); } } diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/PermissionTemplateService.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/PermissionTemplateService.java index c250c6a8156..b59323739b5 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/PermissionTemplateService.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/PermissionTemplateService.java @@ -30,13 +30,14 @@ import java.util.stream.Collectors; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.apache.commons.lang3.StringUtils; -import org.sonar.db.component.ComponentQualifiers; import org.sonar.api.server.ServerSide; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GroupPermissionDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.UserPermissionDto; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; import org.sonar.db.permission.template.PermissionTemplateDto; @@ -53,7 +54,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; import static java.util.Collections.singletonList; import static org.sonar.api.security.DefaultGroups.isAnyone; -import static org.sonar.api.web.UserRole.PUBLIC_PERMISSIONS; import static org.sonar.db.permission.GlobalPermission.SCAN; @ServerSide @@ -179,7 +179,7 @@ public class PermissionTemplateService { } private static boolean permissionValidForProject(boolean isPrivateEntity, String permission) { - return isPrivateEntity || !PUBLIC_PERMISSIONS.contains(permission); + return isPrivateEntity || !ProjectPermission.isPublic(permission); } private static boolean groupNameValidForProject(boolean isPrivateEntity, String groupName) { @@ -226,7 +226,7 @@ public class PermissionTemplateService { private static void checkAtMostOneMatchForComponentKey(String componentKey, List<PermissionTemplateDto> matchingTemplates) { if (matchingTemplates.size() > 1) { StringBuilder templatesNames = new StringBuilder(); - for (Iterator<PermissionTemplateDto> it = matchingTemplates.iterator(); it.hasNext(); ) { + for (Iterator<PermissionTemplateDto> it = matchingTemplates.iterator(); it.hasNext();) { templatesNames.append("\"").append(it.next().getName()).append("\""); if (it.hasNext()) { templatesNames.append(", "); diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/UserPermissionChange.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/UserPermissionChange.java index d20aadc420e..6a4580affa7 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/UserPermissionChange.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/UserPermissionChange.java @@ -23,6 +23,7 @@ import java.util.Optional; import java.util.StringJoiner; import javax.annotation.Nullable; import org.sonar.db.entity.EntityDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.UserId; import org.sonar.server.permission.PermissionService; @@ -32,6 +33,11 @@ public class UserPermissionChange extends PermissionChange { private final UserId userId; + public UserPermissionChange(Operation operation, ProjectPermission permission, @Nullable EntityDto entity, UserId userId, + PermissionService permissionService) { + this(operation, permission.getKey(), entity, userId, permissionService); + } + public UserPermissionChange(Operation operation, String permission, @Nullable EntityDto entity, UserId userId, PermissionService permissionService) { super(operation, permission, entity, permissionService); diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/UserPermissionChanger.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/UserPermissionChanger.java index bc3bb2424fb..8a128906590 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/UserPermissionChanger.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/UserPermissionChanger.java @@ -22,12 +22,12 @@ package org.sonar.server.common.permission; import java.util.HashSet; import java.util.Set; import org.jetbrains.annotations.Nullable; -import org.sonar.api.web.UserRole; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.UserPermissionDto; import static org.sonar.server.common.permission.Operation.ADD; @@ -91,7 +91,7 @@ public class UserPermissionChanger implements GranteeTypeSpecificPermissionUpdat private static boolean isAttemptToAddPublicPermissionToPublicComponent(UserPermissionChange change, EntityDto project) { return !project.isPrivate() && change.getOperation() == ADD - && UserRole.PUBLIC_PERMISSIONS.contains(change.getPermission()); + && ProjectPermission.isPublic(change.getPermission()); } private static void ensureConsistencyWithVisibility(UserPermissionChange change) { @@ -105,7 +105,7 @@ public class UserPermissionChanger implements GranteeTypeSpecificPermissionUpdat private static boolean isAttemptToRemovePublicPermissionFromPublicComponent(UserPermissionChange change, EntityDto entity) { return !entity.isPrivate() && change.getOperation() == REMOVE - && UserRole.PUBLIC_PERMISSIONS.contains(change.getPermission()); + && ProjectPermission.isPublic(change.getPermission()); } private boolean addPermission(DbSession dbSession, Set<String> existingPermissions, UserPermissionChange change) { diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/rule/RuleCreator.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/rule/RuleCreator.java index e5438e557bd..80e876ceb58 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/rule/RuleCreator.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/rule/RuleCreator.java @@ -35,11 +35,11 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; import org.sonar.api.server.ServerSide; import org.sonar.api.server.rule.RuleParamType; import org.sonar.api.server.rule.internal.ImpactMapper; import org.sonar.api.utils.System2; +import org.sonar.core.rule.RuleType; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -59,6 +59,7 @@ import static com.google.common.collect.Lists.newArrayList; import static java.lang.String.format; import static java.util.Objects.requireNonNull; import static java.util.Optional.ofNullable; +import static org.sonar.core.rule.RuleTypeMapper.toApiRuleType; import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection; import static org.sonar.server.exceptions.BadRequestException.checkRequest; @@ -246,7 +247,7 @@ public class RuleCreator { ruleDto.setSeverity(ImpactMapper.convertToDeprecatedSeverity(impact.getValue())); } else { // Map old type and severity to impact - SoftwareQuality softwareQuality = ImpactMapper.convertToSoftwareQuality(RuleType.valueOf(type)); + SoftwareQuality softwareQuality = ImpactMapper.convertToSoftwareQuality(toApiRuleType(RuleType.fromDbConstant(type))); org.sonar.api.issue.impact.Severity impactSeverity = ImpactMapper.convertToImpactSeverity(severity); ruleDto.addDefaultImpact(new ImpactDto() .setSoftwareQuality(softwareQuality) diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/rule/service/NewCustomRule.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/rule/service/NewCustomRule.java index 08933c46993..08157cc0786 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/rule/service/NewCustomRule.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/rule/service/NewCustomRule.java @@ -30,7 +30,7 @@ import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.server.common.rule.ReactivationException; public class NewCustomRule { diff --git a/server/sonar-webserver-common/src/test/java/org/sonar/server/common/almsettings/DefaultDevOpsProjectCreatorTest.java b/server/sonar-webserver-common/src/test/java/org/sonar/server/common/almsettings/DefaultDevOpsProjectCreatorTest.java index 148732905ef..185a4b2b952 100644 --- a/server/sonar-webserver-common/src/test/java/org/sonar/server/common/almsettings/DefaultDevOpsProjectCreatorTest.java +++ b/server/sonar-webserver-common/src/test/java/org/sonar/server/common/almsettings/DefaultDevOpsProjectCreatorTest.java @@ -30,7 +30,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.sonar.db.component.ComponentQualifiers; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.auth.DevOpsPlatformSettings; import org.sonar.db.DbClient; import org.sonar.db.alm.setting.ALM; @@ -289,7 +289,7 @@ class DefaultDevOpsProjectCreatorTest { UserPermissionChange permissionChange = permissionChangesCaptor.getValue().iterator().next(); assertThat(permissionChange.getUserId().getUuid()).isEqualTo(userSession.getUuid()); assertThat(permissionChange.getUserId().getLogin()).isEqualTo(userSession.getLogin()); - assertThat(permissionChange.getPermission()).isEqualTo(UserRole.SCAN); + assertThat(permissionChange.getPermission()).isEqualTo(ProjectPermission.SCAN.getKey()); assertThat(permissionChange.getProjectUuid()).isEqualTo(actualComponentCreationData.projectDto().getUuid()); } diff --git a/server/sonar-webserver-common/src/test/java/org/sonar/server/common/almsettings/github/GithubProjectCreatorTest.java b/server/sonar-webserver-common/src/test/java/org/sonar/server/common/almsettings/github/GithubProjectCreatorTest.java index c9d166b02c4..50b1eb91979 100644 --- a/server/sonar-webserver-common/src/test/java/org/sonar/server/common/almsettings/github/GithubProjectCreatorTest.java +++ b/server/sonar-webserver-common/src/test/java/org/sonar/server/common/almsettings/github/GithubProjectCreatorTest.java @@ -29,16 +29,16 @@ import org.mockito.Answers; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.sonar.alm.client.github.GithubPermissionConverter; -import org.sonar.api.web.UserRole; import org.sonar.auth.github.AppInstallationToken; import org.sonar.auth.github.GitHubSettings; +import org.sonar.auth.github.GithubApplicationClient; import org.sonar.auth.github.GsonRepositoryCollaborator; import org.sonar.auth.github.GsonRepositoryPermissions; import org.sonar.auth.github.GsonRepositoryTeam; -import org.sonar.auth.github.GithubApplicationClient; import org.sonar.db.DbClient; import org.sonar.db.alm.setting.ALM; import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.provisioning.DevOpsPermissionsMappingDto; import org.sonar.db.user.GroupDto; import org.sonar.server.common.almintegration.ProjectKeyGenerator; @@ -125,7 +125,8 @@ class GithubProjectCreatorTest { when(gitHubSettings.getDevOpsPlatform()).thenReturn(GITHUB.getKey()); ProjectCreator projectCreator = new ProjectCreator(userSession, projectDefaultVisibility, componentUpdater); - githubProjectCreator = new GithubProjectCreator(dbClient, devOpsProjectCreationContext, projectKeyGenerator, gitHubSettings, projectCreator, permissionService, permissionUpdater, + githubProjectCreator = new GithubProjectCreator(dbClient, devOpsProjectCreationContext, projectKeyGenerator, gitHubSettings, projectCreator, permissionService, + permissionUpdater, managedProjectService, githubApplicationClient, githubPermissionConverter, authAppInstallationToken); } @@ -146,7 +147,7 @@ class GithubProjectCreatorTest { @Test void isScanAllowedUsingPermissionsFromDevopsPlatform_whenCollaboratorHasDirectAccessButNoScanPermissions_returnsFalse() { - GsonRepositoryCollaborator collaborator1 = mockCollaborator("collaborator1", 1, "role1", "read", "admin"); + GsonRepositoryCollaborator collaborator1 = mockCollaborator("collaborator1", 1, "role1", ProjectPermission.USER, ProjectPermission.ADMIN); mockGithubCollaboratorsFromApi(collaborator1); bindSessionToCollaborator(collaborator1); @@ -155,8 +156,8 @@ class GithubProjectCreatorTest { @Test void isScanAllowedUsingPermissionsFromDevopsPlatform_whenCollaboratorHasDirectAccess_returnsTrue() { - GsonRepositoryCollaborator collaborator1 = mockCollaborator("collaborator1", 1, "role1", "read", "admin"); - GsonRepositoryCollaborator collaborator2 = mockCollaborator("collaborator2", 2, "role2", "read", "scan"); + GsonRepositoryCollaborator collaborator1 = mockCollaborator("collaborator1", 1, "role1", ProjectPermission.USER, ProjectPermission.ADMIN); + GsonRepositoryCollaborator collaborator2 = mockCollaborator("collaborator2", 2, "role2", ProjectPermission.USER, ProjectPermission.SCAN); mockGithubCollaboratorsFromApi(collaborator1, collaborator2); bindSessionToCollaborator(collaborator2); @@ -165,7 +166,7 @@ class GithubProjectCreatorTest { @Test void isScanAllowedUsingPermissionsFromDevopsPlatform_whenAccessViaTeamButNoScanPermissions_returnsFalse() { - GsonRepositoryTeam team2 = mockGithubTeam("team2", 2, "role2", "another_perm", UserRole.ADMIN); + GsonRepositoryTeam team2 = mockGithubTeam("team2", 2, "role2", ProjectPermission.ISSUE_ADMIN, ProjectPermission.ADMIN); mockTeamsFromApi(team2); bindGroupsToUser(team2.name()); @@ -174,8 +175,8 @@ class GithubProjectCreatorTest { @Test void isScanAllowedUsingPermissionsFromDevopsPlatform_whenAccessViaTeam_returnsTrue() { - GsonRepositoryTeam team1 = mockGithubTeam("team1", 1, "role1", "read", "another_perm"); - GsonRepositoryTeam team2 = mockGithubTeam("team2", 2, "role2", "another_perm", UserRole.SCAN); + GsonRepositoryTeam team1 = mockGithubTeam("team1", 1, "role1", ProjectPermission.USER, ProjectPermission.ISSUE_ADMIN); + GsonRepositoryTeam team2 = mockGithubTeam("team2", 2, "role2", ProjectPermission.ISSUE_ADMIN, ProjectPermission.SCAN); mockTeamsFromApi(team1, team2); bindGroupsToUser(team1.name(), team2.name()); @@ -184,8 +185,8 @@ class GithubProjectCreatorTest { @Test void isScanAllowedUsingPermissionsFromDevopsPlatform_whenAccessViaTeamButUserNotInTeam_returnsFalse() { - GsonRepositoryTeam team1 = mockGithubTeam("team1", 1, "role1", "read", "another_perm"); - GsonRepositoryTeam team2 = mockGithubTeam("team2", 2, "role2", "another_perm", UserRole.SCAN); + GsonRepositoryTeam team1 = mockGithubTeam("team1", 1, "role1", ProjectPermission.USER, ProjectPermission.ISSUE_ADMIN); + GsonRepositoryTeam team2 = mockGithubTeam("team2", 2, "role2", ProjectPermission.ISSUE_ADMIN, ProjectPermission.SCAN); mockTeamsFromApi(team1, team2); bindGroupsToUser(team1.name()); @@ -197,7 +198,7 @@ class GithubProjectCreatorTest { when(userSession.getExternalIdentity()).thenReturn(Optional.of(externalIdentity)); } - private GsonRepositoryCollaborator mockCollaborator(String collaboratorLogin, int id, String role1, String... sqPermissions) { + private GsonRepositoryCollaborator mockCollaborator(String collaboratorLogin, int id, String role1, ProjectPermission... sqPermissions) { GsonRepositoryCollaborator collaborator = new GsonRepositoryCollaborator(collaboratorLogin, id, role1, new GsonRepositoryPermissions(false, false, false, false, false)); mockPermissionsConversion(collaborator, sqPermissions); @@ -210,7 +211,7 @@ class GithubProjectCreatorTest { collaborators); } - private GsonRepositoryTeam mockGithubTeam(String name, int id, String role, String... sqPermissions) { + private GsonRepositoryTeam mockGithubTeam(String name, int id, String role, ProjectPermission... sqPermissions) { GsonRepositoryTeam gsonRepositoryTeam = new GsonRepositoryTeam(name, id, name + "slug", role, new GsonRepositoryPermissions(false, false, false, false, false)); mockPermissionsConversion(gsonRepositoryTeam, sqPermissions); return gsonRepositoryTeam; @@ -221,13 +222,13 @@ class GithubProjectCreatorTest { .thenReturn(Arrays.stream(repositoryTeams).collect(toSet())); } - private void mockPermissionsConversion(GsonRepositoryCollaborator collaborator, String... sqPermissions) { + private void mockPermissionsConversion(GsonRepositoryCollaborator collaborator, ProjectPermission... sqPermissions) { Set<DevOpsPermissionsMappingDto> devOpsPermissionsMappingDtos = mockPermissionsMappingsDtos(); lenient().when(githubPermissionConverter.toSonarqubeRolesWithFallbackOnRepositoryPermissions(devOpsPermissionsMappingDtos, collaborator.roleName(), collaborator.permissions())) .thenReturn(Arrays.stream(sqPermissions).collect(toSet())); } - private void mockPermissionsConversion(GsonRepositoryTeam team, String... sqPermissions) { + private void mockPermissionsConversion(GsonRepositoryTeam team, ProjectPermission... sqPermissions) { Set<DevOpsPermissionsMappingDto> devOpsPermissionsMappingDtos = mockPermissionsMappingsDtos(); lenient().when(githubPermissionConverter.toSonarqubeRolesWithFallbackOnRepositoryPermissions(devOpsPermissionsMappingDtos, team.permission(), team.permissions())) .thenReturn(Arrays.stream(sqPermissions).collect(toSet())); diff --git a/server/sonar-webserver-common/src/test/java/org/sonar/server/common/permission/UserPermissionChangeTest.java b/server/sonar-webserver-common/src/test/java/org/sonar/server/common/permission/UserPermissionChangeTest.java index 6149b521e40..6a224c47082 100644 --- a/server/sonar-webserver-common/src/test/java/org/sonar/server/common/permission/UserPermissionChangeTest.java +++ b/server/sonar-webserver-common/src/test/java/org/sonar/server/common/permission/UserPermissionChangeTest.java @@ -22,6 +22,7 @@ package org.sonar.server.common.permission; import java.util.List; import org.junit.jupiter.api.Test; import org.sonar.db.entity.EntityDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.UserIdDto; import org.sonar.server.permission.PermissionService; @@ -34,13 +35,13 @@ class UserPermissionChangeTest { @Test void toString_shouldReturnStringRepresentation() { PermissionService permissionService = mock(); - when(permissionService.getAllProjectPermissions()).thenReturn(List.of("permission1", "permission2")); + when(permissionService.getAllProjectPermissions()).thenReturn(List.of(ProjectPermission.ADMIN, ProjectPermission.SCAN)); EntityDto entityDto = mock(); when(entityDto.getName()).thenReturn("entityName"); - UserPermissionChange userPermissionChange = new UserPermissionChange(Operation.ADD, "permission2", entityDto, new UserIdDto("uuid1", "login1"), permissionService); + UserPermissionChange userPermissionChange = new UserPermissionChange(Operation.ADD, "scan", entityDto, new UserIdDto("uuid1", "login1"), permissionService); - assertThat(userPermissionChange).hasToString("UserPermissionChange[userId=login='login1', operation=ADD, permission='permission2', entity=entityName]"); + assertThat(userPermissionChange).hasToString("UserPermissionChange[userId=login='login1', operation=ADD, permission='scan', entity=entityName]"); } } diff --git a/server/sonar-webserver-core/src/it/java/org/sonar/server/rule/registration/RulesRegistrantIT.java b/server/sonar-webserver-core/src/it/java/org/sonar/server/rule/registration/RulesRegistrantIT.java index 69336850d61..b0e0d335555 100644 --- a/server/sonar-webserver-core/src/it/java/org/sonar/server/rule/registration/RulesRegistrantIT.java +++ b/server/sonar-webserver-core/src/it/java/org/sonar/server/rule/registration/RulesRegistrantIT.java @@ -43,7 +43,7 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleScope; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.rule.Context; import org.sonar.api.server.rule.RuleDescriptionSection; @@ -1235,7 +1235,7 @@ class RulesRegistrantIT { repo.createRule("rule1") .setName("any") .setHtmlDescription("html") - .setType(RuleType.VULNERABILITY) + .setType(org.sonar.api.rules.RuleType.VULNERABILITY) .addDefaultImpact(SoftwareQuality.SECURITY, Severity.HIGH) .setSeverity(SeverityUtil.getSeverityFromOrdinal(2)); repo.done(); @@ -1257,7 +1257,7 @@ class RulesRegistrantIT { repo.createRule("rule1") .setName("any") .setHtmlDescription("html") - .setType(RuleType.VULNERABILITY) + .setType(org.sonar.api.rules.RuleType.VULNERABILITY) .addDefaultImpact(SoftwareQuality.SECURITY, Severity.LOW) .setSeverity(SeverityUtil.getSeverityFromOrdinal(2)); repo.done(); @@ -1341,7 +1341,7 @@ class RulesRegistrantIT { .setSeverity(BLOCKER) .setInternalKey("config1") .setTags("tag1", "tag2", "tag3") - .setType(RuleType.CODE_SMELL) + .setType(org.sonar.api.rules.RuleType.CODE_SMELL) .setStatus(RuleStatus.BETA); } @@ -1352,7 +1352,7 @@ class RulesRegistrantIT { .setName(ruleKey) .setHtmlDescription("Description of One") .setSeverity(BLOCKER) - .setType(RuleType.CODE_SMELL) + .setType(org.sonar.api.rules.RuleType.CODE_SMELL) .setStatus(RuleStatus.BETA); Arrays.stream(consumers).forEach(c -> c.accept(newRule)); @@ -1389,7 +1389,7 @@ class RulesRegistrantIT { .setInternalKey("config1") .setTags("tag1", "tag2", "tag3") .setScope(RuleScope.ALL) - .setType(RuleType.CODE_SMELL) + .setType(org.sonar.api.rules.RuleType.CODE_SMELL) .setStatus(RuleStatus.BETA) .setGapDescription("java.S115.effortToFix") .addEducationPrincipleKeys("concept1", "concept2", "concept3") @@ -1402,7 +1402,7 @@ class RulesRegistrantIT { repo.createRule(HOTSPOT_RULE_KEY.rule()) .setName("Hotspot") .setHtmlDescription("Minimal hotspot") - .setType(RuleType.SECURITY_HOTSPOT) + .setType(org.sonar.api.rules.RuleType.SECURITY_HOTSPOT) .addOwaspTop10(Y2021, OwaspTop10.A1, OwaspTop10.A3) .addCwe(1, 123, 863); @@ -1430,7 +1430,7 @@ class RulesRegistrantIT { .setInternalKey("config1 v2") // tag2 and tag3 removed, tag4 added .setTags("tag1", "tag4") - .setType(RuleType.BUG) + .setType(org.sonar.api.rules.RuleType.BUG) .setStatus(READY) .setGapDescription("java.S115.effortToFix.v2") .addEducationPrincipleKeys("concept1", "concept4"); @@ -1471,14 +1471,14 @@ class RulesRegistrantIT { .setInternalKey("config1") .setTags("tag1", "tag2", "tag3") .setScope(RuleScope.ALL) - .setType(RuleType.CODE_SMELL) + .setType(org.sonar.api.rules.RuleType.CODE_SMELL) .setStatus(RuleStatus.BETA) .addEducationPrincipleKeys("concept1", "concept2", "concept3"); repo.createRule(EXTERNAL_HOTSPOT_RULE_KEY.rule()) .setName("Hotspot") .setHtmlDescription("Minimal hotspot") - .setType(RuleType.SECURITY_HOTSPOT) + .setType(org.sonar.api.rules.RuleType.SECURITY_HOTSPOT) .addOwaspTop10(Y2021, OwaspTop10.A1, OwaspTop10.A3) .addCwe(1, 123, 863); diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java index bf0b395a1e9..16668ca9921 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/DatabaseServerCompatibility.java @@ -22,12 +22,15 @@ package org.sonar.server.platform; import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.SonarEdition; +import org.sonar.api.SonarRuntime; import org.sonar.api.Startable; import org.sonar.api.utils.MessageException; import org.sonar.core.documentation.DocumentationLinkGenerator; import org.sonar.server.platform.db.migration.version.DatabaseVersion; import static org.sonar.server.log.ServerProcessLogging.STARTUP_LOGGER_NAME; +import static org.sonar.server.platform.db.migration.version.DatabaseVersion.MIN_UPGRADE_VERSION_COMMUNITY_BUILD_READABLE; import static org.sonar.server.platform.db.migration.version.DatabaseVersion.MIN_UPGRADE_VERSION_HUMAN_READABLE; public class DatabaseServerCompatibility implements Startable { @@ -38,9 +41,12 @@ public class DatabaseServerCompatibility implements Startable { private final DocumentationLinkGenerator documentationLinkGenerator; - public DatabaseServerCompatibility(DatabaseVersion version, DocumentationLinkGenerator documentationLinkGenerator) { + private final SonarRuntime sonarRuntime; + + public DatabaseServerCompatibility(DatabaseVersion version, DocumentationLinkGenerator documentationLinkGenerator, SonarRuntime sonarRuntime) { this.version = version; this.documentationLinkGenerator = documentationLinkGenerator; + this.sonarRuntime = sonarRuntime; } @Override @@ -53,8 +59,7 @@ public class DatabaseServerCompatibility implements Startable { if (status == DatabaseVersion.Status.REQUIRES_UPGRADE) { Optional<Long> currentVersion = this.version.getVersion(); if (currentVersion.isPresent() && currentVersion.get() < DatabaseVersion.MIN_UPGRADE_VERSION) { - throw MessageException.of("The version of SonarQube you are trying to upgrade from is too old. Please upgrade to the " + - MIN_UPGRADE_VERSION_HUMAN_READABLE + " Long-Term Active version first."); + throw MessageException.of(buildVersionTooOldMessage()); } String documentationLink = documentationLinkGenerator.getDocumentationLink("/server-upgrade-and-maintenance/upgrade/upgrade-the-server/roadmap"); String msg = String.format("The database must be manually upgraded. Please backup the database and browse /setup. " @@ -67,6 +72,17 @@ public class DatabaseServerCompatibility implements Startable { } } + private String buildVersionTooOldMessage() { + if (sonarRuntime.getEdition() == SonarEdition.COMMUNITY) { + return "The version of SonarQube you are trying to upgrade from is too old. Please upgrade to the " + + MIN_UPGRADE_VERSION_COMMUNITY_BUILD_READABLE + " version first."; + } else { + return "The version of SonarQube you are trying to upgrade from is too old. Please upgrade to the " + + MIN_UPGRADE_VERSION_HUMAN_READABLE + " Long-Term Active version first."; + } + + } + @Override public void stop() { // do nothing diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/LegacyHotspotRuleDescriptionSectionsGenerator.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/LegacyHotspotRuleDescriptionSectionsGenerator.java index ed568eb7cc4..514486c609b 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/LegacyHotspotRuleDescriptionSectionsGenerator.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/LegacyHotspotRuleDescriptionSectionsGenerator.java @@ -26,12 +26,13 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.CheckForNull; import org.sonar.api.server.rule.RulesDefinition; +import org.sonar.core.rule.RuleTypeMapper; import org.sonar.core.util.UuidFactory; import org.sonar.db.rule.RuleDescriptionSectionDto; import org.sonar.markdown.Markdown; import static java.util.Collections.emptySet; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ASSESS_THE_PROBLEM_SECTION_KEY; import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.HOW_TO_FIX_SECTION_KEY; import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ROOT_CAUSE_SECTION_KEY; @@ -46,7 +47,7 @@ public class LegacyHotspotRuleDescriptionSectionsGenerator implements RuleDescri @Override public boolean isGeneratorForRule(RulesDefinition.Rule rule) { - return SECURITY_HOTSPOT.equals(rule.type()) && rule.ruleDescriptionSections().isEmpty(); + return SECURITY_HOTSPOT.equals(RuleTypeMapper.toRuleType(rule.type())) && rule.ruleDescriptionSections().isEmpty(); } @Override diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/LegacyIssueRuleDescriptionSectionsGenerator.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/LegacyIssueRuleDescriptionSectionsGenerator.java index 51bda468d96..e1e59b1e8c5 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/LegacyIssueRuleDescriptionSectionsGenerator.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/LegacyIssueRuleDescriptionSectionsGenerator.java @@ -21,17 +21,18 @@ package org.sonar.server.rule; import java.util.EnumSet; import java.util.Set; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RulesDefinition; +import org.sonar.core.rule.RuleTypeMapper; import org.sonar.core.util.UuidFactory; import org.sonar.db.rule.RuleDescriptionSectionDto; import static java.util.Collections.emptySet; import static java.util.Collections.singleton; import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection; public class LegacyIssueRuleDescriptionSectionsGenerator implements RuleDescriptionSectionsGenerator { @@ -45,7 +46,7 @@ public class LegacyIssueRuleDescriptionSectionsGenerator implements RuleDescript @Override public boolean isGeneratorForRule(RulesDefinition.Rule rule) { - return ISSUE_RULE_TYPES.contains(rule.type()) && rule.ruleDescriptionSections().isEmpty(); + return ISSUE_RULE_TYPES.contains(RuleTypeMapper.toRuleType(rule.type())) && rule.ruleDescriptionSections().isEmpty(); } @Override diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/ActiveRulesImpactInitializer.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/ActiveRulesImpactInitializer.java index 715b85ec480..d30353afcc3 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/ActiveRulesImpactInitializer.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/ActiveRulesImpactInitializer.java @@ -25,7 +25,7 @@ import java.util.List; import java.util.Map; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.db.DbClient; import org.sonar.db.DbSession; diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/NewRuleCreator.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/NewRuleCreator.java index 4fa1db8f4ca..dcc51d2fd55 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/NewRuleCreator.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/NewRuleCreator.java @@ -22,10 +22,11 @@ package org.sonar.server.rule.registration; import java.util.stream.Collectors; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.utils.System2; +import org.sonar.core.rule.RuleTypeMapper; import org.sonar.core.util.UuidFactory; import org.sonar.db.issue.ImpactDto; import org.sonar.db.rule.RuleDto; @@ -74,7 +75,7 @@ public class NewRuleCreator { .setUpdatedAt(now) .setEducationPrinciples(ruleDef.educationPrincipleKeys()); - if (!RuleType.SECURITY_HOTSPOT.equals(ruleDef.type())) { + if (RuleType.SECURITY_HOTSPOT != RuleTypeMapper.toRuleType(ruleDef.type())) { CleanCodeAttribute cleanCodeAttribute = ruleDef.cleanCodeAttribute(); ruleDto.setCleanCodeAttribute(cleanCodeAttribute != null ? cleanCodeAttribute : CleanCodeAttribute.defaultCleanCodeAttribute()); ruleDto.replaceAllDefaultImpacts(ruleDef.defaultImpacts().entrySet() diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/StartupRuleUpdater.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/StartupRuleUpdater.java index 726b3820c9b..dcea2bd9f9b 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/StartupRuleUpdater.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/StartupRuleUpdater.java @@ -33,7 +33,7 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.utils.System2; diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/PropertiesDBCleaner.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/PropertiesDBCleaner.java new file mode 100644 index 00000000000..d4f87c46ce4 --- /dev/null +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/PropertiesDBCleaner.java @@ -0,0 +1,62 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.startup; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.SonarEdition; +import org.sonar.api.SonarRuntime; +import org.sonar.api.Startable; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; + +import static java.util.Arrays.asList; + +public class PropertiesDBCleaner implements Startable { + private static final Logger LOG = LoggerFactory.getLogger(PropertiesDBCleaner.class); + private final SonarRuntime runtime; + private final DbClient dbClient; + + public PropertiesDBCleaner(DbClient dbClient, SonarRuntime runtime) { + this.dbClient = dbClient; + this.runtime = runtime; + } + + @Override + public void start() { + LOG.info("Clean up properties from db"); + deleteMisraPropertyIfRequired(); + } + + private void deleteMisraPropertyIfRequired() { + String misraProperty = "sonar.earlyAccess.misra.enabled"; + SonarEdition edition = runtime.getEdition(); + try (DbSession dbSession = dbClient.openSession(false)) { + if (asList(SonarEdition.COMMUNITY, SonarEdition.DEVELOPER).contains(edition)) { + dbClient.propertiesDao().deleteGlobalProperty(misraProperty, dbSession); + dbSession.commit(); + } + } + } + + @Override + public void stop() { + // Nothing to do + } +} diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java index c12e44129b1..45ed2df7d90 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java @@ -27,10 +27,10 @@ import org.sonar.api.utils.System2; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; -import org.sonar.api.web.UserRole; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.user.GroupDto; import org.sonar.server.usergroups.DefaultGroupFinder; @@ -96,7 +96,7 @@ public class RegisterPermissionTemplates implements Startable { private void insertPermissionForAdministrators(DbSession dbSession, PermissionTemplateDto template) { Optional<GroupDto> admins = dbClient.groupDao().selectByName(dbSession, DefaultGroups.ADMINISTRATORS); if (admins.isPresent()) { - insertGroupPermission(dbSession, template, UserRole.ADMIN, admins.get()); + insertGroupPermission(dbSession, template, ProjectPermission.ADMIN, admins.get()); } else { LOG.error("Cannot setup default permission for group: " + DefaultGroups.ADMINISTRATORS); } @@ -104,14 +104,14 @@ public class RegisterPermissionTemplates implements Startable { private void insertPermissionsForDefaultGroup(DbSession dbSession, PermissionTemplateDto template) { GroupDto defaultGroup = defaultGroupFinder.findDefaultGroup(dbSession); - insertGroupPermission(dbSession, template, UserRole.USER, defaultGroup); - insertGroupPermission(dbSession, template, UserRole.CODEVIEWER, defaultGroup); - insertGroupPermission(dbSession, template, UserRole.ISSUE_ADMIN, defaultGroup); - insertGroupPermission(dbSession, template, UserRole.SECURITYHOTSPOT_ADMIN, defaultGroup); + insertGroupPermission(dbSession, template, ProjectPermission.USER, defaultGroup); + insertGroupPermission(dbSession, template, ProjectPermission.CODEVIEWER, defaultGroup); + insertGroupPermission(dbSession, template, ProjectPermission.ISSUE_ADMIN, defaultGroup); + insertGroupPermission(dbSession, template, ProjectPermission.SECURITYHOTSPOT_ADMIN, defaultGroup); } - private void insertGroupPermission(DbSession dbSession, PermissionTemplateDto template, String permission, GroupDto group) { - dbClient.permissionTemplateDao().insertGroupPermission(dbSession, template.getUuid(), group.getUuid(), permission, template.getName(), group.getName()); + private void insertGroupPermission(DbSession dbSession, PermissionTemplateDto template, ProjectPermission permission, GroupDto group) { + dbClient.permissionTemplateDao().insertGroupPermission(dbSession, template.getUuid(), group.getUuid(), permission.getKey(), template.getName(), group.getName()); } } diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/platform/DatabaseServerCompatibilityTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/platform/DatabaseServerCompatibilityTest.java index a4d0ea02611..e2b2319e161 100644 --- a/server/sonar-webserver-core/src/test/java/org/sonar/server/platform/DatabaseServerCompatibilityTest.java +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/platform/DatabaseServerCompatibilityTest.java @@ -23,6 +23,8 @@ import java.util.Optional; import org.junit.Rule; import org.junit.Test; import org.slf4j.event.Level; +import org.sonar.api.SonarEdition; +import org.sonar.api.SonarRuntime; import org.sonar.api.testfixtures.log.LogTester; import org.sonar.api.utils.MessageException; import org.sonar.core.documentation.DocumentationLinkGenerator; @@ -41,7 +43,8 @@ public class DatabaseServerCompatibilityTest { private final DatabaseVersion version = mock(DatabaseVersion.class); private final DocumentationLinkGenerator documentationLinkGenerator = mock(DocumentationLinkGenerator.class); - private final DatabaseServerCompatibility compatibility = new DatabaseServerCompatibility(version, documentationLinkGenerator); + private final SonarRuntime sonarRuntime = mock(); + private final DatabaseServerCompatibility compatibility = new DatabaseServerCompatibility(version, documentationLinkGenerator, sonarRuntime); @Test public void fail_if_requires_downgrade() { @@ -61,7 +64,19 @@ public class DatabaseServerCompatibilityTest { assertThatThrownBy(compatibility::start) .isInstanceOf(MessageException.class) - .hasMessage("The version of SonarQube you are trying to upgrade from is too old. Please upgrade to the 9.9 Long-Term Active version first."); + .hasMessage("The version of SonarQube you are trying to upgrade from is too old. Please upgrade to the 2025.1 Long-Term Active version first."); + verifyNoInteractions(documentationLinkGenerator); + } + + @Test + public void fail_if_requires_firstly_to_upgrade_to_24_12() { + when(version.getStatus()).thenReturn(DatabaseVersion.Status.REQUIRES_UPGRADE); + when(version.getVersion()).thenReturn(Optional.of(12L)); + when(sonarRuntime.getEdition()).thenReturn(SonarEdition.COMMUNITY); + + assertThatThrownBy(compatibility::start) + .isInstanceOf(MessageException.class) + .hasMessage("The version of SonarQube you are trying to upgrade from is too old. Please upgrade to the 24.12 version first."); verifyNoInteractions(documentationLinkGenerator); } diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RuleDescriptionGeneratorTestData.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RuleDescriptionGeneratorTestData.java index f2f7f0d788b..db319d595f5 100644 --- a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RuleDescriptionGeneratorTestData.java +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RuleDescriptionGeneratorTestData.java @@ -25,7 +25,7 @@ import java.util.List; import java.util.Set; import java.util.StringJoiner; import javax.annotation.Nullable; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RuleDescriptionSection; import org.sonar.db.rule.RuleDescriptionSectionDto; diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RuleDescriptionSectionsGeneratorsTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RuleDescriptionSectionsGeneratorsTest.java index 1a52d4c7c3b..467054ad6e7 100644 --- a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RuleDescriptionSectionsGeneratorsTest.java +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RuleDescriptionSectionsGeneratorsTest.java @@ -30,6 +30,7 @@ import org.junit.runners.Parameterized; import org.sonar.api.server.rule.RuleDescriptionSection; import org.sonar.api.server.rule.RuleDescriptionSectionBuilder; import org.sonar.api.server.rule.RulesDefinition; +import org.sonar.core.rule.RuleTypeMapper; import org.sonar.core.util.UuidFactory; import org.sonar.db.rule.RuleDescriptionSectionDto; import org.sonar.server.rule.RuleDescriptionGeneratorTestData.RuleDescriptionSectionGeneratorIdentifier; @@ -37,10 +38,10 @@ import org.sonar.server.rule.RuleDescriptionGeneratorTestData.RuleDescriptionSec import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ROOT_CAUSE_SECTION_KEY; import static org.sonar.server.rule.RuleDescriptionGeneratorTestData.RuleDescriptionSectionGeneratorIdentifier.ADVANCED_RULE; import static org.sonar.server.rule.RuleDescriptionGeneratorTestData.RuleDescriptionSectionGeneratorIdentifier.LEGACY_HOTSPOT; @@ -125,7 +126,7 @@ public class RuleDescriptionSectionsGeneratorsTest { when(rule.htmlDescription()).thenReturn(testData.getHtmlDescription()); when(rule.markdownDescription()).thenReturn(testData.getMarkdownDescription()); when(rule.ruleDescriptionSections()).thenReturn(testData.getRuleDescriptionSections()); - when(rule.type()).thenReturn(testData.getRuleType()); + when(rule.type()).thenReturn(RuleTypeMapper.toApiRuleType(testData.getRuleType())); } @Test diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/NewRuleCreatorTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/NewRuleCreatorTest.java index 6d1c42f64cb..22e6733fe28 100644 --- a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/NewRuleCreatorTest.java +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/NewRuleCreatorTest.java @@ -27,9 +27,10 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleScope; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.utils.System2; +import org.sonar.core.rule.RuleTypeMapper; import org.sonar.core.util.UuidFactory; import org.sonar.db.issue.ImpactDto; import org.sonar.db.rule.RuleDto; @@ -98,7 +99,7 @@ public class NewRuleCreatorTest { when(ruleDef.key()).thenReturn("key"); when(repository.key()).thenReturn("repoKey"); - when(ruleDef.type()).thenReturn(ruleType); + when(ruleDef.type()).thenReturn(RuleTypeMapper.toApiRuleType(ruleType)); when(ruleDef.scope()).thenReturn(RuleScope.TEST); when(ruleDef.cleanCodeAttribute()).thenReturn(attribute); when(ruleDef.severity()).thenReturn(MAJOR); diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/StartupRuleUpdaterTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/StartupRuleUpdaterTest.java index df3d0345df6..c47fbddc3e4 100644 --- a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/StartupRuleUpdaterTest.java +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/registration/StartupRuleUpdaterTest.java @@ -26,7 +26,6 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleScope; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.utils.System2; import org.sonar.core.util.UuidFactory; @@ -112,7 +111,7 @@ public class StartupRuleUpdaterTest { RulesDefinition.Rule ruleDef = mock(); when(ruleDef.scope()).thenReturn(RuleScope.TEST); when(ruleDef.repository()).thenReturn(mock()); - when(ruleDef.type()).thenReturn(RuleType.BUG); + when(ruleDef.type()).thenReturn(org.sonar.api.rules.RuleType.BUG); return ruleDef; } diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/startup/PropertiesDBCleanerTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/startup/PropertiesDBCleanerTest.java new file mode 100644 index 00000000000..15c9955f853 --- /dev/null +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/startup/PropertiesDBCleanerTest.java @@ -0,0 +1,78 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.startup; + +import java.util.Objects; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.sonar.api.SonarEdition; +import org.sonar.api.SonarRuntime; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.property.PropertyDto; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + + +class PropertiesDBCleanerTest { + @RegisterExtension + public DbTester db = DbTester.create(); + private final DbClient dbClient = db.getDbClient(); + private final DbSession dbSession = db.getSession(); + private final SonarRuntime sonarRuntime = mock(SonarRuntime.class); + private static final String MISRA_SETTING = "sonar.earlyAccess.misra.enabled"; + + @ParameterizedTest + @ValueSource(strings = { "COMMUNITY", "DEVELOPER" }) + void should_clean_up_misra_prop_when_dev_or_community_edition(String edition) { + when(sonarRuntime.getEdition()).thenReturn(SonarEdition.valueOf(edition)); + + dbClient + .propertiesDao() + .saveProperty(dbSession, new PropertyDto() + .setKey(MISRA_SETTING) + .setValue("true"), null, null, null, null); + dbSession.commit(); + + new PropertiesDBCleaner(dbClient, sonarRuntime).start(); + assertThat(dbClient.propertiesDao().selectGlobalProperty(MISRA_SETTING)).isNull(); + } + + @ParameterizedTest + @ValueSource(strings = { "ENTERPRISE", "DATACENTER" }) + void should_not_clean_up_misra_prop_when_enterprise_or_above(String edition) { + when(sonarRuntime.getEdition()).thenReturn(SonarEdition.valueOf(edition)); + + PropertyDto prop = new PropertyDto() + .setKey(MISRA_SETTING) + .setValue("true"); + dbClient + .propertiesDao() + .saveProperty(dbSession, prop, null, null, null, null); + dbSession.commit(); + + new PropertiesDBCleaner(dbClient, sonarRuntime).start(); + assertThat(Objects.requireNonNull(dbClient.propertiesDao().selectGlobalProperty(MISRA_SETTING)).getValue()).isEqualTo(prop.getValue()); + } +} diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java index dd0c63742a9..30f76e659aa 100644 --- a/server/sonar-webserver-core/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java @@ -28,7 +28,7 @@ import org.slf4j.event.Level; import org.sonar.api.security.DefaultGroups; import org.sonar.api.testfixtures.log.LogTester; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbTester; import org.sonar.db.permission.template.PermissionTemplateDto; @@ -61,11 +61,11 @@ public class RegisterPermissionTemplatesTest { List<PermissionTemplateGroupDto> groupPermissions = selectGroupPermissions(defaultTemplate); assertThat(groupPermissions).hasSize(5); - expectGroupPermission(groupPermissions, UserRole.ADMIN, DefaultGroups.ADMINISTRATORS); - expectGroupPermission(groupPermissions, UserRole.CODEVIEWER, defaultGroup.getName()); - expectGroupPermission(groupPermissions, UserRole.USER, defaultGroup.getName()); - expectGroupPermission(groupPermissions, UserRole.ISSUE_ADMIN, defaultGroup.getName()); - expectGroupPermission(groupPermissions, UserRole.SECURITYHOTSPOT_ADMIN, defaultGroup.getName()); + expectGroupPermission(groupPermissions, ProjectPermission.ADMIN, DefaultGroups.ADMINISTRATORS); + expectGroupPermission(groupPermissions, ProjectPermission.CODEVIEWER, defaultGroup.getName()); + expectGroupPermission(groupPermissions, ProjectPermission.USER, defaultGroup.getName()); + expectGroupPermission(groupPermissions, ProjectPermission.ISSUE_ADMIN, defaultGroup.getName()); + expectGroupPermission(groupPermissions, ProjectPermission.SECURITYHOTSPOT_ADMIN, defaultGroup.getName()); verifyDefaultTemplateForProject(defaultTemplate.getUuid()); @@ -83,10 +83,10 @@ public class RegisterPermissionTemplatesTest { List<PermissionTemplateGroupDto> groupPermissions = selectGroupPermissions(defaultTemplate); assertThat(groupPermissions).hasSize(4); - expectGroupPermission(groupPermissions, UserRole.CODEVIEWER, defaultGroup.getName()); - expectGroupPermission(groupPermissions, UserRole.USER, defaultGroup.getName()); - expectGroupPermission(groupPermissions, UserRole.ISSUE_ADMIN, defaultGroup.getName()); - expectGroupPermission(groupPermissions, UserRole.SECURITYHOTSPOT_ADMIN, defaultGroup.getName()); + expectGroupPermission(groupPermissions, ProjectPermission.CODEVIEWER, defaultGroup.getName()); + expectGroupPermission(groupPermissions, ProjectPermission.USER, defaultGroup.getName()); + expectGroupPermission(groupPermissions, ProjectPermission.ISSUE_ADMIN, defaultGroup.getName()); + expectGroupPermission(groupPermissions, ProjectPermission.SECURITYHOTSPOT_ADMIN, defaultGroup.getName()); verifyDefaultTemplateForProject(defaultTemplate.getUuid()); @@ -113,10 +113,10 @@ public class RegisterPermissionTemplatesTest { return db.getDbClient().permissionTemplateDao().selectGroupPermissionsByTemplateUuid(db.getSession(), template.getUuid()); } - private void expectGroupPermission(List<PermissionTemplateGroupDto> groupPermissions, String expectedPermission, + private void expectGroupPermission(List<PermissionTemplateGroupDto> groupPermissions, ProjectPermission expectedPermission, String expectedGroupName) { assertThat( - groupPermissions.stream().anyMatch(gp -> gp.getPermission().equals(expectedPermission) && Objects.equals(gp.getGroupName(), expectedGroupName))) + groupPermissions.stream().anyMatch(gp -> gp.getPermission().equals(expectedPermission.getKey()) && Objects.equals(gp.getGroupName(), expectedGroupName))) .isTrue(); } diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java index b77dd42e33a..72b3bd272f0 100644 --- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java +++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java @@ -77,7 +77,7 @@ import org.sonar.api.issue.IssueStatus; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttributeCategory; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version; import org.sonar.api.server.rule.RulesDefinition.PciDssVersion; @@ -120,8 +120,8 @@ import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.index.query.QueryBuilders.termsQuery; import static org.elasticsearch.search.aggregations.AggregationBuilders.filters; import static org.elasticsearch.search.aggregations.AggregationBuilders.reverseNested; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.core.config.MQRModeConstants.MULTI_QUALITY_MODE_DEFAULT_VALUE; import static org.sonar.core.config.MQRModeConstants.MULTI_QUALITY_MODE_ENABLED; import static org.sonar.server.es.EsUtils.escapeSpecialRegexChars; diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java index 6d321828c82..e105cd9d175 100644 --- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java +++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java @@ -47,7 +47,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.db.component.ComponentQualifiers; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ServerSide; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -75,8 +75,8 @@ import static org.sonar.api.measures.CoreMetrics.ANALYSIS_FROM_SONARQUBE_9_4_KEY import static org.sonar.api.utils.DateUtils.longToDate; import static org.sonar.api.utils.DateUtils.parseEndingDateOrDateTime; import static org.sonar.api.utils.DateUtils.parseStartingDateOrDateTime; -import static org.sonar.api.web.UserRole.SCAN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.SCAN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.newcodeperiod.NewCodePeriodType.REFERENCE_BRANCH; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENTS; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENT_UUIDS; diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java index 270c52e46c5..9d8340da24c 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java @@ -31,7 +31,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.sonar.api.issue.IssueStatus; import org.sonar.api.issue.impact.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RulesDefinition.OwaspAsvsVersion; import org.sonar.db.component.ComponentDto; import org.sonar.db.rule.RuleDto; diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java index 36d08eafff8..23daad4fed0 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java @@ -31,7 +31,7 @@ import org.junit.jupiter.params.provider.ValueSource; import org.sonar.api.issue.Issue; import org.sonar.api.issue.IssueStatus; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.component.ComponentDto; import org.sonar.db.rule.RuleDto; import org.sonar.server.es.SearchOptions; diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityCategoriesTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityCategoriesTest.java index 6f39428e060..2cbd1a87fad 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityCategoriesTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityCategoriesTest.java @@ -26,7 +26,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.sonar.api.issue.Issue; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.component.ComponentDto; import static java.util.Arrays.asList; diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java index d1f57ab2e8c..a7de06f6410 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityHotspotsTest.java @@ -33,10 +33,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; import static org.sonar.api.rule.Severity.INFO; import static org.sonar.api.rule.Severity.MAJOR; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; -import static org.sonar.api.rules.RuleType.VULNERABILITY; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; import static org.sonar.server.issue.IssueDocTesting.newDoc; diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java index af9a89b1b86..0eee21734c2 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java @@ -31,7 +31,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.sonar.api.issue.Issue; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RulesDefinition.StigVersion; import org.sonar.db.component.ComponentDto; import org.sonar.server.view.index.ViewDoc; diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java index c4f37ed0913..eb5c05b4ab6 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java @@ -55,7 +55,7 @@ import static org.sonar.api.measures.CoreMetrics.ANALYSIS_FROM_SONARQUBE_9_4_KEY import static org.sonar.db.component.ComponentQualifiers.APP; import static org.sonar.api.utils.DateUtils.addDays; import static org.sonar.api.utils.DateUtils.parseDateTime; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME; import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.component.ComponentTesting.newFileDto; diff --git a/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/sonarlint/SonarLintClientPermissionsValidator.java b/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/sonarlint/SonarLintClientPermissionsValidator.java index 2a4565e5a2a..4163b1392f1 100644 --- a/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/sonarlint/SonarLintClientPermissionsValidator.java +++ b/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/sonarlint/SonarLintClientPermissionsValidator.java @@ -22,7 +22,7 @@ package org.sonar.server.pushapi.sonarlint; import java.util.List; import java.util.Set; import org.sonar.api.server.ServerSide; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.project.ProjectDto; @@ -70,7 +70,7 @@ public class SonarLintClientPermissionsValidator { private static void validateProjectPermissions(UserSession userSession, List<ProjectDto> projectDtos) { validateUsersDeactivationStatus(userSession); for (ProjectDto projectDto : projectDtos) { - userSession.checkEntityPermission(UserRole.USER, projectDto); + userSession.checkEntityPermission(ProjectPermission.USER, projectDto); } } diff --git a/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/issues/IssueChangeEventServiceImplTest.java b/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/issues/IssueChangeEventServiceImplTest.java index 3c4de18aae2..af0bc77997d 100644 --- a/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/issues/IssueChangeEventServiceImplTest.java +++ b/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/issues/IssueChangeEventServiceImplTest.java @@ -32,7 +32,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.FieldDiffs; import org.sonar.core.util.issue.Issue; @@ -57,7 +57,7 @@ import static org.sonar.api.issue.DefaultTransitions.REOPEN; import static org.sonar.api.issue.DefaultTransitions.RESOLVE; import static org.sonar.api.issue.DefaultTransitions.UNCONFIRM; import static org.sonar.api.issue.DefaultTransitions.WONT_FIX; -import static org.sonar.api.rules.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.CODE_SMELL; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonarqube.ws.Common.Severity.BLOCKER; import static org.sonarqube.ws.Common.Severity.CRITICAL; diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/WebApiEndpoints.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/WebApiEndpoints.java index 88a98f1f2d9..f8c11a99d6e 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/WebApiEndpoints.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/WebApiEndpoints.java @@ -21,7 +21,7 @@ package org.sonar.server.v2; public class WebApiEndpoints { public static final String JSON_MERGE_PATCH_CONTENT_TYPE = "application/merge-patch+json"; - public static final String INTERNAL = "internal"; + public static final String INTERNAL = "x-sonar-internal"; public static final String SYSTEM_DOMAIN = "/system"; public static final String LIVENESS_ENDPOINT = SYSTEM_DOMAIN + "/liveness"; @@ -54,6 +54,13 @@ public class WebApiEndpoints { public static final String ACTIVE_RULES_ENDPOINT = ANALYSIS_DOMAIN + "/active_rules"; public static final String SCANNER_ENGINE_ENDPOINT = ANALYSIS_DOMAIN + "/engine"; + public static final String SCA_DOMAIN = "/sca"; + public static final String SCA_RELEASES_ENDPOINT = SCA_DOMAIN + "/releases"; + public static final String SCA_ISSUES_RELEASES_ENDPOINT = SCA_DOMAIN + "/issues-releases"; + public static final String SCA_SBOM_REPORTS_ENDPOINT = SCA_DOMAIN + "/sbom-reports"; + public static final String SCA_CLIS_ENDPOINT = SCA_DOMAIN + "/clis"; + public static final String SCA_FEATURE_ENABLEMENT_ENDPOINT = SCA_DOMAIN + "/feature-enablements"; + private WebApiEndpoints() { } } diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/analysis/service/JresHandlerImpl.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/analysis/service/JresHandlerImpl.java index 2b5cac05451..b4d2620567a 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/analysis/service/JresHandlerImpl.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/analysis/service/JresHandlerImpl.java @@ -21,23 +21,23 @@ package org.sonar.server.v2.api.analysis.service; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.annotations.VisibleForTesting; +import jakarta.annotation.PostConstruct; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Predicate; import javax.annotation.Nullable; -import jakarta.annotation.PostConstruct; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.v2.api.analysis.response.JreInfoRestResponse; +import org.sonar.server.v2.common.model.Arch; +import org.sonar.server.v2.common.model.OS; -import static java.lang.String.join; import static org.apache.commons.lang.StringUtils.isBlank; public class JresHandlerImpl implements JresHandler { @@ -95,54 +95,4 @@ public class JresHandlerImpl implements JresHandler { throw new NotFoundException(String.format("Unable to find JRE '%s'", jreFilename)); } } - - enum OS { - WINDOWS("win", "windows", "win32"), - LINUX("linux"), - MACOS("mac", "macos", "darwin"), - ALPINE("alpine"); - - private final List<String> aliases; - - OS(String... aliases) { - this.aliases = Arrays.stream(aliases).toList(); - } - - private static OS from(String alias) { - return Arrays.stream(values()) - .filter(os -> os.aliases.contains(alias)) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException(String.format("Unsupported OS: '%s'. Supported values are '%s'", alias, join(", ", supportedValues())))); - } - - private static List<String> supportedValues() { - return Arrays.stream(values()) - .flatMap(os -> os.aliases.stream()) - .toList(); - } - } - - enum Arch { - X64("x86_64", "x86-64", "amd64", "x64"), - AARCH64("arm64", "aarch64"); - - private final List<String> aliases; - - Arch(String... aliases) { - this.aliases = Arrays.stream(aliases).toList(); - } - - private static Arch from(String alias) { - return Arrays.stream(values()) - .filter(arch -> arch.aliases.contains(alias)) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException(String.format("Unsupported architecture: '%s'. Supported values are '%s'", alias, join(", ", supportedValues())))); - } - - private static List<String> supportedValues() { - return Arrays.stream(values()) - .flatMap(arch -> arch.aliases.stream()) - .toList(); - } - } } diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/model/RestError.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/model/RestError.java index d00ee8cffa2..2cb534440af 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/model/RestError.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/model/RestError.java @@ -19,4 +19,13 @@ */ package org.sonar.server.v2.api.model; -public record RestError(String message) {} +import com.fasterxml.jackson.annotation.JsonInclude; +import javax.annotation.Nullable; + +public record RestError( + String message, + @Nullable @JsonInclude(JsonInclude.Include.NON_NULL) String relatedField) { + public RestError(String errorMessage) { + this(errorMessage, null); + } +} diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/projectbindings/controller/DefaultProjectBindingsController.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/projectbindings/controller/DefaultProjectBindingsController.java index 9fbc090eba9..3ea79cb5467 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/projectbindings/controller/DefaultProjectBindingsController.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/projectbindings/controller/DefaultProjectBindingsController.java @@ -35,7 +35,7 @@ import org.sonar.server.v2.api.projectbindings.request.ProjectBindingsSearchRest import org.sonar.server.v2.api.projectbindings.response.ProjectBindingsSearchRestResponse; import org.sonar.server.v2.api.response.PageRestResponse; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; public class DefaultProjectBindingsController implements ProjectBindingsController { diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/converter/RuleRestResponseGenerator.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/converter/RuleRestResponseGenerator.java index a7a4236c246..5dc164eee8f 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/converter/RuleRestResponseGenerator.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/converter/RuleRestResponseGenerator.java @@ -29,7 +29,7 @@ import org.jetbrains.annotations.Nullable; import org.sonar.api.resources.Language; import org.sonar.api.resources.Languages; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction; import org.sonar.api.utils.DateUtils; @@ -79,7 +79,7 @@ public class RuleRestResponseGenerator { .setRepositoryKey(ruleDto.getRepositoryKey()) .setName(ruleDto.getName()) .setSeverity(ruleDto.getSeverityString()) - .setType(RuleTypeRestEnum.from(RuleType.valueOf(ruleDto.getType()))) + .setType(RuleTypeRestEnum.from(RuleType.fromDbConstant(ruleDto.getType()))) .setImpacts(toImpactRestResponse(ruleDto.getDefaultImpacts())) .setCleanCodeAttribute(CleanCodeAttributeRestEnum.from(ruleDto.getCleanCodeAttribute())) .setCleanCodeAttributeCategory(ofNullable(ruleDto.getCleanCodeAttribute()) @@ -110,7 +110,7 @@ public class RuleRestResponseGenerator { .map(this::toDescriptionSectionResponse) .ifPresent(section -> builder.setDescriptionSections(List.of(section))); ofNullable(ruleDto.getAdHocSeverity()).ifPresent(builder::setSeverity); - ofNullable(ruleDto.getAdHocType()).ifPresent(type -> builder.setType(RuleTypeRestEnum.from(RuleType.valueOf(type)))); + ofNullable(ruleDto.getAdHocType()).ifPresent(type -> builder.setType(RuleTypeRestEnum.from(RuleType.fromDbConstant(type)))); } return builder.build(); } diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/enums/RuleTypeRestEnum.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/enums/RuleTypeRestEnum.java index aa57cb8080b..f369edb9392 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/enums/RuleTypeRestEnum.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/enums/RuleTypeRestEnum.java @@ -20,7 +20,7 @@ package org.sonar.server.v2.api.rule.enums; import java.util.Arrays; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; public enum RuleTypeRestEnum { CODE_SMELL(RuleType.CODE_SMELL), diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/request/RuleCreateRestRequest.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/request/RuleCreateRestRequest.java index 375a14d7ad9..f9358794f59 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/request/RuleCreateRestRequest.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/rule/request/RuleCreateRestRequest.java @@ -25,7 +25,7 @@ import javax.annotation.Nullable; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.server.v2.api.rule.enums.CleanCodeAttributeRestEnum; import org.sonar.server.v2.api.rule.enums.RuleStatusRestEnum; import org.sonar.server.v2.api.rule.resource.Impact; diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/system/controller/HealthController.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/system/controller/HealthController.java index 8d45e96db24..669296482a4 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/system/controller/HealthController.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/api/system/controller/HealthController.java @@ -19,6 +19,7 @@ */ package org.sonar.server.v2.api.system.controller; +import javax.annotation.Nullable; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.ServerException; import org.sonar.server.health.Health; @@ -26,6 +27,7 @@ import org.sonar.server.health.HealthChecker; import org.sonar.server.platform.NodeInformation; import org.sonar.server.user.SystemPasscode; import org.sonar.server.user.UserSession; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; @@ -47,18 +49,15 @@ public class HealthController { private final NodeInformation nodeInformation; private final UserSession userSession; - public HealthController(HealthChecker healthChecker, SystemPasscode systemPasscode, NodeInformation nodeInformation, - UserSession userSession) { + @Autowired(required=true) + public HealthController(HealthChecker healthChecker, SystemPasscode systemPasscode, @Nullable NodeInformation nodeInformation, + @Nullable UserSession userSession) { this.healthChecker = healthChecker; this.systemPasscode = systemPasscode; this.nodeInformation = nodeInformation; this.userSession = userSession; } - public HealthController(HealthChecker healthChecker, SystemPasscode systemPasscode) { - this(healthChecker, systemPasscode, null, null); - } - @GetMapping public Health getHealth(@RequestHeader(value = "X-Sonar-Passcode", required = false) String requestPassCode) { if (systemPasscode.isValidPasscode(requestPassCode) || isSystemAdmin()) { diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/common/RestResponseEntityExceptionHandler.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/common/RestResponseEntityExceptionHandler.java index 3880a8e3510..409796fbf05 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/common/RestResponseEntityExceptionHandler.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/common/RestResponseEntityExceptionHandler.java @@ -27,6 +27,7 @@ import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.server.authentication.event.AuthenticationException; +import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ServerException; import org.sonar.server.v2.api.model.RestError; import org.springframework.core.convert.ConversionFailedException; @@ -177,6 +178,13 @@ public class RestResponseEntityExceptionHandler { return buildResponse(httpStatus, errorMessage); } + @ExceptionHandler(BadRequestException.class) + protected ResponseEntity<RestError> handleBadRequestException(BadRequestException ex) { + return ex.getRelatedField() + .map(field -> ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new RestError(ex.getMessage(), field))) + .orElse(handleServerException(ex)); + } + @ExceptionHandler({Exception.class}) protected ResponseEntity<RestError> handleUnhandledException(Exception ex) { LOGGER.error(ErrorMessages.UNEXPECTED_ERROR.getMessage(), ex); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/ProjectDependenciesMapper.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/common/model/Arch.java index b0047776c1a..52b54531764 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/dependency/ProjectDependenciesMapper.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/common/model/Arch.java @@ -17,24 +17,34 @@ * 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.dependency; +package org.sonar.server.v2.common.model; +import java.util.Arrays; import java.util.List; -import org.apache.ibatis.annotations.Param; -import org.sonar.db.Pagination; -public interface ProjectDependenciesMapper { - void insert(ProjectDependencyDto dto); +import static java.lang.String.join; +import static java.util.Locale.ENGLISH; - void deleteByUuid(String uuid); +public enum Arch { + X64("x86_64", "x86-64", "amd64", "x64"), + AARCH64("arm64", "aarch64"); - ProjectDependencyDto selectByUuid(String uuid); + private final List<String> aliases; - List<ProjectDependencyDto> selectByBranchUuid(String branchUuid); + Arch(String... aliases) { + this.aliases = Arrays.stream(aliases).toList(); + } - List<ProjectDependencyDto> selectByQuery(@Param("query") ProjectDependenciesQuery query, @Param("pagination") Pagination pagination); + public static Arch from(String alias) { + return Arrays.stream(values()) + .filter(arch -> arch.aliases.contains(alias.toLowerCase(ENGLISH))) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(String.format("Unsupported architecture: '%s'. Supported values are '%s'", alias, join(", ", supportedValues())))); + } - void update(ProjectDependencyDto dto); - - int countByQuery(@Param("query") ProjectDependenciesQuery query); + public static List<String> supportedValues() { + return Arrays.stream(values()) + .flatMap(arch -> arch.aliases.stream()) + .toList(); + } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/DeduplicatePropertiesTable.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/common/model/OS.java index e2d5abff08f..23072d1bb21 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/DeduplicatePropertiesTable.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/common/model/OS.java @@ -17,34 +17,36 @@ * 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.platform.db.migration.version.v103; +package org.sonar.server.v2.common.model; -import java.sql.SQLException; +import java.util.Arrays; import java.util.List; -import org.sonar.db.Database; -import org.sonar.server.platform.db.migration.sql.DeduplicateTableBuilder; -import org.sonar.server.platform.db.migration.step.DataChange; -public class DeduplicatePropertiesTable extends DataChange { - private static final String PROPERTIES_TABLE = "properties"; +import static java.lang.String.join; +import static java.util.Locale.ENGLISH; - public DeduplicatePropertiesTable(Database db) { - super(db); +public enum OS { + WINDOWS("win", "windows", "win32"), + LINUX("linux"), + MACOS("mac", "macos", "darwin"), + ALPINE("alpine"); + + private final List<String> aliases; + + OS(String... aliases) { + this.aliases = Arrays.stream(aliases).toList(); } - @Override - protected void execute(Context context) throws SQLException { - List<String> queries = new DeduplicateTableBuilder(PROPERTIES_TABLE) - .addReferenceColumn("prop_key") - .addReferenceColumn("entity_uuid") - .addReferenceColumn("user_uuid") - .setIdentityColumn("uuid") - .build(); + public static OS from(String alias) { + return Arrays.stream(values()) + .filter(os -> os.aliases.contains(alias.toLowerCase(ENGLISH))) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(String.format("Unsupported OS: '%s'. Supported values are '%s'", alias, join(", ", supportedValues())))); + } - for (String q : queries) { - context.prepareUpsert(q) - .execute() - .commit(); - } + public static List<String> supportedValues() { + return Arrays.stream(values()) + .flatMap(os -> os.aliases.stream()) + .toList(); } } diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/config/PlatformLevel4WebConfig.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/config/PlatformLevel4WebConfig.java index bd010589ae6..962682037d7 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/config/PlatformLevel4WebConfig.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/config/PlatformLevel4WebConfig.java @@ -19,75 +19,30 @@ */ package org.sonar.server.v2.config; -import org.sonar.api.platform.Server; -import org.sonar.api.resources.Languages; -import org.sonar.db.Database; -import org.sonar.db.DbClient; -import org.sonar.server.common.email.config.EmailConfigurationService; -import org.sonar.server.common.github.config.GithubConfigurationService; -import org.sonar.server.common.gitlab.config.GitlabConfigurationService; -import org.sonar.server.common.group.service.GroupMembershipService; -import org.sonar.server.common.group.service.GroupService; -import org.sonar.server.common.management.ManagedInstanceChecker; -import org.sonar.server.common.platform.LivenessChecker; -import org.sonar.server.common.project.ImportProjectService; -import org.sonar.server.common.projectbindings.service.ProjectBindingsService; -import org.sonar.server.common.rule.service.RuleService; -import org.sonar.server.common.text.MacroInterpreter; -import org.sonar.server.common.user.service.UserService; -import org.sonar.server.health.HealthChecker; -import org.sonar.server.notification.NotificationManager; -import org.sonar.server.platform.NodeInformation; -import org.sonar.server.platform.ServerFileSystem; -import org.sonar.server.platform.db.migration.DatabaseMigrationState; -import org.sonar.server.platform.db.migration.version.DatabaseVersion; -import org.sonar.server.qualitygate.QualityGateConditionsValidator; import org.sonar.server.rule.ActiveRuleService; -import org.sonar.server.rule.RuleDescriptionFormatter; -import org.sonar.server.setting.SettingsChangeNotifier; -import org.sonar.server.user.SystemPasscode; import org.sonar.server.user.UserSession; -import org.sonar.server.v2.api.analysis.controller.ActiveRulesController; import org.sonar.server.v2.api.analysis.controller.DefaultActiveRulesController; import org.sonar.server.v2.api.analysis.controller.DefaultJresController; import org.sonar.server.v2.api.analysis.controller.DefaultScannerEngineController; import org.sonar.server.v2.api.analysis.controller.DefaultVersionController; -import org.sonar.server.v2.api.analysis.controller.JresController; -import org.sonar.server.v2.api.analysis.controller.ScannerEngineController; -import org.sonar.server.v2.api.analysis.controller.VersionController; -import org.sonar.server.v2.api.analysis.service.ActiveRulesHandler; import org.sonar.server.v2.api.analysis.service.ActiveRulesHandlerImpl; -import org.sonar.server.v2.api.analysis.service.JresHandler; import org.sonar.server.v2.api.analysis.service.JresHandlerImpl; -import org.sonar.server.v2.api.analysis.service.ScannerEngineHandler; import org.sonar.server.v2.api.analysis.service.ScannerEngineHandlerImpl; import org.sonar.server.v2.api.dop.controller.DefaultDopSettingsController; -import org.sonar.server.v2.api.dop.controller.DopSettingsController; import org.sonar.server.v2.api.email.config.controller.DefaultEmailConfigurationController; -import org.sonar.server.v2.api.email.config.controller.EmailConfigurationController; import org.sonar.server.v2.api.github.config.controller.DefaultGithubConfigurationController; -import org.sonar.server.v2.api.github.config.controller.GithubConfigurationController; import org.sonar.server.v2.api.gitlab.config.controller.DefaultGitlabConfigurationController; -import org.sonar.server.v2.api.gitlab.config.controller.GitlabConfigurationController; import org.sonar.server.v2.api.group.controller.DefaultGroupController; -import org.sonar.server.v2.api.group.controller.GroupController; import org.sonar.server.v2.api.membership.controller.DefaultGroupMembershipController; -import org.sonar.server.v2.api.membership.controller.GroupMembershipController; import org.sonar.server.v2.api.mode.controller.DefaultModeController; -import org.sonar.server.v2.api.mode.controller.ModeController; import org.sonar.server.v2.api.projectbindings.controller.DefaultProjectBindingsController; -import org.sonar.server.v2.api.projectbindings.controller.ProjectBindingsController; -import org.sonar.server.v2.api.projects.controller.BoundProjectsController; import org.sonar.server.v2.api.projects.controller.DefaultBoundProjectsController; import org.sonar.server.v2.api.rule.controller.DefaultRuleController; -import org.sonar.server.v2.api.rule.controller.RuleController; import org.sonar.server.v2.api.rule.converter.RuleRestResponseGenerator; import org.sonar.server.v2.api.system.controller.DatabaseMigrationsController; import org.sonar.server.v2.api.system.controller.DefaultLivenessController; import org.sonar.server.v2.api.system.controller.HealthController; -import org.sonar.server.v2.api.system.controller.LivenessController; import org.sonar.server.v2.api.user.controller.DefaultUserController; -import org.sonar.server.v2.api.user.controller.UserController; import org.sonar.server.v2.api.user.converter.UsersSearchRestResponseGenerator; import org.sonar.server.v2.common.DeprecatedHandler; import org.springframework.context.annotation.Bean; @@ -97,60 +52,35 @@ import org.springframework.context.annotation.Primary; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @Configuration -@Import(CommonWebConfig.class) +@Import({ + ActiveRulesHandlerImpl.class, + ActiveRuleService.class, + CommonWebConfig.class, + DatabaseMigrationsController.class, + DefaultActiveRulesController.class, + DefaultBoundProjectsController.class, + DefaultDopSettingsController.class, + DefaultEmailConfigurationController.class, + DefaultGithubConfigurationController.class, + DefaultGitlabConfigurationController.class, + DefaultGroupController.class, + DefaultGroupMembershipController.class, + DefaultJresController.class, + DefaultLivenessController.class, + DefaultModeController.class, + DefaultProjectBindingsController.class, + DefaultRuleController.class, + DefaultScannerEngineController.class, + DefaultUserController.class, + DefaultVersionController.class, + HealthController.class, + JresHandlerImpl.class, + ScannerEngineHandlerImpl.class, + UsersSearchRestResponseGenerator.class, + RuleRestResponseGenerator.class +}) public class PlatformLevel4WebConfig { - @Bean - public LivenessController livenessController(LivenessChecker livenessChecker, UserSession userSession, SystemPasscode systemPasscode) { - return new DefaultLivenessController(livenessChecker, systemPasscode, userSession); - } - - @Bean - public HealthController healthController(HealthChecker healthChecker, SystemPasscode systemPasscode, NodeInformation nodeInformation, - UserSession userSession) { - return new HealthController(healthChecker, systemPasscode, nodeInformation, userSession); - } - - @Bean - public DatabaseMigrationsController databaseMigrationsController(DatabaseVersion databaseVersion, DatabaseMigrationState databaseMigrationState, - Database database) { - return new DatabaseMigrationsController(databaseVersion, databaseMigrationState, database); - } - - @Bean - public UsersSearchRestResponseGenerator usersSearchResponseGenerator(UserSession userSession) { - return new UsersSearchRestResponseGenerator(userSession); - } - - @Bean - public UserController userController( - UserSession userSession, - UsersSearchRestResponseGenerator usersSearchResponseGenerator, - UserService userService) { - return new DefaultUserController(userSession, userService, usersSearchResponseGenerator); - } - - @Bean - public GroupController groupController(UserSession userSession, DbClient dbClient, GroupService groupService, ManagedInstanceChecker managedInstanceChecker) { - return new DefaultGroupController(userSession, dbClient, groupService, managedInstanceChecker); - } - - @Bean - public GroupMembershipController groupMembershipsController(UserSession userSession, - GroupMembershipService groupMembershipService, ManagedInstanceChecker managedInstanceChecker) { - return new DefaultGroupMembershipController(userSession, groupMembershipService, managedInstanceChecker); - } - - @Bean - public RuleRestResponseGenerator ruleRestResponseGenerator(Languages languages, MacroInterpreter macroInterpreter, RuleDescriptionFormatter ruleDescriptionFormatter) { - return new RuleRestResponseGenerator(languages, macroInterpreter, ruleDescriptionFormatter); - } - - @Bean - public RuleController ruleController(UserSession userSession, RuleService ruleService, RuleRestResponseGenerator ruleRestResponseGenerator) { - return new DefaultRuleController(userSession, ruleService, ruleRestResponseGenerator); - } - @Primary @Bean("org.sonar.server.v2.config.PlatformLevel4WebConfig.requestMappingHandlerMapping") public RequestMappingHandlerMapping requestMappingHandlerMapping(UserSession userSession) { @@ -159,80 +89,4 @@ public class PlatformLevel4WebConfig { return handlerMapping; } - @Bean - public GitlabConfigurationController gitlabConfigurationController(UserSession userSession, GitlabConfigurationService gitlabConfigurationService) { - return new DefaultGitlabConfigurationController(userSession, gitlabConfigurationService); - } - - @Bean - public GithubConfigurationController githubConfigurationController(UserSession userSession, GithubConfigurationService githubConfigurationService) { - return new DefaultGithubConfigurationController(userSession, githubConfigurationService); - } - - @Bean - public BoundProjectsController importedProjectsController(UserSession userSession, ImportProjectService importProjectService) { - return new DefaultBoundProjectsController(userSession, importProjectService); - } - - @Bean - public DopSettingsController dopSettingsController(UserSession userSession, DbClient dbClient) { - return new DefaultDopSettingsController(userSession, dbClient); - } - - @Bean - public ProjectBindingsController projectBindingsController(UserSession userSession, ProjectBindingsService projectBindingsService) { - return new DefaultProjectBindingsController(userSession, projectBindingsService); - } - - @Bean - public VersionController versionController(Server server) { - return new DefaultVersionController(server); - } - - @Bean - public JresHandler jresHandler() { - return new JresHandlerImpl(); - } - - @Bean - public JresController jresController(JresHandler jresHandler) { - return new DefaultJresController(jresHandler); - } - - @Bean - public ScannerEngineHandler scannerEngineHandler(ServerFileSystem serverFileSystem) { - return new ScannerEngineHandlerImpl(serverFileSystem); - } - - @Bean - public ScannerEngineController scannerEngineController(ScannerEngineHandler scannerEngineHandler) { - return new DefaultScannerEngineController(scannerEngineHandler); - } - - @Bean - public EmailConfigurationController emailConfigurationController(UserSession userSession, EmailConfigurationService emailConfigurationService) { - return new DefaultEmailConfigurationController(userSession, emailConfigurationService); - } - - @Bean - public ModeController modeController(UserSession userSession, org.sonar.api.config.Configuration configuration, DbClient dbClient, - SettingsChangeNotifier settingsChangeNotifier, NotificationManager notificationManager, QualityGateConditionsValidator qualityGateConditionsValidator) { - return new DefaultModeController(userSession, dbClient, configuration, settingsChangeNotifier, notificationManager, qualityGateConditionsValidator); - } - - @Bean - public ActiveRuleService activeRuleService(DbClient dbClient, Languages languages) { - return new ActiveRuleService(dbClient, languages); - } - - @Bean - public ActiveRulesHandler activeRulesHandler(DbClient dbClient, ActiveRuleService activeRuleService) { - return new ActiveRulesHandlerImpl(dbClient, activeRuleService); - } - - @Bean - public ActiveRulesController activeRulesController(ActiveRulesHandler activeRulesHandler) { - return new DefaultActiveRulesController(activeRulesHandler); - } - } diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/config/SafeModeWebConfig.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/config/SafeModeWebConfig.java index 1810e0dbbc9..db4cf56e25f 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/config/SafeModeWebConfig.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/config/SafeModeWebConfig.java @@ -19,11 +19,8 @@ */ package org.sonar.server.v2.config; -import org.sonar.db.Database; import org.sonar.server.common.platform.LivenessChecker; import org.sonar.server.health.HealthChecker; -import org.sonar.server.platform.db.migration.DatabaseMigrationState; -import org.sonar.server.platform.db.migration.version.DatabaseVersion; import org.sonar.server.user.SystemPasscode; import org.sonar.server.v2.api.system.controller.DatabaseMigrationsController; import org.sonar.server.v2.api.system.controller.DefaultLivenessController; @@ -36,7 +33,10 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc; @Configuration @EnableWebMvc -@Import(CommonWebConfig.class) +@Import({ + CommonWebConfig.class, + DatabaseMigrationsController.class +}) public class SafeModeWebConfig { @Bean @@ -46,12 +46,7 @@ public class SafeModeWebConfig { @Bean public HealthController healthController(HealthChecker healthChecker, SystemPasscode systemPasscode) { - return new HealthController(healthChecker, systemPasscode); + return new HealthController(healthChecker, systemPasscode, null, null); } - @Bean - public DatabaseMigrationsController databaseMigrationsController(DatabaseVersion databaseVersion, DatabaseMigrationState databaseMigrationState, - Database database) { - return new DatabaseMigrationsController(databaseVersion, databaseMigrationState, database); - } } diff --git a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/analysis/service/JresHandlerImplTest.java b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/analysis/service/JresHandlerImplTest.java index 452fa756d3e..c2b999f0b20 100644 --- a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/analysis/service/JresHandlerImplTest.java +++ b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/analysis/service/JresHandlerImplTest.java @@ -106,6 +106,15 @@ class JresHandlerImplTest { assertThat(result).isEmpty(); } + @Test + void getJresMetadata_shoudBeCaseInsensitive() { + List<JreInfoRestResponse> resultList = jresHandler.getJresMetadata("LiNux", "AARCH64"); + + assertThat(resultList).hasSize(1); + JreInfoRestResponse result = resultList.get(0); + assertThat(result).usingRecursiveComparison().isEqualTo(JRE_METADATA.get("2")); + } + @ParameterizedTest @ValueSource(strings = {"1", "2", "3"}) void getJreMetadata(String id) { @@ -127,4 +136,5 @@ class JresHandlerImplTest { .isInstanceOf(NotFoundException.class) .hasMessage("Unable to find JRE 'jre1'"); } + } diff --git a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/projectbindings/controller/DefaultProjectBindingsControllerTest.java b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/projectbindings/controller/DefaultProjectBindingsControllerTest.java index 80e007b1ad9..65ef60637d1 100644 --- a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/projectbindings/controller/DefaultProjectBindingsControllerTest.java +++ b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/projectbindings/controller/DefaultProjectBindingsControllerTest.java @@ -39,7 +39,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.db.permission.ProjectPermission.ADMIN; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; import static org.sonar.server.v2.WebApiEndpoints.PROJECT_BINDINGS_ENDPOINT; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; diff --git a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/rule/controller/DefaultRuleControllerTest.java b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/rule/controller/DefaultRuleControllerTest.java index 7ca361be6c4..8ccc2b3e4f3 100644 --- a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/rule/controller/DefaultRuleControllerTest.java +++ b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/rule/controller/DefaultRuleControllerTest.java @@ -28,7 +28,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.resources.Languages; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.rule.RuleDescriptionSectionDto; import org.sonar.db.rule.RuleDto; import org.sonar.db.rule.RuleTesting; @@ -57,7 +57,7 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.sonar.api.rule.Severity.BLOCKER; -import static org.sonar.api.rules.RuleType.BUG; +import static org.sonar.core.rule.RuleType.BUG; import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_PROFILES; import static org.sonar.server.v2.WebApiEndpoints.RULES_ENDPOINT; import static org.sonar.server.v2.api.rule.enums.CleanCodeAttributeRestEnum.MODULAR; diff --git a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/rule/converter/RuleRestResponseGeneratorTest.java b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/rule/converter/RuleRestResponseGeneratorTest.java index e68974fe135..760514cb7e8 100644 --- a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/rule/converter/RuleRestResponseGeneratorTest.java +++ b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/api/rule/converter/RuleRestResponseGeneratorTest.java @@ -31,7 +31,7 @@ import org.mockito.junit.MockitoJUnitRunner; import org.sonar.api.resources.Languages; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction; import org.sonar.api.utils.DateUtils; @@ -83,7 +83,7 @@ public class RuleRestResponseGeneratorTest { .extracting(RuleDescriptionSectionRestResponse::key, RuleDescriptionSectionRestResponse::content, RuleDescriptionSectionRestResponse::context) .containsExactly(dto.getRuleDescriptionSectionDtos().stream().map(s -> tuple(s.getKey(), "interpreted" + "html" + s.getContent(), s.getContext())).toArray(Tuple[]::new)); assertThat(ruleRestResponse.severity()).isEqualTo(dto.getSeverityString()); - assertThat(ruleRestResponse.type().name()).isEqualTo(RuleType.valueOf(dto.getType()).name()); + assertThat(ruleRestResponse.type().name()).isEqualTo(RuleType.fromDbConstant(dto.getType()).name()); assertThat(ruleRestResponse.impacts()).extracting(r -> r.severity().name(), r -> r.softwareQuality().name()) .containsExactly(dto.getDefaultImpacts().stream().map(e -> tuple(e.getSeverity().name(), e.getSoftwareQuality().name())).toArray(Tuple[]::new)); assertThat(ruleRestResponse.cleanCodeAttribute().name()).isEqualTo(dto.getCleanCodeAttribute().name()); @@ -146,7 +146,7 @@ public class RuleRestResponseGeneratorTest { .extracting(RuleDescriptionSectionRestResponse::key, RuleDescriptionSectionRestResponse::content, RuleDescriptionSectionRestResponse::context) .containsExactly(tuple("default", "interpreted" + dto.getAdHocDescription(), null)); assertThat(ruleRestResponse.severity()).isEqualTo(dto.getAdHocSeverity()); - assertThat(ruleRestResponse.type().name()).isEqualTo(RuleType.valueOf(dto.getAdHocType()).name()); + assertThat(ruleRestResponse.type().name()).isEqualTo(RuleType.fromDbConstant(dto.getAdHocType()).name()); } @Test @@ -165,7 +165,7 @@ public class RuleRestResponseGeneratorTest { .extracting(RuleDescriptionSectionRestResponse::key, RuleDescriptionSectionRestResponse::content, RuleDescriptionSectionRestResponse::context) .containsExactly(tuple("default", "interpreted" + dto.getAdHocDescription(), null)); assertThat(ruleRestResponse.severity()).isEqualTo(dto.getAdHocSeverity()); - assertThat(ruleRestResponse.type().name()).isEqualTo(RuleType.valueOf(dto.getAdHocType()).name()); + assertThat(ruleRestResponse.type().name()).isEqualTo(RuleType.fromDbConstant(dto.getAdHocType()).name()); } } diff --git a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/common/RestResponseEntityExceptionHandlerTest.java b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/common/RestResponseEntityExceptionHandlerTest.java index a83b8ba073b..7dbe13a3a18 100644 --- a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/common/RestResponseEntityExceptionHandlerTest.java +++ b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/common/RestResponseEntityExceptionHandlerTest.java @@ -102,7 +102,7 @@ class RestResponseEntityExceptionHandlerTest { assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); assertThat(response.getBody()).isNotNull(); - assertThat(response.getBody().message()).isEqualTo("Value <rejectedValue> for field <field> was rejected. Error: <defaultMessage>." /* ErrorMessages.VALIDATION_ERROR.getMessage() */); + assertThat(response.getBody().message()).isEqualTo("Value <rejectedValue> for field <field> was rejected. Error: <defaultMessage>."); // Verify logging assertThat(logs.logs(Level.INFO)).anyMatch(log -> log.startsWith(ErrorMessages.VALIDATION_ERROR.getMessage())); @@ -333,6 +333,7 @@ class RestResponseEntityExceptionHandlerTest { assertThat(response.getStatusCode()).isEqualTo(expectedStatus); assertThat(response.getBody()).isNotNull(); assertThat(response.getBody().message()).isEqualTo(ex.getMessage()); + assertThat(response.getBody().relatedField()).isNull(); } static Stream<Arguments> serverExceptionsProvider() { @@ -358,6 +359,16 @@ class RestResponseEntityExceptionHandlerTest { assertThat(logs.logs(Level.ERROR)).contains(ErrorMessages.UNEXPECTED_ERROR.getMessage()); } + @Test + void handleBadRequestException_shouldReturnRelatedField_whenItIsProvided() { + ResponseEntity<RestError> response = underTest.handleBadRequestException(BadRequestException.createWithRelatedField("Bad request message", "related field")); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + assertThat(response.getBody()).isNotNull(); + assertThat(response.getBody().message()).isEqualTo("Bad request message"); + assertThat(response.getBody().relatedField()).isEqualTo("related field"); + } + // endregion server } diff --git a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/config/PlatformLevel4WebConfigTest.java b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/config/PlatformLevel4WebConfigTest.java index 27c05bc9e3f..dc2e42ad426 100644 --- a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/config/PlatformLevel4WebConfigTest.java +++ b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/config/PlatformLevel4WebConfigTest.java @@ -23,15 +23,8 @@ import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.sonar.api.platform.Server; -import org.sonar.server.platform.ServerFileSystem; -import org.sonar.server.v2.api.analysis.controller.DefaultJresController; -import org.sonar.server.v2.api.analysis.controller.DefaultVersionController; -import org.sonar.server.v2.api.analysis.controller.DefaultScannerEngineController; -import org.sonar.server.v2.api.analysis.service.JresHandler; -import org.sonar.server.v2.api.analysis.service.JresHandlerImpl; -import org.sonar.server.v2.api.analysis.service.ScannerEngineHandler; -import org.sonar.server.v2.api.analysis.service.ScannerEngineHandlerImpl; +import org.sonar.server.user.UserSession; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.params.provider.Arguments.arguments; @@ -43,17 +36,12 @@ class PlatformLevel4WebConfigTest { private static Stream<Arguments> components() { return Stream.of( - arguments(platformLevel4WebConfig.versionController(mock(Server.class)), DefaultVersionController.class), - arguments(platformLevel4WebConfig.jresHandler(), JresHandlerImpl.class), - arguments(platformLevel4WebConfig.jresController(mock(JresHandler.class)), DefaultJresController.class), - arguments(platformLevel4WebConfig.scannerEngineHandler(mock(ServerFileSystem.class)), ScannerEngineHandlerImpl.class), - arguments(platformLevel4WebConfig.scannerEngineController(mock(ScannerEngineHandler.class)), DefaultScannerEngineController.class) - ); + arguments(platformLevel4WebConfig.requestMappingHandlerMapping(mock(UserSession.class)), RequestMappingHandlerMapping.class)); } @ParameterizedTest @MethodSource("components") - void components_shouldBeInjectedInPlatformLevel4WebConfig(Object component, Class<?> instanceClass) { + void custom_components_shouldBeInjectedInPlatformLevel4WebConfig(Object component, Class<?> instanceClass) { assertThat(component).isNotNull().isInstanceOf(instanceClass); } } diff --git a/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/config/SafeModeWebConfigTest.java b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/config/SafeModeWebConfigTest.java new file mode 100644 index 00000000000..a9d87095b5a --- /dev/null +++ b/server/sonar-webserver-webapi-v2/src/test/java/org/sonar/server/v2/config/SafeModeWebConfigTest.java @@ -0,0 +1,51 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.v2.config; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.sonar.server.common.platform.LivenessChecker; +import org.sonar.server.health.HealthChecker; +import org.sonar.server.user.SystemPasscode; +import org.sonar.server.v2.api.system.controller.DefaultLivenessController; +import org.sonar.server.v2.api.system.controller.HealthController; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.params.provider.Arguments.arguments; +import static org.mockito.Mockito.mock; + +class SafeModeWebConfigTest { + + private static final SafeModeWebConfig safeModeWebConfig = new SafeModeWebConfig(); + + private static Stream<Arguments> components() { + return Stream.of( + arguments(safeModeWebConfig.livenessController(mock(LivenessChecker.class), mock(SystemPasscode.class)), DefaultLivenessController.class), + arguments(safeModeWebConfig.healthController(mock(HealthChecker.class), mock(SystemPasscode.class)), HealthController.class)); + } + + @ParameterizedTest + @MethodSource("components") + void custom_components_shouldBeInjectedInSafeModeWebConfig(Object component, Class<?> instanceClass) { + assertThat(component).isNotNull().isInstanceOf(instanceClass); + } +} diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectActionIT.java index c4175f49ee5..77c69d2fad5 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/almintegration/ws/github/ImportGithubProjectActionIT.java @@ -27,14 +27,13 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.sonar.alm.client.github.GithubApplicationClientImpl; import org.sonar.alm.client.github.GithubPermissionConverter; -import org.sonar.db.component.ComponentQualifiers; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; import org.sonar.auth.github.ExpiringAppInstallationToken; import org.sonar.auth.github.GitHubSettings; +import org.sonar.auth.github.GithubApplicationClient; import org.sonar.auth.github.GsonRepositoryCollaborator; import org.sonar.auth.github.GsonRepositoryPermissions; -import org.sonar.auth.github.GithubApplicationClient; import org.sonar.core.i18n.I18n; import org.sonar.core.platform.EditionProvider; import org.sonar.core.platform.PlatformEditionProvider; @@ -43,10 +42,11 @@ import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.alm.setting.AlmSettingDto; import org.sonar.db.component.BranchDto; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.entity.EntityDto; import org.sonar.db.newcodeperiod.NewCodePeriodDto; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.CreationMethod; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.UserDto; @@ -63,6 +63,7 @@ import org.sonar.server.common.permission.UserPermissionChange; import org.sonar.server.common.permission.UserPermissionChanger; import org.sonar.server.common.project.ImportProjectService; import org.sonar.server.common.project.ProjectCreator; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.es.EsTester; import org.sonar.server.es.IndexersImpl; import org.sonar.server.es.TestIndexers; @@ -365,7 +366,7 @@ public class ImportGithubProjectActionIT { String role = gsonRepositoryCollaborator.roleName(); GsonRepositoryPermissions permissions = gsonRepositoryCollaborator.permissions(); - when(githubPermissionConverter.toSonarqubeRolesWithFallbackOnRepositoryPermissions(Set.of(), role, permissions)).thenReturn(Set.of("scan")); + when(githubPermissionConverter.toSonarqubeRolesWithFallbackOnRepositoryPermissions(Set.of(), role, permissions)).thenReturn(Set.of(ProjectPermission.SCAN)); } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/almsettings/ws/GetBindingActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/almsettings/ws/GetBindingActionIT.java index 42bcb7cbb53..e38ad58e71d 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/almsettings/ws/GetBindingActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/almsettings/ws/GetBindingActionIT.java @@ -39,7 +39,7 @@ import org.sonarqube.ws.AlmSettings.GetBindingWsResponse; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.groups.Tuple.tuple; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.test.JsonAssert.assertJson; public class GetBindingActionIT { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/almsettings/ws/ListActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/almsettings/ws/ListActionIT.java index e5c8e380b8b..85500f5bb67 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/almsettings/ws/ListActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/almsettings/ws/ListActionIT.java @@ -41,9 +41,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.groups.Tuple.tuple; import static org.mockito.Mockito.mock; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.SCAN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.SCAN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; import static org.sonar.test.JsonAssert.assertJson; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/MeasureActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/MeasureActionIT.java index 83ff4275910..e78bfaa9981 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/MeasureActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/MeasureActionIT.java @@ -71,7 +71,7 @@ import static org.sonar.api.measures.Metric.ValueType.LEVEL; import static org.sonar.api.measures.Metric.ValueType.PERCENT; import static org.sonar.api.measures.Metric.ValueType.RATING; import static org.sonar.api.measures.Metric.ValueType.WORK_DUR; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.BranchType.BRANCH; import static org.sonar.server.badge.ws.SvgGenerator.Color.DEFAULT; import static org.sonar.server.badge.ws.SvgGenerator.Color.QUALITY_GATE_ERROR; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/QualityGateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/QualityGateActionIT.java index 629fca17853..1faa2f829f7 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/QualityGateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/QualityGateActionIT.java @@ -59,7 +59,7 @@ import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY; import static org.sonar.api.measures.Metric.Level.ERROR; import static org.sonar.api.measures.Metric.Level.OK; import static org.sonar.api.measures.Metric.ValueType.LEVEL; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.BranchType.BRANCH; @RunWith(DataProviderRunner.class) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/TokenActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/TokenActionIT.java index 7c876cfe071..8ada0a56fb6 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/TokenActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/TokenActionIT.java @@ -23,7 +23,7 @@ import org.assertj.core.api.Assertions; import org.junit.Rule; import org.junit.Test; import org.mockito.Mockito; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.project.ProjectDto; @@ -74,7 +74,7 @@ public class TokenActionIT { @Test public void should_generate_token() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project); when(tokenGenerator.generate(TokenType.PROJECT_BADGE_TOKEN)).thenReturn("generated_token"); TestResponse response = ws.newRequest().setParam("project", project.getKey()).execute(); @@ -85,7 +85,7 @@ public class TokenActionIT { @Test public void handle_whenApplicationKeyPassed_shouldReturnToken() { ProjectDto application = db.components().insertPrivateApplication().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.USER, application); + userSession.logIn().addProjectPermission(ProjectPermission.USER, application); when(tokenGenerator.generate(TokenType.PROJECT_BADGE_TOKEN)).thenReturn("generated_token"); TestResponse response = ws.newRequest().setParam("project", application.getKey()).execute(); @@ -96,7 +96,7 @@ public class TokenActionIT { @Test public void should_reuse_generated_token() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project); when(tokenGenerator.generate(TokenType.PROJECT_BADGE_TOKEN)).thenReturn("generated_token"); // first call, generating the token diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/TokenRenewActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/TokenRenewActionIT.java index e6feafee464..ba9f2bbacb5 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/TokenRenewActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/badge/ws/TokenRenewActionIT.java @@ -25,7 +25,7 @@ import org.junit.Rule; import org.junit.Test; import org.mockito.Mockito; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbTester; import org.sonar.db.component.ProjectData; import org.sonar.db.project.ProjectBadgeTokenDto; @@ -86,7 +86,7 @@ public class TokenRenewActionIT { @Test public void should_add_token_when_no_token_yet_and_return_204() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); when(tokenGenerator.generate(TokenType.PROJECT_BADGE_TOKEN)).thenReturn("generated_token"); TestResponse response = ws.newRequest().setParam("project", project.getKey()).execute(); @@ -100,7 +100,7 @@ public class TokenRenewActionIT { @Test public void handle_whenApplicationKeyPassed_shouldAddTokenAndReturn204() { ProjectDto application = db.components().insertPrivateApplication().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, application); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, application); when(tokenGenerator.generate(TokenType.PROJECT_BADGE_TOKEN)).thenReturn("generated_token"); TestResponse response = ws.newRequest().setParam("project", application.getKey()).execute(); @@ -114,7 +114,7 @@ public class TokenRenewActionIT { @Test public void should_replace_existing_token_when__token_already_present_and_update_update_at() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); when(tokenGenerator.generate(TokenType.PROJECT_BADGE_TOKEN)).thenReturn("generated_token"); ws.newRequest().setParam("project", project.getKey()).execute(); //inserting first token with updated at 1000 diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/batch/ProjectDataLoaderIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/batch/ProjectDataLoaderIT.java index c61955d17b5..5a5a9071ad6 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/batch/ProjectDataLoaderIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/batch/ProjectDataLoaderIT.java @@ -21,20 +21,20 @@ package org.sonar.server.batch; import org.junit.Rule; import org.junit.Test; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.db.component.ComponentScopes; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.ComponentQualifiers; +import org.sonar.db.component.ComponentScopes; import org.sonar.db.component.ProjectData; -import org.sonar.server.component.ComponentTypesRule; import org.sonar.db.project.ProjectDto; import org.sonar.db.source.FileSourceDto; import org.sonar.scanner.protocol.input.FileData; import org.sonar.scanner.protocol.input.ProjectRepositories; import org.sonar.server.component.ComponentFinder; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.tester.UserSessionRule; @@ -44,7 +44,7 @@ import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.sonar.db.component.ComponentTesting.newFileDto; -import static org.sonar.db.permission.GlobalPermission.SCAN; +import static org.sonar.db.permission.ProjectPermission.SCAN; public class ProjectDataLoaderIT { @Rule @@ -61,8 +61,8 @@ public class ProjectDataLoaderIT { public void throws_NotFoundException_when_branch_does_not_exist() { ProjectData projectData = db.components().insertPrivateProject(); ProjectDto project = projectData.getProjectDto(); - userSession.logIn().addProjectPermission(SCAN.getKey(), project) - .registerBranches(projectData.getMainBranchDto()); + userSession.logIn().addProjectPermission(SCAN, project) + .registerBranches(projectData.getMainBranchDto()); assertThatThrownBy(() -> { underTest.load(ProjectDataQuery.create() @@ -77,7 +77,7 @@ public class ProjectDataLoaderIT { public void return_file_data_from_single_project() { ProjectData projectData = db.components().insertPrivateProject(); ProjectDto project = projectData.getProjectDto(); - userSession.logIn().addProjectPermission(SCAN.getKey(), project) + userSession.logIn().addProjectPermission(SCAN, project) .registerBranches(projectData.getMainBranchDto()); ComponentDto file = db.components().insertComponent(newFileDto(projectData.getMainBranchComponent())); dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(file).setSrcHash("123456")); @@ -95,7 +95,7 @@ public class ProjectDataLoaderIT { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); ComponentDto branch = db.components().insertProjectBranch(mainBranch, b -> b.setKey("my_branch")); - userSession.logIn().addProjectPermission(SCAN.getKey(), projectData.getProjectDto()) + userSession.logIn().addProjectPermission(SCAN, projectData.getProjectDto()) .registerBranches(projectData.getMainBranchDto()) .addProjectBranchMapping(projectData.projectUuid(), branch); // File on branch diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/DeleteActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/DeleteActionIT.java index 39788c99944..3cfd49472a5 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/DeleteActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/DeleteActionIT.java @@ -24,7 +24,7 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.BranchDto; @@ -65,7 +65,7 @@ public class DeleteActionIT { public void delete_branch() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); db.components().insertProjectBranch(project, b -> b.setKey("branch1")); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); tester.newRequest() .setParam("project", project.getKey()) @@ -104,7 +104,7 @@ public class DeleteActionIT { @Test public void fail_if_branch_does_not_exist() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); assertThatThrownBy(() -> tester.newRequest() .setParam("project", project.getKey()) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/ListActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/ListActionIT.java index adf8465480d..df13fe1aa44 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/ListActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/ListActionIT.java @@ -22,7 +22,6 @@ package org.sonar.server.branch.ws; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; @@ -30,11 +29,12 @@ 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.server.component.ComponentTypesRule; import org.sonar.db.metric.MetricDto; import org.sonar.db.project.ProjectDto; import org.sonar.db.rule.RuleDto; import org.sonar.server.component.ComponentFinder; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.es.EsTester; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.issue.index.AsyncIssueIndexing; @@ -54,15 +54,15 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.tuple; import static org.mockito.Mockito.mock; import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY; -import static org.sonar.db.component.ComponentQualifiers.PROJECT; -import static org.sonar.api.rules.RuleType.BUG; +import static org.sonar.core.rule.RuleType.BUG; import static org.sonar.api.utils.DateUtils.dateToLong; import static org.sonar.api.utils.DateUtils.parseDateTime; -import static org.sonar.api.web.UserRole.USER; import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME; import static org.sonar.db.component.BranchType.BRANCH; +import static org.sonar.db.component.ComponentQualifiers.PROJECT; import static org.sonar.db.component.SnapshotTesting.newAnalysis; -import static org.sonar.db.permission.GlobalPermission.SCAN; +import static org.sonar.db.permission.ProjectPermission.SCAN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.test.JsonAssert.assertJson; public class ListActionIT { @@ -158,7 +158,7 @@ public class ListActionIT { db.issues().insert(rule, branch, db.components().getComponentDto(branch), i -> i.setType(BUG).setResolution(null)); indexIssues(); - userSession.logIn().addProjectPermission(SCAN.getKey(), project); + userSession.logIn().addProjectPermission(SCAN, project); String json = ws.newRequest() .setParam("project", project.getKey()) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/RenameActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/RenameActionIT.java index 1445a715f62..5d083ef3e8a 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/RenameActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/RenameActionIT.java @@ -25,7 +25,7 @@ import org.junit.Test; import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbTester; import org.sonar.db.component.BranchDto; import org.sonar.db.component.ComponentDto; @@ -107,7 +107,7 @@ public class RenameActionIT { userSession.logIn(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); BranchDto branch = db.components().insertProjectBranch(project, b -> b.setKey("branch")); - userSession.addProjectPermission(UserRole.ADMIN, project); + userSession.addProjectPermission(ProjectPermission.ADMIN, project); tester.newRequest() .setParam("project", project.getKey()) @@ -127,7 +127,7 @@ public class RenameActionIT { userSession.logIn(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); db.newCodePeriods().insert(getBranchReferenceNewCodePeriod(project)); - userSession.addProjectPermission(UserRole.ADMIN, project); + userSession.addProjectPermission(ProjectPermission.ADMIN, project); tester.newRequest() .setParam("project", project.getKey()) @@ -155,7 +155,7 @@ public class RenameActionIT { userSession.logIn(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); BranchDto branch = db.components().insertProjectBranch(project, b -> b.setKey("branch")); - userSession.addProjectPermission(UserRole.ADMIN, project); + userSession.addProjectPermission(ProjectPermission.ADMIN, project); tester.newRequest() .setParam("project", project.getKey()) @@ -179,7 +179,7 @@ public class RenameActionIT { public void fail_if_name_already_used() { userSession.logIn(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.addProjectPermission(UserRole.ADMIN, project); + userSession.addProjectPermission(ProjectPermission.ADMIN, project); db.components().insertProjectBranch(project, b -> b.setKey("branch")); assertThatThrownBy(() -> tester.newRequest() diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/SetAutomaticDeletionProtectionActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/SetAutomaticDeletionProtectionActionIT.java index 7406042df04..46cde7696af 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/SetAutomaticDeletionProtectionActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/SetAutomaticDeletionProtectionActionIT.java @@ -25,7 +25,7 @@ import org.junit.Test; import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbTester; import org.sonar.db.component.BranchDto; import org.sonar.server.component.ComponentTypesRule; @@ -121,7 +121,7 @@ public class SetAutomaticDeletionProtectionActionIT { userSession.logIn(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); BranchDto branch = db.components().insertProjectBranch(project, b -> b.setKey("branch1").setExcludeFromPurge(false)); - userSession.addProjectPermission(UserRole.ADMIN, project); + userSession.addProjectPermission(ProjectPermission.ADMIN, project); assertThatThrownBy(() -> tester.newRequest() .setParam("project", project.getKey()) @@ -137,7 +137,7 @@ public class SetAutomaticDeletionProtectionActionIT { userSession.logIn(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); BranchDto branch = db.components().insertProjectBranch(project, b -> b.setKey("branch1").setExcludeFromPurge(false)); - userSession.addProjectPermission(UserRole.ADMIN, project); + userSession.addProjectPermission(ProjectPermission.ADMIN, project); tester.newRequest() .setParam("project", project.getKey()) @@ -186,7 +186,7 @@ public class SetAutomaticDeletionProtectionActionIT { public void fail_if_branch_does_not_exist() { userSession.logIn(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.addProjectPermission(UserRole.ADMIN, project); + userSession.addProjectPermission(ProjectPermission.ADMIN, project); assertThatThrownBy(() -> tester.newRequest() .setParam("project", project.getKey()) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/SetMainBranchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/SetMainBranchActionIT.java index 0670746fc4b..83c7c2e849e 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/SetMainBranchActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/branch/ws/SetMainBranchActionIT.java @@ -28,7 +28,7 @@ import org.slf4j.event.Level; import org.sonar.api.server.ws.WebService; import org.sonar.api.testfixtures.log.LogTester; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbTester; import org.sonar.db.component.BranchDto; import org.sonar.db.component.ComponentTesting; @@ -140,7 +140,7 @@ public class SetMainBranchActionIT { public void fail_whenKeyPassedIsApplicationKey_shouldThrowIllegalArgumentException() { userSession.logIn(); ProjectData application = db.components().insertPublicApplication(); - userSession.addProjectPermission(UserRole.ADMIN, application.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.ADMIN, application.getProjectDto()); TestRequest request = tester.newRequest() .setParam(PARAM_PROJECT, application.projectKey()) @@ -156,7 +156,7 @@ public class SetMainBranchActionIT { userSession.logIn(); ProjectData projectData = db.components().insertPublicProject(); - userSession.addProjectPermission(UserRole.ADMIN, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.ADMIN, projectData.getProjectDto()); String nonExistingBranch = "aNonExistingBranch"; TestRequest request = tester.newRequest() @@ -172,7 +172,7 @@ public class SetMainBranchActionIT { public void fail_whenProjectHasNoMainBranch_shouldThrowIllegalStateException() { userSession.logIn(); ProjectDto project = insertProjectWithoutMainBranch(); - userSession.addProjectPermission(UserRole.ADMIN, project); + userSession.addProjectPermission(ProjectPermission.ADMIN, project); TestRequest request = tester.newRequest() .setParam(PARAM_PROJECT, project.getKey()) @@ -195,7 +195,7 @@ public class SetMainBranchActionIT { userSession.logIn(); ProjectData projectData = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.ADMIN, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.ADMIN, projectData.getProjectDto()); TestRequest request = tester.newRequest() .setParam(PARAM_PROJECT, projectData.projectKey()) @@ -213,7 +213,7 @@ public class SetMainBranchActionIT { ProjectData projectData = db.components().insertPrivateProject(); BranchDto newMainBranch = db.components().insertProjectBranch(projectData.getProjectDto(), branchDto -> branchDto.setKey("newMain")); - userSession.addProjectPermission(UserRole.ADMIN, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.ADMIN, projectData.getProjectDto()); tester.newRequest() .setParam(PARAM_PROJECT, projectData.projectKey()) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/BranchReportSubmitterIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/BranchReportSubmitterIT.java index dee0b9a0026..d1df85bb22e 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/BranchReportSubmitterIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/BranchReportSubmitterIT.java @@ -44,6 +44,8 @@ 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.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.CreationMethod; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.UserDto; @@ -82,6 +84,7 @@ import static org.sonar.db.component.ComponentTesting.newBranchDto; import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; import static org.sonar.db.permission.GlobalPermission.SCAN; +import static org.sonar.db.permission.ProjectPermission.SCAN; /** * Tests of {@link ReportSubmitter} when branch support is installed. @@ -126,7 +129,7 @@ public class BranchReportSubmitterIT { ProjectData projectData = db.components().insertPublicProject(); ProjectDto project = projectData.getProjectDto(); UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(SCAN.getKey(), project) + userSession.logIn(user).addProjectPermission(ProjectPermission.SCAN, project) .registerBranches(projectData.getMainBranchDto()); mockSuccessfulPrepareSubmitCall(); InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8); @@ -142,7 +145,7 @@ public class BranchReportSubmitterIT { ComponentDto mainBranch = projectData.getMainBranchComponent(); ComponentDto branch = db.components().insertProjectBranch(mainBranch, b -> b.setKey("branch1")); UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(SCAN.getKey(), projectData.getProjectDto()) + userSession.logIn(user).addProjectPermission(ProjectPermission.SCAN, projectData.getProjectDto()) .registerBranches(projectData.getMainBranchDto()) .addProjectBranchMapping(projectData.projectUuid(), branch); BranchSupport.ComponentKey componentKey = createComponentKeyOfBranch(mainBranch.getKey(), "branch1"); @@ -170,7 +173,7 @@ public class BranchReportSubmitterIT { ComponentDto mainBranch = projectData.getMainBranchComponent(); BranchDto exitingProjectMainBranch = db.getDbClient().branchDao().selectByUuid(db.getSession(), mainBranch.uuid()).get(); UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(SCAN.getKey(), projectData.getProjectDto()) + userSession.logIn(user).addProjectPermission(ProjectPermission.SCAN, projectData.getProjectDto()) .registerBranches(projectData.getMainBranchDto()); ComponentDto createdBranch = createButDoNotInsertBranch(mainBranch, projectData.projectUuid()); userSession.addProjectBranchMapping(projectData.projectUuid(), createdBranch); @@ -198,7 +201,7 @@ public class BranchReportSubmitterIT { UserDto user = db.users().insertUser(); userSession.logIn(user) .addPermission(PROVISION_PROJECTS) - .addPermission(SCAN); + .addPermission(GlobalPermission.SCAN); ComponentDto createdBranch = createButDoNotInsertBranch(nonExistingBranch, PROJECT_UUID); BranchSupport.ComponentKey componentKey = createComponentKeyOfBranch(nonExistingBranch.getKey()); @@ -235,7 +238,7 @@ public class BranchReportSubmitterIT { ProjectData projectData = db.components().insertPublicProject(); ComponentDto project = projectData.getMainBranchComponent(); UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(SCAN.getKey(), projectData.getProjectDto()); + userSession.logIn(user).addProjectPermission(ProjectPermission.SCAN, projectData.getProjectDto()); InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8); RuntimeException expected = new RuntimeException("Faking an exception thrown by branchSupportDelegate"); when(branchSupportDelegate.createComponentKey(any(), any())).thenThrow(expected); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/ReportSubmitterIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/ReportSubmitterIT.java index fe97c19f2c5..e4be15ba26a 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/ReportSubmitterIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/queue/ReportSubmitterIT.java @@ -45,6 +45,7 @@ import org.sonar.db.component.BranchDto; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ProjectData; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.CreationMethod; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.UserDto; @@ -95,7 +96,6 @@ import static org.sonar.core.ce.CeTaskCharacteristics.BRANCH; import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME; import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; -import static org.sonar.db.permission.GlobalPermission.SCAN; public class ReportSubmitterIT { @@ -127,7 +127,8 @@ public class ReportSubmitterIT { new FavoriteUpdater(db.getDbClient()), projectIndexers, new SequenceUuidFactory(), defaultBranchNameResolver, mock(PermissionUpdater.class), permissionService); private final ManagedProjectService managedProjectService = mock(); private final ManagedInstanceService managedInstanceService = mock(); - private final GithubDevOpsProjectCreationContextService githubDevOpsProjectService = new GithubDevOpsProjectCreationContextService(db.getDbClient(), userSession, githubApplicationClient); + private final GithubDevOpsProjectCreationContextService githubDevOpsProjectService = new GithubDevOpsProjectCreationContextService(db.getDbClient(), userSession, + githubApplicationClient); private final ProjectCreator projectCreator = new ProjectCreator(userSession, projectDefaultVisibility, componentUpdater); private final GithubProjectCreatorFactory githubProjectCreatorFactory = new GithubProjectCreatorFactory(db.getDbClient(), githubGlobalSettingsValidator, githubApplicationClient, projectKeyGenerator, projectCreator, gitHubSettings, null, permissionUpdater, permissionService, @@ -137,7 +138,6 @@ public class ReportSubmitterIT { private final DevOpsProjectCreatorFactory devOpsProjectCreatorFactorySpy = spy(devOpsProjectCreatorFactory); - private final ReportSubmitter underTest = new ReportSubmitter(queue, userSession, projectCreator, componentUpdater, permissionTemplateService, db.getDbClient(), ossEditionBranchSupport, devOpsProjectCreatorFactorySpy, managedInstanceService); @@ -182,7 +182,7 @@ public class ReportSubmitterIT { public void submit_a_report_on_existing_project() { ProjectData project = db.components().insertPrivateProject(); UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(SCAN.getKey(), project.getProjectDto()) + userSession.logIn(user).addProjectPermission(ProjectPermission.SCAN, project.getProjectDto()) .addProjectBranchMapping(project.projectUuid(), project.getMainBranchComponent()); mockSuccessfulPrepareSubmitCall(); @@ -191,11 +191,11 @@ public class ReportSubmitterIT { verifyReportIsPersisted(TASK_UUID); verifyNoInteractions(permissionTemplateService); verify(queue).submit(argThat(submit -> submit.getType().equals(CeTaskTypes.REPORT) - && submit.getComponent() - .filter(cpt -> cpt.getUuid().equals(project.getMainBranchComponent().uuid()) && cpt.getEntityUuid().equals(project.projectUuid())) - .isPresent() - && submit.getSubmitterUuid().equals(user.getUuid()) - && submit.getUuid().equals(TASK_UUID))); + && submit.getComponent() + .filter(cpt -> cpt.getUuid().equals(project.getMainBranchComponent().uuid()) && cpt.getEntityUuid().equals(project.projectUuid())) + .isPresent() + && submit.getSubmitterUuid().equals(user.getUuid()) + && submit.getUuid().equals(TASK_UUID))); } @Test @@ -214,9 +214,9 @@ public class ReportSubmitterIT { 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(projectDto.getUuid())) - .isPresent() - && submit.getUuid().equals(TASK_UUID))); + && 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_API); } @@ -274,7 +274,7 @@ public class ReportSubmitterIT { @Test public void submit_whenReportIsForANewProjectWithoutDevOpsMetadata_createsLocalProject() { - userSession.addPermission(PROVISION_PROJECTS).addPermission(SCAN); + userSession.addPermission(PROVISION_PROJECTS).addPermission(GlobalPermission.SCAN); mockSuccessfulPrepareSubmitCall(); when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(), anyString(), anyString())).thenReturn(true); @@ -287,7 +287,7 @@ public class ReportSubmitterIT { @Test public void submit_whenReportIsForANewProjectWithValidAlmSettingsAutoProvisioningOnAndPermOnGh_createsProjectWithBinding() { UserDto user = db.users().insertUser(); - userSession.logIn(user).addPermission(PROVISION_PROJECTS).addPermission(SCAN); + userSession.logIn(user).addPermission(PROVISION_PROJECTS).addPermission(GlobalPermission.SCAN); when(gitHubSettings.isProvisioningEnabled()).thenReturn(true); mockSuccessfulPrepareSubmitCall(); @@ -304,7 +304,7 @@ public class ReportSubmitterIT { @Test public void submit_whenReportIsForANewProjectWithValidAlmSettingsAutoProvisioningOnAndProjectVisibilitySyncAndPermOnGh_createsProjectWithBinding() { UserDto user = db.users().insertUser(); - userSession.logIn(user).addPermission(PROVISION_PROJECTS).addPermission(SCAN); + userSession.logIn(user).addPermission(PROVISION_PROJECTS).addPermission(GlobalPermission.SCAN); when(gitHubSettings.isProvisioningEnabled()).thenReturn(true); when(gitHubSettings.isProjectVisibilitySynchronizationActivated()).thenReturn(true); @@ -394,7 +394,8 @@ public class ReportSubmitterIT { mockGithubRepository(isPrivate); - DevOpsProjectCreationContext devOpsProjectCreationContext = new DevOpsProjectCreationContext("repo", "orga/repo", "orga/repo", true, "defaultBranch", almSettingDto, userSession); + DevOpsProjectCreationContext devOpsProjectCreationContext = new DevOpsProjectCreationContext("repo", "orga/repo", "orga/repo", true, "defaultBranch", almSettingDto, + userSession); DevOpsProjectCreator devOpsProjectCreator = spy(new GithubProjectCreator(db.getDbClient(), devOpsProjectCreationContext, projectKeyGenerator, gitHubSettings, projectCreator, permissionService, permissionUpdater, managedProjectService, githubApplicationClient, null, null)); @@ -414,7 +415,7 @@ public class ReportSubmitterIT { @Test public void user_with_scan_permission_is_allowed_to_submit_a_report_on_existing_project() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addPermission(SCAN); + userSession.addPermission(GlobalPermission.SCAN); mockSuccessfulPrepareSubmitCall(); underTest.submit(project.getKey(), project.name(), emptyMap(), IOUtils.toInputStream("{binary}", UTF_8)); @@ -426,7 +427,7 @@ public class ReportSubmitterIT { public void submit_a_report_on_existing_project_with_project_scan_permission() { ProjectData projectData = db.components().insertPrivateProject(); ProjectDto project = projectData.getProjectDto(); - userSession.addProjectPermission(SCAN.getKey(), project) + userSession.addProjectPermission(ProjectPermission.SCAN, project) .addProjectBranchMapping(project.getUuid(), projectData.getMainBranchComponent()); mockSuccessfulPrepareSubmitCall(); @@ -438,7 +439,7 @@ public class ReportSubmitterIT { @Test public void fail_if_component_is_not_a_project() { ComponentDto component = db.components().insertPublicPortfolio(); - userSession.logIn().addPortfolioPermission(SCAN.getKey(), component); + userSession.logIn().addPortfolioPermission(ProjectPermission.SCAN, component); mockSuccessfulPrepareSubmitCall(); String dbKey = component.getKey(); @@ -455,7 +456,7 @@ public class ReportSubmitterIT { ProjectData projectData = db.components().insertPrivateProject(); ProjectDto project = projectData.getProjectDto(); ComponentDto dir = db.components().insertComponent(newDirectory(projectData.getMainBranchComponent(), "path")); - userSession.logIn().addProjectPermission(SCAN.getKey(), project); + userSession.logIn().addProjectPermission(ProjectPermission.SCAN, project); mockSuccessfulPrepareSubmitCall(); String dirDbKey = dir.getKey(); @@ -467,7 +468,7 @@ public class ReportSubmitterIT { .extracting(throwable -> ((BadRequestException) throwable).errors()) .asList() .contains(format("The project '%s' is already defined in SonarQube but as a module of project '%s'. " + - "If you really want to stop directly analysing project '%s', please first delete it from SonarQube and then relaunch the analysis of project '%s'.", + "If you really want to stop directly analysing project '%s', please first delete it from SonarQube and then relaunch the analysis of project '%s'.", dir.getKey(), project.getKey(), project.getKey(), dir.getKey())); } @@ -482,7 +483,7 @@ public class ReportSubmitterIT { @Test public void fail_with_forbidden_exception_on_new_project_when_only_project_scan_permission() { ProjectDto project = db.components().insertPrivateProject(PROJECT_UUID).getProjectDto(); - userSession.addProjectPermission(SCAN.getKey(), project); + userSession.addProjectPermission(ProjectPermission.SCAN, project); mockSuccessfulPrepareSubmitCall(); Map<String, String> emptyMap = emptyMap(); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java index 19accf4b68d..11deb107024 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityActionIT.java @@ -28,7 +28,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.ce.task.taskprocessor.CeTaskProcessor; import org.sonar.core.ce.CeTaskCharacteristics; import org.sonar.core.util.Uuids; @@ -302,7 +302,7 @@ public class ActivityActionIT { ProjectData project1 = db.components().insertPrivateProject(); ProjectData project2 = db.components().insertPrivateProject(); // no need to be a system admin - userSession.logIn().addProjectPermission(UserRole.ADMIN, project1.getProjectDto()); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project1.getProjectDto()); insertActivity("T1", project1, SUCCESS); insertActivity("T2", project2, FAILED); @@ -401,7 +401,7 @@ public class ActivityActionIT { // is reserved to roots PortfolioData view = db.components().insertPrivatePortfolioData(); insertActivity("T1", view, SUCCESS); - userSession.logIn().addPortfolioPermission(UserRole.ADMIN, view.getPortfolioDto()); + userSession.logIn().addPortfolioPermission(ProjectPermission.ADMIN, view.getPortfolioDto()); TestRequest request = ws.newRequest().setParam(TEXT_QUERY, "T1"); assertThatThrownBy(() -> call(request)) @@ -413,7 +413,7 @@ public class ActivityActionIT { public void branch_in_past_activity() { logInAsSystemAdministrator(); ProjectData project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); String branchName = "branch1"; ComponentDto branch = db.components().insertProjectBranch(project.getMainBranchComponent(), b -> b.setBranchType(BRANCH).setKey(branchName)); SnapshotDto analysis = db.components().insertSnapshot(branch); @@ -455,7 +455,7 @@ public class ActivityActionIT { public void pull_request_in_past_activity() { logInAsSystemAdministrator(); ProjectData project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); String pullRequestKey = RandomStringUtils.secure().nextAlphanumeric(100); ComponentDto pullRequest = db.components().insertProjectBranch(project.getMainBranchComponent(), b -> b.setBranchType(BranchType.PULL_REQUEST).setKey(pullRequestKey)); SnapshotDto analysis = db.components().insertSnapshot(pullRequest); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityStatusActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityStatusActionIT.java index 87508bfe7e5..36b16dcdd7e 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityStatusActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ActivityStatusActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -93,7 +93,7 @@ public class ActivityStatusActionIT { String anotherProjectKey = "another-project-key"; ProjectData project = db.components().insertPrivateProject(c -> c.setKey(projectKey)); ProjectData anotherProject = db.components().insertPrivateProject(c -> c.setKey(anotherProjectKey)); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); // pending tasks returned insertInQueue(CeQueueDto.Status.PENDING, project); insertInQueue(CeQueueDto.Status.PENDING, project); @@ -119,7 +119,7 @@ public class ActivityStatusActionIT { String projectKey = "project-key"; ProjectData project = db.components().insertPrivateProject(c -> c.setKey(projectKey)); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); when(system2.now()).thenReturn(2000L); insertInQueue(CeQueueDto.Status.PENDING, project, 1000L); Ce.ActivityStatusWsResponse result = callByComponentKey(projectKey); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/AnalysisStatusActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/AnalysisStatusActionIT.java index 7a9e863c9e0..6c854c4df8b 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/AnalysisStatusActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/AnalysisStatusActionIT.java @@ -23,7 +23,7 @@ import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.ce.CeActivityDto; @@ -76,7 +76,7 @@ public class AnalysisStatusActionIT { @Test public void no_errors_no_warnings() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().setSystemAdministrator().addProjectPermission(UserRole.USER, project); + userSession.logIn().setSystemAdministrator().addProjectPermission(ProjectPermission.USER, project); Ce.AnalysisStatusWsResponse response = ws.newRequest() .setParam(PARAM_COMPONENT, project.getKey()) @@ -106,7 +106,7 @@ public class AnalysisStatusActionIT { public void return_warnings_for_last_analysis_of_main() { ProjectData projectData = db.components().insertPrivateProject(); ProjectDto project = projectData.getProjectDto(); - userSession.logIn().setSystemAdministrator().addProjectPermission(UserRole.USER, project); + userSession.logIn().setSystemAdministrator().addProjectPermission(ProjectPermission.USER, project); SnapshotDto analysis = db.components().insertSnapshot(project); CeActivityDto activity = insertActivity("task-uuid" + counter++, projectData.getMainBranchDto(), SUCCESS, analysis, REPORT); @@ -137,7 +137,7 @@ public class AnalysisStatusActionIT { @Test public void return_warnings_for_last_analysis_of_branch() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().setSystemAdministrator().addProjectPermission(UserRole.USER, project); + userSession.logIn().setSystemAdministrator().addProjectPermission(ProjectPermission.USER, project); BranchDto branch = db.components().insertProjectBranch(project, b -> b.setKey(BRANCH_WITH_WARNING)); SnapshotDto analysis = db.components().insertSnapshot(branch); @@ -168,7 +168,7 @@ public class AnalysisStatusActionIT { @Test public void return_warnings_for_last_analysis_of_pull_request() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().setSystemAdministrator().addProjectPermission(UserRole.USER, project); + userSession.logIn().setSystemAdministrator().addProjectPermission(ProjectPermission.USER, project); BranchDto pullRequest = db.components().insertProjectBranch(project, b -> { b.setBranchType(BranchType.PULL_REQUEST); @@ -203,7 +203,7 @@ public class AnalysisStatusActionIT { public void return_warnings_per_branch() { ProjectData projectData = db.components().insertPrivateProject(); ProjectDto project = projectData.getProjectDto(); - userSession.logIn().setSystemAdministrator().addProjectPermission(UserRole.USER, project); + userSession.logIn().setSystemAdministrator().addProjectPermission(ProjectPermission.USER, project); SnapshotDto analysis = db.components().insertSnapshot(project); CeActivityDto activity = insertActivity("task-uuid" + counter++, projectData.getMainBranchDto(), SUCCESS, analysis, REPORT); @@ -263,7 +263,7 @@ public class AnalysisStatusActionIT { @Test public void response_contains_branch_or_pullRequest_for_branch_or_pullRequest_only() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().setSystemAdministrator().addProjectPermission(UserRole.USER, project); + userSession.logIn().setSystemAdministrator().addProjectPermission(ProjectPermission.USER, project); db.components().insertProjectBranch(project, b -> b.setKey(BRANCH_WITHOUT_WARNING)); @@ -312,7 +312,7 @@ public class AnalysisStatusActionIT { db.getDbClient().ceTaskMessageDao().insert(db.getSession(), ceTaskMessage); db.commit(); - userSession.logIn().setSystemAdministrator().addProjectPermission(UserRole.USER, project); + userSession.logIn().setSystemAdministrator().addProjectPermission(ProjectPermission.USER, project); String result = ws.newRequest() .setParam(PARAM_COMPONENT, project.getKey()) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/CancelActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/CancelActionIT.java index ffa7b0043b2..d2c1ec9e6b7 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/CancelActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/CancelActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.impl.utils.TestSystem2; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.ce.queue.CeQueue; import org.sonar.ce.queue.CeQueueImpl; import org.sonar.ce.queue.CeTaskSubmit; @@ -103,7 +103,7 @@ public class CancelActionIT { ProjectData project = db.components().insertPrivateProject(); ProjectDto projectDto = project.getProjectDto(); ComponentDto mainBranchComponent = project.getMainBranchComponent(); - userSession.addProjectPermission(UserRole.ADMIN, projectDto); + userSession.addProjectPermission(ProjectPermission.ADMIN, projectDto); userSession.addProjectBranchMapping(projectDto.getUuid(), mainBranchComponent); CeQueueDto queue = createTaskSubmit(mainBranchComponent); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java index 2002c015b3d..5dc2e4374ba 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/ComponentActionIT.java @@ -26,7 +26,7 @@ import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.ce.CeTaskCharacteristics; import org.sonar.core.util.Uuids; import org.sonar.db.DbTester; @@ -77,7 +77,7 @@ public class ComponentActionIT { @Test public void empty_queue_and_empty_activity() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); Ce.ComponentResponse response = ws.newRequest() .setParam(PARAM_COMPONENT, project.getKey()) @@ -92,7 +92,7 @@ public class ComponentActionIT { ProjectData project1 = db.components().insertPrivateProject(); SnapshotDto analysisProject1 = db.components().insertSnapshot(project1.getMainBranchComponent()); ProjectData project2 = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project1.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project1.getProjectDto()); insertActivity("T1", project1.getMainBranchComponent(), project1.getProjectDto(), CeActivityDto.Status.SUCCESS, analysisProject1); insertActivity("T2", project2.getMainBranchComponent(), project2.getProjectDto(), CeActivityDto.Status.FAILED, null); insertActivity("T3", project1.getMainBranchComponent(), project1.getProjectDto(), CeActivityDto.Status.FAILED, null); @@ -153,7 +153,7 @@ public class ComponentActionIT { @Test public void canceled_tasks_must_not_be_picked_as_current_analysis() { ProjectData project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); insertActivity("T1", project.getMainBranchComponent(), project.getProjectDto(), CeActivityDto.Status.SUCCESS); insertActivity("T2", project.getMainBranchComponent(), project.getProjectDto(), CeActivityDto.Status.FAILED); insertActivity("T3", project.getMainBranchComponent(), project.getProjectDto(), CeActivityDto.Status.SUCCESS); @@ -175,7 +175,7 @@ public class ComponentActionIT { @Test public void branch_in_activity() { ProjectData project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); String branchName = secure().nextAlphanumeric(248); ComponentDto branch = db.components().insertProjectBranch(project.getMainBranchComponent(), b -> b.setBranchType(BRANCH).setKey(branchName)); SnapshotDto analysis = db.components().insertSnapshot(branch); @@ -196,7 +196,7 @@ public class ComponentActionIT { @Test public void branch_in_queue_analysis() { ProjectData project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); String branchName = secure().nextAlphanumeric(248); ComponentDto branch = db.components().insertProjectBranch(project.getMainBranchComponent(), b -> b.setBranchType(BRANCH).setKey(branchName)); CeQueueDto queue1 = insertQueue("T1", project.getMainBranchComponent(), project.getProjectDto(), IN_PROGRESS); @@ -220,7 +220,7 @@ public class ComponentActionIT { @Test public void return_many_tasks_from_same_project() { ProjectData project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); insertQueue("Main", project.getMainBranchComponent(), project.getProjectDto(), IN_PROGRESS); String branchName1 = "Branch1"; @@ -250,7 +250,7 @@ public class ComponentActionIT { @Test public void populates_warning_count_and_warnings_of_activities() { ProjectData privateProject = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, privateProject.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, privateProject.getProjectDto()); SnapshotDto analysis = db.components().insertSnapshot(privateProject.getMainBranchComponent()); CeActivityDto activity = insertActivity("Branch", privateProject.getMainBranchComponent(), privateProject.getProjectDto(), SUCCESS, analysis); int messageCount = 5; @@ -307,7 +307,7 @@ public class ComponentActionIT { } private void logInWithBrowsePermission(ProjectDto project) { - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project); } private CeQueueDto insertQueue(String taskUuid, ComponentDto component, EntityDto entityDto, CeQueueDto.Status status) { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/DismissAnalysisWarningActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/DismissAnalysisWarningActionIT.java index 60af166f28c..cb0cd4348ae 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/DismissAnalysisWarningActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/DismissAnalysisWarningActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbTester; import org.sonar.db.ce.CeActivityDto; import org.sonar.db.ce.CeQueueDto; @@ -104,7 +104,7 @@ public class DismissAnalysisWarningActionIT { public void return_204_on_success() { UserDto user = db.users().insertUser(); ProjectData project = db.components().insertPrivateProject(); - userSession.logIn(user).addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.logIn(user).addProjectPermission(ProjectPermission.USER, project.getProjectDto()); SnapshotDto analysis = db.components().insertSnapshot(project.getMainBranchComponent()); CeActivityDto activity = insertActivity("task-uuid" + counter++, project.getMainBranchComponent(), SUCCESS, analysis, REPORT); CeTaskMessageDto taskMessageDismissible = createTaskMessage(activity, "dismissable warning", MessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE); @@ -124,7 +124,7 @@ public class DismissAnalysisWarningActionIT { public void is_idempotent() { UserDto user = db.users().insertUser(); ProjectData project = db.components().insertPrivateProject(); - userSession.logIn(user).addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.logIn(user).addProjectPermission(ProjectPermission.USER, project.getProjectDto()); SnapshotDto analysis = db.components().insertSnapshot(project.getMainBranchComponent()); CeActivityDto activity = insertActivity("task-uuid" + counter++, project.getMainBranchComponent(), SUCCESS, analysis, REPORT); CeTaskMessageDto taskMessageDismissible = createTaskMessage(activity, "dismissable warning", MessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE); @@ -148,7 +148,7 @@ public class DismissAnalysisWarningActionIT { public void returns_400_if_warning_is_not_dismissable() { UserDto user = db.users().insertUser(); ProjectData project = db.components().insertPrivateProject(); - userSession.logIn(user).addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.logIn(user).addProjectPermission(ProjectPermission.USER, project.getProjectDto()); SnapshotDto analysis = db.components().insertSnapshot(project.getMainBranchComponent()); CeActivityDto activity = insertActivity("task-uuid" + counter++, project.getMainBranchComponent(), SUCCESS, analysis, REPORT); CeTaskMessageDto taskMessage = createTaskMessage(activity, "generic warning"); @@ -167,7 +167,7 @@ public class DismissAnalysisWarningActionIT { public void returns_404_if_warning_does_not_exist() { UserDto user = db.users().insertUser(); ProjectData project = db.components().insertPrivateProject(); - userSession.logIn(user).addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.logIn(user).addProjectPermission(ProjectPermission.USER, project.getProjectDto()); SnapshotDto analysis = db.components().insertSnapshot(project.getMainBranchComponent()); insertActivity("task-uuid" + counter++, project.getMainBranchComponent(), SUCCESS, analysis, REPORT); String warningUuid = "78d1e2ff-3e67-4037-ba58-0d57d5f88e44"; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java index b3c42ee922a..b889a5c2fed 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ce/ws/TaskActionIT.java @@ -27,7 +27,6 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.ce.CeTaskCharacteristics; import org.sonar.core.util.CloseableIterator; import org.sonar.core.util.UuidFactoryFast; @@ -42,6 +41,7 @@ import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ProjectData; import org.sonar.db.dismissmessage.MessageType; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.UserDto; import org.sonar.server.exceptions.ForbiddenException; @@ -56,10 +56,10 @@ import static java.util.Collections.singleton; import static org.apache.commons.lang3.RandomStringUtils.secure; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.SCAN; import static org.sonar.core.ce.CeTaskCharacteristics.BRANCH_TYPE; import static org.sonar.db.component.BranchType.BRANCH; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.SCAN; public class TaskActionIT { @@ -144,7 +144,7 @@ public class TaskActionIT { @Test public void task_is_archived() { UserDto user = db.users().insertUser(); - loginAndAddProjectPermission(user, GlobalPermission.SCAN.getKey()); + loginAndAddProjectPermission(user, ProjectPermission.SCAN); CeActivityDto activityDto = createActivityDto(SOME_TASK_UUID); persist(activityDto); @@ -169,7 +169,7 @@ public class TaskActionIT { logInAsSystemAdministrator(); ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); String branchName = secure().nextAlphanumeric(248); ComponentDto branch = db.components().insertProjectBranch(mainBranch, b -> b.setBranchType(BRANCH).setKey(branchName)); db.components().insertSnapshot(branch); @@ -307,7 +307,7 @@ public class TaskActionIT { @Test public void get_project_queue_task_with_scan_permission_on_project() { UserDto user = db.users().insertUser(); - loginAndAddProjectPermission(user, GlobalPermission.SCAN.getKey()); + loginAndAddProjectPermission(user, ProjectPermission.SCAN); CeQueueDto task = createAndPersistQueueTask(privateProjectMainBranch, user); call(task.getUuid()); @@ -327,7 +327,7 @@ public class TaskActionIT { @Test public void get_project_queue_task_of_private_project_with_user_permission_fails_with_ForbiddenException() { UserDto user = db.users().insertUser(); - userSession.logIn().addProjectPermission(UserRole.USER, privateProject); + userSession.logIn().addProjectPermission(ProjectPermission.USER, privateProject); CeQueueDto task = createAndPersistQueueTask(privateProjectMainBranch, user); String uuid = task.getUuid(); @@ -338,13 +338,13 @@ public class TaskActionIT { @Test public void get_project_queue_task_on_public_project() { UserDto user = db.users().insertUser(); - loginAndAddProjectPermission(user, GlobalPermission.SCAN.getKey()); + loginAndAddProjectPermission(user, ProjectPermission.SCAN); CeQueueDto task = createAndPersistQueueTask(privateProjectMainBranch, user); call(task.getUuid()); } - private void loginAndAddProjectPermission(@Nullable UserDto user, String permission) { + private void loginAndAddProjectPermission(@Nullable UserDto user, ProjectPermission permission) { if (user != null) { userSession.logIn(user); } else { @@ -474,7 +474,7 @@ public class TaskActionIT { @Test public void get_warnings_on_private_project_archived_task_if_user_fails_with_ForbiddenException() { - userSession.logIn().addProjectPermission(UserRole.USER, privateProject); + userSession.logIn().addProjectPermission(ProjectPermission.USER, privateProject); CeActivityDto persistArchivedTask = createAndPersistArchivedTask(privateProjectMainBranch); assertThatThrownBy(() -> insertWarningsCallEndpointAndAssertWarnings(persistArchivedTask)) @@ -483,7 +483,7 @@ public class TaskActionIT { @Test public void get_warnings_on_private_project_archived_task_if_scan() { - loginAndAddProjectPermission(null, GlobalPermission.SCAN.getKey()); + loginAndAddProjectPermission(null, ProjectPermission.SCAN); insertWarningsCallEndpointAndAssertWarnings(createAndPersistArchivedTask(privateProjectMainBranch)); } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ComponentServiceUpdateKeyIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ComponentServiceUpdateKeyIT.java index 23e942fcdac..96bc3dbf7c1 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ComponentServiceUpdateKeyIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ComponentServiceUpdateKeyIT.java @@ -26,7 +26,7 @@ import java.util.Set; import org.junit.Rule; import org.junit.Test; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -114,7 +114,7 @@ public class ComponentServiceUpdateKeyIT { @Test public void fail_to_update_project_key_without_admin_permission() { ProjectDto project = insertSampleProject(); - userSession.logIn("john").addProjectPermission(UserRole.USER, project); + userSession.logIn("john").addProjectPermission(ProjectPermission.USER, project); assertThatThrownBy(() -> underTest.updateKey(dbSession, project, "sample2:root")) .isInstanceOf(ForbiddenException.class); @@ -167,6 +167,6 @@ public class ComponentServiceUpdateKeyIT { } private void logInAsProjectAdministrator(ProjectDto provisionedProject) { - userSession.logIn("john").addProjectPermission(UserRole.ADMIN, provisionedProject); + userSession.logIn("john").addProjectPermission(ProjectPermission.ADMIN, provisionedProject); } } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/AppActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/AppActionIT.java index 1ebb7e2b2e9..1894d26a0ae 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/AppActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/AppActionIT.java @@ -45,7 +45,7 @@ import static org.sonar.api.measures.CoreMetrics.LINES_KEY; import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT_KEY; import static org.sonar.api.measures.CoreMetrics.TESTS_KEY; import static org.sonar.api.measures.CoreMetrics.VIOLATIONS_KEY; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.BranchType.PULL_REQUEST; import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.component.ComponentTesting.newFileDto; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java index f350e374dba..46234f54245 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java @@ -40,7 +40,7 @@ import org.sonar.api.measures.Metric; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.platform.EditionProvider.Edition; import org.sonar.core.platform.PlatformEditionProvider; import org.sonar.db.DbClient; @@ -1377,7 +1377,7 @@ class SearchProjectsActionIT { authorizationIndexerTester.allowOnlyAnyone(publicProject); index(); - userSession.addProjectPermission(UserRole.USER, privateProject); + userSession.addProjectPermission(ProjectPermission.USER, privateProject); SearchProjectsWsResponse result = call(request); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/ShowActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/ShowActionIT.java index 74393eaa54e..e4d6d5b2281 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/ShowActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/ShowActionIT.java @@ -29,12 +29,11 @@ import org.junit.jupiter.params.provider.ValueSource; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentQualifiers; -import org.sonar.db.component.ComponentTesting; import org.sonar.db.component.PortfolioData; import org.sonar.db.component.ProjectData; import org.sonar.server.component.TestComponentFinder; @@ -53,7 +52,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.tuple; import static org.sonar.api.utils.DateUtils.formatDateTime; import static org.sonar.api.utils.DateUtils.parseDateTime; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME; import static org.sonar.db.component.BranchType.BRANCH; import static org.sonar.db.component.BranchType.PULL_REQUEST; @@ -289,7 +288,7 @@ public class ShowActionIT { public void branch() { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); String branchKey = "my_branch"; ComponentDto branch = db.components().insertProjectBranch(mainBranch, b -> b.setKey(branchKey)); userSession.addProjectBranchMapping(projectData.projectUuid(), branch); @@ -315,7 +314,7 @@ public class ShowActionIT { public void dont_show_branch_if_main_branch() { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()) .registerBranches(projectData.getMainBranchDto()); ShowWsResponse response = ws.newRequest() @@ -332,7 +331,7 @@ public class ShowActionIT { public void pull_request() { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); String pullRequest = "pr-1234"; ComponentDto branch = db.components().insertProjectBranch(mainBranch, b -> b.setKey(pullRequest).setBranchType(PULL_REQUEST)); userSession.addProjectBranchMapping(projectData.projectUuid(), branch); @@ -392,7 +391,7 @@ public class ShowActionIT { userSession.addProjectBranchMapping(projectData3.projectUuid(), branch4); userSession.addProjectBranchMapping(projectData3.projectUuid(), branch5); - userSession.addProjectPermission(UserRole.USER, projectData1.getProjectDto(), projectData2.getProjectDto(), projectData3.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, projectData1.getProjectDto(), projectData2.getProjectDto(), projectData3.getProjectDto()) .registerBranches(projectData1.getMainBranchDto(), projectData2.getMainBranchDto(), projectData3.getMainBranchDto()); userSession.registerPortfolios(portfolio1, portfolio2, subview); userSession.registerProjects(projectData1.getProjectDto(), projectData2.getProjectDto(), projectData3.getProjectDto()); @@ -469,7 +468,7 @@ public class ShowActionIT { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); ComponentDto file = db.components().insertComponent(newFileDto(mainBranch)); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()) .registerBranches(projectData.getMainBranchDto()); db.components().insertProjectBranch(mainBranch, b -> b.setKey("my_branch")); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SuggestionsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SuggestionsActionIT.java index e245c0b21cc..a22fcfa9786 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SuggestionsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SuggestionsActionIT.java @@ -66,7 +66,7 @@ import static org.sonar.db.component.ComponentQualifiers.PROJECT; import static org.sonar.db.component.ComponentQualifiers.SUBVIEW; import static org.sonar.db.component.ComponentQualifiers.UNIT_TEST_FILE; import static org.sonar.db.component.ComponentQualifiers.VIEW; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.server.component.ws.SuggestionsAction.PARAM_MORE; import static org.sonar.server.component.ws.SuggestionsAction.PARAM_QUERY; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/TreeActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/TreeActionIT.java index 540914522b4..7d69a2a27c0 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/TreeActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/TreeActionIT.java @@ -36,7 +36,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.server.component.DefaultComponentTypes; import org.sonar.core.i18n.I18n; import org.sonar.db.DbClient; @@ -378,7 +378,7 @@ public class TreeActionIT { @Test public void branch() { ProjectData project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); String branchKey = "my_branch"; ComponentDto branch = db.components().insertProjectBranch(project.getMainBranchComponent(), b -> b.setKey(branchKey)); userSession.addProjectBranchMapping(project.projectUuid(), branch); @@ -402,7 +402,7 @@ public class TreeActionIT { public void dont_show_branch_if_main_branch() { ProjectData project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertFile(project.getMainBranchDto()); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .addProjectBranchMapping(project.projectUuid(), project.getMainBranchComponent()); TreeWsResponse response = ws.newRequest() @@ -417,7 +417,7 @@ public class TreeActionIT { @Test public void pull_request() { ProjectData project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); String pullRequestId = "pr-123"; ComponentDto branch = db.components().insertProjectBranch(project.getMainBranchComponent(), b -> b.setKey(pullRequestId).setBranchType(PULL_REQUEST)); userSession.addProjectBranchMapping(project.projectUuid(), branch); @@ -440,7 +440,7 @@ public class TreeActionIT { public void fail_when_not_enough_privileges() { ProjectData project = db.components().insertPrivateProject("project-uuid"); userSession.logIn() - .addProjectPermission(UserRole.CODEVIEWER, project.getProjectDto()); + .addProjectPermission(ProjectPermission.CODEVIEWER, project.getProjectDto()); db.commit(); TestRequest request = ws.newRequest() @@ -533,7 +533,7 @@ public class TreeActionIT { @Test public void fail_if_branch_does_not_exist() { ProjectData project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); db.components().insertProjectBranch(project.getProjectDto(), b -> b.setKey("my_branch")); TestRequest request = ws.newRequest() @@ -592,7 +592,7 @@ public class TreeActionIT { } private void logInWithBrowsePermission(ProjectData project) { - userSession.logIn().addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.logIn().addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .addProjectBranchMapping(project.projectUuid(), project.getMainBranchComponent()); } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/developers/ws/SearchEventsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/developers/ws/SearchEventsActionIT.java index b2d794be1c2..c55ef73a7f3 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/developers/ws/SearchEventsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/developers/ws/SearchEventsActionIT.java @@ -28,10 +28,10 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.config.Configuration; import org.sonar.api.platform.Server; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbTester; import org.sonar.db.ce.CeActivityDto; import org.sonar.db.ce.CeQueueDto; @@ -64,7 +64,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.sonar.api.utils.DateUtils.formatDateTime; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.event.EventTesting.newEvent; import static org.sonar.server.developers.ws.SearchEventsAction.PARAM_FROM; import static org.sonar.server.developers.ws.SearchEventsAction.PARAM_PROJECTS; @@ -199,8 +199,8 @@ class SearchEventsActionIT { void does_not_return_events_of_project_for_which_the_current_user_has_no_browse_permission() { ProjectData projectData1 = db.components().insertPrivateProject(); ComponentDto mainBranch1 = projectData1.getMainBranchComponent(); - userSession.addProjectPermission(UserRole.CODEVIEWER, projectData1.getProjectDto()); - userSession.addProjectPermission(UserRole.ISSUE_ADMIN, projectData1.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.CODEVIEWER, projectData1.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.ISSUE_ADMIN, projectData1.getProjectDto()); ProjectData projectData2 = db.components().insertPrivateProject(); ComponentDto mainBranch2 = projectData2.getMainBranchComponent(); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/developers/ws/SearchEventsActionNewIssuesIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/developers/ws/SearchEventsActionNewIssuesIT.java index b9282eff617..c979a6c93af 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/developers/ws/SearchEventsActionNewIssuesIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/developers/ws/SearchEventsActionNewIssuesIT.java @@ -29,7 +29,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.config.Configuration; import org.sonar.api.platform.Server; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.DbTester; import org.sonar.db.ce.CeActivityDto; import org.sonar.db.ce.CeQueueDto; @@ -57,7 +57,7 @@ import static org.assertj.core.api.Assertions.tuple; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.sonar.api.utils.DateUtils.formatDateTime; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.BranchType.BRANCH; import static org.sonar.server.developers.ws.SearchEventsAction.PARAM_FROM; import static org.sonar.server.developers.ws.SearchEventsAction.PARAM_PROJECTS; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/developers/ws/SearchEventsActionQualityGateIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/developers/ws/SearchEventsActionQualityGateIT.java index e9503e09cfe..9231f33bc03 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/developers/ws/SearchEventsActionQualityGateIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/developers/ws/SearchEventsActionQualityGateIT.java @@ -47,7 +47,7 @@ import static org.assertj.core.api.Assertions.tuple; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.sonar.api.utils.DateUtils.formatDateTime; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.BranchType.BRANCH; import static org.sonar.db.component.BranchType.PULL_REQUEST; import static org.sonar.db.event.EventTesting.newEvent; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/duplication/ws/ShowActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/duplication/ws/ShowActionIT.java index 887b53a1d66..1ba4bc8b1b2 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/duplication/ws/ShowActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/duplication/ws/ShowActionIT.java @@ -25,7 +25,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; @@ -93,7 +93,7 @@ public class ShowActionIT { ComponentDto file = db.components().insertComponent(newFileDto(project).setKey("foo.js")); db.components().insertSnapshot(newAnalysis(project)); - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project); + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project); TestResponse result = newBaseRequest().setParam("key", file.getKey()).execute(); @@ -108,7 +108,7 @@ public class ShowActionIT { @Test public void duplications_by_file_key_and_branch() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project); + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project); String branchName = secure().nextAlphanumeric(248); ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey(branchName)); userSessionRule.addProjectBranchMapping(project.uuid(), branch); @@ -164,7 +164,7 @@ public class ShowActionIT { @Test public void duplications_by_file_key_and_pull_request() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project); + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project); String pullRequestKey = secure().nextAlphanumeric(100); ComponentDto pullRequest = db.components().insertProjectBranch(project, b -> b.setBranchType(PULL_REQUEST).setKey(pullRequestKey)); userSessionRule.addProjectBranchMapping(project.uuid(), pullRequest); @@ -250,7 +250,7 @@ public class ShowActionIT { private void verifyCallToFileWithDuplications(Function<ComponentDto, TestRequest> requestFactory) { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project); + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project); ComponentDto file = db.components().insertComponent(newFileDto(project).setKey("foo.js")); String xml = """ <duplications> diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/favorite/ws/AddActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/favorite/ws/AddActionIT.java index 0c7c87aa9dd..3e244135780 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/favorite/ws/AddActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/favorite/ws/AddActionIT.java @@ -24,7 +24,7 @@ import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -47,7 +47,7 @@ import static java.net.HttpURLConnection.HTTP_NO_CONTENT; import static java.util.Optional.ofNullable; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.server.favorite.ws.FavoritesWsParameters.PARAM_COMPONENT; @@ -86,7 +86,7 @@ public class AddActionIT { @Test public void fail_when_no_browse_permission_on_the_project() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); assertThatThrownBy(() -> call(project.getKey())) .isInstanceOf(ForbiddenException.class); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/favorite/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/favorite/ws/SearchActionIT.java index 1577dce501d..271d143f2e8 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/favorite/ws/SearchActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/favorite/ws/SearchActionIT.java @@ -26,7 +26,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.project.ProjectDto; @@ -177,7 +177,7 @@ public class SearchActionIT { private void addPermissionAndFavorite(ProjectDto component) { db.favorites().add(component, userUuid, userLogin); db.commit(); - userSession.addProjectPermission(UserRole.USER, component); + userSession.addProjectPermission(ProjectPermission.USER, component); } private SearchResponse call(@Nullable Integer page, @Nullable Integer pageSize) { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/AddCommentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/AddCommentActionIT.java index c51aaf89d35..8eea70cf9b4 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/AddCommentActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/AddCommentActionIT.java @@ -31,9 +31,9 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.IssueChangeContext; import org.sonar.db.DbClient; @@ -212,7 +212,7 @@ public class AddCommentActionIT { ComponentDto project = projectData.getMainBranchComponent(); userSessionRule.logIn().registerProjects(projectData.getProjectDto()) - .addProjectPermission(UserRole.USER, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); RuleDto rule = dbTester.rules().insertHotspotRule(); IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/AssignActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/AssignActionIT.java index c5e7d8118ae..ad12e3e1472 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/AssignActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/AssignActionIT.java @@ -35,11 +35,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.IssueChangeContext; import org.sonar.db.DbClient; @@ -86,7 +86,7 @@ import static org.sonar.api.issue.Issue.STATUSES; import static org.sonar.api.issue.Issue.STATUS_CLOSED; import static org.sonar.api.issue.Issue.STATUS_REVIEWED; import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.db.component.ComponentTesting.newFileDto; @RunWith(DataProviderRunner.class) @@ -210,7 +210,7 @@ public class AssignActionIT { ComponentDto file = dbTester.components().insertComponent(newFileDto(project.getMainBranchComponent())); IssueDto hotspot = dbTester.issues().insertHotspot(project.getMainBranchComponent(), file); - insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), UserRole.USER); + insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), ProjectPermission.USER); UserDto assignee = insertUserWithProjectUserPermission(secure().nextAlphanumeric(15), project.getProjectDto()); when(issueFieldsSetter.assign(eq(hotspot.toDefaultIssue()), userMatcher(assignee), any(IssueChangeContext.class))).thenReturn(true); @@ -227,7 +227,7 @@ public class AssignActionIT { UserDto assignee = insertUser(secure().nextAlphanumeric(15)); IssueDto hotspot = dbTester.issues().insertHotspot(project.getMainBranchComponent(), file, h -> h.setAssigneeUuid(assignee.getUuid())); - insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), UserRole.USER); + insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), ProjectPermission.USER); when(issueFieldsSetter.assign(eq(hotspot.toDefaultIssue()), isNull(), any(IssueChangeContext.class))).thenReturn(true); @@ -243,7 +243,7 @@ public class AssignActionIT { ComponentDto file = dbTester.components().insertComponent(newFileDto(branch, project.getMainBranchComponent().uuid())); IssueDto hotspot = dbTester.issues().insertHotspot(branch, file); - insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), UserRole.USER); + insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), ProjectPermission.USER); userSessionRule.addProjectBranchMapping(project.projectUuid(), branch); UserDto assignee = insertUserWithProjectUserPermission(secure().nextAlphanumeric(15), project.getProjectDto()); @@ -260,7 +260,7 @@ public class AssignActionIT { ComponentDto file = dbTester.components().insertComponent(newFileDto(project.getMainBranchComponent())); IssueDto hotspot = dbTester.issues().insertHotspot(project.getMainBranchComponent(), file); - insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), UserRole.USER); + insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), ProjectPermission.USER); UserDto assignee = insertUser(secure().nextAlphanumeric(15)); when(issueFieldsSetter.assign(eq(hotspot.toDefaultIssue()), userMatcher(assignee), any(IssueChangeContext.class))).thenReturn(true); @@ -278,7 +278,7 @@ public class AssignActionIT { ComponentDto file = dbTester.components().insertComponent(newFileDto(branch, project.getMainBranchComponent())); IssueDto hotspot = dbTester.issues().insertHotspot(branch, file); - insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), UserRole.USER); + insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), ProjectPermission.USER); userSessionRule.addProjectBranchMapping(project.projectUuid(), branch); UserDto assignee = insertUser(secure().nextAlphanumeric(15)); @@ -296,7 +296,7 @@ public class AssignActionIT { ComponentDto file = dbTester.components().insertComponent(newFileDto(project.getMainBranchComponent())); IssueDto hotspot = dbTester.issues().insertHotspot(project.getMainBranchComponent(), file); - UserDto me = insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), UserRole.USER); + UserDto me = insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), ProjectPermission.USER); when(issueFieldsSetter.assign(eq(hotspot.toDefaultIssue()), userMatcher(me), any(IssueChangeContext.class))).thenReturn(true); @@ -479,7 +479,7 @@ public class AssignActionIT { ComponentDto file = dbTester.components().insertComponent(newFileDto(project.getMainBranchComponent())); IssueDto hotspot = dbTester.issues().insertHotspot(project.getMainBranchComponent(), file); - UserDto me = insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), UserRole.CODEVIEWER); + UserDto me = insertAndLoginAsUserWithProjectUserPermission(secure().nextAlphanumeric(10), project.getProjectDto(), ProjectPermission.CODEVIEWER); when(issueFieldsSetter.assign(eq(hotspot.toDefaultIssue()), userMatcher(me), any(IssueChangeContext.class))).thenReturn(true); @@ -613,17 +613,17 @@ public class AssignActionIT { return dbTester.users().insertUser(login); } - private UserDto insertUserWithProjectPermission(String login, EntityDto project, String permission) { + private UserDto insertUserWithProjectPermission(String login, EntityDto project, ProjectPermission permission) { UserDto user = dbTester.users().insertUser(login); dbTester.users().insertProjectPermissionOnUser(user, permission, project); return user; } private UserDto insertUserWithProjectUserPermission(String login, EntityDto project) { - return insertUserWithProjectPermission(login, project, UserRole.USER); + return insertUserWithProjectPermission(login, project, ProjectPermission.USER); } - private UserDto insertAndLoginAsUserWithProjectUserPermission(String login, ProjectDto project, String permission) { + private UserDto insertAndLoginAsUserWithProjectUserPermission(String login, ProjectDto project, ProjectPermission permission) { UserDto user = insertUserWithProjectUserPermission(login, project); userSessionRule.logIn(user).addProjectPermission(permission, project); return user; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/ChangeStatusActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/ChangeStatusActionIT.java index 519c249287d..9c7c0851a4a 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/ChangeStatusActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/ChangeStatusActionIT.java @@ -36,9 +36,9 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.sonar.api.issue.DefaultTransitions; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.IssueChangeContext; import org.sonar.db.DbClient; @@ -81,7 +81,7 @@ import static org.sonar.api.issue.Issue.RESOLUTION_SAFE; import static org.sonar.api.issue.Issue.STATUS_CLOSED; import static org.sonar.api.issue.Issue.STATUS_REVIEWED; import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.core.issue.IssueChangeContext.issueChangeContextByUserBuilder; import static org.sonar.db.component.ComponentTesting.newFileDto; @@ -307,7 +307,7 @@ public class ChangeStatusActionIT { @Test @UseDataProvider("anyPublicProjectPermissionButHotspotAdmin") - public void fails_with_ForbiddenException_if_project_is_public_and_user_has_no_HotspotAdmin_permission_on_it(String permission) { + public void fails_with_ForbiddenException_if_project_is_public_and_user_has_no_HotspotAdmin_permission_on_it(ProjectPermission permission) { ProjectData projectData = dbTester.components().insertPublicProject(); ComponentDto project = projectData.getMainBranchComponent(); @@ -331,15 +331,15 @@ public class ChangeStatusActionIT { @DataProvider public static Object[][] anyPublicProjectPermissionButHotspotAdmin() { return new Object[][] { - {UserRole.ADMIN}, - {UserRole.ISSUE_ADMIN}, - {UserRole.SCAN} + {ProjectPermission.ADMIN}, + {ProjectPermission.ISSUE_ADMIN}, + {ProjectPermission.SCAN} }; } @Test @UseDataProvider("anyPrivateProjectPermissionButHotspotAdmin") - public void fails_with_ForbiddenException_if_project_is_private_and_has_no_IssueAdmin_permission_on_it(String permission) { + public void fails_with_ForbiddenException_if_project_is_private_and_has_no_IssueAdmin_permission_on_it(ProjectPermission permission) { ProjectData projectData = dbTester.components().insertPrivateProject(); ComponentDto project = projectData.getMainBranchComponent(); @@ -363,11 +363,11 @@ public class ChangeStatusActionIT { @DataProvider public static Object[][] anyPrivateProjectPermissionButHotspotAdmin() { return new Object[][] { - {UserRole.USER}, - {UserRole.ADMIN}, - {UserRole.ISSUE_ADMIN}, - {UserRole.CODEVIEWER}, - {UserRole.SCAN} + {ProjectPermission.USER}, + {ProjectPermission.ADMIN}, + {ProjectPermission.ISSUE_ADMIN}, + {ProjectPermission.CODEVIEWER}, + {ProjectPermission.SCAN} }; } @@ -378,7 +378,7 @@ public class ChangeStatusActionIT { ComponentDto project = projectData.getMainBranchComponent(); userSessionRule.logIn().registerProjects(projectData.getProjectDto()) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); IssueDto hotspot = dbTester.issues().insertHotspot(project, file); @@ -392,7 +392,7 @@ public class ChangeStatusActionIT { ComponentDto project = projectData.getMainBranchComponent(); userSessionRule.logIn().registerProjects(projectData.getProjectDto()) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); IssueDto hotspot = dbTester.issues().insertHotspot(project, file); @@ -406,7 +406,7 @@ public class ChangeStatusActionIT { ComponentDto project = projectData.getMainBranchComponent(); userSessionRule.logIn().registerProjects(projectData.getProjectDto()) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); IssueDto hotspot = dbTester.issues().insertHotspot(project, file, h -> h.setStatus(status).setResolution(resolution)); @@ -424,7 +424,7 @@ public class ChangeStatusActionIT { ComponentDto project = projectData.getMainBranchComponent(); userSessionRule.logIn().registerProjects(projectData.getProjectDto()) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); IssueDto hotspot = dbTester.issues().insertHotspot(project, file, h -> h.setStatus(STATUS_TO_REVIEW).setResolution(null)); when(transitionService.doTransition(any(), any(), any())).thenReturn(transitionDone); @@ -459,7 +459,7 @@ public class ChangeStatusActionIT { ComponentDto project = projectData.getMainBranchComponent(); userSessionRule.logIn().registerProjects(projectData.getProjectDto()) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); when(branchDto.getBranchType()).thenReturn(BranchType.BRANCH); String projectUuid = "projectUuid"; @@ -485,7 +485,7 @@ public class ChangeStatusActionIT { userSessionRule.logIn().registerProjects(project) .registerBranches(branch) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, project); + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, project); newRequest(hotspot, STATUS_REVIEWED, RESOLUTION_FIXED, NO_COMMENT).execute(); verify(hotspotChangeEventService).distributeHotspotChangedEvent(eq(branchDto.getProjectUuid()), any(HotspotChangedEvent.class)); @@ -497,7 +497,7 @@ public class ChangeStatusActionIT { ComponentDto project = projectData.getMainBranchComponent(); userSessionRule.logIn().registerProjects(projectData.getProjectDto()) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); when(branchDto.getBranchType()).thenReturn(BranchType.PULL_REQUEST); IssueDto hotspot = dbTester.issues().insertHotspot(project, file); @@ -529,7 +529,7 @@ public class ChangeStatusActionIT { ComponentDto project = projectData.getMainBranchComponent(); userSessionRule.logIn().registerProjects(projectData.getProjectDto()) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); IssueDto hotspot = dbTester.issues().insertHotspot(project, file, h -> h.setStatus(STATUS_REVIEWED).setResolution(resolution)); @@ -581,7 +581,7 @@ public class ChangeStatusActionIT { ComponentDto project = projectData.getMainBranchComponent(); userSessionRule.logIn().registerProjects(projectData.getProjectDto()) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); IssueDto hotspot = dbTester.issues().insertHotspot(project, file, h -> h.setStatus(currentStatus).setResolution(currentResolution)); @@ -641,7 +641,7 @@ public class ChangeStatusActionIT { ComponentDto project = projectData.getMainBranchComponent(); userSessionRule.logIn().registerProjects(projectData.getProjectDto()) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); IssueDto hotspot = dbTester.issues().insertHotspot(project, file, h -> h.setStatus(status).setResolution(resolution)); String comment = secure().nextAlphabetic(12); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/DeleteCommentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/DeleteCommentActionIT.java index 5705602bc60..2bdff9c7b95 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/DeleteCommentActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/DeleteCommentActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; @@ -78,7 +78,7 @@ public class DeleteCommentActionIT { IssueChangeDto comment = dbTester.issues().insertComment(hotspot, userDeletingOwnComment, "Some comment"); userSessionRule.logIn(userDeletingOwnComment); - userSessionRule.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); TestRequest request = newRequest(comment.getKey()); @@ -144,7 +144,7 @@ public class DeleteCommentActionIT { IssueChangeDto comment = dbTester.issues().insertComment(hotspot, userWithHotspotComment, "Some comment"); userSessionRule.logIn(userTryingToDelete); - userSessionRule.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); TestRequest request = newRequest(comment.getKey()); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/EditCommentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/EditCommentActionIT.java index 64088115ada..e8e478c32f2 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/EditCommentActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/EditCommentActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; @@ -86,7 +86,7 @@ public class EditCommentActionIT { .isNotEmpty(); userSessionRule.logIn(userEditingOwnComment); - userSessionRule.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); TestRequest request = newRequest(comment.getKey(), "new comment"); @@ -151,7 +151,7 @@ public class EditCommentActionIT { IssueChangeDto comment = dbTester.issues().insertComment(hotspot, userWithHotspotComment, "Some comment"); userSessionRule.logIn(userTryingToDelete); - userSessionRule.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); TestRequest request = newRequest(comment.getKey(), "new comment"); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/ListActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/ListActionIT.java index ca1b195156a..2a23e0c69cf 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/ListActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/ListActionIT.java @@ -30,7 +30,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; import org.sonar.db.DbTester; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/PullActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/PullActionIT.java index d6b430e9796..c572267b7d3 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/PullActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/PullActionIT.java @@ -60,7 +60,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME; import static org.sonar.db.component.ComponentTesting.newFileDto; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java index 29fec55809e..11f125d7a36 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java @@ -43,7 +43,7 @@ import org.sonar.api.config.Configuration; import org.sonar.api.impl.utils.TestSystem2; import org.sonar.api.issue.Issue; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; import org.sonar.db.DbClient; @@ -103,9 +103,9 @@ import static org.sonar.api.issue.Issue.STATUS_CLOSED; import static org.sonar.api.issue.Issue.STATUS_RESOLVED; import static org.sonar.api.issue.Issue.STATUS_REVIEWED; import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.api.utils.DateUtils.formatDateTime; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.component.ComponentTesting.newDirectoryOnBranch; import static org.sonar.db.component.ComponentTesting.newFileDto; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/ShowActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/ShowActionIT.java index 4e3d1a85314..4f668d0562d 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/ShowActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/ShowActionIT.java @@ -41,9 +41,8 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentMatcher; import org.mockito.Mockito; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.util.UuidFactory; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; @@ -53,6 +52,7 @@ import org.sonar.db.component.BranchType; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ProjectData; import org.sonar.db.issue.IssueDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.protobuf.DbCommons.TextRange; import org.sonar.db.protobuf.DbIssues; @@ -96,7 +96,7 @@ import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ASSESS_THE_PROBLEM_SECTION_KEY; import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.HOW_TO_FIX_SECTION_KEY; import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.INTRODUCTION_SECTION_KEY; @@ -289,7 +289,7 @@ public class ShowActionIT { ComponentDto mainBranchComponent = projectData.getMainBranchComponent(); userSessionRule.registerProjects(projectData.getProjectDto()); - userSessionRule.logIn().addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSessionRule.logIn().addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(mainBranchComponent)); RuleDto rule = newRule(SECURITY_HOTSPOT); IssueDto hotspot = dbTester.issues().insertHotspot(rule, mainBranchComponent, file); @@ -320,7 +320,7 @@ public class ShowActionIT { @Test @UseDataProvider("allPublicProjectPermissionsButSECURITYHOTSPOT_ADMIN") - public void return_canChangeStatus_false_on_public_project_when_authenticated_without_SECURITYHOTSPOT_ADMIN_permission(@Nullable String permission) { + public void return_canChangeStatus_false_on_public_project_when_authenticated_without_SECURITYHOTSPOT_ADMIN_permission(@Nullable ProjectPermission permission) { ProjectData projectData = dbTester.components().insertPublicProject(); ComponentDto mainBranchComponent = projectData.getMainBranchComponent(); @@ -341,12 +341,12 @@ public class ShowActionIT { @Test @UseDataProvider("allPublicProjectPermissionsButSECURITYHOTSPOT_ADMIN") - public void return_canChangeStatus_true_on_public_project_when_authenticated_with_SECURITYHOTSPOT_ADMIN_permission(@Nullable String permission) { + public void return_canChangeStatus_true_on_public_project_when_authenticated_with_SECURITYHOTSPOT_ADMIN_permission(@Nullable ProjectPermission permission) { ProjectData projectData = dbTester.components().insertPublicProject(); ComponentDto mainBranchComponent = projectData.getMainBranchComponent(); userSessionRule.registerProjects(projectData.getProjectDto()) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); if (permission != null) { userSessionRule.addProjectPermission(permission, projectData.getProjectDto()); } @@ -365,21 +365,21 @@ public class ShowActionIT { public static Object[][] allPublicProjectPermissionsButSECURITYHOTSPOT_ADMIN() { return new Object[][] { {null}, // no permission - {UserRole.ADMIN}, - {UserRole.SCAN}, - {UserRole.ISSUE_ADMIN} + {ProjectPermission.ADMIN}, + {ProjectPermission.SCAN}, + {ProjectPermission.ISSUE_ADMIN} }; } @Test @UseDataProvider("allPrivateProjectPermissionsButSECURITYHOTSPOT_ADMIN_and_USER") - public void return_canChangeStatus_false_on_private_project_without_SECURITYHOTSPOT_ADMIN_permission(@Nullable String permission) { + public void return_canChangeStatus_false_on_private_project_without_SECURITYHOTSPOT_ADMIN_permission(@Nullable ProjectPermission permission) { ProjectData projectData = dbTester.components().insertPrivateProject(); ComponentDto mainBranchComponent = projectData.getMainBranchComponent(); userSessionRule .registerProjects(projectData.getProjectDto()) .logIn() - .addProjectPermission(UserRole.USER, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); if (permission != null) { userSessionRule.addProjectPermission(permission, projectData.getProjectDto()); } @@ -396,14 +396,14 @@ public class ShowActionIT { @Test @UseDataProvider("allPrivateProjectPermissionsButSECURITYHOTSPOT_ADMIN_and_USER") - public void return_canChangeStatus_false_on_private_project_with_SECURITYHOTSPOT_ADMIN_permission(@Nullable String permission) { + public void return_canChangeStatus_false_on_private_project_with_SECURITYHOTSPOT_ADMIN_permission(@Nullable ProjectPermission permission) { ProjectData projectData = dbTester.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); userSessionRule .registerProjects(projectData.getProjectDto()) .logIn() - .addProjectPermission(UserRole.USER, projectData.getProjectDto()) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()) + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); if (permission != null) { userSessionRule.addProjectPermission(permission, projectData.getProjectDto()); } @@ -422,10 +422,10 @@ public class ShowActionIT { public static Object[][] allPrivateProjectPermissionsButSECURITYHOTSPOT_ADMIN_and_USER() { return new Object[][] { {null}, // only USER permission - {UserRole.CODEVIEWER}, - {UserRole.ADMIN}, - {UserRole.SCAN}, - {UserRole.ISSUE_ADMIN} + {ProjectPermission.CODEVIEWER}, + {ProjectPermission.ADMIN}, + {ProjectPermission.SCAN}, + {ProjectPermission.ISSUE_ADMIN} }; } @@ -436,7 +436,7 @@ public class ShowActionIT { ComponentDto mainBranchComponent = projectData.getMainBranchComponent(); userSessionRule.registerProjects(projectData.getProjectDto()); - userSessionRule.logIn().addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSessionRule.logIn().addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(mainBranchComponent)); RuleDto rule = newRule(SECURITY_HOTSPOT); IssueDto hotspot = dbTester.issues().insertHotspot(rule, mainBranchComponent, file, t -> t.setStatus(status).setResolution(resolution)); @@ -468,7 +468,7 @@ public class ShowActionIT { ComponentDto mainBranchComponent = projectData.getMainBranchComponent(); userSessionRule.registerProjects(projectData.getProjectDto()); - userSessionRule.logIn().addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSessionRule.logIn().addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(mainBranchComponent)); RuleDescriptionSectionDto introductionSection = generateSectionWithKey(INTRODUCTION_SECTION_KEY); @@ -504,7 +504,7 @@ public class ShowActionIT { ComponentDto mainBranchComponent = projectData.getMainBranchComponent(); userSessionRule.registerProjects(projectData.getProjectDto()); - userSessionRule.logIn().addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSessionRule.logIn().addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(mainBranchComponent)); RuleDescriptionSectionDto introductionSection = generateSectionWithKey(DEFAULT_KEY); @@ -530,7 +530,7 @@ public class ShowActionIT { ComponentDto mainBranchComponent = projectData.getMainBranchComponent(); userSessionRule.registerProjects(projectData.getProjectDto()); - userSessionRule.logIn().addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSessionRule.logIn().addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(mainBranchComponent)); RuleDescriptionSectionDto introductionSection = generateSectionWithKey(INTRODUCTION_SECTION_KEY); @@ -568,7 +568,7 @@ public class ShowActionIT { ComponentDto mainBranchComponent = projectData.getMainBranchComponent(); userSessionRule.registerProjects(projectData.getProjectDto()); - userSessionRule.logIn().addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSessionRule.logIn().addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(mainBranchComponent)); String description = "== Title\n<div>line1\nline2</div>"; @@ -599,7 +599,7 @@ public class ShowActionIT { ComponentDto mainBranchComponent = projectData.getMainBranchComponent(); userSessionRule.registerProjects(projectData.getProjectDto()); - userSessionRule.logIn().addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSessionRule.logIn().addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(mainBranchComponent)); RuleDto rule = newRuleWithoutSection(SECURITY_HOTSPOT, r -> r.setTemplateUuid("123")); @@ -619,7 +619,7 @@ public class ShowActionIT { ComponentDto mainBranchComponent = projectData.getMainBranchComponent(); userSessionRule.registerProjects(projectData.getProjectDto()); - userSessionRule.logIn().addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSessionRule.logIn().addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent(newFileDto(mainBranchComponent)); RuleDescriptionSectionDto vaadinSection = newContextSpecificDescriptionSection("vaadin"); @@ -1104,8 +1104,8 @@ public class ShowActionIT { .extracting(User::getLogin, User::getName, User::getActive) .containsExactlyInAnyOrder( Stream.concat( - Stream.of(author, assignee), - changeLogAndCommentsUsers.stream()) + Stream.of(author, assignee), + changeLogAndCommentsUsers.stream()) .map(t -> tuple(t.getLogin(), t.getName(), t.isActive())) .toArray(Tuple[]::new)); } @@ -1159,7 +1159,7 @@ public class ShowActionIT { ComponentDto mainBranchComponent = projectData.getMainBranchComponent(); userSessionRule.registerProjects(projectData.getProjectDto()) - .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); + .addProjectPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, projectData.getProjectDto()); ComponentDto file = dbTester.components().insertComponent( newFileDto(mainBranchComponent) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/IssueFinderIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/IssueFinderIT.java index 80c431a4779..118be21b2b9 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/IssueFinderIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/IssueFinderIT.java @@ -28,6 +28,7 @@ import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ProjectData; import org.sonar.db.issue.IssueDbTester; import org.sonar.db.issue.IssueDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.rule.RuleDbTester; import org.sonar.db.rule.RuleDto; @@ -37,10 +38,10 @@ import org.sonar.server.tester.UserSessionRule; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.issue.IssueTesting.newIssue; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.rule.RuleTesting.newRule; public class IssueFinderIT { @@ -94,7 +95,7 @@ public class IssueFinderIT { return issueDbTester.insert(newIssue(rule, project.getMainBranchComponent(), file)); } - private void addProjectPermission(IssueDto issueDto, String permission) { + private void addProjectPermission(IssueDto issueDto, ProjectPermission permission) { BranchDto branchDto = db.getDbClient().branchDao().selectByUuid(db.getSession(), issueDto.getProjectUuid()) .orElseThrow(() -> new IllegalStateException("Couldn't find branch :" + issueDto.getProjectUuid())); ProjectDto projectDto = db.getDbClient().projectDao().selectByUuid(db.getSession(), branchDto.getProjectUuid()).get(); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/SetSeverityActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/SetSeverityActionIT.java index b17db72a3d6..b58504431ef 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/SetSeverityActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/SetSeverityActionIT.java @@ -30,7 +30,7 @@ import org.junit.Test; import org.sonar.api.issue.Issue; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.FieldDiffs; import org.sonar.db.DbTester; @@ -48,8 +48,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.sonar.api.rule.Severity.MAJOR; import static org.sonar.api.rule.Severity.MINOR; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.core.issue.IssueChangeContext.issueChangeContextByUserBuilder; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.rule.RuleTesting.newRule; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/SetTypeActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/SetTypeActionIT.java index d63375ad18b..430edd6417c 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/SetTypeActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/SetTypeActionIT.java @@ -39,10 +39,10 @@ import org.sonar.server.tester.UserSessionRule; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.VULNERABILITY; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.VULNERABILITY; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.core.issue.IssueChangeContext.issueChangeContextByUserBuilder; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.rule.RuleTesting.newRule; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/TransitionActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/TransitionActionIT.java index 5e6e93ecabf..54a49be6a29 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/TransitionActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/TransitionActionIT.java @@ -26,7 +26,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.util.Uuids; import org.sonar.db.component.BranchDto; @@ -35,6 +35,7 @@ import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentTesting; import org.sonar.db.issue.IssueDto; import org.sonar.db.issue.IssueTesting; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.rule.RuleDto; import org.sonar.server.issue.workflow.FunctionExecutor; @@ -47,9 +48,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.sonar.api.issue.Issue.STATUS_CLOSED; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; import static org.sonar.core.issue.IssueChangeContext.issueChangeContextByUserBuilder; import static org.sonar.db.component.ComponentTesting.newFileDto; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; import static org.sonar.db.rule.RuleTesting.newRule; public class TransitionActionIT { @@ -124,7 +125,7 @@ public class TransitionActionIT { return IssueTesting.newIssue(rule, project, file); } - private void loginAndAddProjectPermission(String login, String permission) { + private void loginAndAddProjectPermission(String login, ProjectPermission permission) { ProjectDto projectDto = ComponentTesting.newProjectDto(); BranchDto branchDto = ComponentTesting.newBranchDto(projectDto.getUuid(), BranchType.BRANCH).setIsMain(true).setUuid(issue.projectUuid()); userSession.logIn(login).addProjectPermission(permission, projectDto) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/TransitionServiceIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/TransitionServiceIT.java index 772d0869824..df10afba46a 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/TransitionServiceIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/TransitionServiceIT.java @@ -39,8 +39,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.sonar.api.issue.Issue.STATUS_CONFIRMED; import static org.sonar.api.issue.Issue.STATUS_OPEN; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; import static org.sonar.core.issue.IssueChangeContext.issueChangeContextByUserBuilder; import static org.sonar.db.component.ComponentTesting.newFileDto; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/WebIssueStorageIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/WebIssueStorageIT.java index 5b3664c516e..9468de7356c 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/WebIssueStorageIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/WebIssueStorageIT.java @@ -28,7 +28,7 @@ import org.sonar.api.impl.utils.TestSystem2; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.Duration; import org.sonar.api.utils.System2; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/AddCommentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/AddCommentActionIT.java index 5f72f9259a5..8a1250057d8 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/AddCommentActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/AddCommentActionIT.java @@ -35,6 +35,7 @@ import org.sonar.db.component.ComponentDto; import org.sonar.db.issue.IssueChangeDto; import org.sonar.db.issue.IssueDbTester; import org.sonar.db.issue.IssueDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.rule.RuleDto; import org.sonar.db.user.UserDto; import org.sonar.server.es.EsTester; @@ -65,15 +66,14 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; import static org.sonar.db.issue.IssueChangeDto.TYPE_COMMENT; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; public class AddCommentActionIT { private static final long NOW = 10_000_000_000L; - @Rule public DbTester dbTester = DbTester.create(System2.INSTANCE); @@ -220,7 +220,7 @@ public class AddCommentActionIT { return request.execute(); } - private void loginWithBrowsePermission(IssueDto issueDto, String permission) { + private void loginWithBrowsePermission(IssueDto issueDto, ProjectPermission permission) { UserDto user = dbTester.users().insertUser("john"); userSession.logIn(user) .addProjectPermission(permission, diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/AssignActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/AssignActionIT.java index d6711fd3a0f..196650c0906 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/AssignActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/AssignActionIT.java @@ -24,12 +24,13 @@ import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; import org.sonar.api.impl.utils.TestSystem2; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.issue.IssueDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.UserDto; import org.sonar.server.es.EsTester; import org.sonar.server.exceptions.ForbiddenException; @@ -56,9 +57,9 @@ 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.verify; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.tester.UserSessionRule.standalone; public class AssignActionIT { @@ -289,7 +290,7 @@ public class AssignActionIT { setUserWithPermission(issue, USER); } - private void setUserWithPermission(IssueDto issue, String permission) { + private void setUserWithPermission(IssueDto issue, ProjectPermission permission) { currentUser = insertUser(CURRENT_USER_LOGIN); userSession.logIn(currentUser) .addProjectPermission(permission, diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/BulkChangeActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/BulkChangeActionIT.java index 9eb6f0a93c4..0dd5c62d035 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/BulkChangeActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/BulkChangeActionIT.java @@ -30,7 +30,7 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.sonar.api.impl.utils.TestSystem2; import org.sonar.api.issue.IssueStatus; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; import org.sonar.core.util.SequenceUuidFactory; @@ -41,6 +41,7 @@ import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ProjectData; import org.sonar.db.issue.IssueChangeDto; import org.sonar.db.issue.IssueDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.rule.RuleDto; import org.sonar.db.user.UserDto; import org.sonar.server.es.EsTester; @@ -91,14 +92,14 @@ import static org.sonar.api.issue.Issue.STATUS_OPEN; import static org.sonar.api.issue.Issue.STATUS_RESOLVED; import static org.sonar.api.rule.Severity.MAJOR; import static org.sonar.api.rule.Severity.MINOR; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.VULNERABILITY; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.api.web.UserRole.SECURITYHOTSPOT_ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.VULNERABILITY; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.issue.IssueChangeDto.TYPE_COMMENT; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.SECURITYHOTSPOT_ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.issue.notification.IssuesChangesNotificationBuilderTesting.projectBranchOf; import static org.sonar.server.issue.notification.IssuesChangesNotificationBuilderTesting.projectOf; import static org.sonar.server.issue.notification.IssuesChangesNotificationBuilderTesting.ruleOf; @@ -790,8 +791,8 @@ public class BulkChangeActionIT { return request.executeProtobuf(BulkChangeWsResponse.class); } - private void addUserProjectPermissions(UserDto user, ProjectData project, String... permissions) { - for (String permission : permissions) { + private void addUserProjectPermissions(UserDto user, ProjectData project, ProjectPermission... permissions) { + for (ProjectPermission permission : permissions) { db.users().insertProjectPermissionOnUser(user, permission, project.getProjectDto()); userSession.addProjectPermission(permission, project.getProjectDto()); userSession.addProjectBranchMapping(project.projectUuid(), project.getMainBranchComponent()); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ChangelogActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ChangelogActionIT.java index 5505f47f054..64524018aed 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ChangelogActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ChangelogActionIT.java @@ -50,8 +50,8 @@ import static java.util.Optional.ofNullable; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.groups.Tuple.tuple; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.user.UserTesting.newUserDto; import static org.sonar.test.JsonAssert.assertJson; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/DeleteCommentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/DeleteCommentActionIT.java index 04daecbfa75..d78a444753c 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/DeleteCommentActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/DeleteCommentActionIT.java @@ -31,6 +31,7 @@ import org.sonar.db.DbTester; import org.sonar.db.issue.IssueChangeDto; import org.sonar.db.issue.IssueDbTester; import org.sonar.db.issue.IssueDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.UserDto; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; @@ -48,8 +49,8 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; public class DeleteCommentActionIT { @@ -177,7 +178,7 @@ public class DeleteCommentActionIT { return request.execute(); } - private void loginAndAddProjectPermission(UserDto user, IssueDto issueDto, String permission) { + private void loginAndAddProjectPermission(UserDto user, IssueDto issueDto, ProjectPermission permission) { userSession.logIn(user).addProjectPermission(permission, dbClient.componentDao().selectByUuid(dbTester.getSession(), issueDto.getProjectUuid()).get()); } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/DoTransitionActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/DoTransitionActionIT.java index 1e2bbb79f2a..3a4805c777c 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/DoTransitionActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/DoTransitionActionIT.java @@ -25,7 +25,7 @@ import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.sonar.api.impl.utils.TestSystem2; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.utils.System2; @@ -71,9 +71,9 @@ import static org.mockito.Mockito.verifyNoInteractions; import static org.sonar.api.issue.Issue.STATUS_CONFIRMED; import static org.sonar.api.issue.Issue.STATUS_OPEN; import static org.sonar.api.rule.Severity.MAJOR; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.issue.IssueTesting.newIssue; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/EditCommentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/EditCommentActionIT.java index 4fb47f95a0f..8a932c3f800 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/EditCommentActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/EditCommentActionIT.java @@ -33,6 +33,7 @@ import org.sonar.db.DbTester; import org.sonar.db.issue.IssueChangeDto; import org.sonar.db.issue.IssueDbTester; import org.sonar.db.issue.IssueDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.UserDto; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; @@ -51,8 +52,8 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; public class EditCommentActionIT { @@ -128,7 +129,7 @@ public class EditCommentActionIT { IssueChangeDto commentDto = issueDbTester.insertComment(issueDto, null, "please fix it"); loginWithBrowsePermission(user, USER, issueDto); - assertThatThrownBy(() -> call(commentDto.getKey(), "please have a look")) + assertThatThrownBy(() -> call(commentDto.getKey(), "please have a look")) .isInstanceOf(IllegalArgumentException.class) .hasMessage("You can only edit your own comments"); } @@ -218,7 +219,7 @@ public class EditCommentActionIT { return issueDbTester.insertIssue(); } - private void loginWithBrowsePermission(UserDto user, String permission, IssueDto issueDto) { + private void loginWithBrowsePermission(UserDto user, ProjectPermission permission, IssueDto issueDto) { userSession.logIn(user).addProjectPermission(permission, dbClient.componentDao().selectByUuid(dbTester.getSession(), issueDto.getProjectUuid()).get(), dbClient.componentDao().selectByUuid(dbTester.getSession(), issueDto.getComponentUuid()).get()); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ListActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ListActionIT.java index 389e71106f5..d108dc09dd4 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ListActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ListActionIT.java @@ -32,7 +32,7 @@ import org.junit.runner.RunWith; import org.sonar.api.resources.Languages; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Durations; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullActionIT.java index 783e6e76195..8b6fa673272 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullActionIT.java @@ -62,7 +62,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME; import static org.sonar.db.component.ComponentTesting.newFileDto; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullTaintActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullTaintActionIT.java index ebda6513b12..df1cb973755 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullTaintActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/PullTaintActionIT.java @@ -67,7 +67,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.groups.Tuple.tuple; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.protobuf.DbIssues.MessageFormattingType.CODE; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ReindexActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ReindexActionIT.java index 9ce1775f34b..31a6f03598d 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ReindexActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/ReindexActionIT.java @@ -22,7 +22,7 @@ package org.sonar.server.issue.ws; import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbTester; import org.sonar.db.project.ProjectDto; import org.sonar.server.es.EsTester; @@ -70,7 +70,7 @@ public class ReindexActionIT { public void reindex_project() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); userSession.logIn().setSystemAdministrator(); - userSession.addProjectPermission(UserRole.ADMIN, project); + userSession.addProjectPermission(ProjectPermission.ADMIN, project); TestResponse response = tester.newRequest() .setParam("project", project.getKey()) @@ -102,7 +102,7 @@ public class ReindexActionIT { @Test public void fail_if_not_authorized() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); TestRequest testRequest = tester.newRequest().setParam("project", project.getKey()); assertThatThrownBy(testRequest::execute) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionComponentsIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionComponentsIT.java index 372f88969fd..67199c026e2 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionComponentsIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionComponentsIT.java @@ -67,7 +67,7 @@ import static org.assertj.core.api.Assertions.tuple; import static org.mockito.Mockito.mock; import static org.sonar.api.utils.DateUtils.addDays; import static org.sonar.api.utils.DateUtils.parseDateTime; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02; import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionFacetsIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionFacetsIT.java index 3194ceb7d87..6249b00a829 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionFacetsIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionFacetsIT.java @@ -29,7 +29,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.config.Configuration; import org.sonar.api.issue.Issue; import org.sonar.api.resources.Languages; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.Durations; import org.sonar.api.utils.System2; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java index 4b4fb97231e..0fbb78a3287 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java @@ -47,11 +47,10 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; import org.sonar.api.rules.CleanCodeAttributeCategory; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.Durations; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.util.UuidFactoryFast; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; @@ -67,6 +66,7 @@ import org.sonar.db.issue.IssueChangeDto; import org.sonar.db.issue.IssueDto; import org.sonar.db.issue.IssueFixedDto; import org.sonar.db.permission.GroupPermissionDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.protobuf.DbCommons; import org.sonar.db.protobuf.DbIssues; @@ -121,16 +121,16 @@ import static org.sonar.api.issue.Issue.STATUS_RESOLVED; import static org.sonar.api.issue.Issue.STATUS_REVIEWED; import static org.sonar.api.issue.impact.Severity.HIGH; import static org.sonar.api.issue.impact.SoftwareQuality.SECURITY; -import static org.sonar.api.rules.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.CODE_SMELL; import static org.sonar.api.server.ws.WebService.Param.FACETS; import static org.sonar.api.utils.DateUtils.formatDateTime; import static org.sonar.api.utils.DateUtils.parseDate; import static org.sonar.api.utils.DateUtils.parseDateTime; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; import static org.sonar.core.config.MQRModeConstants.MULTI_QUALITY_MODE_ENABLED; import static org.sonar.db.component.ComponentQualifiers.UNIT_TEST_FILE; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.issue.IssueTesting.newIssue; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; import static org.sonar.db.protobuf.DbIssues.MessageFormattingType.CODE; import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection; import static org.sonar.db.rule.RuleTesting.XOO_X1; @@ -205,7 +205,7 @@ class SearchActionIT { ProjectData projectData = db.components().insertPrivateProject(); ProjectDto projectDto = projectData.getProjectDto(); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, projectDto); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, projectDto); ComponentDto project = projectData.getMainBranchComponent(); ComponentDto file = db.components().insertComponent(newFileDto(project)); @@ -233,8 +233,7 @@ class SearchActionIT { assertThat(response.getIssuesList()) .extracting( - Issue::getKey, Issue::getRule, Issue::getSeverity, Issue::getComponent, Issue::getResolution, Issue::getStatus, Issue::getMessage - , Issue::getMessageFormattingsList, + Issue::getKey, Issue::getRule, Issue::getSeverity, Issue::getComponent, Issue::getResolution, Issue::getStatus, Issue::getMessage, Issue::getMessageFormattingsList, Issue::getEffort, Issue::getAssignee, Issue::getAuthor, Issue::getLine, Issue::getHash, Issue::getTagsList, Issue::getCreationDate, Issue::getUpdateDate, Issue::getQuickFixAvailable, Issue::getCodeVariantsList) @@ -399,7 +398,7 @@ class SearchActionIT { assertThat(result.getIssuesCount()).isOne(); assertThat(result.getIssues(0).getFlows(0).getLocationsList()).extracting(Common.Location::getComponent, Common.Location::getMsg, - Common.Location::getMsgFormattingsList) + Common.Location::getMsgFormattingsList) .containsExactlyInAnyOrder( tuple(file.getKey(), "FLOW MESSAGE", List.of()), tuple(anotherFile.getKey(), "ANOTHER FLOW MESSAGE", List.of(Common.MessageFormatting.newBuilder() @@ -522,8 +521,7 @@ class SearchActionIT { c -> c.setKey("PROJECT_KEY").setName("NAME_PROJECT_ID").setLongName("LONG_NAME_PROJECT_ID").setLanguage("java")); grantPermissionToAnyone(project.getProjectDto(), ISSUE_ADMIN); indexPermissions(); - ComponentDto file = - db.components().insertComponent(newFileDto(project.getMainBranchComponent(), null, "FILE_ID").setKey("FILE_KEY").setLanguage("js")); + ComponentDto file = db.components().insertComponent(newFileDto(project.getMainBranchComponent(), null, "FILE_ID").setKey("FILE_KEY").setLanguage("js")); IssueDto issue = newIssue(newIssueRule(), project.getMainBranchComponent(), file) .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") @@ -913,8 +911,7 @@ class SearchActionIT { @Test void issue_on_removed_file() { RuleDto rule = newIssueRule(); - ComponentDto project = - db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setKey("PROJECT_KEY")).getMainBranchComponent(); + ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setKey("PROJECT_KEY")).getMainBranchComponent(); indexPermissions(); ComponentDto removedFile = db.components().insertComponent(newFileDto(project).setUuid("REMOVED_FILE_ID") .setKey("REMOVED_FILE_KEY") @@ -939,8 +936,7 @@ class SearchActionIT { @Test void apply_paging_with_one_component() { RuleDto rule = newIssueRule(); - ComponentDto project = - db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setKey("PROJECT_KEY")).getMainBranchComponent(); + ComponentDto project = db.components().insertPublicProject("PROJECT_ID", c -> c.setKey("PROJECT_KEY").setKey("PROJECT_KEY")).getMainBranchComponent(); indexPermissions(); ComponentDto file = db.components().insertComponent(newFileDto(project, null, "FILE_ID").setKey("FILE_KEY")); for (int i = 0; i < SearchOptions.MAX_PAGE_SIZE + 1; i++) { @@ -1273,7 +1269,7 @@ class SearchActionIT { assertThat(response.getIssuesList()) .extracting(Issue::getAuthor) .containsExactlyInAnyOrder("", ""); - assertThat(response.getFacets().getFacetsList()).isEmpty(); + assertThat(response.getFacets().getFacetsList()).isEmpty(); } @Test @@ -2294,7 +2290,8 @@ class SearchActionIT { "additionalFields", "asc", "assigned", "assignees", "author", "components", "branch", "pullRequest", "createdAfter", "createdAt", "createdBefore", "createdInLast", "directories", "facets", "files", "issues", "scopes", "languages", "onComponentOnly", "p", "projects", "ps", "resolutions", "resolved", "rules", "s", "severities", "statuses", "tags", "types", "pciDss-3.2", "pciDss-4" + - ".0", "owaspAsvs-4.0", + ".0", + "owaspAsvs-4.0", "owaspAsvsLevel", "owaspTop10", "owaspTop10-2021", "stig-ASD_V5R3", "casa", "sansTop25", "cwe", "sonarsourceSecurity", "timeZone", "inNewCodePeriod", "codeVariants", "cleanCodeAttributeCategories", "impactSeverities", "impactSoftwareQualities", "issueStatuses", "fixedInPullRequest", @@ -2562,7 +2559,7 @@ class SearchActionIT { issueIndexer.indexAllIssues(); } - private void grantPermissionToAnyone(ProjectDto project, String permission) { + private void grantPermissionToAnyone(ProjectDto project, ProjectPermission permission) { dbClient.groupPermissionDao().insert(session, new GroupPermissionDto() .setUuid(Uuids.createFast()) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SetSeverityActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SetSeverityActionIT.java index fe7fcae0415..cbd41ad685f 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SetSeverityActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SetSeverityActionIT.java @@ -42,6 +42,7 @@ import org.sonar.db.component.ComponentDto; import org.sonar.db.issue.ImpactDto; import org.sonar.db.issue.IssueDbTester; import org.sonar.db.issue.IssueDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.rule.RuleDto; import org.sonar.db.user.UserDto; @@ -77,12 +78,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.sonar.api.rule.Severity.MAJOR; import static org.sonar.api.rule.Severity.MINOR; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.issue.IssueTesting.newIssue; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; class SetSeverityActionIT { @@ -394,7 +395,7 @@ class SetSeverityActionIT { return request.execute(); } - private void logInAndAddProjectPermission(IssueDto issueDto, String permission) { + private void logInAndAddProjectPermission(IssueDto issueDto, ProjectPermission permission) { BranchDto branchDto = dbClient.branchDao().selectByUuid(dbTester.getSession(), issueDto.getProjectUuid()) .orElseThrow(() -> new IllegalStateException(format("Couldn't find branch with uuid : %s", issueDto.getProjectUuid()))); UserDto user = dbTester.users().insertUser("john"); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SetTagsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SetTagsActionIT.java index bf6d1fd6cb3..13e54528ada 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SetTagsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SetTagsActionIT.java @@ -38,6 +38,7 @@ import org.sonar.db.DbTester; import org.sonar.db.component.BranchDto; import org.sonar.db.component.ComponentDto; import org.sonar.db.issue.IssueDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.rule.RuleDto; import org.sonar.db.user.UserDto; @@ -68,9 +69,9 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newPublicProjectDto; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; public class SetTagsActionIT { @@ -261,7 +262,7 @@ public class SetTagsActionIT { .orElseThrow(); } - private void logInAndAddProjectPermission(IssueDto issueDto, String permission) { + private void logInAndAddProjectPermission(IssueDto issueDto, ProjectPermission permission) { UserDto user = db.users().insertUser("john"); ProjectDto projectDto = retrieveProjectDto(issueDto); userSession.logIn(user) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SetTypeActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SetTypeActionIT.java index c782eecf0e3..f1750b94ef2 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SetTypeActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SetTypeActionIT.java @@ -32,7 +32,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; @@ -46,6 +46,7 @@ import org.sonar.db.component.BranchType; import org.sonar.db.component.ComponentDto; import org.sonar.db.issue.IssueDbTester; import org.sonar.db.issue.IssueDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.rule.RuleDto; import org.sonar.db.user.UserDto; @@ -80,13 +81,13 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import static org.sonar.api.rule.Severity.MAJOR; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.issue.IssueTesting.newIssue; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; @RunWith(DataProviderRunner.class) public class SetTypeActionIT { @@ -209,7 +210,7 @@ public class SetTypeActionIT { public void fail_when_missing_browse_permission() { IssueDto issueDto = issueDbTester.insertIssue(); String login = "john"; - String permission = ISSUE_ADMIN; + ProjectPermission permission = ISSUE_ADMIN; logInAndAddProjectPermission(login, issueDto, permission); assertThatThrownBy(() -> call(issueDto.getKey(), BUG.name())) @@ -278,7 +279,7 @@ public class SetTypeActionIT { .registerBranches(branchDto); } - private void logInAndAddProjectPermission(String login, IssueDto issueDto, String permission) { + private void logInAndAddProjectPermission(String login, IssueDto issueDto, ProjectPermission permission) { BranchDto branchDto = dbClient.branchDao().selectByUuid(dbTester.getSession(), issueDto.getProjectUuid()) .orElseThrow(() -> new IllegalStateException(format("Couldn't find branch with uuid : %s", issueDto.getProjectUuid()))); userSession.logIn(login) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsActionIT.java index 8aeadec956c..a6c7a15b94b 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsActionIT.java @@ -24,17 +24,18 @@ import java.nio.file.Files; import java.nio.file.Path; import org.junit.Rule; import org.junit.Test; -import org.sonar.server.component.ComponentTypeTree; -import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.WebService; -import org.sonar.server.component.DefaultComponentTypes; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbTester; import org.sonar.db.issue.AnticipatedTransitionDao; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.UserDto; import org.sonar.server.component.ComponentFinder; +import org.sonar.server.component.ComponentTypeTree; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.DefaultComponentTypes; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; @@ -44,9 +45,9 @@ import org.sonar.server.ws.WsActionTester; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.tuple; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; import static org.sonar.db.component.ProjectTesting.newPrivateProjectDto; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; public class AnticipatedTransitionsActionIT { @@ -57,7 +58,7 @@ public class AnticipatedTransitionsActionIT { @Rule public DbTester db = DbTester.create(); - private final ComponentFinder componentFinder = new ComponentFinder(db.getDbClient(), new ComponentTypes(new ComponentTypeTree[]{DefaultComponentTypes.get()})); + private final ComponentFinder componentFinder = new ComponentFinder(db.getDbClient(), new ComponentTypes(new ComponentTypeTree[] {DefaultComponentTypes.get()})); private final AnticipatedTransitionsActionValidator validator = new AnticipatedTransitionsActionValidator(db.getDbClient(), componentFinder, userSession); private final UuidFactory uuidFactory = new SequenceUuidFactory(); private final AnticipatedTransitionDao anticipatedTransitionDao = db.getDbClient().anticipatedTransitionDao(); @@ -97,9 +98,9 @@ public class AnticipatedTransitionsActionIT { ]</code></pre>"""); assertThat(definition.isPost()).isTrue(); assertThat(definition.isInternal()).isTrue(); - assertThat(definition.params()).extracting(WebService.Param::key, WebService.Param::isRequired, WebService.Param::description, WebService.Param::since).containsExactlyInAnyOrder( - tuple("projectKey", true, "The key of the project", "10.2") - ); + assertThat(definition.params()).extracting(WebService.Param::key, WebService.Param::isRequired, WebService.Param::description, WebService.Param::since) + .containsExactlyInAnyOrder( + tuple("projectKey", true, "The key of the project", "10.2")); } @Test @@ -220,7 +221,7 @@ public class AnticipatedTransitionsActionIT { .setPayload(requestBody); } - private void mockUser(ProjectDto projectDto, String permission) { + private void mockUser(ProjectDto projectDto, ProjectPermission permission) { UserDto user = db.users().insertUser(); db.users().insertProjectPermissionOnUser(user, permission, projectDto); userSession.logIn(user); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/live/LiveMeasureTreeUpdaterImplIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/live/LiveMeasureTreeUpdaterImplIT.java index e4dbb0202fb..faaf4201f42 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/live/LiveMeasureTreeUpdaterImplIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/live/LiveMeasureTreeUpdaterImplIT.java @@ -28,7 +28,7 @@ import org.junit.Test; import org.sonar.api.config.Configuration; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.measures.Metric; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.DbTester; import org.sonar.db.component.BranchDto; import org.sonar.db.component.BranchType; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentActionIT.java index 95a2e80093a..0aa8f7a5624 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentActionIT.java @@ -33,6 +33,7 @@ import org.sonar.db.component.ProjectData; import org.sonar.db.component.SnapshotDto; import org.sonar.db.measure.MeasureDto; import org.sonar.db.metric.MetricDto; +import org.sonar.db.permission.GlobalPermission; import org.sonar.server.component.TestComponentFinder; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; @@ -50,11 +51,12 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.tuple; import static org.sonar.api.measures.CoreMetrics.RELIABILITY_ISSUES; import static org.sonar.api.utils.DateUtils.parseDateTime; -import static org.sonar.api.web.UserRole.USER; import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME; import static org.sonar.db.component.BranchType.PULL_REQUEST; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newProjectCopy; +import static org.sonar.db.permission.ProjectPermission.SCAN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_ADDITIONAL_FIELDS; import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_BRANCH; import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_COMPONENT; @@ -107,6 +109,32 @@ public class ComponentActionIT { } @Test + public void user_with_project_scan_permission_is_allowed_to_get_project_measures() { + ProjectData projectData = db.components().insertPrivateProject(); + ComponentDto mainBranch = projectData.getMainBranchComponent(); + userSession.addProjectPermission(SCAN, projectData.getProjectDto()) + .registerBranches(projectData.getMainBranchDto()); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); + + ComponentWsResponse response = newRequest(mainBranch.getKey(), metric.getKey()); + + assertThat(response.getMetrics().getMetricsCount()).isOne(); + } + + @Test + public void user_with_global_scan_permission_is_allowed_to_get_project_status() { + ProjectData projectData = db.components().insertPrivateProject(); + ComponentDto mainBranch = projectData.getMainBranchComponent(); + userSession.addPermission(GlobalPermission.SCAN); + + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); + + ComponentWsResponse response = newRequest(mainBranch.getKey(), metric.getKey()); + + assertThat(response.getMetrics().getMetricsCount()).isOne(); + } + + @Test public void without_additional_fields() { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java index acd063a15b2..54ea579220e 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java @@ -73,7 +73,7 @@ import static org.sonar.api.measures.Metric.ValueType.INT; import static org.sonar.api.measures.Metric.ValueType.RATING; import static org.sonar.api.server.ws.WebService.Param.SORT; import static org.sonar.api.utils.DateUtils.parseDateTime; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.BranchType.PULL_REQUEST; import static org.sonar.db.component.ComponentDbTester.toProjectDto; import static org.sonar.db.component.ComponentQualifiers.APP; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchActionIT.java index 587ec58355b..fc80616a584 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchActionIT.java @@ -28,7 +28,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.metric.MetricDto; @@ -71,9 +71,9 @@ public class SearchActionIT { ComponentDto project2 = db.components().insertPrivateProject(p -> p.setKey("MY_PROJECT_2").setName("Project 2")).getMainBranchComponent(); ComponentDto project3 = db.components().insertPrivateProject(p -> p.setKey("MY_PROJECT_3").setName("Project 3")).getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, project1); - userSession.addProjectPermission(UserRole.USER, project2); - userSession.addProjectPermission(UserRole.USER, project3); + userSession.addProjectPermission(ProjectPermission.USER, project1); + userSession.addProjectPermission(ProjectPermission.USER, project2); + userSession.addProjectPermission(ProjectPermission.USER, project3); MetricDto complexity = db.measures().insertMetric(m -> m.setKey("complexity").setValueType(INT.name())); db.measures().insertMeasure(project1, m -> m.addValue(complexity.getKey(), 12.0d)); @@ -104,7 +104,7 @@ public class SearchActionIT { @Test public void return_measures() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); MetricDto coverage = db.measures().insertMetric(m -> m.setValueType(FLOAT.name())); db.measures().insertMeasure(project, m -> m.addValue(coverage.getKey(), 15.5d)); @@ -120,7 +120,7 @@ public class SearchActionIT { @Test public void search_shouldReturnAcceptedIssuesMetric_whenIsCalledWithDeprecatedWontFixIssuesMetric() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); MetricDto acceptedIssues = db.measures().insertMetric(m -> m.setValueType(INT.name()) .setKey("accepted_issues") .setShortName("Accepted Issues")); @@ -138,7 +138,7 @@ public class SearchActionIT { @Test public void return_best_value() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); MetricDto matchBestValue = db.measures().insertMetric(m -> m.setValueType(FLOAT.name()).setBestValue(15.5d)); db.measures().insertMeasure(project, m -> m.addValue(matchBestValue.getKey(), 15.5d)); MetricDto doesNotMatchBestValue = db.measures().insertMetric(m -> m.setValueType(INT.name()).setBestValue(50d)); @@ -161,7 +161,7 @@ public class SearchActionIT { @Test public void return_measures_on_new_code_period() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); MetricDto coverage = db.measures().insertMetric(m -> m.setKey("new_metric").setValueType(FLOAT.name())); db.measures().insertMeasure(project, m -> m.addValue(coverage.getKey(), 10d)); @@ -182,9 +182,9 @@ public class SearchActionIT { ComponentDto project1 = db.components().insertPrivateProject(p -> p.setName("C")).getMainBranchComponent(); ComponentDto project2 = db.components().insertPrivateProject(p -> p.setName("A")).getMainBranchComponent(); ComponentDto project3 = db.components().insertPrivateProject(p -> p.setName("B")).getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, project1); - userSession.addProjectPermission(UserRole.USER, project2); - userSession.addProjectPermission(UserRole.USER, project3); + userSession.addProjectPermission(ProjectPermission.USER, project1); + userSession.addProjectPermission(ProjectPermission.USER, project2); + userSession.addProjectPermission(ProjectPermission.USER, project3); db.measures().insertMeasure(project1, m -> m.addValue(coverage.getKey(), 5.5d)); db.measures().insertMeasure(project2, m -> m.addValue(coverage.getKey(), 6.5d)); db.measures().insertMeasure(project3, m -> m.addValue(coverage.getKey(), 7.5d)); @@ -203,7 +203,7 @@ public class SearchActionIT { @Test public void return_measures_on_view() { ComponentDto view = db.components().insertPrivatePortfolio(); - userSession.addProjectPermission(UserRole.USER, view); + userSession.addProjectPermission(ProjectPermission.USER, view); MetricDto coverage = db.measures().insertMetric(m -> m.setValueType(FLOAT.name())); db.measures().insertMeasure(view, m -> m.addValue(coverage.getKey(), 15.5d)); @@ -219,7 +219,7 @@ public class SearchActionIT { @Test public void return_measures_on_application() { ComponentDto application = db.components().insertPrivateApplication().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, application); + userSession.addProjectPermission(ProjectPermission.USER, application); MetricDto coverage = db.measures().insertMetric(m -> m.setValueType(FLOAT.name())); db.measures().insertMeasure(application, m -> m.addValue(coverage.getKey(), 15.5d)); @@ -236,8 +236,8 @@ public class SearchActionIT { public void return_measures_on_sub_view() { ComponentDto view = db.components().insertPrivatePortfolio(); ComponentDto subView = db.components().insertComponent(newSubPortfolio(view)); - userSession.addProjectPermission(UserRole.USER, view); - userSession.addProjectPermission(UserRole.USER, subView); + userSession.addProjectPermission(ProjectPermission.USER, view); + userSession.addProjectPermission(ProjectPermission.USER, subView); MetricDto metric = db.measures().insertMetric(m -> m.setValueType(FLOAT.name())); db.measures().insertMeasure(subView, m -> m.addValue(metric.getKey(), 15.5d)); @@ -257,7 +257,7 @@ public class SearchActionIT { ComponentDto project2 = db.components().insertPrivateProject().getMainBranchComponent(); db.measures().insertMeasure(project1, m -> m.addValue(metric.getKey(), 15.5d)); db.measures().insertMeasure(project2, m -> m.addValue(metric.getKey(), 42.0d)); - Arrays.stream(new ComponentDto[] {project1}).forEach(p -> userSession.addProjectPermission(UserRole.USER, p)); + Arrays.stream(new ComponentDto[] {project1}).forEach(p -> userSession.addProjectPermission(ProjectPermission.USER, p)); SearchWsResponse result = call(asList(project1.getKey(), project2.getKey()), singletonList(metric.getKey())); @@ -270,7 +270,7 @@ public class SearchActionIT { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); ComponentDto branch = db.components().insertProjectBranch(project); db.measures().insertMeasure(branch, m -> m.addValue(coverage.getKey(), 10d)); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); SearchWsResponse result = call(singletonList(branch.getKey()), singletonList(coverage.getKey())); @@ -280,7 +280,7 @@ public class SearchActionIT { @Test public void fail_if_no_metric() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); assertThatThrownBy(() -> call(singletonList(project.uuid()), null)) .isInstanceOf(IllegalArgumentException.class) @@ -290,7 +290,7 @@ public class SearchActionIT { @Test public void fail_if_empty_metric() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); assertThatThrownBy(() -> call(singletonList(project.uuid()), emptyList())) .isInstanceOf(IllegalArgumentException.class) @@ -300,7 +300,7 @@ public class SearchActionIT { @Test public void fail_if_unknown_metric() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); MetricDto metric = db.measures().insertMetric(); assertThatThrownBy(() -> call(singletonList(project.getKey()), newArrayList("violations", metric.getKey(), "ncloc"))) @@ -354,7 +354,7 @@ public class SearchActionIT { public void fail_if_directory() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); ComponentDto dir = db.components().insertComponent(newDirectory(project, "dir")); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); MetricDto metric = db.measures().insertMetric(); assertThatThrownBy(() -> call(singletonList(dir.getKey()), singletonList(metric.getKey()))) @@ -366,7 +366,7 @@ public class SearchActionIT { public void fail_if_file() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); ComponentDto file = db.components().insertComponent(newFileDto(project)); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); MetricDto metric = db.measures().insertMetric(); assertThatThrownBy(() -> call(singletonList(file.getKey()), singletonList(metric.getKey()))) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java index 80b0965d1b2..4bcf2197152 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java @@ -29,7 +29,7 @@ import org.sonar.api.measures.Metric.ValueType; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -107,7 +107,7 @@ class SearchHistoryActionIT { public void setUp() { project = db.components().insertPrivateProject(); analysis = db.components().insertSnapshot(project.getProjectDto()); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); nclocMetric = insertNclocMetric(); complexityMetric = insertComplexityMetric(); @@ -119,7 +119,7 @@ class SearchHistoryActionIT { @Test void empty_response() { project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); SearchHistoryRequest request = SearchHistoryRequest.builder() .setComponent(project.projectKey()) @@ -140,7 +140,7 @@ class SearchHistoryActionIT { void analyses_but_no_measure() { project = db.components().insertPrivateProject(); analysis = db.components().insertSnapshot(project.getProjectDto()); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); SearchHistoryRequest request = SearchHistoryRequest.builder() @@ -235,7 +235,7 @@ class SearchHistoryActionIT { @Test void pagination_applies_to_analyses() { project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); List<String> analysisDates = LongStream.rangeClosed(1, 9) .mapToObj(i -> dbClient.snapshotDao().insert(dbSession, newAnalysis(project.mainBranchUuid()).setCreatedAt(i * 1_000_000_000))) @@ -260,7 +260,7 @@ class SearchHistoryActionIT { @Test void inclusive_from_and_to_dates() { project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); List<String> analysisDates = LongStream.rangeClosed(1, 9) .mapToObj(i -> dbClient.snapshotDao().insert(dbSession, newAnalysis(project.mainBranchUuid()).setCreatedAt(System2.INSTANCE.now() + i * 1_000_000_000L))) @@ -328,7 +328,7 @@ class SearchHistoryActionIT { @Test void branch() { ProjectData project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); ComponentDto branch = db.components().insertProjectBranch(project.getMainBranchComponent(), b -> b.setKey("my_branch")); userSession.addProjectBranchMapping(project.projectUuid(), branch); ComponentDto file = db.components().insertComponent(newFileDto(branch, project.mainBranchUuid())); @@ -352,7 +352,7 @@ class SearchHistoryActionIT { @Test void pull_request() { ProjectData project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); ComponentDto branch = db.components().insertProjectBranch(project.getMainBranchComponent(), b -> b.setKey("pr-123").setBranchType(PULL_REQUEST)); userSession.addProjectBranchMapping(project.projectUuid(), branch); ComponentDto file = db.components().insertComponent(newFileDto(branch, project.mainBranchUuid())); @@ -387,7 +387,7 @@ class SearchHistoryActionIT { @Test void fail_if_not_enough_permissions() { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); SearchHistoryRequest request = SearchHistoryRequest.builder() .setComponent(project.projectKey()) .setMetrics(singletonList(complexityMetric.getKey())) @@ -408,7 +408,7 @@ class SearchHistoryActionIT { application.getProjectDto(), project1.getProjectDto(), project2.getProjectDto()) - .addProjectPermission(UserRole.USER, application.getProjectDto(), project1.getProjectDto()); + .addProjectPermission(ProjectPermission.USER, application.getProjectDto(), project1.getProjectDto()); SearchHistoryRequest request = SearchHistoryRequest.builder() .setComponent(application.projectKey()) @@ -434,7 +434,7 @@ class SearchHistoryActionIT { void fail_when_component_is_removed() { ProjectData projectData = db.components().insertPrivateProject(); db.components().insertComponent(newFileDto(project.getMainBranchComponent()).setKey("file-key").setEnabled(false)); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); assertThatThrownBy(() -> ws.newRequest() .setParam(PARAM_COMPONENT, "file-key") @@ -448,7 +448,7 @@ class SearchHistoryActionIT { void fail_if_branch_does_not_exist() { ProjectData project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project.getMainBranchComponent())); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); db.components().insertProjectBranch(project.getProjectDto(), b -> b.setKey("my_branch")); assertThatThrownBy(() -> ws.newRequest() @@ -480,7 +480,7 @@ class SearchHistoryActionIT { @Test void json_example() { project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); long now = parseDateTime("2017-01-23T17:00:53+0100").getTime(); LongStream.rangeClosed(0, 2) @@ -521,10 +521,10 @@ class SearchHistoryActionIT { @Test void handle_shouldUpdateTelemetryProviders() { PortfolioData portfolioData = db.components().insertPrivatePortfolioData(); - userSession.addPortfolioPermission(UserRole.USER, portfolioData.getPortfolioDto()); + userSession.addPortfolioPermission(ProjectPermission.USER, portfolioData.getPortfolioDto()); project = db.components().insertPrivateProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); db.commit(); // Request for a portfolio diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/ListActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/ListActionIT.java index a6384cc7bb8..4d68e4360bd 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/ListActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/ListActionIT.java @@ -27,7 +27,7 @@ import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.documentation.DocumentationLinkGenerator; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; @@ -122,7 +122,7 @@ public class ListActionIT { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); userSession.registerProjects(project); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project); ListWSResponse response = ws.newRequest() .setParam("project", project.getKey()) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/SetActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/SetActionIT.java index 5cb712b30bd..0d0c0c4221e 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/SetActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/SetActionIT.java @@ -30,7 +30,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.documentation.DocumentationLinkGenerator; import org.sonar.core.platform.EditionProvider; import org.sonar.core.platform.PlatformEditionProvider; @@ -458,7 +458,7 @@ public class SetActionIT { } private void logInAsProjectAdministrator(ProjectDto project) { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); } private void logInAsSystemAdministrator() { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/ShowActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/ShowActionIT.java index 848e88b2185..f7327c19a84 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/ShowActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/ShowActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.documentation.DocumentationLinkGenerator; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; @@ -257,15 +257,15 @@ public class ShowActionIT { } private void logInAsProjectAdministrator(ProjectDto project) { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); } private void logInAsProjectScan(ProjectDto project) { - userSession.logIn().addProjectPermission(UserRole.SCAN, project); + userSession.logIn().addProjectPermission(ProjectPermission.SCAN, project); } private void logInAsProjectIssueAdmin(ProjectDto project) { - userSession.logIn().addProjectPermission(UserRole.ISSUE_ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ISSUE_ADMIN, project); } } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/UnsetActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/UnsetActionIT.java index c1666d4d254..7257a6ef223 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/UnsetActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/newcodeperiod/ws/UnsetActionIT.java @@ -26,7 +26,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.documentation.DocumentationLinkGenerator; import org.sonar.core.platform.EditionProvider; import org.sonar.core.platform.PlatformEditionProvider; @@ -393,7 +393,7 @@ public class UnsetActionIT { } private void logInAsProjectAdministrator(ProjectDto project) { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); } private void logInAsSystemAdministrator() { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/notification/ws/AddActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/notification/ws/AddActionIT.java index bdc0e7c97f2..ace01dfb093 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/notification/ws/AddActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/notification/ws/AddActionIT.java @@ -49,7 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.ComponentTesting.newPortfolio; import static org.sonar.server.notification.ws.NotificationsWsParameters.PARAM_CHANNEL; import static org.sonar.server.notification.ws.NotificationsWsParameters.PARAM_LOGIN; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/notification/ws/ListActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/notification/ws/ListActionIT.java index a692e7dd63a..3a759421b2b 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/notification/ws/ListActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/notification/ws/ListActionIT.java @@ -47,7 +47,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.tuple; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; import static org.sonar.test.JsonAssert.assertJson; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddGroupActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddGroupActionIT.java index 3c74c3f2e9c..915eb176521 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddGroupActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddGroupActionIT.java @@ -20,23 +20,23 @@ package org.sonar.server.permission.ws; import org.junit.Test; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService.Action; -import org.sonar.api.web.UserRole; import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.component.ComponentTesting; -import org.sonar.server.component.ComponentTypesRule; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.portfolio.PortfolioDto; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.GroupDto; +import org.sonar.server.common.management.ManagedInstanceChecker; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.ServerException; -import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; import org.sonar.server.ws.TestRequest; @@ -110,7 +110,6 @@ public class AddGroupActionIT extends BasePermissionWsIT<AddGroupAction> { assertThat(db.users().selectGroupPermissions(group, null)).containsOnly("provisioning"); } - @Test public void add_permission_to_project_referenced_by_its_id() { GroupDto group = db.users().insertGroup("sonar-administrators"); @@ -219,13 +218,13 @@ public class AddGroupActionIT extends BasePermissionWsIT<AddGroupAction> { TestRequest request = newRequest() .setParam(PARAM_GROUP_NAME, group.getName()) .setParam(PARAM_PROJECT_KEY, project.getKey()) - .setParam(PARAM_PERMISSION, UserRole.CODEVIEWER); + .setParam(PARAM_PERMISSION, ProjectPermission.CODEVIEWER.getKey()); assertThatThrownBy(request::execute) .isInstanceOf(IllegalStateException.class) .hasMessage("Managed project"); - assertThat(db.users().selectGroupPermissions(group, project)).doesNotContain(UserRole.CODEVIEWER); + assertThat(db.users().selectGroupPermissions(group, project)).doesNotContain(ProjectPermission.CODEVIEWER.getKey()); } @Test @@ -234,7 +233,7 @@ public class AddGroupActionIT extends BasePermissionWsIT<AddGroupAction> { loginAsAdmin(); assertThatThrownBy(() -> { - executeRequest(group, UserRole.ISSUE_ADMIN); + executeRequest(group, ProjectPermission.ISSUE_ADMIN.getKey()); }) .isInstanceOf(BadRequestException.class); } @@ -364,21 +363,21 @@ public class AddGroupActionIT extends BasePermissionWsIT<AddGroupAction> { public void adding_project_permission_is_allowed_to_project_administrators() { GroupDto group = db.users().insertGroup("sonar-administrators"); ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); newRequest() .setParam(PARAM_GROUP_NAME, group.getName()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()) .execute(); - assertThat(db.users().selectGroupPermissions(group, project)).containsOnly(UserRole.ISSUE_ADMIN); + assertThat(db.users().selectGroupPermissions(group, project)).containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); } @Test public void fails_when_adding_any_permission_to_group_AnyOne_on_a_private_project() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); permissionService.getAllProjectPermissions() .forEach(permission -> { @@ -386,7 +385,7 @@ public class AddGroupActionIT extends BasePermissionWsIT<AddGroupAction> { newRequest() .setParam(PARAM_GROUP_NAME, "anyone") .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, permission) + .setParam(PARAM_PERMISSION, permission.getKey()) .execute(); fail("a BadRequestException should have been raised for " + permission); } catch (BadRequestException e) { @@ -398,12 +397,12 @@ public class AddGroupActionIT extends BasePermissionWsIT<AddGroupAction> { @Test public void no_effect_when_adding_USER_permission_to_group_AnyOne_on_a_public_project() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); newRequest() .setParam(PARAM_GROUP_NAME, "anyone") .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.USER) + .setParam(PARAM_PERMISSION, ProjectPermission.USER.getKey()) .execute(); assertThat(db.users().selectAnyonePermissions(project.getUuid())).isEmpty(); @@ -412,12 +411,12 @@ public class AddGroupActionIT extends BasePermissionWsIT<AddGroupAction> { @Test public void no_effect_when_adding_CODEVIEWER_permission_to_group_AnyOne_on_a_public_project() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); newRequest() .setParam(PARAM_GROUP_NAME, "anyone") .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.CODEVIEWER) + .setParam(PARAM_PERMISSION, ProjectPermission.CODEVIEWER.getKey()) .execute(); assertThat(db.users().selectAnyonePermissions(project.getUuid())).isEmpty(); @@ -427,12 +426,12 @@ public class AddGroupActionIT extends BasePermissionWsIT<AddGroupAction> { public void no_effect_when_adding_USER_permission_to_group_on_a_public_project() { GroupDto group = db.users().insertGroup(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); newRequest() .setParam(PARAM_GROUP_NAME, group.getName()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.USER) + .setParam(PARAM_PERMISSION, ProjectPermission.USER.getKey()) .execute(); assertThat(db.users().selectAnyonePermissions(project.getUuid())).isEmpty(); @@ -442,12 +441,12 @@ public class AddGroupActionIT extends BasePermissionWsIT<AddGroupAction> { public void no_effect_when_adding_CODEVIEWER_permission_to_group_on_a_public_project() { GroupDto group = db.users().insertGroup(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); newRequest() .setParam(PARAM_GROUP_NAME, group.getName()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.CODEVIEWER) + .setParam(PARAM_PERMISSION, ProjectPermission.CODEVIEWER.getKey()) .execute(); assertThat(db.users().selectAnyonePermissions(project.getUuid())).isEmpty(); @@ -457,14 +456,15 @@ public class AddGroupActionIT extends BasePermissionWsIT<AddGroupAction> { public void fail_when_using_branch_uuid() { GroupDto group = db.users().insertGroup(); ComponentDto project = db.components().insertPublicProject().getMainBranchComponent(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); ComponentDto branch = db.components().insertProjectBranch(project); - assertThatThrownBy(() -> newRequest() + var testRequest = newRequest() .setParam(PARAM_PROJECT_ID, branch.uuid()) .setParam(PARAM_GROUP_NAME, group.getName()) - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) - .execute()) + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()); + + assertThatThrownBy(testRequest::execute) .isInstanceOf(NotFoundException.class) .hasMessage("Entity not found"); } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddUserActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddUserActionIT.java index 337eb7ebc21..0094beccb07 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddUserActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/AddUserActionIT.java @@ -24,7 +24,7 @@ import org.junit.Test; import org.sonar.api.config.Configuration; import org.sonar.db.component.ComponentQualifiers; import org.sonar.server.component.ComponentTypes; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.component.ComponentDto; import org.sonar.server.component.ComponentTypesRule; import org.sonar.db.permission.GlobalPermission; @@ -191,7 +191,7 @@ public class AddUserActionIT extends BasePermissionWsIT<AddUserAction> { assertThatThrownBy(() -> { newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()) .execute(); }) .isInstanceOf(BadRequestException.class); @@ -223,30 +223,30 @@ public class AddUserActionIT extends BasePermissionWsIT<AddUserAction> { newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.SCAN) + .setParam(PARAM_PERMISSION, ProjectPermission.SCAN.getKey()) .execute(); assertThat(db.users().selectPermissionsOfUser(user)).isEmpty(); - assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).containsOnly(UserRole.SCAN); + assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).containsOnly(ProjectPermission.SCAN.getKey()); } @Test public void fail_when_project_is_managed_and_user_not_sysadmin() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); doThrow(new IllegalStateException("Managed project")).when(managedInstanceChecker).throwIfProjectIsManaged(any(), eq(project.getUuid())); TestRequest request = newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_KEY, project.getKey()) - .setParam(PARAM_PERMISSION, UserRole.CODEVIEWER); + .setParam(PARAM_PERMISSION, ProjectPermission.CODEVIEWER.getKey()); assertThatThrownBy(request::execute) .isInstanceOf(IllegalStateException.class) .hasMessage("Managed project"); - assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).doesNotContain(UserRole.CODEVIEWER); + assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).doesNotContain(ProjectPermission.CODEVIEWER.getKey()); } @Test @@ -364,26 +364,26 @@ public class AddUserActionIT extends BasePermissionWsIT<AddUserAction> { public void adding_project_permission_is_allowed_to_project_administrators() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_KEY, project.getKey()) - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()) .execute(); - assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).containsOnly(UserRole.ISSUE_ADMIN); + assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); } @Test public void no_effect_when_adding_USER_permission_on_a_public_project() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.USER) + .setParam(PARAM_PERMISSION, ProjectPermission.USER.getKey()) .execute(); assertThat(db.users().selectAnyonePermissions(project.getUuid())).isEmpty(); @@ -392,12 +392,12 @@ public class AddUserActionIT extends BasePermissionWsIT<AddUserAction> { @Test public void no_effect_when_adding_CODEVIEWER_permission_on_a_public_project() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.CODEVIEWER) + .setParam(PARAM_PERMISSION, ProjectPermission.CODEVIEWER.getKey()) .execute(); assertThat(db.users().selectAnyonePermissions(project.getUuid())).isEmpty(); @@ -406,7 +406,7 @@ public class AddUserActionIT extends BasePermissionWsIT<AddUserAction> { @Test public void fail_when_using_branch_uuid() { ComponentDto project = db.components().insertPublicProject().getMainBranchComponent(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); ComponentDto branch = db.components().insertProjectBranch(project); TestRequest request = newRequest() diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/GroupsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/GroupsActionIT.java index 60ae505a138..85eea064a88 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/GroupsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/GroupsActionIT.java @@ -25,7 +25,7 @@ import org.junit.Test; import org.sonar.api.security.DefaultGroups; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService.Action; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.permission.GlobalPermission; @@ -53,7 +53,7 @@ import static org.mockito.Mockito.when; 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.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; import static org.sonar.test.JsonAssert.assertJson; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; @@ -194,9 +194,9 @@ public class GroupsActionIT extends BasePermissionWsIT<GroupsAction> { GroupDto groupWithoutPermission = db.users().insertGroup("group-without-permission"); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); String result = newRequest() - .setParam(PARAM_PERMISSION, ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ISSUE_ADMIN.getKey()) .setParam(PARAM_PROJECT_ID, project.getUuid()) .execute() .getInput(); @@ -217,7 +217,7 @@ public class GroupsActionIT extends BasePermissionWsIT<GroupsAction> { loginAsAdmin(); String result = newRequest() - .setParam(PARAM_PERMISSION, ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ISSUE_ADMIN.getKey()) .setParam(PARAM_PROJECT_ID, project.getUuid()) .setParam(TEXT_QUERY, "group-with") .execute() @@ -238,7 +238,7 @@ public class GroupsActionIT extends BasePermissionWsIT<GroupsAction> { loginAsAdmin(); String result = newRequest() - .setParam(PARAM_PERMISSION, ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ISSUE_ADMIN.getKey()) .setParam(PARAM_PROJECT_ID, project.getUuid()) .execute() .getInput(); @@ -270,7 +270,7 @@ public class GroupsActionIT extends BasePermissionWsIT<GroupsAction> { loginAsAdmin(); String result = newRequest() - .setParam(PARAM_PERMISSION, ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ISSUE_ADMIN.getKey()) .setParam(PARAM_PROJECT_ID, "view-uuid") .execute() .getInput(); @@ -292,7 +292,7 @@ public class GroupsActionIT extends BasePermissionWsIT<GroupsAction> { loginAsAdmin(); String result = newRequest() - .setParam(PARAM_PERMISSION, ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ISSUE_ADMIN.getKey()) .setParam(PARAM_PROJECT_ID, "view-uuid") .execute() .getInput(); @@ -365,7 +365,7 @@ public class GroupsActionIT extends BasePermissionWsIT<GroupsAction> { assertThatThrownBy(() -> { newRequest() - .setParam(PARAM_PERMISSION, ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ISSUE_ADMIN.getKey()) .setParam(PARAM_PROJECT_ID, branch.uuid()) .execute(); }) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveGroupActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveGroupActionIT.java index 477d18260f8..76c708e8183 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveGroupActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveGroupActionIT.java @@ -23,24 +23,24 @@ import com.tngtech.java.junit.dataprovider.DataProviderRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService.Action; -import org.sonar.api.web.UserRole; import org.sonar.core.util.Uuids; import org.sonar.db.component.ComponentDto; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; import org.sonar.db.permission.GroupPermissionDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; +import org.sonar.server.common.management.ManagedInstanceChecker; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; import org.sonar.server.ws.TestRequest; @@ -109,54 +109,54 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { public void wsAction_shouldRemoveProjectPermission() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); db.users().insertPermissionOnGroup(aGroup, GlobalPermission.ADMINISTER); - db.users().insertEntityPermissionOnGroup(aGroup, UserRole.ADMIN, project); - db.users().insertEntityPermissionOnGroup(aGroup, UserRole.ISSUE_ADMIN, project); + db.users().insertEntityPermissionOnGroup(aGroup, ProjectPermission.ADMIN, project); + db.users().insertEntityPermissionOnGroup(aGroup, ProjectPermission.ISSUE_ADMIN, project); loginAsAdmin(); newRequest() .setParam(PARAM_GROUP_NAME, aGroup.getName()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ADMIN.getKey()) .execute(); assertThat(db.users().selectGroupPermissions(aGroup, null)).containsOnly(GlobalPermission.ADMINISTER.getKey()); - assertThat(db.users().selectGroupPermissions(aGroup, project)).containsOnly(UserRole.ISSUE_ADMIN); + assertThat(db.users().selectGroupPermissions(aGroup, project)).containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); } @Test public void wsAction_whenUsingViewUuid_shouldRemovePermission() { EntityDto portfolio = db.components().insertPrivatePortfolioDto(); db.users().insertPermissionOnGroup(aGroup, GlobalPermission.ADMINISTER); - db.users().insertEntityPermissionOnGroup(aGroup, UserRole.ADMIN, portfolio); - db.users().insertEntityPermissionOnGroup(aGroup, UserRole.ISSUE_ADMIN, portfolio); + db.users().insertEntityPermissionOnGroup(aGroup, ProjectPermission.ADMIN, portfolio); + db.users().insertEntityPermissionOnGroup(aGroup, ProjectPermission.ISSUE_ADMIN, portfolio); loginAsAdmin(); newRequest() .setParam(PARAM_GROUP_NAME, aGroup.getName()) .setParam(PARAM_PROJECT_ID, portfolio.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ADMIN.getKey()) .execute(); assertThat(db.users().selectGroupPermissions(aGroup, null)).containsOnly(GlobalPermission.ADMINISTER.getKey()); - assertThat(db.users().selectGroupPermissions(aGroup, portfolio)).containsOnly(UserRole.ISSUE_ADMIN); + assertThat(db.users().selectGroupPermissions(aGroup, portfolio)).containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); } @Test public void wsAction_whenUsingProjectKey_shouldRemovePermission() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); db.users().insertPermissionOnGroup(aGroup, GlobalPermission.ADMINISTER); - db.users().insertEntityPermissionOnGroup(aGroup, UserRole.ADMIN, project); - db.users().insertEntityPermissionOnGroup(aGroup, UserRole.ISSUE_ADMIN, project); + db.users().insertEntityPermissionOnGroup(aGroup, ProjectPermission.ADMIN, project); + db.users().insertEntityPermissionOnGroup(aGroup, ProjectPermission.ISSUE_ADMIN, project); loginAsAdmin(); newRequest() .setParam(PARAM_GROUP_NAME, aGroup.getName()) .setParam(PARAM_PROJECT_KEY, project.getKey()) - .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ADMIN.getKey()) .execute(); assertThat(db.users().selectGroupPermissions(aGroup, null)).containsOnly(GlobalPermission.ADMINISTER.getKey()); - assertThat(db.users().selectGroupPermissions(aGroup, project)).containsOnly(UserRole.ISSUE_ADMIN); + assertThat(db.users().selectGroupPermissions(aGroup, project)).containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); } @Test @@ -165,8 +165,7 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { db.users().insertPermissionOnGroup(aGroup, GlobalPermission.PROVISION_PROJECTS); loginAsAdmin(); - String administerPermission = GlobalPermission.ADMINISTER.getKey(); - assertThatThrownBy(() -> executeRequest(aGroup, administerPermission)) + assertThatThrownBy(() -> executeRequest(aGroup, GlobalPermission.ADMINISTER)) .isInstanceOf(BadRequestException.class) .hasMessage("Last group with permission 'admin'. Permission cannot be removed."); } @@ -189,7 +188,7 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { public void wsAction_whenUsingProjectPermissionWithoutProject_shouldFail() { loginAsAdmin(); - assertThatThrownBy(() -> executeRequest(aGroup, UserRole.ISSUE_ADMIN)) + assertThatThrownBy(() -> executeRequest(aGroup, ProjectPermission.ISSUE_ADMIN)) .isInstanceOf(BadRequestException.class) .hasMessage("Invalid global permission 'issueadmin'. Valid values are [admin, gateadmin, profileadmin, provisioning, scan]"); } @@ -232,7 +231,7 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { @Test public void wsAction_whenGroupAndProjectAreManaged_shouldFailAndNotRemovePermissions() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertEntityPermissionOnGroup(aGroup, UserRole.CODEVIEWER, project); + db.users().insertEntityPermissionOnGroup(aGroup, ProjectPermission.CODEVIEWER, project); doThrow(new IllegalStateException("Managed project and group")).when(managedInstanceChecker).throwIfGroupAndProjectAreManaged(any(), eq(aGroup.getUuid()), eq(project.getUuid())); @@ -245,7 +244,7 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { .isInstanceOf(IllegalStateException.class) .hasMessage("Managed project and group"); - assertThat(db.users().selectGroupPermissions(aGroup, project)).containsOnly(UserRole.CODEVIEWER); + assertThat(db.users().selectGroupPermissions(aGroup, project)).containsOnly(ProjectPermission.CODEVIEWER.getKey()); } @Test @@ -286,6 +285,14 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { .hasMessage("Project id or project key can be provided, not both."); } + private void executeRequest(GroupDto groupDto, ProjectPermission permission) { + executeRequest(groupDto, permission.getKey()); + } + + private void executeRequest(GroupDto groupDto, GlobalPermission permission) { + executeRequest(groupDto, permission.getKey()); + } + private void executeRequest(GroupDto groupDto, String permission) { newRequest() .setParam(PARAM_GROUP_NAME, groupDto.getName()) @@ -322,17 +329,17 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { @Test public void wsAction_whenRemovingProjectPermissionAsProjectAdminButNotSystemAdmin_shouldRemovePermission() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertEntityPermissionOnGroup(aGroup, UserRole.CODEVIEWER, project); - db.users().insertEntityPermissionOnGroup(aGroup, UserRole.ISSUE_ADMIN, project); + db.users().insertEntityPermissionOnGroup(aGroup, ProjectPermission.CODEVIEWER, project); + db.users().insertEntityPermissionOnGroup(aGroup, ProjectPermission.ISSUE_ADMIN, project); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); newRequest() .setParam(PARAM_GROUP_NAME, aGroup.getName()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()) .execute(); - assertThat(db.users().selectGroupPermissions(aGroup, project)).containsOnly(UserRole.CODEVIEWER); + assertThat(db.users().selectGroupPermissions(aGroup, project)).containsOnly(ProjectPermission.CODEVIEWER.getKey()); } @Test @@ -340,29 +347,29 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); permissionService.getAllProjectPermissions() .forEach(perm -> unsafeInsertProjectPermissionOnAnyone(perm, project)); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); permissionService.getAllProjectPermissions() .forEach(permission -> { newRequest() .setParam(PARAM_GROUP_NAME, "anyone") .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, permission) + .setParam(PARAM_PERMISSION, permission.getKey()) .execute(); - assertThat(db.users().selectAnyonePermissions(project.getUuid())).contains(permission); + assertThat(db.users().selectAnyonePermissions(project.getUuid())).contains(permission.getKey()); }); } @Test public void wsAction_whenRemovingBrowsePermissionFromGroupAnyoneOnPublicProject_shouldFail() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestRequest testRequest = newRequest() .setParam(PARAM_GROUP_NAME, "anyone") .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.USER); + .setParam(PARAM_PERMISSION, ProjectPermission.USER.getKey()); assertThatThrownBy(testRequest::execute) .isInstanceOf(BadRequestException.class) @@ -372,12 +379,12 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { @Test public void wsAction_whenRemovingCodeviewerPermissionFromGroupAnyoneOnPublicProject_shouldFail() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestRequest testRequest = newRequest() .setParam(PARAM_GROUP_NAME, "anyone") .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.CODEVIEWER); + .setParam(PARAM_PERMISSION, ProjectPermission.CODEVIEWER.getKey()); assertThatThrownBy(testRequest::execute) .isInstanceOf(BadRequestException.class) @@ -388,12 +395,12 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { public void wsAction_whenRemovingBrowsePermissionFromGroupOnPublicProject_shouldFail() { GroupDto group = db.users().insertGroup(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestRequest testRequest = newRequest() .setParam(PARAM_GROUP_NAME, group.getName()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.USER); + .setParam(PARAM_PERMISSION, ProjectPermission.USER.getKey()); assertThatThrownBy(testRequest::execute) .isInstanceOf(BadRequestException.class) @@ -404,12 +411,12 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { public void wsAction_whenRemovingCodeviewerPermissionFromGroupOnPublicProject() { GroupDto group = db.users().insertGroup(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestRequest testRequest = newRequest() .setParam(PARAM_GROUP_NAME, group.getName()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.CODEVIEWER); + .setParam(PARAM_PERMISSION, ProjectPermission.CODEVIEWER.getKey()); assertThatThrownBy(testRequest::execute) .isInstanceOf(BadRequestException.class) @@ -420,7 +427,7 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { public void wsAction_whenUsingBranchUuid_shouldFail() { GroupDto group = db.users().insertGroup(); ComponentDto project = db.components().insertPublicProject().getMainBranchComponent(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); ComponentDto branch = db.components().insertProjectBranch(project); TestRequest testRequest = newRequest() @@ -438,10 +445,10 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); UserDto user = db.users().insertUser(); GroupDto projectAdminGroup = db.users().insertGroup(); - db.users().insertEntityPermissionOnGroup(projectAdminGroup, UserRole.USER, project); - db.users().insertEntityPermissionOnGroup(projectAdminGroup, UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(projectAdminGroup, ProjectPermission.USER, project); + db.users().insertEntityPermissionOnGroup(projectAdminGroup, ProjectPermission.ADMIN, project); - userSession.logIn(user).setGroups(projectAdminGroup).addProjectPermission(UserRole.ADMIN, project); + userSession.logIn(user).setGroups(projectAdminGroup).addProjectPermission(ProjectPermission.ADMIN, project); assertThatThrownBy(() -> removeBrowsePermissionFromGroup(project, projectAdminGroup)) .isInstanceOf(BadRequestException.class) @@ -454,16 +461,16 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { UserDto user = db.users().insertUser(); GroupDto projectAdminGroup = db.users().insertGroup(); GroupDto otherProjectAdminGroup = db.users().insertGroup(); - db.users().insertEntityPermissionOnGroup(projectAdminGroup, UserRole.USER, project); - db.users().insertEntityPermissionOnGroup(projectAdminGroup, UserRole.ADMIN, project); - db.users().insertEntityPermissionOnGroup(otherProjectAdminGroup, UserRole.USER, project); - db.users().insertEntityPermissionOnGroup(otherProjectAdminGroup, UserRole.ADMIN, project); - userSession.logIn(user).setGroups(projectAdminGroup, otherProjectAdminGroup).addProjectPermission(UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(projectAdminGroup, ProjectPermission.USER, project); + db.users().insertEntityPermissionOnGroup(projectAdminGroup, ProjectPermission.ADMIN, project); + db.users().insertEntityPermissionOnGroup(otherProjectAdminGroup, ProjectPermission.USER, project); + db.users().insertEntityPermissionOnGroup(otherProjectAdminGroup, ProjectPermission.ADMIN, project); + userSession.logIn(user).setGroups(projectAdminGroup, otherProjectAdminGroup).addProjectPermission(ProjectPermission.ADMIN, project); removeBrowsePermissionFromGroup(project, projectAdminGroup); - assertThat(db.users().selectGroupPermissions(projectAdminGroup, project)).containsOnly(UserRole.ADMIN); - assertThat(db.users().selectGroupPermissions(otherProjectAdminGroup, project)).containsExactlyInAnyOrder(UserRole.USER, UserRole.ADMIN); + assertThat(db.users().selectGroupPermissions(projectAdminGroup, project)).containsOnly(ProjectPermission.ADMIN.getKey()); + assertThat(db.users().selectGroupPermissions(otherProjectAdminGroup, project)).containsExactlyInAnyOrder(ProjectPermission.USER.getKey(), ProjectPermission.ADMIN.getKey()); } @Test @@ -472,29 +479,29 @@ public class RemoveGroupActionIT extends BasePermissionWsIT<RemoveGroupAction> { UserDto user = db.users().insertUser(); GroupDto projectAdminGroup = db.users().insertGroup(); db.users().insertMember(projectAdminGroup, user); - db.users().insertEntityPermissionOnGroup(projectAdminGroup, UserRole.USER, project); - db.users().insertEntityPermissionOnGroup(projectAdminGroup, UserRole.ADMIN, project); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project); - userSession.logIn(user).addProjectPermission(UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(projectAdminGroup, ProjectPermission.USER, project); + db.users().insertEntityPermissionOnGroup(projectAdminGroup, ProjectPermission.ADMIN, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project); + userSession.logIn(user).addProjectPermission(ProjectPermission.ADMIN, project); removeBrowsePermissionFromGroup(project, projectAdminGroup); - assertThat(db.users().selectGroupPermissions(projectAdminGroup, project)).containsOnly(UserRole.ADMIN); + assertThat(db.users().selectGroupPermissions(projectAdminGroup, project)).containsOnly(ProjectPermission.ADMIN.getKey()); } private void removeBrowsePermissionFromGroup(ProjectDto project, GroupDto projectAdminGroup) { newRequest() .setParam(PARAM_PROJECT_ID, project.getUuid()) .setParam(PARAM_GROUP_NAME, projectAdminGroup.getName()) - .setParam(PARAM_PERMISSION, UserRole.USER) + .setParam(PARAM_PERMISSION, ProjectPermission.USER.getKey()) .execute(); } - private void unsafeInsertProjectPermissionOnAnyone(String perm, ProjectDto project) { + private void unsafeInsertProjectPermissionOnAnyone(ProjectPermission perm, ProjectDto project) { GroupPermissionDto dto = new GroupPermissionDto() .setUuid(Uuids.createFast()) .setGroupUuid(null) - .setRole(perm) + .setRole(perm.getKey()) .setEntityUuid(project.getUuid()) .setEntityName(project.getName()); db.getDbClient().groupPermissionDao().insert(db.getSession(), dto, project, null); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveUserActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveUserActionIT.java index 35f8c85ed32..75875875daa 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveUserActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/RemoveUserActionIT.java @@ -21,10 +21,10 @@ package org.sonar.server.permission.ws; import org.junit.Before; import org.junit.Test; -import org.sonar.api.web.UserRole; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; @@ -143,9 +143,9 @@ public class RemoveUserActionIT extends BasePermissionWsIT<RemoveUserAction> { GroupDto projectAdmins = createGroupAndAddUser(admin, userSessionRule); ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(admin, UserRole.USER, project); - db.users().insertEntityPermissionOnGroup(projectAdmins, UserRole.USER, project); - userSessionRule.addProjectPermission(UserRole.ADMIN, project); + db.users().insertProjectPermissionOnUser(admin, ProjectPermission.USER, project); + db.users().insertEntityPermissionOnGroup(projectAdmins, ProjectPermission.USER, project); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project); TestRequest request = removeBrowseRight(project); @@ -178,7 +178,7 @@ public class RemoveUserActionIT extends BasePermissionWsIT<RemoveUserAction> { return newRequest() .setParam(PARAM_USER_LOGIN, userSession.getLogin()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.USER); + .setParam(PARAM_PERMISSION, ProjectPermission.USER.getKey()); } @Test @@ -188,7 +188,7 @@ public class RemoveUserActionIT extends BasePermissionWsIT<RemoveUserAction> { TestRequest testRequest = newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) - .setParam(PARAM_PERMISSION, UserRole.ADMIN); + .setParam(PARAM_PERMISSION, ProjectPermission.ADMIN.getKey()); assertThatThrownBy(testRequest::execute) .isInstanceOf(BadRequestException.class) @@ -198,49 +198,49 @@ public class RemoveUserActionIT extends BasePermissionWsIT<RemoveUserAction> { @Test public void wsAction_whenProject_shouldRemovePermission() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, project); - db.users().insertProjectPermissionOnUser(user, UserRole.ISSUE_ADMIN, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ISSUE_ADMIN, project); loginAsAdmin(); newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.CODEVIEWER) + .setParam(PARAM_PERMISSION, ProjectPermission.CODEVIEWER.getKey()) .execute(); - assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).containsOnly(UserRole.ISSUE_ADMIN); + assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); } @Test public void wsAction_whenUsingProjectKey_shouldRemovePermission() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(user, UserRole.ISSUE_ADMIN, project); - db.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ISSUE_ADMIN, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, project); loginAsAdmin(); newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_KEY, project.getKey()) - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()) .execute(); - assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).containsOnly(UserRole.CODEVIEWER); + assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).containsOnly(ProjectPermission.CODEVIEWER.getKey()); } @Test public void wsAction_whenUsingViewUuid_shouldRemovePermission() { ComponentDto view = db.components().insertPrivatePortfolio(); - db.users().insertProjectPermissionOnUser(user, UserRole.ISSUE_ADMIN, view); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, view); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ISSUE_ADMIN, view); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, view); loginAsAdmin(); newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_KEY, view.getKey()) - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()) .execute(); - assertThat(db.users().selectEntityPermissionOfUser(user, view.uuid())).containsOnly(UserRole.ADMIN); + assertThat(db.users().selectEntityPermissionOfUser(user, view.uuid())).containsOnly(ProjectPermission.ADMIN.getKey()); } @Test @@ -250,7 +250,7 @@ public class RemoveUserActionIT extends BasePermissionWsIT<RemoveUserAction> { TestRequest testRequest = newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_ID, "unknown-project-uuid") - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN); + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()); assertThatThrownBy(testRequest::execute) .isInstanceOf(NotFoundException.class); @@ -262,7 +262,7 @@ public class RemoveUserActionIT extends BasePermissionWsIT<RemoveUserAction> { TestRequest testRequest = newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN); + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()); assertThatThrownBy(testRequest::execute) .isInstanceOf(BadRequestException.class); @@ -308,7 +308,7 @@ public class RemoveUserActionIT extends BasePermissionWsIT<RemoveUserAction> { @Test public void wsAction_whenProjectAndUserAreManaged_shouldThrowAndNotRemovePermissions() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, project); doThrow(new IllegalStateException("Managed project")).when(managedInstanceChecker).throwIfUserAndProjectAreManaged(any(), eq(user.getUuid()), eq(project.getUuid())); @@ -316,13 +316,13 @@ public class RemoveUserActionIT extends BasePermissionWsIT<RemoveUserAction> { TestRequest request = newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.CODEVIEWER); + .setParam(PARAM_PERMISSION, ProjectPermission.CODEVIEWER.getKey()); assertThatThrownBy(request::execute) .isInstanceOf(IllegalStateException.class) .hasMessage("Managed project"); - assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).containsOnly(UserRole.CODEVIEWER); + assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).containsOnly(ProjectPermission.CODEVIEWER.getKey()); } @Test @@ -393,7 +393,7 @@ public class RemoveUserActionIT extends BasePermissionWsIT<RemoveUserAction> { TestRequest testRequest = newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()) .setParam(PARAM_PROJECT_KEY, project.getKey()); assertThatThrownBy(testRequest::execute) @@ -406,28 +406,28 @@ public class RemoveUserActionIT extends BasePermissionWsIT<RemoveUserAction> { @Test public void wsAction_whenProjectPermissionAndProjectAdmin_shouldRemovePermission() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, project); - db.users().insertProjectPermissionOnUser(user, UserRole.ISSUE_ADMIN, project); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ISSUE_ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()) .execute(); - assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).containsOnly(UserRole.CODEVIEWER); + assertThat(db.users().selectEntityPermissionOfUser(user, project.getUuid())).containsOnly(ProjectPermission.CODEVIEWER.getKey()); } @Test public void wsAction_whenBrowsePermissionAndPublicProject_shouldFail() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestRequest testRequest = newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.USER); + .setParam(PARAM_PERMISSION, ProjectPermission.USER.getKey()); assertThatThrownBy(testRequest::execute) .isInstanceOf(BadRequestException.class) @@ -438,12 +438,12 @@ public class RemoveUserActionIT extends BasePermissionWsIT<RemoveUserAction> { @Test public void wsAction_whenCodeviewerPermissionAndPublicProject_shouldFail() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestRequest testRequest = newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_ID, project.getUuid()) - .setParam(PARAM_PERMISSION, UserRole.CODEVIEWER); + .setParam(PARAM_PERMISSION, ProjectPermission.CODEVIEWER.getKey()); assertThatThrownBy(testRequest::execute) .isInstanceOf(BadRequestException.class) @@ -453,7 +453,7 @@ public class RemoveUserActionIT extends BasePermissionWsIT<RemoveUserAction> { @Test public void wsAction_whenUsingBranchUuid_shouldFail() { ComponentDto project = db.components().insertPublicProject().getMainBranchComponent(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); ComponentDto branch = db.components().insertProjectBranch(project); TestRequest testRequest = newRequest() diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/UsersActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/UsersActionIT.java index 7f17f9e45b4..38ff869f905 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/UsersActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/UsersActionIT.java @@ -23,7 +23,7 @@ import java.util.Set; import org.junit.Test; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.server.ws.WebService.SelectionMode; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.component.BranchDto; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentQualifiers; @@ -106,19 +106,19 @@ public class UsersActionIT extends BasePermissionWsIT<UsersAction> { // User has permission on project ProjectDto project = db.components().insertPrivateProject().getProjectDto(); UserDto user = db.users().insertUser(newUserDto()); - db.users().insertProjectPermissionOnUser(user, UserRole.ISSUE_ADMIN, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ISSUE_ADMIN, project); // User has permission on another project ProjectDto anotherProject = db.components().insertPrivateProject().getProjectDto(); UserDto userHavePermissionOnAnotherProject = db.users().insertUser(newUserDto()); - db.users().insertProjectPermissionOnUser(userHavePermissionOnAnotherProject, UserRole.ISSUE_ADMIN, anotherProject); + db.users().insertProjectPermissionOnUser(userHavePermissionOnAnotherProject, ProjectPermission.ISSUE_ADMIN, anotherProject); // User has no permission UserDto withoutPermission = db.users().insertUser(newUserDto()); - userSession.logIn().addProjectPermission(GlobalPermission.ADMINISTER.getKey(), project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); String result = newRequest() - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()) .setParam(PARAM_PROJECT_ID, project.getUuid()) .execute() .getInput(); @@ -133,7 +133,7 @@ public class UsersActionIT extends BasePermissionWsIT<UsersAction> { // User with permission on project ProjectDto project = db.components().insertPrivateProject().getProjectDto(); UserDto user = db.users().insertUser(newUserDto("with-permission-login", "with-permission-name", "with-permission-email")); - db.users().insertProjectPermissionOnUser(user, UserRole.ISSUE_ADMIN, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ISSUE_ADMIN, project); // User without permission UserDto withoutPermission = db.users().insertUser(newUserDto("without-permission-login", "without-permission-name", "without-permission-email")); @@ -154,7 +154,7 @@ public class UsersActionIT extends BasePermissionWsIT<UsersAction> { // User with permission on project ProjectDto project = db.components().insertPrivateProject().getProjectDto(); UserDto user = db.users().insertUser(newUserDto("with-permission-login", "with-permission-name", "with-permission-email")); - db.users().insertProjectPermissionOnUser(user, UserRole.ISSUE_ADMIN, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ISSUE_ADMIN, project); // User without permission UserDto withoutPermission = db.users().insertUser(newUserDto("without-permission-login", "without-permission-name", "without-permission-email")); @@ -171,7 +171,7 @@ public class UsersActionIT extends BasePermissionWsIT<UsersAction> { // User with permission on project ProjectDto project = db.components().insertPrivateProject().getProjectDto(); UserDto user = db.users().insertUser(newUserDto("with-permission-login", "with-permission-name", "with-permission-email")); - db.users().insertProjectPermissionOnUser(user, UserRole.ISSUE_ADMIN, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ISSUE_ADMIN, project); // User without permission UserDto withoutPermission = db.users().insertUser(newUserDto("without-permission-login", "without-permission-name", "without-permission-email")); @@ -277,7 +277,7 @@ public class UsersActionIT extends BasePermissionWsIT<UsersAction> { assertThatThrownBy(() -> { newRequest() - .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ISSUE_ADMIN.getKey()) .setParam(Param.SELECTED, SelectionMode.ALL.value()) .execute(); }) @@ -336,8 +336,8 @@ public class UsersActionIT extends BasePermissionWsIT<UsersAction> { UserDto user = db.users().insertUser(newUserDto()); ProjectData project = db.components().insertPublicProject(); BranchDto branch = db.components().insertProjectBranch(project.getProjectDto()); - db.users().insertProjectPermissionOnUser(user, UserRole.ISSUE_ADMIN, project.getProjectDto()); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ISSUE_ADMIN, project.getProjectDto()); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); assertThatThrownBy(() -> { newRequest() diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/AddGroupToTemplateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/AddGroupToTemplateActionIT.java index 08907248d1a..544b77e44f2 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/AddGroupToTemplateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/AddGroupToTemplateActionIT.java @@ -23,15 +23,15 @@ import java.util.List; import javax.annotation.Nullable; import org.junit.Before; import org.junit.Test; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService.Action; -import org.sonar.api.web.UserRole; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.user.GroupDto; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; @@ -45,10 +45,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.tuple; import static org.sonar.api.security.DefaultGroups.ANYONE; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID; @@ -100,7 +100,7 @@ public class AddGroupToTemplateActionIT extends BasePermissionWsIT<AddGroupToTem newRequest() .setParam(PARAM_GROUP_NAME, group.getName()) - .setParam(PARAM_PERMISSION, CODEVIEWER) + .setParam(PARAM_PERMISSION, CODEVIEWER.getKey()) .setParam(PARAM_TEMPLATE_NAME, template.getName().toUpperCase()) .execute(); @@ -132,7 +132,7 @@ public class AddGroupToTemplateActionIT extends BasePermissionWsIT<AddGroupToTem assertThatThrownBy(() -> newRequest(ANYONE, template.getUuid(), ADMIN)) .isInstanceOf(BadRequestException.class) - .hasMessage(String.format("It is not possible to add the '%s' permission to the group 'Anyone'.", UserRole.ADMIN)); + .hasMessage(String.format("It is not possible to add the '%s' permission to the group 'Anyone'.", ProjectPermission.ADMIN)); } @Test @@ -163,7 +163,7 @@ public class AddGroupToTemplateActionIT extends BasePermissionWsIT<AddGroupToTem public void fail_if_permission_missing() { loginAsAdmin(); - assertThatThrownBy(() -> newRequest(group.getName(), template.getUuid(), null)) + assertThatThrownBy(() -> newRequest(group.getName(), template.getUuid(), (String) null)) .isInstanceOf(IllegalArgumentException.class); } @@ -193,6 +193,10 @@ public class AddGroupToTemplateActionIT extends BasePermissionWsIT<AddGroupToTem .hasMessage("Permission template with id 'unknown-key' is not found"); } + private void newRequest(@Nullable String groupName, @Nullable String templateKey, ProjectPermission permission) { + newRequest(groupName, templateKey, permission.getKey()); + } + private void newRequest(@Nullable String groupName, @Nullable String templateKey, @Nullable String permission) { TestRequest request = newRequest(); if (groupName != null) { @@ -208,7 +212,7 @@ public class AddGroupToTemplateActionIT extends BasePermissionWsIT<AddGroupToTem request.execute(); } - private List<String> getGroupNamesInTemplateAndPermission(PermissionTemplateDto template, String permission) { + private List<String> getGroupNamesInTemplateAndPermission(PermissionTemplateDto template, ProjectPermission permission) { PermissionQuery query = PermissionQuery.builder().setPermission(permission).build(); return db.getDbClient().permissionTemplateDao() .selectGroupNamesByQueryAndTemplate(db.getSession(), query, template.getUuid()); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateActionIT.java index a7acb89ca58..9ce4d0b92e3 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateActionIT.java @@ -22,14 +22,14 @@ package org.sonar.server.permission.ws.template; import java.util.Optional; import org.junit.Before; import org.junit.Test; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentTypes; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.util.Uuids; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.component.ComponentQualifiers; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; import org.sonar.db.permission.template.PermissionTemplateDto; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.permission.PermissionService; @@ -72,11 +72,11 @@ public class AddProjectCreatorToTemplateActionIT extends BasePermissionWsIT<AddP loginAsAdmin(); newRequest() - .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ADMIN.getKey()) .setParam(PARAM_TEMPLATE_ID, template.getUuid()) .execute(); - assertThatProjectCreatorIsPresentFor(UserRole.ADMIN, template.getUuid()); + assertThatProjectCreatorIsPresentFor(ProjectPermission.ADMIN, template.getUuid()); } @Test @@ -86,7 +86,7 @@ public class AddProjectCreatorToTemplateActionIT extends BasePermissionWsIT<AddP new PermissionTemplateCharacteristicDto() .setUuid(Uuids.createFast()) .setTemplateUuid(template.getUuid()) - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setWithProjectCreator(false) .setCreatedAt(1_000_000_000L) .setUpdatedAt(1_000_000_000L), @@ -95,11 +95,11 @@ public class AddProjectCreatorToTemplateActionIT extends BasePermissionWsIT<AddP when(system.now()).thenReturn(3_000_000_000L); newRequest() - .setParam(PARAM_PERMISSION, UserRole.USER) + .setParam(PARAM_PERMISSION, ProjectPermission.USER.getKey()) .setParam(PARAM_TEMPLATE_NAME, template.getName()) .execute(); - assertThatProjectCreatorIsPresentFor(UserRole.USER, template.getUuid()); + assertThatProjectCreatorIsPresentFor(ProjectPermission.USER, template.getUuid()); PermissionTemplateCharacteristicDto reloaded = reload(characteristic); assertThat(reloaded.getCreatedAt()).isEqualTo(1_000_000_000L); assertThat(reloaded.getUpdatedAt()).isEqualTo(3_000_000_000L); @@ -111,7 +111,7 @@ public class AddProjectCreatorToTemplateActionIT extends BasePermissionWsIT<AddP assertThatThrownBy(() -> { newRequest() - .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ADMIN.getKey()) .setParam(PARAM_TEMPLATE_ID, "42") .execute(); }) @@ -137,14 +137,14 @@ public class AddProjectCreatorToTemplateActionIT extends BasePermissionWsIT<AddP assertThatThrownBy(() -> { newRequest() - .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ADMIN.getKey()) .setParam(PARAM_TEMPLATE_ID, template.getUuid()) .execute(); }) .isInstanceOf(ForbiddenException.class); } - private void assertThatProjectCreatorIsPresentFor(String permission, String templateUuid) { + private void assertThatProjectCreatorIsPresentFor(ProjectPermission permission, String templateUuid) { Optional<PermissionTemplateCharacteristicDto> templatePermission = db.getDbClient().permissionTemplateCharacteristicDao().selectByPermissionAndTemplateId(db.getSession(), permission, templateUuid); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/AddUserToTemplateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/AddUserToTemplateActionIT.java index 1bd85e4ecf4..d00548bf023 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/AddUserToTemplateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/AddUserToTemplateActionIT.java @@ -24,11 +24,13 @@ import javax.annotation.Nullable; import org.junit.Before; import org.junit.Test; import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentTypes; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.permission.GlobalPermission; import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.user.UserDto; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; @@ -40,10 +42,10 @@ import org.sonar.server.ws.TestRequest; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_PROFILES; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME; @@ -83,7 +85,7 @@ public class AddUserToTemplateActionIT extends BasePermissionWsIT<AddUserToTempl newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) - .setParam(PARAM_PERMISSION, CODEVIEWER) + .setParam(PARAM_PERMISSION, CODEVIEWER.getKey()) .setParam(PARAM_TEMPLATE_NAME, permissionTemplate.getName().toUpperCase()) .execute(); @@ -105,7 +107,7 @@ public class AddUserToTemplateActionIT extends BasePermissionWsIT<AddUserToTempl loginAsAdmin(); assertThatThrownBy(() -> { - newRequest(user.getLogin(), permissionTemplate.getUuid(), PROVISION_PROJECTS.getKey()); + newRequest(user.getLogin(), permissionTemplate.getUuid(), PROVISION_PROJECTS); }) .isInstanceOf(IllegalArgumentException.class); } @@ -135,7 +137,7 @@ public class AddUserToTemplateActionIT extends BasePermissionWsIT<AddUserToTempl loginAsAdmin(); assertThatThrownBy(() -> { - newRequest(user.getLogin(), permissionTemplate.getUuid(), null); + newRequest(user.getLogin(), permissionTemplate.getUuid(), (String) null); }) .isInstanceOf(IllegalArgumentException.class); } @@ -171,6 +173,14 @@ public class AddUserToTemplateActionIT extends BasePermissionWsIT<AddUserToTempl .hasMessage("Permission template with id 'unknown-key' is not found"); } + private void newRequest(@Nullable String userLogin, @Nullable String templateKey, @Nullable ProjectPermission permission) { + newRequest(userLogin, templateKey, permission != null ? permission.getKey() : null); + } + + private void newRequest(@Nullable String userLogin, @Nullable String templateKey, @Nullable GlobalPermission permission) { + newRequest(userLogin, templateKey, permission != null ? permission.getKey() : null); + } + private void newRequest(@Nullable String userLogin, @Nullable String templateKey, @Nullable String permission) { TestRequest request = newRequest(); if (userLogin != null) { @@ -186,7 +196,7 @@ public class AddUserToTemplateActionIT extends BasePermissionWsIT<AddUserToTempl request.execute(); } - private List<String> getLoginsInTemplateAndPermission(PermissionTemplateDto template, String permission) { + private List<String> getLoginsInTemplateAndPermission(PermissionTemplateDto template, ProjectPermission permission) { PermissionQuery permissionQuery = PermissionQuery.builder().setPermission(permission).build(); return db.getDbClient().permissionTemplateDao() .selectUserLoginsByQueryAndTemplate(db.getSession(), permissionQuery, template.getUuid()); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/ApplyTemplateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/ApplyTemplateActionIT.java index 8b07cbb4c04..1dc6258f976 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/ApplyTemplateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/ApplyTemplateActionIT.java @@ -24,25 +24,25 @@ import javax.annotation.Nullable; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.sonar.api.web.UserRole; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.db.DbTester; -import org.sonar.server.component.ComponentTypesRule; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; +import org.sonar.server.common.management.ManagedInstanceChecker; +import org.sonar.server.common.permission.DefaultTemplatesResolver; +import org.sonar.server.common.permission.DefaultTemplatesResolverImpl; +import org.sonar.server.common.permission.PermissionTemplateService; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.es.TestIndexers; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.common.management.ManagedInstanceChecker; import org.sonar.server.management.ManagedProjectService; -import org.sonar.server.common.permission.DefaultTemplatesResolver; -import org.sonar.server.common.permission.DefaultTemplatesResolverImpl; -import org.sonar.server.common.permission.PermissionTemplateService; import org.sonar.server.permission.ws.BasePermissionWsIT; import org.sonar.server.ws.TestRequest; @@ -95,22 +95,22 @@ public class ApplyTemplateActionIT extends BasePermissionWsIT<ApplyTemplateActio // template 1 template1 = db.permissionTemplates().insertTemplate(); - addUserToTemplate(user1, template1, UserRole.CODEVIEWER); - addUserToTemplate(user2, template1, UserRole.ISSUE_ADMIN); - addGroupToTemplate(group1, template1, UserRole.ADMIN); - addGroupToTemplate(group2, template1, UserRole.USER); + addUserToTemplate(user1, template1, ProjectPermission.CODEVIEWER); + addUserToTemplate(user2, template1, ProjectPermission.ISSUE_ADMIN); + addGroupToTemplate(group1, template1, ProjectPermission.ADMIN); + addGroupToTemplate(group2, template1, ProjectPermission.USER); // template 2 PermissionTemplateDto template2 = db.permissionTemplates().insertTemplate(); - addUserToTemplate(user1, template2, UserRole.USER); - addUserToTemplate(user2, template2, UserRole.USER); - addGroupToTemplate(group1, template2, UserRole.USER); - addGroupToTemplate(group2, template2, UserRole.USER); + addUserToTemplate(user1, template2, ProjectPermission.USER); + addUserToTemplate(user2, template2, ProjectPermission.USER); + addGroupToTemplate(group1, template2, ProjectPermission.USER); + addGroupToTemplate(group2, template2, ProjectPermission.USER); project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(user1, UserRole.ADMIN, project); - db.users().insertProjectPermissionOnUser(user2, UserRole.ADMIN, project); - db.users().insertEntityPermissionOnGroup(group1, UserRole.ADMIN, project); - db.users().insertEntityPermissionOnGroup(group2, UserRole.ADMIN, project); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.ADMIN, project); + db.users().insertProjectPermissionOnUser(user2, ProjectPermission.ADMIN, project); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.ADMIN, project); + db.users().insertEntityPermissionOnGroup(group2, ProjectPermission.ADMIN, project); } @Test @@ -217,11 +217,11 @@ public class ApplyTemplateActionIT extends BasePermissionWsIT<ApplyTemplateActio } private void assertTemplate1AppliedToProject() { - assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).containsExactly(group1.getName()); - assertThat(selectProjectPermissionGroups(project, UserRole.USER)).containsExactly(group2.getName()); - assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).isEmpty(); - assertThat(selectProjectPermissionUsers(project, UserRole.CODEVIEWER)).containsExactly(user1.getUuid()); - assertThat(selectProjectPermissionUsers(project, UserRole.ISSUE_ADMIN)).containsExactly(user2.getUuid()); + assertThat(selectProjectPermissionGroups(project, ProjectPermission.ADMIN)).containsExactly(group1.getName()); + assertThat(selectProjectPermissionGroups(project, ProjectPermission.USER)).containsExactly(group2.getName()); + assertThat(selectProjectPermissionUsers(project, ProjectPermission.ADMIN)).isEmpty(); + assertThat(selectProjectPermissionUsers(project, ProjectPermission.CODEVIEWER)).containsExactly(user1.getUuid()); + assertThat(selectProjectPermissionUsers(project, ProjectPermission.ISSUE_ADMIN)).containsExactly(user2.getUuid()); } private void newRequest(@Nullable String templateUuid, @Nullable String projectUuid, @Nullable String projectKey) { @@ -238,24 +238,24 @@ public class ApplyTemplateActionIT extends BasePermissionWsIT<ApplyTemplateActio request.execute(); } - private void addUserToTemplate(UserDto user, PermissionTemplateDto permissionTemplate, String permission) { + private void addUserToTemplate(UserDto user, PermissionTemplateDto permissionTemplate, ProjectPermission permission) { db.getDbClient().permissionTemplateDao().insertUserPermission(db.getSession(), permissionTemplate.getUuid(), user.getUuid(), permission, permissionTemplate.getName(), user.getLogin()); db.commit(); } - private void addGroupToTemplate(GroupDto group, PermissionTemplateDto permissionTemplate, String permission) { + private void addGroupToTemplate(GroupDto group, PermissionTemplateDto permissionTemplate, ProjectPermission permission) { db.getDbClient().permissionTemplateDao().insertGroupPermission(db.getSession(), permissionTemplate.getUuid(), group.getUuid(), permission, permissionTemplate.getName(), group.getName()); db.commit(); } - private List<String> selectProjectPermissionGroups(EntityDto entity, String permission) { + private List<String> selectProjectPermissionGroups(EntityDto entity, ProjectPermission permission) { PermissionQuery query = PermissionQuery.builder().setPermission(permission).setEntity(entity).build(); return db.getDbClient().groupPermissionDao().selectGroupNamesByQuery(db.getSession(), query); } - private List<String> selectProjectPermissionUsers(EntityDto entity, String permission) { + private List<String> selectProjectPermissionUsers(EntityDto entity, ProjectPermission permission) { PermissionQuery query = PermissionQuery.builder().setPermission(permission).setEntity(entity).build(); return db.getDbClient().userPermissionDao().selectUserUuidsByQuery(db.getSession(), query); } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/BulkApplyTemplateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/BulkApplyTemplateActionIT.java index dedc507cc63..e9bdddc83ef 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/BulkApplyTemplateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/BulkApplyTemplateActionIT.java @@ -25,7 +25,6 @@ import org.apache.commons.lang3.StringUtils; import org.junit.Before; import org.junit.Test; import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.web.UserRole; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentQualifiers; @@ -33,6 +32,7 @@ import org.sonar.db.component.ComponentTesting; import org.sonar.db.component.ProjectData; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.portfolio.PortfolioDto; import org.sonar.db.project.ProjectDto; @@ -99,16 +99,16 @@ public class BulkApplyTemplateActionIT extends BasePermissionWsIT<BulkApplyTempl // template 1 for org 1 template1 = db.permissionTemplates().insertTemplate(); - addUserToTemplate(user1, template1, UserRole.CODEVIEWER); - addUserToTemplate(user2, template1, UserRole.ISSUE_ADMIN); - addGroupToTemplate(group1, template1, UserRole.ADMIN); - addGroupToTemplate(group2, template1, UserRole.USER); + addUserToTemplate(user1, template1, ProjectPermission.CODEVIEWER); + addUserToTemplate(user2, template1, ProjectPermission.ISSUE_ADMIN); + addGroupToTemplate(group1, template1, ProjectPermission.ADMIN); + addGroupToTemplate(group2, template1, ProjectPermission.USER); // template 2 PermissionTemplateDto template2 = db.permissionTemplates().insertTemplate(); - addUserToTemplate(user1, template2, UserRole.USER); - addUserToTemplate(user2, template2, UserRole.USER); - addGroupToTemplate(group1, template2, UserRole.USER); - addGroupToTemplate(group2, template2, UserRole.USER); + addUserToTemplate(user1, template2, ProjectPermission.USER); + addUserToTemplate(user2, template2, ProjectPermission.USER); + addGroupToTemplate(group1, template2, ProjectPermission.USER); + addGroupToTemplate(group2, template2, ProjectPermission.USER); } @Test @@ -334,50 +334,50 @@ public class BulkApplyTemplateActionIT extends BasePermissionWsIT<BulkApplyTempl } private void assertTemplate1AppliedToPublicProject(ProjectDto project) { - assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).containsExactly(group1.getName()); - assertThat(selectProjectPermissionGroups(project, UserRole.USER)).isEmpty(); - assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).isEmpty(); - assertThat(selectProjectPermissionUsers(project, UserRole.CODEVIEWER)).isEmpty(); - assertThat(selectProjectPermissionUsers(project, UserRole.ISSUE_ADMIN)).containsExactly(user2.getUuid()); + assertThat(selectProjectPermissionGroups(project, ProjectPermission.ADMIN)).containsExactly(group1.getName()); + assertThat(selectProjectPermissionGroups(project, ProjectPermission.USER)).isEmpty(); + assertThat(selectProjectPermissionUsers(project, ProjectPermission.ADMIN)).isEmpty(); + assertThat(selectProjectPermissionUsers(project, ProjectPermission.CODEVIEWER)).isEmpty(); + assertThat(selectProjectPermissionUsers(project, ProjectPermission.ISSUE_ADMIN)).containsExactly(user2.getUuid()); } private void assertTemplate1AppliedToPrivateProject(ProjectDto project) { - assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).containsExactly(group1.getName()); - assertThat(selectProjectPermissionGroups(project, UserRole.USER)).containsExactly(group2.getName()); - assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).isEmpty(); - assertThat(selectProjectPermissionUsers(project, UserRole.CODEVIEWER)).containsExactly(user1.getUuid()); - assertThat(selectProjectPermissionUsers(project, UserRole.ISSUE_ADMIN)).containsExactly(user2.getUuid()); + assertThat(selectProjectPermissionGroups(project, ProjectPermission.ADMIN)).containsExactly(group1.getName()); + assertThat(selectProjectPermissionGroups(project, ProjectPermission.USER)).containsExactly(group2.getName()); + assertThat(selectProjectPermissionUsers(project, ProjectPermission.ADMIN)).isEmpty(); + assertThat(selectProjectPermissionUsers(project, ProjectPermission.CODEVIEWER)).containsExactly(user1.getUuid()); + assertThat(selectProjectPermissionUsers(project, ProjectPermission.ISSUE_ADMIN)).containsExactly(user2.getUuid()); } private void assertNoPermissionOnEntity(EntityDto entity) { - assertThat(selectProjectPermissionGroups(entity, UserRole.ADMIN)).isEmpty(); - assertThat(selectProjectPermissionGroups(entity, UserRole.CODEVIEWER)).isEmpty(); - assertThat(selectProjectPermissionGroups(entity, UserRole.ISSUE_ADMIN)).isEmpty(); - assertThat(selectProjectPermissionGroups(entity, UserRole.USER)).isEmpty(); - assertThat(selectProjectPermissionUsers(entity, UserRole.ADMIN)).isEmpty(); - assertThat(selectProjectPermissionUsers(entity, UserRole.CODEVIEWER)).isEmpty(); - assertThat(selectProjectPermissionUsers(entity, UserRole.ISSUE_ADMIN)).isEmpty(); - assertThat(selectProjectPermissionUsers(entity, UserRole.USER)).isEmpty(); + assertThat(selectProjectPermissionGroups(entity, ProjectPermission.ADMIN)).isEmpty(); + assertThat(selectProjectPermissionGroups(entity, ProjectPermission.CODEVIEWER)).isEmpty(); + assertThat(selectProjectPermissionGroups(entity, ProjectPermission.ISSUE_ADMIN)).isEmpty(); + assertThat(selectProjectPermissionGroups(entity, ProjectPermission.USER)).isEmpty(); + assertThat(selectProjectPermissionUsers(entity, ProjectPermission.ADMIN)).isEmpty(); + assertThat(selectProjectPermissionUsers(entity, ProjectPermission.CODEVIEWER)).isEmpty(); + assertThat(selectProjectPermissionUsers(entity, ProjectPermission.ISSUE_ADMIN)).isEmpty(); + assertThat(selectProjectPermissionUsers(entity, ProjectPermission.USER)).isEmpty(); } - private void addUserToTemplate(UserDto user, PermissionTemplateDto permissionTemplate, String permission) { + private void addUserToTemplate(UserDto user, PermissionTemplateDto permissionTemplate, ProjectPermission permission) { db.getDbClient().permissionTemplateDao().insertUserPermission(db.getSession(), permissionTemplate.getUuid(), user.getUuid(), permission, permissionTemplate.getName(), user.getLogin()); db.commit(); } - private void addGroupToTemplate(GroupDto group, PermissionTemplateDto permissionTemplate, String permission) { + private void addGroupToTemplate(GroupDto group, PermissionTemplateDto permissionTemplate, ProjectPermission permission) { db.getDbClient().permissionTemplateDao().insertGroupPermission(db.getSession(), permissionTemplate.getUuid(), group.getUuid(), permission, permissionTemplate.getName(), group.getName()); db.commit(); } - private List<String> selectProjectPermissionGroups(EntityDto project, String permission) { + private List<String> selectProjectPermissionGroups(EntityDto project, ProjectPermission permission) { PermissionQuery query = PermissionQuery.builder().setPermission(permission).setEntity(project).build(); return db.getDbClient().groupPermissionDao().selectGroupNamesByQuery(db.getSession(), query); } - private List<String> selectProjectPermissionUsers(EntityDto project, String permission) { + private List<String> selectProjectPermissionUsers(EntityDto project, ProjectPermission permission) { PermissionQuery query = PermissionQuery.builder().setPermission(permission).setEntity(project).build(); return db.getDbClient().userPermissionDao().selectUserUuidsByQuery(db.getSession(), query); } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/DeleteTemplateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/DeleteTemplateActionIT.java index 1622446d1f0..635aa5188e6 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/DeleteTemplateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/DeleteTemplateActionIT.java @@ -25,7 +25,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.config.Configuration; import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.server.component.ComponentTypesRule; @@ -217,9 +217,9 @@ public class DeleteTemplateActionIT { PermissionTemplateDto dto = db.permissionTemplates().insertTemplate(); UserDto user = db.getDbClient().userDao().insert(db.getSession(), UserTesting.newUserDto().setActive(true)); GroupDto group = db.getDbClient().groupDao().insert(db.getSession(), GroupTesting.newGroupDto()); - db.getDbClient().permissionTemplateDao().insertUserPermission(db.getSession(), dto.getUuid(), user.getUuid(), UserRole.ADMIN, + db.getDbClient().permissionTemplateDao().insertUserPermission(db.getSession(), dto.getUuid(), user.getUuid(), ProjectPermission.ADMIN, dto.getName(), user.getLogin()); - db.getDbClient().permissionTemplateDao().insertGroupPermission(db.getSession(), dto.getUuid(), group.getUuid(), UserRole.CODEVIEWER, + db.getDbClient().permissionTemplateDao().insertGroupPermission(db.getSession(), dto.getUuid(), group.getUuid(), ProjectPermission.CODEVIEWER, dto.getName(), group.getName()); db.commit(); return dto; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateActionIT.java index d9607ad3843..a1c875d86f8 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateActionIT.java @@ -23,14 +23,16 @@ import java.util.List; import javax.annotation.Nullable; import org.junit.Before; import org.junit.Test; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService.Action; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.component.ComponentQualifiers; +import org.sonar.db.permission.GlobalPermission; import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.user.GroupDto; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; @@ -45,9 +47,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.tuple; import static org.sonar.api.security.DefaultGroups.ANYONE; -import static org.sonar.api.web.UserRole.CODEVIEWER; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; import static org.sonar.db.permission.GlobalPermission.SCAN; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID; @@ -55,7 +57,7 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_T public class RemoveGroupFromTemplateActionIT extends BasePermissionWsIT<RemoveGroupFromTemplateAction> { - private static final String PERMISSION = CODEVIEWER; + private static final ProjectPermission PERMISSION = CODEVIEWER; private GroupDto group; private PermissionTemplateDto template; @@ -100,7 +102,7 @@ public class RemoveGroupFromTemplateActionIT extends BasePermissionWsIT<RemoveGr public void remove_group_from_template_by_name_case_insensitive() { newRequest() .setParam(PARAM_GROUP_NAME, group.getName()) - .setParam(PARAM_PERMISSION, PERMISSION) + .setParam(PARAM_PERMISSION, PERMISSION.getKey()) .setParam(PARAM_TEMPLATE_NAME, template.getName().toUpperCase()) .execute(); @@ -126,7 +128,10 @@ public class RemoveGroupFromTemplateActionIT extends BasePermissionWsIT<RemoveGr @Test public void fail_if_not_a_project_permission() { - assertThatThrownBy(() -> newRequest(group.getName(), template.getUuid(), PROVISION_PROJECTS.getKey())) + var groupName = group.getName(); + var templateUuid = template.getUuid(); + + assertThatThrownBy(() -> newRequest(groupName, templateUuid, PROVISION_PROJECTS)) .isInstanceOf(IllegalArgumentException.class); } @@ -140,7 +145,7 @@ public class RemoveGroupFromTemplateActionIT extends BasePermissionWsIT<RemoveGr @Test public void fail_if_not_logged_in() { - assertThatThrownBy(() -> { + assertThatThrownBy(() -> { userSession.anonymous(); newRequest(group.getName(), template.getUuid(), PERMISSION); }) @@ -149,7 +154,7 @@ public class RemoveGroupFromTemplateActionIT extends BasePermissionWsIT<RemoveGr @Test public void fail_if_group_params_missing() { - assertThatThrownBy(() -> { + assertThatThrownBy(() -> { newRequest(null, template.getUuid(), PERMISSION); }) .isInstanceOf(IllegalArgumentException.class) @@ -158,15 +163,15 @@ public class RemoveGroupFromTemplateActionIT extends BasePermissionWsIT<RemoveGr @Test public void fail_if_permission_missing() { - assertThatThrownBy(() -> { - newRequest(group.getName(), template.getUuid(), null); + assertThatThrownBy(() -> { + newRequest(group.getName(), template.getUuid(), (String) null); }) .isInstanceOf(IllegalArgumentException.class); } @Test public void fail_if_template_missing() { - assertThatThrownBy(() -> { + assertThatThrownBy(() -> { newRequest(group.getName(), null, PERMISSION); }) .isInstanceOf(BadRequestException.class); @@ -174,7 +179,7 @@ public class RemoveGroupFromTemplateActionIT extends BasePermissionWsIT<RemoveGr @Test public void fail_if_group_does_not_exist() { - assertThatThrownBy(() -> { + assertThatThrownBy(() -> { newRequest("unknown-group-name", template.getUuid(), PERMISSION); }) .isInstanceOf(NotFoundException.class) @@ -183,13 +188,21 @@ public class RemoveGroupFromTemplateActionIT extends BasePermissionWsIT<RemoveGr @Test public void fail_if_template_key_does_not_exist() { - assertThatThrownBy(() -> { + assertThatThrownBy(() -> { newRequest(group.getName(), "unknown-key", PERMISSION); }) .isInstanceOf(NotFoundException.class) .hasMessage("Permission template with id 'unknown-key' is not found"); } + private void newRequest(@Nullable String groupName, @Nullable String templateKey, @Nullable GlobalPermission permission) { + newRequest(groupName, templateKey, permission != null ? permission.getKey() : null); + } + + private void newRequest(@Nullable String groupName, @Nullable String templateKey, @Nullable ProjectPermission permission) { + newRequest(groupName, templateKey, permission != null ? permission.getKey() : null); + } + private void newRequest(@Nullable String groupName, @Nullable String templateKey, @Nullable String permission) { TestRequest request = newRequest(); if (groupName != null) { @@ -205,13 +218,13 @@ public class RemoveGroupFromTemplateActionIT extends BasePermissionWsIT<RemoveGr request.execute(); } - private void addGroupToTemplate(PermissionTemplateDto template, @Nullable String groupUuid, String permission, String groupName) { + private void addGroupToTemplate(PermissionTemplateDto template, @Nullable String groupUuid, ProjectPermission permission, String groupName) { db.getDbClient().permissionTemplateDao().insertGroupPermission(db.getSession(), template.getUuid(), groupUuid, permission, template.getName(), groupName); db.commit(); } - private List<String> getGroupNamesInTemplateAndPermission(PermissionTemplateDto template, String permission) { + private List<String> getGroupNamesInTemplateAndPermission(PermissionTemplateDto template, ProjectPermission permission) { PermissionQuery permissionQuery = PermissionQuery.builder().setPermission(permission).build(); return db.getDbClient().permissionTemplateDao() .selectGroupNamesByQueryAndTemplate(db.getSession(), permissionQuery, template.getUuid()); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/RemoveProjectCreatorFromTemplateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/RemoveProjectCreatorFromTemplateActionIT.java index 4ecdaf491bd..75195381899 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/RemoveProjectCreatorFromTemplateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/RemoveProjectCreatorFromTemplateActionIT.java @@ -22,14 +22,14 @@ package org.sonar.server.permission.ws.template; import java.util.Optional; import org.junit.Before; import org.junit.Test; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentTypes; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.util.Uuids; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.component.ComponentQualifiers; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; import org.sonar.db.permission.template.PermissionTemplateDto; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.UnauthorizedException; @@ -75,7 +75,7 @@ public class RemoveProjectCreatorFromTemplateActionIT extends BasePermissionWsIT new PermissionTemplateCharacteristicDto() .setUuid(Uuids.createFast()) .setTemplateUuid(template.getUuid()) - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setWithProjectCreator(false) .setCreatedAt(1_000_000_000L) .setUpdatedAt(1_000_000_000L), @@ -84,11 +84,11 @@ public class RemoveProjectCreatorFromTemplateActionIT extends BasePermissionWsIT when(system.now()).thenReturn(3_000_000_000L); newRequest() - .setParam(PARAM_PERMISSION, UserRole.USER) + .setParam(PARAM_PERMISSION, ProjectPermission.USER.getKey()) .setParam(PARAM_TEMPLATE_NAME, template.getName()) .execute(); - assertWithoutProjectCreatorFor(UserRole.USER); + assertWithoutProjectCreatorFor(ProjectPermission.USER); PermissionTemplateCharacteristicDto reloaded = reload(characteristic); assertThat(reloaded.getCreatedAt()).isEqualTo(1_000_000_000L); assertThat(reloaded.getUpdatedAt()).isEqualTo(3_000_000_000L); @@ -97,18 +97,18 @@ public class RemoveProjectCreatorFromTemplateActionIT extends BasePermissionWsIT @Test public void do_not_fail_when_no_template_permission() { newRequest() - .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ADMIN.getKey()) .setParam(PARAM_TEMPLATE_ID, template.getUuid()) .execute(); - assertNoTemplatePermissionFor(UserRole.ADMIN); + assertNoTemplatePermissionFor(ProjectPermission.ADMIN); } @Test public void fail_when_template_does_not_exist() { - assertThatThrownBy(() -> { + assertThatThrownBy(() -> { newRequest() - .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ADMIN.getKey()) .setParam(PARAM_TEMPLATE_ID, "42") .execute(); }) @@ -117,7 +117,7 @@ public class RemoveProjectCreatorFromTemplateActionIT extends BasePermissionWsIT @Test public void fail_if_permission_is_not_a_project_permission() { - assertThatThrownBy(() -> { + assertThatThrownBy(() -> { newRequest() .setParam(PARAM_PERMISSION, ADMINISTER_QUALITY_GATES.getKey()) .setParam(PARAM_TEMPLATE_ID, template.getUuid()) @@ -130,9 +130,9 @@ public class RemoveProjectCreatorFromTemplateActionIT extends BasePermissionWsIT public void fail_if_not_authenticated() { userSession.anonymous(); - assertThatThrownBy(() -> { + assertThatThrownBy(() -> { newRequest() - .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ADMIN.getKey()) .setParam(PARAM_TEMPLATE_ID, template.getUuid()) .execute(); }) @@ -143,23 +143,23 @@ public class RemoveProjectCreatorFromTemplateActionIT extends BasePermissionWsIT public void fail_if_insufficient_privileges() { userSession.logIn(); - assertThatThrownBy(() -> { + assertThatThrownBy(() -> { newRequest() - .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_PERMISSION, ProjectPermission.ADMIN.getKey()) .setParam(PARAM_TEMPLATE_ID, template.getUuid()) .execute(); }) .isInstanceOf(ForbiddenException.class); } - private void assertWithoutProjectCreatorFor(String permission) { + private void assertWithoutProjectCreatorFor(ProjectPermission permission) { Optional<PermissionTemplateCharacteristicDto> templatePermission = db.getDbClient().permissionTemplateCharacteristicDao().selectByPermissionAndTemplateId(db.getSession(), permission, template.getUuid()); assertThat(templatePermission).isPresent(); assertThat(templatePermission.get().getWithProjectCreator()).isFalse(); } - private void assertNoTemplatePermissionFor(String permission) { + private void assertNoTemplatePermissionFor(ProjectPermission permission) { Optional<PermissionTemplateCharacteristicDto> templatePermission = db.getDbClient().permissionTemplateCharacteristicDao().selectByPermissionAndTemplateId(db.getSession(), permission, template.getUuid()); assertThat(templatePermission).isNotPresent(); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateActionIT.java index 835f3549d96..1d85d6c8954 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateActionIT.java @@ -24,11 +24,13 @@ import javax.annotation.Nullable; import org.junit.Before; import org.junit.Test; import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentTypes; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.permission.GlobalPermission; import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.user.UserDto; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; @@ -42,9 +44,9 @@ import org.sonar.server.ws.TestRequest; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME; @@ -52,7 +54,7 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_U public class RemoveUserFromTemplateActionIT extends BasePermissionWsIT<RemoveUserFromTemplateAction> { - private static final String DEFAULT_PERMISSION = CODEVIEWER; + private static final ProjectPermission DEFAULT_PERMISSION = CODEVIEWER; private UserDto user; private PermissionTemplateDto template; @@ -86,7 +88,7 @@ public class RemoveUserFromTemplateActionIT extends BasePermissionWsIT<RemoveUse loginAsAdmin(); newRequest() .setParam(PARAM_USER_LOGIN, user.getLogin()) - .setParam(PARAM_PERMISSION, DEFAULT_PERMISSION) + .setParam(PARAM_PERMISSION, DEFAULT_PERMISSION.getKey()) .setParam(PARAM_TEMPLATE_NAME, template.getName().toUpperCase()) .execute(); @@ -129,7 +131,7 @@ public class RemoveUserFromTemplateActionIT extends BasePermissionWsIT<RemoveUse loginAsAdmin(); assertThatThrownBy(() -> { - newRequest(user.getLogin(), template.getUuid(), PROVISION_PROJECTS.getKey()); + newRequest(user.getLogin(), template.getUuid(), PROVISION_PROJECTS); }) .isInstanceOf(IllegalArgumentException.class); } @@ -169,7 +171,7 @@ public class RemoveUserFromTemplateActionIT extends BasePermissionWsIT<RemoveUse loginAsAdmin(); assertThatThrownBy(() -> { - newRequest(user.getLogin(), template.getUuid(), null); + newRequest(user.getLogin(), template.getUuid(), (String) null); }) .isInstanceOf(IllegalArgumentException.class); } @@ -204,6 +206,14 @@ public class RemoveUserFromTemplateActionIT extends BasePermissionWsIT<RemoveUse .hasMessage("Permission template with id 'unknown-key' is not found"); } + private void newRequest(@Nullable String userLogin, @Nullable String templateKey, @Nullable GlobalPermission permission) { + newRequest(userLogin, templateKey, permission != null ? permission.getKey() : null); + } + + private void newRequest(@Nullable String userLogin, @Nullable String templateKey, @Nullable ProjectPermission permission) { + newRequest(userLogin, templateKey, permission != null ? permission.getKey() : null); + } + private void newRequest(@Nullable String userLogin, @Nullable String templateKey, @Nullable String permission) { TestRequest request = newRequest(); if (userLogin != null) { @@ -219,13 +229,13 @@ public class RemoveUserFromTemplateActionIT extends BasePermissionWsIT<RemoveUse request.execute(); } - private List<String> getLoginsInTemplateAndPermission(PermissionTemplateDto template, String permission) { + private List<String> getLoginsInTemplateAndPermission(PermissionTemplateDto template, ProjectPermission permission) { PermissionQuery permissionQuery = PermissionQuery.builder().setPermission(permission).build(); return db.getDbClient().permissionTemplateDao() .selectUserLoginsByQueryAndTemplate(db.getSession(), permissionQuery, template.getUuid()); } - private void addUserToTemplate(UserDto user, PermissionTemplateDto template, String permission) { + private void addUserToTemplate(UserDto user, PermissionTemplateDto template, ProjectPermission permission) { db.getDbClient().permissionTemplateDao().insertUserPermission(db.getSession(), template.getUuid(), user.getUuid(), permission, template.getName(), user.getLogin()); db.commit(); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/SearchTemplatesActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/SearchTemplatesActionIT.java index 4aa21c0b3b9..e0fb6156ce5 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/SearchTemplatesActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/SearchTemplatesActionIT.java @@ -23,20 +23,20 @@ import java.util.Date; import javax.annotation.Nullable; import org.junit.Before; import org.junit.Test; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.api.web.UserRole; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.component.ComponentQualifiers; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.l18n.I18nRule; import org.sonar.server.common.permission.DefaultTemplatesResolver; import org.sonar.server.common.permission.DefaultTemplatesResolverImpl; +import org.sonar.server.component.ComponentTypesRule; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.l18n.I18nRule; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; import org.sonar.server.permission.ws.BasePermissionWsIT; @@ -93,12 +93,12 @@ public class SearchTemplatesActionIT extends BasePermissionWsIT<SearchTemplatesA GroupDto group2 = db.users().insertGroup(); GroupDto group3 = db.users().insertGroup(); - addUserToTemplate(projectTemplate.getUuid(), user1.getUuid(), UserRole.ISSUE_ADMIN, projectTemplate.getName(), user1.getLogin()); - addUserToTemplate(projectTemplate.getUuid(), user2.getUuid(), UserRole.ISSUE_ADMIN, projectTemplate.getName(), user2.getLogin()); - addUserToTemplate(projectTemplate.getUuid(), user3.getUuid(), UserRole.ISSUE_ADMIN, projectTemplate.getName(), user3.getLogin()); - addUserToTemplate(projectTemplate.getUuid(), user1.getUuid(), UserRole.CODEVIEWER, projectTemplate.getName(), user1.getLogin()); - addGroupToTemplate(projectTemplate.getUuid(), group1.getUuid(), UserRole.ADMIN, projectTemplate.getName(), group1.getName()); - addPermissionTemplateWithProjectCreator(projectTemplate.getUuid(), UserRole.ADMIN, projectTemplate.getName()); + addUserToTemplate(projectTemplate.getUuid(), user1.getUuid(), ProjectPermission.ISSUE_ADMIN, projectTemplate.getName(), user1.getLogin()); + addUserToTemplate(projectTemplate.getUuid(), user2.getUuid(), ProjectPermission.ISSUE_ADMIN, projectTemplate.getName(), user2.getLogin()); + addUserToTemplate(projectTemplate.getUuid(), user3.getUuid(), ProjectPermission.ISSUE_ADMIN, projectTemplate.getName(), user3.getLogin()); + addUserToTemplate(projectTemplate.getUuid(), user1.getUuid(), ProjectPermission.CODEVIEWER, projectTemplate.getName(), user1.getLogin()); + addGroupToTemplate(projectTemplate.getUuid(), group1.getUuid(), ProjectPermission.ADMIN, projectTemplate.getName(), group1.getName()); + addPermissionTemplateWithProjectCreator(projectTemplate.getUuid(), ProjectPermission.ADMIN, projectTemplate.getName()); db.permissionTemplates().setDefaultTemplates(projectTemplate, null, null); @@ -123,18 +123,18 @@ public class SearchTemplatesActionIT extends BasePermissionWsIT<SearchTemplatesA GroupDto group2 = db.users().insertGroup(); GroupDto group3 = db.users().insertGroup(); - addUserToTemplate(projectTemplate.getUuid(), user1.getUuid(), UserRole.ISSUE_ADMIN, projectTemplate.getName(), user1.getLogin()); - addUserToTemplate(projectTemplate.getUuid(), user2.getUuid(), UserRole.ISSUE_ADMIN, projectTemplate.getName(), user2.getLogin()); - addUserToTemplate(projectTemplate.getUuid(), user3.getUuid(), UserRole.ISSUE_ADMIN, projectTemplate.getName(), user3.getLogin()); - addUserToTemplate(projectTemplate.getUuid(), user1.getUuid(), UserRole.CODEVIEWER, projectTemplate.getName(), user1.getLogin()); - addGroupToTemplate(projectTemplate.getUuid(), group1.getUuid(), UserRole.ADMIN, projectTemplate.getName(), group1.getName()); - addPermissionTemplateWithProjectCreator(projectTemplate.getUuid(), UserRole.ADMIN, projectTemplate.getName()); + addUserToTemplate(projectTemplate.getUuid(), user1.getUuid(), ProjectPermission.ISSUE_ADMIN, projectTemplate.getName(), user1.getLogin()); + addUserToTemplate(projectTemplate.getUuid(), user2.getUuid(), ProjectPermission.ISSUE_ADMIN, projectTemplate.getName(), user2.getLogin()); + addUserToTemplate(projectTemplate.getUuid(), user3.getUuid(), ProjectPermission.ISSUE_ADMIN, projectTemplate.getName(), user3.getLogin()); + addUserToTemplate(projectTemplate.getUuid(), user1.getUuid(), ProjectPermission.CODEVIEWER, projectTemplate.getName(), user1.getLogin()); + addGroupToTemplate(projectTemplate.getUuid(), group1.getUuid(), ProjectPermission.ADMIN, projectTemplate.getName(), group1.getName()); + addPermissionTemplateWithProjectCreator(projectTemplate.getUuid(), ProjectPermission.ADMIN, projectTemplate.getName()); - addUserToTemplate(portfoliosTemplate.getUuid(), user1.getUuid(), UserRole.USER, portfoliosTemplate.getName(), user1.getLogin()); - addUserToTemplate(portfoliosTemplate.getUuid(), user2.getUuid(), UserRole.USER, portfoliosTemplate.getName(), user2.getLogin()); - addGroupToTemplate(portfoliosTemplate.getUuid(), group1.getUuid(), UserRole.ISSUE_ADMIN, portfoliosTemplate.getName(), group1.getName()); - addGroupToTemplate(portfoliosTemplate.getUuid(), group2.getUuid(), UserRole.ISSUE_ADMIN, portfoliosTemplate.getName(), group2.getName()); - addGroupToTemplate(portfoliosTemplate.getUuid(), group3.getUuid(), UserRole.ISSUE_ADMIN, portfoliosTemplate.getName(), group3.getName()); + addUserToTemplate(portfoliosTemplate.getUuid(), user1.getUuid(), ProjectPermission.USER, portfoliosTemplate.getName(), user1.getLogin()); + addUserToTemplate(portfoliosTemplate.getUuid(), user2.getUuid(), ProjectPermission.USER, portfoliosTemplate.getName(), user2.getLogin()); + addGroupToTemplate(portfoliosTemplate.getUuid(), group1.getUuid(), ProjectPermission.ISSUE_ADMIN, portfoliosTemplate.getName(), group1.getName()); + addGroupToTemplate(portfoliosTemplate.getUuid(), group2.getUuid(), ProjectPermission.ISSUE_ADMIN, portfoliosTemplate.getName(), group2.getName()); + addGroupToTemplate(portfoliosTemplate.getUuid(), group3.getUuid(), ProjectPermission.ISSUE_ADMIN, portfoliosTemplate.getName(), group3.getName()); db.permissionTemplates().setDefaultTemplates(projectTemplate, applicationsTemplate, portfoliosTemplate); @@ -354,22 +354,22 @@ public class SearchTemplatesActionIT extends BasePermissionWsIT<SearchTemplatesA return insert; } - private void addGroupToTemplate(String templateUuid, @Nullable String groupUuid, String permission, String templateName, String groupName) { + private void addGroupToTemplate(String templateUuid, @Nullable String groupUuid, ProjectPermission permission, String templateName, String groupName) { dbClient.permissionTemplateDao().insertGroupPermission(db.getSession(), templateUuid, groupUuid, permission, templateName, groupName); db.getSession().commit(); } - private void addUserToTemplate(String templateUuid, String userId, String permission, String templateName, String userLogin) { + private void addUserToTemplate(String templateUuid, String userId, ProjectPermission permission, String templateName, String userLogin) { dbClient.permissionTemplateDao().insertUserPermission(db.getSession(), templateUuid, userId, permission, templateName, userLogin); db.getSession().commit(); } - private void addPermissionTemplateWithProjectCreator(String templateUuid, String permission, String templateName) { + private void addPermissionTemplateWithProjectCreator(String templateUuid, ProjectPermission permission, String templateName) { dbClient.permissionTemplateCharacteristicDao().insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid(Uuids.createFast()) .setWithProjectCreator(true) .setTemplateUuid(templateUuid) - .setPermission(permission) + .setPermission(permission.getKey()) .setCreatedAt(1_000_000_000L) .setUpdatedAt(2_000_000_000L), templateName); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/TemplateGroupsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/TemplateGroupsActionIT.java index a41f0ceb066..b7ee1dcf3c0 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/TemplateGroupsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/TemplateGroupsActionIT.java @@ -22,14 +22,14 @@ package org.sonar.server.permission.ws.template; import java.util.stream.IntStream; import javax.annotation.Nullable; import org.junit.Test; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.component.ComponentQualifiers; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.permission.template.PermissionTemplateGroupDto; import org.sonar.db.user.GroupDto; +import org.sonar.server.component.ComponentTypes; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; @@ -46,12 +46,12 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; 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.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.api.web.UserRole.USER; import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_GATES; import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateGroupDto; import static org.sonar.db.user.GroupTesting.newGroupDto; import static org.sonar.test.JsonAssert.assertJson; @@ -96,7 +96,7 @@ public class TemplateGroupsActionIT extends BasePermissionWsIT<TemplateGroupsAct loginAsAdmin(); String response = newRequest() - .setParam(PARAM_PERMISSION, ISSUE_ADMIN) + .setParam(PARAM_PERMISSION, ISSUE_ADMIN.getKey()) .setParam(PARAM_TEMPLATE_ID, template.getUuid()) .execute() .getInput(); @@ -163,7 +163,7 @@ public class TemplateGroupsActionIT extends BasePermissionWsIT<TemplateGroupsAct loginAsAdmin(); WsGroupsResponse response = newRequest() - .setParam(PARAM_PERMISSION, USER) + .setParam(PARAM_PERMISSION, USER.getKey()) .setParam(PARAM_TEMPLATE_ID, template.getUuid()) .executeProtobuf(WsGroupsResponse.class); @@ -204,7 +204,7 @@ public class TemplateGroupsActionIT extends BasePermissionWsIT<TemplateGroupsAct loginAsAdmin(); WsGroupsResponse response = newRequest() - .setParam(PARAM_PERMISSION, USER) + .setParam(PARAM_PERMISSION, USER.getKey()) .setParam(PARAM_TEMPLATE_NAME, template.getName()) .setParam(PAGE, "2") .setParam(PAGE_SIZE, "1") @@ -271,10 +271,10 @@ public class TemplateGroupsActionIT extends BasePermissionWsIT<TemplateGroupsAct PermissionTemplateDto otherTemplate = db.permissionTemplates().insertTemplate(); IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> { GroupDto group = db.users().insertGroup("Group-" + i); - db.permissionTemplates().addGroupToTemplate(otherTemplate, group, UserRole.USER); + db.permissionTemplates().addGroupToTemplate(otherTemplate, group, ProjectPermission.USER); }); String lastGroupName = "Group-" + (DEFAULT_PAGE_SIZE + 1); - db.permissionTemplates().addGroupToTemplate(template, db.users().selectGroup(lastGroupName).get(), UserRole.USER); + db.permissionTemplates().addGroupToTemplate(template, db.users().selectGroup(lastGroupName).get(), ProjectPermission.USER); loginAsAdmin(); WsGroupsResponse response = newRequest() @@ -294,7 +294,7 @@ public class TemplateGroupsActionIT extends BasePermissionWsIT<TemplateGroupsAct assertThatThrownBy(() -> { newRequest() - .setParam(PARAM_PERMISSION, USER) + .setParam(PARAM_PERMISSION, USER.getKey()) .setParam(PARAM_TEMPLATE_ID, template1.getUuid()) .execute(); }) @@ -308,7 +308,7 @@ public class TemplateGroupsActionIT extends BasePermissionWsIT<TemplateGroupsAct assertThatThrownBy(() -> { newRequest() - .setParam(PARAM_PERMISSION, USER) + .setParam(PARAM_PERMISSION, USER.getKey()) .setParam(PARAM_TEMPLATE_ID, template1.getUuid()) .execute(); }) @@ -322,7 +322,7 @@ public class TemplateGroupsActionIT extends BasePermissionWsIT<TemplateGroupsAct assertThatThrownBy(() -> { newRequest() - .setParam(PARAM_PERMISSION, USER) + .setParam(PARAM_PERMISSION, USER.getKey()) .setParam(PARAM_TEMPLATE_ID, template1.getUuid()) .setParam(PARAM_TEMPLATE_NAME, template1.getName()) .execute(); @@ -336,7 +336,7 @@ public class TemplateGroupsActionIT extends BasePermissionWsIT<TemplateGroupsAct assertThatThrownBy(() -> { newRequest() - .setParam(PARAM_PERMISSION, USER) + .setParam(PARAM_PERMISSION, USER.getKey()) .execute(); }) .isInstanceOf(BadRequestException.class); @@ -348,7 +348,7 @@ public class TemplateGroupsActionIT extends BasePermissionWsIT<TemplateGroupsAct assertThatThrownBy(() -> { newRequest() - .setParam(PARAM_PERMISSION, USER) + .setParam(PARAM_PERMISSION, USER.getKey()) .setParam(PARAM_TEMPLATE_ID, "unknown-uuid") .execute(); }) @@ -378,6 +378,10 @@ public class TemplateGroupsActionIT extends BasePermissionWsIT<TemplateGroupsAct db.commit(); } + private static PermissionTemplateGroupDto newPermissionTemplateGroup(ProjectPermission permission, String templateUuid, @Nullable String groupUuid) { + return newPermissionTemplateGroup(permission.getKey(), templateUuid, groupUuid); + } + private static PermissionTemplateGroupDto newPermissionTemplateGroup(String permission, String templateUuid, @Nullable String groupUuid) { return newPermissionTemplateGroupDto() .setPermission(permission) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/TemplateUsersActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/TemplateUsersActionIT.java index ec61476fdde..96e9205f417 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/TemplateUsersActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/permission/ws/template/TemplateUsersActionIT.java @@ -25,7 +25,7 @@ import org.junit.Test; import org.sonar.db.component.ComponentQualifiers; import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.server.component.ComponentTypesRule; import org.sonar.db.permission.GlobalPermission; import org.sonar.db.permission.template.PermissionTemplateDto; @@ -46,10 +46,10 @@ import org.sonarqube.ws.Permissions; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.permission.GlobalPermission.SCAN; import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE; import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateUserDto; @@ -96,7 +96,7 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio addUserToTemplate(newPermissionTemplateUser(ADMIN, template1, user2), template1.getName()); loginAsAdmin(); - String result = newRequest(null, template1.getUuid()).execute().getInput(); + String result = newRequest((String) null, template1.getUuid()).execute().getInput(); assertJson(result).isSimilarTo(getClass().getResource("template_users-example.json")); } @@ -117,7 +117,7 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio PermissionTemplateDto anotherTemplate = addTemplate(); addUserToTemplate(newPermissionTemplateUser(USER, anotherTemplate, user1), anotherTemplate.getName()); - Permissions.UsersWsResponse response = newRequest(null, null) + Permissions.UsersWsResponse response = newRequest((String) null, null) .setParam(PARAM_TEMPLATE_NAME, template.getName()) .executeProtobuf(Permissions.UsersWsResponse.class); @@ -144,7 +144,7 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio PermissionTemplateDto anotherTemplate = addTemplate(); addUserToTemplate(newPermissionTemplateUser(USER, anotherTemplate, user1), anotherTemplate.getName()); - Permissions.UsersWsResponse response = newRequest(null, null) + Permissions.UsersWsResponse response = newRequest((String) null, null) .setParam(PARAM_TEMPLATE_NAME, template.getName()) .setParam(WebService.Param.TEXT_QUERY, "ame-1") .executeProtobuf(Permissions.UsersWsResponse.class); @@ -162,7 +162,7 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio String templateName = addUsersToSomeTemplate(user1, user2, user3); - Permissions.UsersWsResponse response = newRequest(null, null) + Permissions.UsersWsResponse response = newRequest((String) null, null) .setParam(PARAM_TEMPLATE_NAME, templateName) .setParam(WebService.Param.TEXT_QUERY, "ran") .executeProtobuf(Permissions.UsersWsResponse.class); @@ -181,7 +181,7 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio String templateName = addUsersToSomeTemplate(user1, user2, user3); - Permissions.UsersWsResponse response = newRequest(null, null) + Permissions.UsersWsResponse response = newRequest((String) null, null) .setParam(PARAM_TEMPLATE_NAME, templateName) .setParam(WebService.Param.TEXT_QUERY, "xyz") .executeProtobuf(Permissions.UsersWsResponse.class); @@ -259,7 +259,7 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio addUserToTemplate(newPermissionTemplateUser(ISSUE_ADMIN, template, user3), template.getName()); loginAsAdmin(); - Permissions.UsersWsResponse response = newRequest(null, null) + Permissions.UsersWsResponse response = newRequest((String) null, null) .setParam(PARAM_TEMPLATE_NAME, template.getName()) .executeProtobuf(Permissions.UsersWsResponse.class); @@ -273,13 +273,13 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio PermissionTemplateDto otherTemplate = db.permissionTemplates().insertTemplate(); IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> { UserDto user = db.users().insertUser("User-" + i); - db.permissionTemplates().addUserToTemplate(otherTemplate, user, UserRole.USER); + db.permissionTemplates().addUserToTemplate(otherTemplate, user, ProjectPermission.USER); }); String lastLogin = "User-" + (DEFAULT_PAGE_SIZE + 1); - db.permissionTemplates().addUserToTemplate(template, db.users().selectUserByLogin(lastLogin).get(), UserRole.USER); + db.permissionTemplates().addUserToTemplate(template, db.users().selectUserByLogin(lastLogin).get(), ProjectPermission.USER); loginAsAdmin(); - Permissions.UsersWsResponse response = newRequest(null, null) + Permissions.UsersWsResponse response = newRequest((String) null, null) .setParam(PARAM_TEMPLATE_NAME, template.getName()) .executeProtobuf(Permissions.UsersWsResponse.class); @@ -306,7 +306,7 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio loginAsAdmin(); assertThatThrownBy(() -> { - newRequest(null, null) + newRequest((String) null, null) .execute(); }) .isInstanceOf(BadRequestException.class); @@ -317,7 +317,7 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio loginAsAdmin(); assertThatThrownBy(() -> { - newRequest(null, "unknown-template-uuid") + newRequest((String) null, "unknown-template-uuid") .execute(); }) .isInstanceOf(NotFoundException.class); @@ -329,7 +329,7 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio loginAsAdmin(); assertThatThrownBy(() -> { - newRequest(null, template.getUuid()) + newRequest((String) null, template.getUuid()) .setParam(PARAM_TEMPLATE_NAME, template.getName()) .execute(); }) @@ -342,7 +342,7 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio userSession.anonymous(); assertThatThrownBy(() -> { - newRequest(null, template.getUuid()).execute(); + newRequest((String) null, template.getUuid()).execute(); }) .isInstanceOf(UnauthorizedException.class); } @@ -353,7 +353,7 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio userSession.logIn().addPermission(SCAN); assertThatThrownBy(() -> { - newRequest(null, template.getUuid()).execute(); + newRequest((String) null, template.getUuid()).execute(); }) .isInstanceOf(ForbiddenException.class); } @@ -369,6 +369,10 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio db.commit(); } + private static PermissionTemplateUserDto newPermissionTemplateUser(ProjectPermission permission, PermissionTemplateDto template, UserDto user) { + return newPermissionTemplateUser(permission.getKey(), template, user); + } + private static PermissionTemplateUserDto newPermissionTemplateUser(String permission, PermissionTemplateDto template, UserDto user) { return newPermissionTemplateUserDto() .setPermission(permission) @@ -376,6 +380,14 @@ public class TemplateUsersActionIT extends BasePermissionWsIT<TemplateUsersActio .setUserUuid(user.getUuid()); } + private TestRequest newRequest(@Nullable ProjectPermission permission, @Nullable String templateUuid) { + return newRequest(permission != null ? permission.getKey() : null, templateUuid); + } + + private TestRequest newRequest(@Nullable GlobalPermission permission, @Nullable String templateUuid) { + return newRequest(permission != null ? permission.getKey() : null, templateUuid); + } + private TestRequest newRequest(@Nullable String permission, @Nullable String templateUuid) { TestRequest request = newRequest(); if (permission != null) { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/platform/ws/LogsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/platform/ws/LogsActionIT.java index 12055ed972b..e0eeaed7ac2 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/platform/ws/LogsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/platform/ws/LogsActionIT.java @@ -118,7 +118,7 @@ public class LogsActionIT { when(cluster.getMembers()).thenReturn(members); when(configuration.get(ProcessProperties.Property.WEB_HOST.getKey())).thenReturn(Optional.of("anyhost")); when(hazelcastMember.call(any(), any(), anyLong())).thenReturn(answer); - when(answer.getSingleAnswer()).thenReturn(Optional.of(new DistributedServerLogging.WebAddress("anyhost", 9000))); + when(answer.getSingleAnswer()).thenReturn(Optional.of(new DistributedServerLogging.WebAddress("anyhost", "/any", 9000))); when(hazelcastMember.getUuid()).thenReturn(UUID.fromString("00000000-0000-0000-0000-000000000001")); when(member1.getUuid()).thenReturn(UUID.fromString("00000000-0000-0000-0000-000000000002")); when(member2.getUuid()).thenReturn(UUID.fromString("00000000-0000-0000-0000-000000000003")); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/DeleteActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/DeleteActionIT.java index 7a297c4ab98..d299b1e4e65 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/DeleteActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/DeleteActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -96,7 +96,7 @@ public class DeleteActionIT { public void project_administrator_deletes_the_project_by_key() { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto project = projectData.getMainBranchComponent(); - userSessionRule.logIn().addProjectPermission(UserRole.ADMIN, projectData.getProjectDto()); + userSessionRule.logIn().addProjectPermission(ProjectPermission.ADMIN, projectData.getProjectDto()); call(tester.newRequest().setParam(PARAM_PROJECT, project.getKey())); @@ -111,7 +111,7 @@ public class DeleteActionIT { UserDto insert = dbClient.userDao().insert(dbSession, newUserDto().setHomepageType("PROJECT").setHomepageParameter(projectData.projectUuid())); dbSession.commit(); - userSessionRule.logIn().addProjectPermission(UserRole.ADMIN, projectData.getProjectDto()); + userSessionRule.logIn().addProjectPermission(ProjectPermission.ADMIN, projectData.getProjectDto()); DeleteAction underTest = new DeleteAction( new ComponentCleanerService(dbClient, new TestIndexers()), from(db), dbClient, userSessionRule, projectLifeCycleListeners); @@ -134,7 +134,7 @@ public class DeleteActionIT { webhookDbTester.insertWebhook(project); webhookDbTester.insertWebhook(project); - userSessionRule.logIn().addProjectPermission(UserRole.ADMIN, project); + userSessionRule.logIn().addProjectPermission(ProjectPermission.ADMIN, project); DeleteAction underTest = new DeleteAction( new ComponentCleanerService(dbClient, new TestIndexers()), from(db), dbClient, userSessionRule, projectLifeCycleListeners); @@ -153,9 +153,9 @@ public class DeleteActionIT { ProjectData project = db.components().insertPrivateProject(); userSessionRule.logIn() - .addProjectPermission(UserRole.CODEVIEWER, project.getProjectDto()) - .addProjectPermission(UserRole.ISSUE_ADMIN, project.getProjectDto()) - .addProjectPermission(UserRole.USER, project.getProjectDto()); + .addProjectPermission(ProjectPermission.CODEVIEWER, project.getProjectDto()) + .addProjectPermission(ProjectPermission.ISSUE_ADMIN, project.getProjectDto()) + .addProjectPermission(ProjectPermission.USER, project.getProjectDto()); TestRequest request = tester.newRequest().setParam(PARAM_PROJECT, project.projectKey()); assertThatThrownBy(() -> call(request)) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/ProjectFinderIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/ProjectFinderIT.java index 8e5664062f7..72bbc2def18 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/ProjectFinderIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/ProjectFinderIT.java @@ -30,7 +30,7 @@ import org.sonar.server.tester.UserSessionRule; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; -import static org.sonar.api.web.UserRole.SCAN; +import static org.sonar.db.permission.ProjectPermission.SCAN; import static org.sonar.server.project.ws.ProjectFinder.SearchResult; public class ProjectFinderIT { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/SearchMyProjectsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/SearchMyProjectsActionIT.java index 90219a90c82..f47fd14098f 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/SearchMyProjectsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/SearchMyProjectsActionIT.java @@ -28,7 +28,7 @@ import org.sonar.api.measures.Metric.ValueType; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -92,8 +92,8 @@ public class SearchMyProjectsActionIT { SnapshotDto cLangSnapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(cLang.getMainBranchDto()).setCreatedAt(anotherTime)); dbClient.measureDao().insert(dbSession, newMeasure(jdk7.getMainBranchDto(), alertStatusMetric, Level.ERROR.name())); dbClient.measureDao().insert(dbSession, newMeasure(cLang.getMainBranchDto(), alertStatusMetric, Level.OK.name())); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, jdk7.getProjectDto()); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, cLang.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, jdk7.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, cLang.getProjectDto()); db.commit(); System.setProperty("user.timezone", "UTC"); @@ -107,8 +107,8 @@ public class SearchMyProjectsActionIT { ProjectData jdk7 = insertJdk7(); ProjectData cLang = insertClang(); UserDto anotherUser = db.users().insertUser(newUserDto()); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, jdk7.getProjectDto()); - db.users().insertProjectPermissionOnUser(anotherUser, UserRole.ADMIN, cLang.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, jdk7.getProjectDto()); + db.users().insertProjectPermissionOnUser(anotherUser, ProjectPermission.ADMIN, cLang.getProjectDto()); SearchMyProjectsWsResponse result = callWs(); @@ -119,7 +119,7 @@ public class SearchMyProjectsActionIT { public void return_only_first_1000_projects() { IntStream.range(0, 1_010).forEach(i -> { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, project); }); SearchMyProjectsWsResponse result = callWs(); @@ -133,9 +133,9 @@ public class SearchMyProjectsActionIT { ComponentDto c_project = db.components().insertPrivateProject(p -> p.setName("c_project_name")).getMainBranchComponent(); ComponentDto a_project = db.components().insertPrivateProject(p -> p.setName("A_project_name")).getMainBranchComponent(); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, b_project); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, a_project); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, c_project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, b_project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, a_project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, c_project); SearchMyProjectsWsResponse result = callWs(); @@ -147,7 +147,7 @@ public class SearchMyProjectsActionIT { for (int i = 0; i < 10; i++) { int j = i; ProjectData project = db.components().insertPrivateProject(p -> p.setName("project-" + j)); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, project.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, project.getProjectDto()); } SearchMyProjectsWsResponse result = ws.newRequest() @@ -164,8 +164,8 @@ public class SearchMyProjectsActionIT { ProjectData jdk7 = insertJdk7(); ProjectData clang = insertClang(); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, jdk7.getProjectDto()); - db.users().insertProjectPermissionOnUser(user, UserRole.ISSUE_ADMIN, clang.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, jdk7.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ISSUE_ADMIN, clang.getProjectDto()); SearchMyProjectsWsResponse result = callWs(); @@ -177,8 +177,8 @@ public class SearchMyProjectsActionIT { ProjectData jdk7 = insertJdk7(); PortfolioDto portfolio = insertPortfolio(); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, jdk7.getProjectDto()); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, portfolio); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, jdk7.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, portfolio); SearchMyProjectsWsResponse result = callWs(); @@ -189,7 +189,7 @@ public class SearchMyProjectsActionIT { public void does_not_return_branches() { ProjectData project = db.components().insertPublicProject(); BranchDto branch = db.components().insertProjectBranch(project.getProjectDto()); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, project.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, project.getProjectDto()); SearchMyProjectsWsResponse result = callWs(); @@ -206,8 +206,8 @@ public class SearchMyProjectsActionIT { GroupDto group = db.users().insertGroup(); db.users().insertMember(group, user); - db.users().insertEntityPermissionOnGroup(group, UserRole.ADMIN, jdk7.getProjectDto()); - db.users().insertEntityPermissionOnGroup(group, UserRole.USER, cLang.getProjectDto()); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.ADMIN, jdk7.getProjectDto()); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.USER, cLang.getProjectDto()); SearchMyProjectsWsResponse result = callWs(); @@ -223,11 +223,11 @@ public class SearchMyProjectsActionIT { GroupDto group = db.users().insertGroup(); db.users().insertMember(group, user); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, jdk7.getProjectDto()); - db.users().insertEntityPermissionOnGroup(group, UserRole.ADMIN, cLang.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, jdk7.getProjectDto()); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.ADMIN, cLang.getProjectDto()); // admin via group and user - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, sonarqube.getProjectDto()); - db.users().insertEntityPermissionOnGroup(group, UserRole.ADMIN, sonarqube.getProjectDto()); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, sonarqube.getProjectDto()); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.ADMIN, sonarqube.getProjectDto()); SearchMyProjectsWsResponse result = callWs(); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/SearchMyScannableProjectsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/SearchMyScannableProjectsActionIT.java index 3f45a029a3f..7c9b4750296 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/SearchMyScannableProjectsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/SearchMyScannableProjectsActionIT.java @@ -33,7 +33,7 @@ import org.sonar.server.ws.WsActionTester; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY; -import static org.sonar.api.web.UserRole.SCAN; +import static org.sonar.db.permission.ProjectPermission.SCAN; import static org.sonar.test.JsonAssert.assertJson; import static org.sonarqube.ws.Projects.SearchMyScannableProjectsResponse; import static org.sonarqube.ws.Projects.SearchMyScannableProjectsResponse.Project; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/UpdateKeyActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/UpdateKeyActionIT.java index 4dbb4f2f92c..64eb6b7eb1f 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/UpdateKeyActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/UpdateKeyActionIT.java @@ -26,7 +26,7 @@ import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; @@ -64,7 +64,7 @@ public class UpdateKeyActionIT { @Test public void update_key_of_project_referenced_by_its_key() { ProjectData project = insertProject(); - userSessionRule.addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); call(project.projectKey(), ANOTHER_KEY); @@ -78,7 +78,7 @@ public class UpdateKeyActionIT { @Test public void fail_if_not_authorized() { ProjectData project = insertProject(); - userSessionRule.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); String projectKey = project.projectKey(); assertThatThrownBy(() -> call(projectKey, ANOTHER_KEY)) @@ -89,7 +89,7 @@ public class UpdateKeyActionIT { @Test public void fail_if_new_key_is_not_provided() { ProjectData project = insertProject(); - userSessionRule.addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); String projectKey = project.projectKey(); assertThatThrownBy(() -> call(projectKey, null)) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/UpdateVisibilityActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/UpdateVisibilityActionIT.java index 77c598f9ede..7acd2e7dbe2 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/UpdateVisibilityActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/project/ws/UpdateVisibilityActionIT.java @@ -32,7 +32,7 @@ import org.sonar.db.component.ComponentQualifiers; import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; @@ -103,8 +103,9 @@ public class UpdateVisibilityActionIT { private final ComponentTypes componentTypes = new ComponentTypesRule().setRootQualifiers(ComponentQualifiers.PROJECT); private final PermissionService permissionService = new PermissionServiceImpl(componentTypes); private final Set<String> PROJECT_PERMISSIONS_BUT_USER_AND_CODEVIEWER = permissionService.getAllProjectPermissions().stream() - .filter(perm -> !perm.equals(UserRole.USER) && !perm.equals(UserRole.CODEVIEWER)) - .collect(Collectors.toSet()); + .filter(perm -> !perm.equals(ProjectPermission.USER) && !perm.equals(ProjectPermission.CODEVIEWER)) + .map(ProjectPermission::getKey) + .collect(Collectors.toSet()); private final DbClient dbClient = dbTester.getDbClient(); private final DbSession dbSession = dbTester.getSession(); @@ -208,8 +209,8 @@ public class UpdateVisibilityActionIT { ComponentDto subView = ComponentTesting.newSubPortfolio(portfolio.getRootComponent()); ComponentDto projectCopy = newProjectCopy("foo", project.getMainBranchComponent(), subView); dbTester.components().insertComponents(subView, projectCopy); - userSessionRule.addProjectPermission(UserRole.ADMIN, project.getProjectDto(), application); - userSessionRule.addPortfolioPermission(UserRole.ADMIN, portfolio.getPortfolioDto()); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto(), application); + userSessionRule.addPortfolioPermission(ProjectPermission.ADMIN, portfolio.getPortfolioDto()); Stream.of(project.getProjectDto(), portfolio.getPortfolioDto(), application).forEach(c -> request .setParam(PARAM_PROJECT, c.getKey()) @@ -246,7 +247,7 @@ public class UpdateVisibilityActionIT { ProjectData project = dbTester.components().insertPublicProject(); request.setParam(PARAM_PROJECT, project.projectKey()) .setParam(PARAM_VISIBILITY, randomVisibility); - userSessionRule.addProjectPermission(UserRole.ISSUE_ADMIN, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.ISSUE_ADMIN, project.getProjectDto()); Arrays.stream(GlobalPermission.values()) .forEach(userSessionRule::addPermission); @@ -261,7 +262,7 @@ public class UpdateVisibilityActionIT { ProjectData project = dbTester.components().insertPublicProject(); request.setParam(PARAM_PROJECT, project.projectKey()) .setParam(PARAM_VISIBILITY, randomVisibility); - userSessionRule.addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); assertThatThrownBy(request::execute) .isInstanceOf(ForbiddenException.class) @@ -272,7 +273,7 @@ public class UpdateVisibilityActionIT { public void execute_throws_ForbiddenException_if_user_has_global_ADMIN_permission_even_if_sonar_allowPermissionManagementForProjectAdmins_is_set_to_false() { when(configuration.getBoolean(CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_PROPERTY)).thenReturn(of(false)); ProjectDto project = dbTester.components().insertPublicProject().getProjectDto(); - userSessionRule.setSystemAdministrator().addProjectPermission(UserRole.ADMIN, project); + userSessionRule.setSystemAdministrator().addProjectPermission(ProjectPermission.ADMIN, project); request.setParam(PARAM_PROJECT, project.getKey()) .setParam(PARAM_VISIBILITY, "private"); @@ -288,7 +289,7 @@ public class UpdateVisibilityActionIT { .forEach(i -> insertPendingTask(project.getMainBranchDto())); request.setParam(PARAM_PROJECT, project.projectKey()) .setParam(PARAM_VISIBILITY, randomVisibility); - userSessionRule.addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); assertThatThrownBy(request::execute) .isInstanceOf(IllegalStateException.class) @@ -302,7 +303,7 @@ public class UpdateVisibilityActionIT { .forEach(i -> insertInProgressTask(project.getMainBranchDto())); request.setParam(PARAM_PROJECT, project.projectKey()) .setParam(PARAM_VISIBILITY, randomVisibility); - userSessionRule.addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); assertThatThrownBy(request::execute) .isInstanceOf(IllegalStateException.class) @@ -314,7 +315,7 @@ public class UpdateVisibilityActionIT { ProjectDto project = dbTester.components().insertPublicProject(p -> p.setKey(MANAGED_PROJECT_KEY)).getProjectDto(); request.setParam(PARAM_PROJECT, project.getKey()) .setParam(PARAM_VISIBILITY, Visibility.PUBLIC.getLabel()); - userSessionRule.addProjectPermission(UserRole.ADMIN, project); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project); doThrow(new IllegalStateException("Managed project")).when(managedInstanceChecker).throwIfProjectIsManaged(any(), eq(project.getUuid())); @@ -336,7 +337,7 @@ public class UpdateVisibilityActionIT { ComponentDto file = ComponentTesting.newFileDto(project.getMainBranchComponent()); dbTester.components().insertComponents(branch, dir, file); - userSessionRule.addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); request.setParam(PARAM_PROJECT, project.projectKey()) .setParam(PARAM_VISIBILITY, initiallyPrivate ? PUBLIC : PRIVATE) @@ -364,7 +365,7 @@ public class UpdateVisibilityActionIT { ComponentDto file = ComponentTesting.newFileDto(project.getMainBranchComponent()) .setPrivate(initiallyPrivate); dbTester.components().insertComponents(branch, dir, file); - userSessionRule.addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); request.setParam(PARAM_PROJECT, project.projectKey()) .setParam(PARAM_VISIBILITY, initiallyPrivate ? PRIVATE : PUBLIC) @@ -382,7 +383,7 @@ public class UpdateVisibilityActionIT { UserDto user = dbTester.users().insertUser(); GroupDto group = dbTester.users().insertGroup(); unsafeGiveAllPermissionsToRootComponent(project, user, group); - userSessionRule.addProjectPermission(UserRole.ADMIN, project); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project); request.setParam(PARAM_PROJECT, project.getKey()) .setParam(PARAM_VISIBILITY, PRIVATE) @@ -397,7 +398,7 @@ public class UpdateVisibilityActionIT { UserDto user = dbTester.users().insertUser(); GroupDto group = dbTester.users().insertGroup(); unsafeGiveAllPermissionsToRootComponent(project, user, group); - userSessionRule.addProjectPermission(UserRole.ADMIN, project); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project); request.setParam(PARAM_PROJECT, project.getKey()) .setParam(PARAM_VISIBILITY, PRIVATE) @@ -412,7 +413,7 @@ public class UpdateVisibilityActionIT { UserDto user = dbTester.users().insertUser(); GroupDto group = dbTester.users().insertGroup(); unsafeGiveAllPermissionsToRootComponent(project, user, group); - userSessionRule.addProjectPermission(UserRole.ADMIN, project); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project); request.setParam(PARAM_PROJECT, project.getKey()) .setParam(PARAM_VISIBILITY, PUBLIC) @@ -427,7 +428,7 @@ public class UpdateVisibilityActionIT { UserDto user = dbTester.users().insertUser(); GroupDto group = dbTester.users().insertGroup(); unsafeGiveAllPermissionsToRootComponent(project, user, group); - userSessionRule.addProjectPermission(UserRole.ADMIN, project); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project); request.setParam(PARAM_PROJECT, project.getKey()) .setParam(PARAM_VISIBILITY, PUBLIC) @@ -440,7 +441,7 @@ public class UpdateVisibilityActionIT { public void execute_updates_permission_of_specified_project_in_indexes_when_changing_visibility() { ProjectData project = randomPublicOrPrivateProject(); boolean initiallyPrivate = project.getProjectDto().isPrivate(); - userSessionRule.addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); request.setParam(PARAM_PROJECT, project.projectKey()) .setParam(PARAM_VISIBILITY, initiallyPrivate ? PUBLIC : PRIVATE) @@ -453,7 +454,7 @@ public class UpdateVisibilityActionIT { public void execute_does_not_update_permission_of_specified_project_in_indexes_if_already_has_specified_visibility() { ProjectData project = randomPublicOrPrivateProject(); boolean initiallyPrivate = project.getProjectDto().isPrivate(); - userSessionRule.addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); request.setParam(PARAM_PROJECT, project.projectKey()) .setParam(PARAM_VISIBILITY, initiallyPrivate ? PRIVATE : PUBLIC) @@ -471,16 +472,16 @@ public class UpdateVisibilityActionIT { dbTester.users().insertProjectPermissionOnUser(user1, "p1", project); dbTester.users().insertProjectPermissionOnUser(user1, "p2", project); dbTester.users().insertProjectPermissionOnUser(user2, "p2", project); - userSessionRule.addProjectPermission(UserRole.ADMIN, project); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project); request.setParam(PARAM_PROJECT, project.getKey()) .setParam(PARAM_VISIBILITY, PRIVATE) .execute(); assertThat(dbClient.userPermissionDao().selectEntityPermissionsOfUser(dbSession, user1.getUuid(), project.getUuid())) - .containsOnly(UserRole.USER, UserRole.CODEVIEWER, "p1", "p2"); + .containsOnly(ProjectPermission.USER.getKey(), ProjectPermission.CODEVIEWER.getKey(), "p1", "p2"); assertThat(dbClient.userPermissionDao().selectEntityPermissionsOfUser(dbSession, user2.getUuid(), project.getUuid())) - .containsOnly(UserRole.USER, UserRole.CODEVIEWER, "p2"); + .containsOnly(ProjectPermission.USER.getKey(), ProjectPermission.CODEVIEWER.getKey(), "p2"); assertThat(dbClient.userPermissionDao().selectEntityPermissionsOfUser(dbSession, user3.getUuid(), project.getUuid())) .isEmpty(); } @@ -494,16 +495,16 @@ public class UpdateVisibilityActionIT { dbTester.users().insertEntityPermissionOnGroup(group1, "p1", project); dbTester.users().insertEntityPermissionOnGroup(group1, "p2", project); dbTester.users().insertEntityPermissionOnGroup(group2, "p2", project); - userSessionRule.addProjectPermission(UserRole.ADMIN, project); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, project); request.setParam(PARAM_PROJECT, project.getKey()) .setParam(PARAM_VISIBILITY, PRIVATE) .execute(); assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, group1.getUuid(), project.getUuid())) - .containsOnly(UserRole.USER, UserRole.CODEVIEWER, "p1", "p2"); + .containsOnly(ProjectPermission.USER.getKey(), ProjectPermission.CODEVIEWER.getKey(), "p1", "p2"); assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, group2.getUuid(), project.getUuid())) - .containsOnly(UserRole.USER, UserRole.CODEVIEWER, "p2"); + .containsOnly(ProjectPermission.USER.getKey(), ProjectPermission.CODEVIEWER.getKey(), "p2"); assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, group3.getUuid(), project.getUuid())) .isEmpty(); } @@ -512,10 +513,10 @@ public class UpdateVisibilityActionIT { public void update_a_portfolio_to_private() { PortfolioDto portfolio = dbTester.components().insertPublicPortfolioDto(); GroupDto group = dbTester.users().insertGroup(); - dbTester.users().insertEntityPermissionOnGroup(group, UserRole.ISSUE_ADMIN, portfolio); + dbTester.users().insertEntityPermissionOnGroup(group, ProjectPermission.ISSUE_ADMIN, portfolio); UserDto user = dbTester.users().insertUser(); - dbTester.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, portfolio); - userSessionRule.addPortfolioPermission(UserRole.ADMIN, portfolio); + dbTester.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, portfolio); + userSessionRule.addPortfolioPermission(ProjectPermission.ADMIN, portfolio); request.setParam(PARAM_PROJECT, portfolio.getKey()) .setParam(PARAM_VISIBILITY, PRIVATE) @@ -523,23 +524,23 @@ public class UpdateVisibilityActionIT { assertThat(dbClient.portfolioDao().selectByUuid(dbSession, portfolio.getUuid()).get().isPrivate()).isTrue(); assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, group.getUuid(), portfolio.getUuid())) - .containsOnly(UserRole.USER, UserRole.CODEVIEWER, UserRole.ISSUE_ADMIN); + .containsOnly(ProjectPermission.USER.getKey(), ProjectPermission.CODEVIEWER.getKey(), ProjectPermission.ISSUE_ADMIN.getKey()); assertThat(dbClient.userPermissionDao().selectEntityPermissionsOfUser(dbSession, user.getUuid(), portfolio.getUuid())) - .containsOnly(UserRole.USER, UserRole.CODEVIEWER, UserRole.ADMIN); + .containsOnly(ProjectPermission.USER.getKey(), ProjectPermission.CODEVIEWER.getKey(), ProjectPermission.ADMIN.getKey()); } @Test public void update_a_portfolio_to_public() { PortfolioDto portfolio = dbTester.components().insertPrivatePortfolioDto(); - userSessionRule.addPortfolioPermission(UserRole.ADMIN, portfolio); + userSessionRule.addPortfolioPermission(ProjectPermission.ADMIN, portfolio); GroupDto group = dbTester.users().insertGroup(); - dbTester.users().insertEntityPermissionOnGroup(group, UserRole.ISSUE_ADMIN, portfolio); - dbTester.users().insertEntityPermissionOnGroup(group, UserRole.USER, portfolio); - dbTester.users().insertEntityPermissionOnGroup(group, UserRole.CODEVIEWER, portfolio); + dbTester.users().insertEntityPermissionOnGroup(group, ProjectPermission.ISSUE_ADMIN, portfolio); + dbTester.users().insertEntityPermissionOnGroup(group, ProjectPermission.USER, portfolio); + dbTester.users().insertEntityPermissionOnGroup(group, ProjectPermission.CODEVIEWER, portfolio); UserDto user = dbTester.users().insertUser(); - dbTester.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, portfolio); - dbTester.users().insertProjectPermissionOnUser(user, UserRole.USER, portfolio); - dbTester.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, portfolio); + dbTester.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, portfolio); + dbTester.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, portfolio); + dbTester.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, portfolio); request.setParam(PARAM_PROJECT, portfolio.getKey()) .setParam(PARAM_VISIBILITY, PUBLIC) @@ -547,19 +548,19 @@ public class UpdateVisibilityActionIT { assertThat(dbClient.componentDao().selectByUuid(dbSession, portfolio.getUuid()).get().isPrivate()).isFalse(); assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, group.getUuid(), portfolio.getUuid())) - .containsOnly(UserRole.ISSUE_ADMIN); + .containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); assertThat(dbClient.userPermissionDao().selectEntityPermissionsOfUser(dbSession, user.getUuid(), portfolio.getUuid())) - .containsOnly(UserRole.ADMIN); + .containsOnly(ProjectPermission.ADMIN.getKey()); } @Test public void update_an_application_to_private() { ProjectDto application = dbTester.components().insertPublicApplication().getProjectDto(); GroupDto group = dbTester.users().insertGroup(); - dbTester.users().insertEntityPermissionOnGroup(group, UserRole.ISSUE_ADMIN, application); + dbTester.users().insertEntityPermissionOnGroup(group, ProjectPermission.ISSUE_ADMIN, application); UserDto user = dbTester.users().insertUser(); - dbTester.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, application); - userSessionRule.addProjectPermission(UserRole.ADMIN, application); + dbTester.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, application); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, application); request.setParam(PARAM_PROJECT, application.getKey()) .setParam(PARAM_VISIBILITY, PRIVATE) @@ -567,23 +568,23 @@ public class UpdateVisibilityActionIT { assertThat(dbClient.projectDao().selectByUuid(dbSession, application.getUuid()).get().isPrivate()).isTrue(); assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, group.getUuid(), application.getUuid())) - .containsOnly(UserRole.USER, UserRole.CODEVIEWER, UserRole.ISSUE_ADMIN); + .containsOnly(ProjectPermission.USER.getKey(), ProjectPermission.CODEVIEWER.getKey(), ProjectPermission.ISSUE_ADMIN.getKey()); assertThat(dbClient.userPermissionDao().selectEntityPermissionsOfUser(dbSession, user.getUuid(), application.getUuid())) - .containsOnly(UserRole.USER, UserRole.CODEVIEWER, UserRole.ADMIN); + .containsOnly(ProjectPermission.USER.getKey(), ProjectPermission.CODEVIEWER.getKey(), ProjectPermission.ADMIN.getKey()); } @Test public void update_an_application_to_public() { ProjectDto application = dbTester.components().insertPrivateApplication().getProjectDto(); - userSessionRule.addProjectPermission(UserRole.ADMIN, application); + userSessionRule.addProjectPermission(ProjectPermission.ADMIN, application); GroupDto group = dbTester.users().insertGroup(); - dbTester.users().insertEntityPermissionOnGroup(group, UserRole.ISSUE_ADMIN, application); - dbTester.users().insertEntityPermissionOnGroup(group, UserRole.USER, application); - dbTester.users().insertEntityPermissionOnGroup(group, UserRole.CODEVIEWER, application); + dbTester.users().insertEntityPermissionOnGroup(group, ProjectPermission.ISSUE_ADMIN, application); + dbTester.users().insertEntityPermissionOnGroup(group, ProjectPermission.USER, application); + dbTester.users().insertEntityPermissionOnGroup(group, ProjectPermission.CODEVIEWER, application); UserDto user = dbTester.users().insertUser(); - dbTester.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, application); - dbTester.users().insertProjectPermissionOnUser(user, UserRole.USER, application); - dbTester.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, application); + dbTester.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, application); + dbTester.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, application); + dbTester.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, application); request.setParam(PARAM_PROJECT, application.getKey()) .setParam(PARAM_VISIBILITY, PUBLIC) @@ -591,9 +592,9 @@ public class UpdateVisibilityActionIT { assertThat(dbClient.projectDao().selectApplicationByKey(dbSession, application.getKey()).get().isPrivate()).isFalse(); assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, group.getUuid(), application.getUuid())) - .containsOnly(UserRole.ISSUE_ADMIN); + .containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); assertThat(dbClient.userPermissionDao().selectEntityPermissionsOfUser(dbSession, user.getUuid(), application.getUuid())) - .containsOnly(UserRole.ADMIN); + .containsOnly(ProjectPermission.ADMIN.getKey()); } private void unsafeGiveAllPermissionsToRootComponent(ProjectDto projectDto, UserDto user, GroupDto group) { @@ -611,7 +612,7 @@ public class UpdateVisibilityActionIT { }); } - private void unsafeInsertProjectPermissionOnAnyone(ProjectDto projectDto, String permission) { + private void unsafeInsertProjectPermissionOnAnyone(ProjectDto projectDto, ProjectPermission permission) { GroupPermissionDto dto = new GroupPermissionDto() .setUuid(Uuids.createFast()) .setGroupUuid(null) @@ -622,7 +623,7 @@ public class UpdateVisibilityActionIT { dbTester.commit(); } - private void unsafeInsertProjectPermissionOnGroup(ProjectDto projectDto, GroupDto group, String permission) { + private void unsafeInsertProjectPermissionOnGroup(ProjectDto projectDto, GroupDto group, ProjectPermission permission) { GroupPermissionDto dto = new GroupPermissionDto() .setUuid(Uuids.createFast()) .setGroupUuid(group.getUuid()) @@ -634,8 +635,8 @@ public class UpdateVisibilityActionIT { dbTester.commit(); } - private void unsafeInsertProjectPermissionOnUser(ProjectDto component, UserDto user, String permission) { - UserPermissionDto dto = new UserPermissionDto(Uuids.create(), permission, user.getUuid(), component.getUuid()); + private void unsafeInsertProjectPermissionOnUser(ProjectDto component, UserDto user, ProjectPermission permission) { + UserPermissionDto dto = new UserPermissionDto(Uuids.create(), permission.getKey(), user.getUuid(), component.getUuid()); dbTester.getDbClient().userPermissionDao().insert(dbTester.getSession(), dto, component, user, null); dbTester.commit(); } @@ -650,9 +651,9 @@ public class UpdateVisibilityActionIT { assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, null, projectUuid)) .isEmpty(); assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, group.getUuid(), projectUuid)) - .containsAll(permissionService.getAllProjectPermissions()); + .containsAll(permissionService.getAllProjectPermissions().stream().map(ProjectPermission::getKey).collect(Collectors.toSet())); assertThat(dbClient.userPermissionDao().selectEntityPermissionsOfUser(dbSession, user.getUuid(), projectUuid)) - .containsAll(permissionService.getAllProjectPermissions()); + .containsAll(permissionService.getAllProjectPermissions().stream().map(ProjectPermission::getKey).collect(Collectors.toSet())); } private void verifyHasAllPermissionsButProjectPermissionsUserAndBrowse(String projectUuid, UserDto user, GroupDto group) { @@ -663,16 +664,16 @@ public class UpdateVisibilityActionIT { assertThat(dbClient.userPermissionDao().selectGlobalPermissionsOfUser(dbSession, user.getUuid())) .containsAll(GLOBAL_PERMISSIONS_NAME_SET); assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, null, projectUuid)) - .doesNotContain(UserRole.USER) - .doesNotContain(UserRole.CODEVIEWER) + .doesNotContain(ProjectPermission.USER.getKey()) + .doesNotContain(ProjectPermission.CODEVIEWER.getKey()) .containsAll(PROJECT_PERMISSIONS_BUT_USER_AND_CODEVIEWER); assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, group.getUuid(), projectUuid)) - .doesNotContain(UserRole.USER) - .doesNotContain(UserRole.CODEVIEWER) + .doesNotContain(ProjectPermission.USER.getKey()) + .doesNotContain(ProjectPermission.CODEVIEWER.getKey()) .containsAll(PROJECT_PERMISSIONS_BUT_USER_AND_CODEVIEWER); assertThat(dbClient.userPermissionDao().selectEntityPermissionsOfUser(dbSession, user.getUuid(), projectUuid)) - .doesNotContain(UserRole.USER) - .doesNotContain(UserRole.CODEVIEWER) + .doesNotContain(ProjectPermission.USER.getKey()) + .doesNotContain(ProjectPermission.CODEVIEWER.getKey()) .containsAll(PROJECT_PERMISSIONS_BUT_USER_AND_CODEVIEWER); } @@ -684,11 +685,11 @@ public class UpdateVisibilityActionIT { assertThat(dbClient.userPermissionDao().selectGlobalPermissionsOfUser(dbSession, user.getUuid())) .containsAll(GLOBAL_PERMISSIONS_NAME_SET); assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, null, projectUuid)) - .containsAll(permissionService.getAllProjectPermissions()); + .containsAll(permissionService.getAllProjectPermissions().stream().map(ProjectPermission::getKey).collect(Collectors.toSet())); assertThat(dbClient.groupPermissionDao().selectEntityPermissionsOfGroup(dbSession, group.getUuid(), projectUuid)) - .containsAll(permissionService.getAllProjectPermissions()); + .containsAll(permissionService.getAllProjectPermissions().stream().map(ProjectPermission::getKey).collect(Collectors.toSet())); assertThat(dbClient.userPermissionDao().selectEntityPermissionsOfUser(dbSession, user.getUuid(), projectUuid)) - .containsAll(permissionService.getAllProjectPermissions()); + .containsAll(permissionService.getAllProjectPermissions().stream().map(ProjectPermission::getKey).collect(Collectors.toSet())); } private void insertPendingTask(BranchDto branch) { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/CreateEventActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/CreateEventActionIT.java index fc422a000ab..37ec51ffe6c 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/CreateEventActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/CreateEventActionIT.java @@ -26,7 +26,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.UuidFactory; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; @@ -325,7 +325,7 @@ public class CreateEventActionIT { } private void logInAsProjectAdministrator(ProjectDto project) { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); } private CreateEventResponse call(String categoryName, String name, String analysis) { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/DeleteActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/DeleteActionIT.java index 1750eb21b25..d075650e2dd 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/DeleteActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/DeleteActionIT.java @@ -23,7 +23,7 @@ import org.apache.commons.lang3.RandomStringUtils; import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -146,7 +146,7 @@ public class DeleteActionIT { } private void logInAsProjectAdministrator(ProjectData project) { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); } } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/DeleteEventActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/DeleteEventActionIT.java index cd517e6120d..553e7da6897 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/DeleteEventActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/DeleteEventActionIT.java @@ -25,7 +25,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -149,7 +149,7 @@ public class DeleteEventActionIT { } private void logInAsProjectAdministrator(ProjectData project) { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); } } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/SearchActionIT.java index 97ce26c55b6..68e0d7c664c 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/SearchActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/SearchActionIT.java @@ -35,7 +35,7 @@ import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.testfixtures.log.LogAndArguments; import org.sonar.api.testfixtures.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.config.CorePropertyDefinitions; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; @@ -186,7 +186,7 @@ public class SearchActionIT { } private void addProjectPermission(ProjectData projectData) { - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()) .addProjectBranchMapping(projectData.getProjectDto().getUuid(), projectData.getMainBranchComponent()); } @@ -684,7 +684,7 @@ public class SearchActionIT { userSession.logIn() .registerApplication(application) .registerProjects(project1, project2) - .addProjectPermission(UserRole.USER, application, project1); + .addProjectPermission(ProjectPermission.USER, application, project1); var projectDbKey = application.getKey(); assertThatThrownBy(() -> call(projectDbKey)) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/UpdateEventActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/UpdateEventActionIT.java index 366ed153bb8..5cefc8b4537 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/UpdateEventActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectanalysis/ws/UpdateEventActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -161,7 +161,7 @@ public class UpdateEventActionIT { ProjectData project = db.components().insertPrivateProject(); SnapshotDto analysis = db.components().insertSnapshot(project.getMainBranchDto()); db.events().insertEvent(newEvent(analysis).setUuid("E1")); - userSession.logIn().addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project.getProjectDto()); assertThatThrownBy(() -> call("E1", "name")) .isInstanceOf(ForbiddenException.class); @@ -244,7 +244,7 @@ public class UpdateEventActionIT { } private void logInAsProjectAdministrator(ProjectData project) { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectdump/ws/ExportActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectdump/ws/ExportActionIT.java index 8f6709a3e03..c853b11035c 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectdump/ws/ExportActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectdump/ws/ExportActionIT.java @@ -23,7 +23,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.sonar.db.component.ComponentQualifiers; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.ce.task.CeTask; import org.sonar.db.DbTester; import org.sonar.db.ce.CeTaskTypes; @@ -94,7 +94,7 @@ public class ExportActionIT { @Test public void triggers_CE_task() { UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(UserRole.ADMIN, project); + userSession.logIn(user).addProjectPermission(ProjectPermission.ADMIN, project); when(exportSubmitter.submitProjectExport(project.getKey(), user.getUuid())).thenReturn(createResponseExampleTask()); TestResponse response = actionTester.newRequest().setMethod("POST").setParam("key", project.getKey()).execute(); @@ -115,7 +115,7 @@ public class ExportActionIT { @Test public void triggers_CE_task_if_project_admin() { UserDto user = db.users().insertUser(); - userSession.logIn(user).addProjectPermission(UserRole.ADMIN, project); + userSession.logIn(user).addProjectPermission(ProjectPermission.ADMIN, project); when(exportSubmitter.submitProjectExport(project.getKey(), user.getUuid())).thenReturn(createResponseExampleTask()); TestResponse response = actionTester.newRequest().setMethod("POST").setParam("key", project.getKey()).execute(); @@ -124,7 +124,7 @@ public class ExportActionIT { } private void logInAsProjectAdministrator(String login) { - userSession.logIn(login).addProjectPermission(UserRole.ADMIN, project); + userSession.logIn(login).addProjectPermission(ProjectPermission.ADMIN, project); } private String responseExample() { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectdump/ws/StatusActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectdump/ws/StatusActionIT.java index a1e66d4a4ec..87d3f266ffb 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectdump/ws/StatusActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectdump/ws/StatusActionIT.java @@ -32,7 +32,7 @@ import org.junit.Test; import org.sonar.api.config.Configuration; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Slug; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -297,7 +297,7 @@ public class StatusActionIT { } private void logInAsProjectAdministrator(String login) { - userSession.logIn(login).addProjectPermission(UserRole.ADMIN, project); + userSession.logIn(login).addProjectPermission(ProjectPermission.ADMIN, project); } private String ensureDumpFileExists(String projectKey, boolean isImport) throws IOException { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/CreateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/CreateActionIT.java index 2f57a80f8fe..f818315c655 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/CreateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/CreateActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -210,7 +210,7 @@ public class CreateActionIT { public void fail_if_view() { PortfolioData view = db.components().insertPrivatePortfolioData(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, view.getRootComponent()); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, view.getRootComponent()); TestRequest testRequest = ws.newRequest() .setParam(PARAM_NAME, "Custom") .setParam(PARAM_URL, "http://example.org") @@ -232,7 +232,7 @@ public class CreateActionIT { @Test public void fail_when_using_branch_db_uuid() { ProjectData project = db.components().insertPrivateProject(); - userSession.logIn().addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project.getProjectDto()); BranchDto branch = db.components().insertProjectBranch(project.getProjectDto()); TestRequest testRequest = ws.newRequest() @@ -255,7 +255,7 @@ public class CreateActionIT { } private void failIfNotAProjectWithKey(ProjectDto project, ComponentDto component) { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestRequest testRequest = ws.newRequest() .setParam(PARAM_NAME, "Custom") @@ -267,7 +267,7 @@ public class CreateActionIT { } private void failIfNotAProjectWithUuid(ProjectDto project, ComponentDto component) { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestRequest testRequest = ws.newRequest() .setParam(PARAM_NAME, "Custom") @@ -299,6 +299,6 @@ public class CreateActionIT { } private void logInAsProjectAdministrator(ProjectDto project) { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); } } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/DeleteActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/DeleteActionIT.java index 3812f694ee0..bcbaa7bdf0a 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/DeleteActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/DeleteActionIT.java @@ -40,7 +40,7 @@ import org.sonar.server.ws.WsActionTester; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.db.permission.ProjectPermission.ADMIN; import static org.sonar.server.projectlink.ws.ProjectLinksWsParameters.PARAM_ID; public class DeleteActionIT { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/SearchActionIT.java index 23a9a9d253d..012afe3e689 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/SearchActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/SearchActionIT.java @@ -41,8 +41,8 @@ import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.tuple; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.projectlink.ws.ProjectLinksWsParameters.PARAM_PROJECT_ID; import static org.sonar.server.projectlink.ws.ProjectLinksWsParameters.PARAM_PROJECT_KEY; import static org.sonar.test.JsonAssert.assertJson; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projecttag/ws/SetActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projecttag/ws/SetActionIT.java index 17a01df1092..e212b81861f 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projecttag/ws/SetActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projecttag/ws/SetActionIT.java @@ -46,8 +46,8 @@ import static java.net.HttpURLConnection.HTTP_NO_CONTENT; import static java.util.Optional.ofNullable; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.ComponentDbTester.defaults; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.server.es.Indexers.EntityEvent.PROJECT_TAGS_UPDATE; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/QualityGateCaycCheckerIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/QualityGateCaycCheckerIT.java index db9a52ecaf6..343e1854127 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/QualityGateCaycCheckerIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/QualityGateCaycCheckerIT.java @@ -131,6 +131,15 @@ public class QualityGateCaycCheckerIT { assertEquals(COMPLIANT, underTest.checkCaycCompliant(db.getSession(), qualityGateUuid)); } + @Test + public void checkCaycCompliant_whenDuplicatedCondition_doNotThrow() { + String qualityGateUuid = "abcd"; + MetricDto metric = insertMetric(NEW_VIOLATIONS); + insertCondition(metric, qualityGateUuid, metric.getBestValue()); + insertCondition(metric, qualityGateUuid, metric.getBestValue()); + assertEquals(NON_COMPLIANT, underTest.checkCaycCompliant(db.getSession(), qualityGateUuid)); + } + @DataProvider public static Object[][] caycMetrics() { return new Object[][]{ diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/DeselectActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/DeselectActionIT.java index df07675c8e8..2b651ca5e81 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/DeselectActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/DeselectActionIT.java @@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; @@ -76,7 +76,7 @@ class DeselectActionIT { QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); ProjectDto project = db.components().insertPrivateProject().getProjectDto(); associateProjectToQualityGate(project, qualityGate); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); ws.newRequest() .setParam("projectKey", project.getKey()) @@ -141,7 +141,7 @@ class DeselectActionIT { @Test void fail_when_not_project_admin() { ProjectData project = db.components().insertPrivateProject(); - userSession.logIn().addProjectPermission(UserRole.ISSUE_ADMIN, project.getProjectDto()); + userSession.logIn().addProjectPermission(ProjectPermission.ISSUE_ADMIN, project.getProjectDto()); assertThatThrownBy(() -> ws.newRequest() .setParam("projectKey", project.projectKey()) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/GetByProjectActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/GetByProjectActionIT.java index a1a6c209018..229afb86992 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/GetByProjectActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/GetByProjectActionIT.java @@ -22,7 +22,7 @@ package org.sonar.server.qualitygate.ws; import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; @@ -136,7 +136,7 @@ public class GetByProjectActionIT { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); db.qualityGates().setDefaultQualityGate(qualityGate); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); GetByProjectResponse result = ws.newRequest() .setParam("project", project.getKey()) @@ -150,7 +150,7 @@ public class GetByProjectActionIT { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); db.qualityGates().setDefaultQualityGate(qualityGate); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project); GetByProjectResponse result = ws.newRequest() .setParam("project", project.getKey()) @@ -188,6 +188,6 @@ public class GetByProjectActionIT { } private void logInAsProjectUser(ProjectDto project) { - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project); } } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/ProjectStatusActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/ProjectStatusActionIT.java index d990ae3dac0..43140f0e7ed 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/ProjectStatusActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/ProjectStatusActionIT.java @@ -28,7 +28,7 @@ import org.junit.Test; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -108,7 +108,7 @@ public class ProjectStatusActionIT { public void test_json_example() throws IOException { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); MetricDto gateDetailsMetric = insertGateDetailMetric(); SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(mainBranch) @@ -149,7 +149,7 @@ public class ProjectStatusActionIT { newProjectMeasureDto(gateDetailsMetric, mainBranch, lastAnalysis) .setData("not_used")); dbSession.commit(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); String response = ws.newRequest() .setParam(PARAM_ANALYSIS_ID, pastAnalysis.getUuid()) @@ -170,7 +170,7 @@ public class ProjectStatusActionIT { dbClient.measureDao().insert(dbSession, newMeasure(mainBranch, gateDetailsMetric, IOUtils.toString(getClass().getResource("ProjectStatusActionIT/measure_data.json"), UTF_8))); dbSession.commit(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); String response = ws.newRequest() .setParam(PARAM_PROJECT_ID, projectData.projectUuid()) @@ -202,7 +202,7 @@ public class ProjectStatusActionIT { newProjectMeasureDto(gateDetailsMetric, branch, lastAnalysis) .setData("not_used")); dbSession.commit(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); String response = ws.newRequest() .setParam(PARAM_ANALYSIS_ID, pastAnalysis.getUuid()) @@ -223,7 +223,7 @@ public class ProjectStatusActionIT { dbClient.measureDao().insert(dbSession, newMeasure(project, gateDetailsMetric, IOUtils.toString(getClass().getResource("ProjectStatusActionIT/measure_data.json"), UTF_8))); dbSession.commit(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); String response = ws.newRequest() .setParam(PARAM_PROJECT_KEY, project.getKey()) @@ -247,7 +247,7 @@ public class ProjectStatusActionIT { dbClient.measureDao().insert(dbSession, newMeasure(branch, gateDetailsMetric, IOUtils.toString(getClass().getResource("ProjectStatusActionIT/measure_data.json"), UTF_8))); dbSession.commit(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); String response = ws.newRequest() .setParam(PARAM_PROJECT_KEY, mainBranch.getKey()) @@ -273,7 +273,7 @@ public class ProjectStatusActionIT { dbClient.measureDao().insert(dbSession, newMeasure(pr, gateDetailsMetric, IOUtils.toString(getClass().getResource("ProjectStatusActionIT/measure_data.json"), UTF_8))); dbSession.commit(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); String response = ws.newRequest() .setParam(PARAM_PROJECT_KEY, mainBranch.getKey()) @@ -289,7 +289,7 @@ public class ProjectStatusActionIT { ComponentDto mainBranch = projectData.getMainBranchComponent(); SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(mainBranch)); dbSession.commit(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ProjectStatusResponse result = ws.newRequest() .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid()) @@ -303,7 +303,7 @@ public class ProjectStatusActionIT { public void return_undefined_status_if_project_is_not_analyzed() { ProjectData projectData = db.components().insertPrivateProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ProjectStatusResponse result = ws.newRequest() .setParam(PARAM_PROJECT_ID, projectData.projectUuid()) @@ -319,7 +319,7 @@ public class ProjectStatusActionIT { ComponentDto mainBranch = projectData.getMainBranchComponent(); SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(mainBranch)); dbSession.commit(); - userSession.addProjectPermission(UserRole.ADMIN, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.ADMIN, projectData.getProjectDto()); ws.newRequest() .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid()) @@ -332,7 +332,7 @@ public class ProjectStatusActionIT { ComponentDto mainBranch = projectData.getMainBranchComponent(); SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(mainBranch)); dbSession.commit(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ws.newRequest() .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid()) @@ -348,7 +348,7 @@ public class ProjectStatusActionIT { when(qualityGateCaycChecker.checkCaycCompliantFromProject(any(DbSession.class), eq(projectData.projectUuid()))).thenReturn(COMPLIANT); SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(mainBranch)); dbSession.commit(); - userSession.addProjectPermission(UserRole.USER, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()); ProjectStatusResponse result = ws.newRequest() .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid()) @@ -363,7 +363,7 @@ public class ProjectStatusActionIT { ComponentDto mainBranch = projectData.getMainBranchComponent(); SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(mainBranch)); dbSession.commit(); - userSession.addProjectPermission(UserRole.SCAN, projectData.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.SCAN, projectData.getProjectDto()); var response = ws.newRequest() .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid()).execute(); @@ -451,7 +451,7 @@ public class ProjectStatusActionIT { public void fail_when_using_branch_uuid() { ProjectData projectData = db.components().insertPublicProject(); ComponentDto mainBranch = projectData.getMainBranchComponent(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, projectData.getProjectDto()); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, projectData.getProjectDto()); ComponentDto branch = db.components().insertProjectBranch(mainBranch); SnapshotDto snapshot = db.components().insertSnapshot(branch); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/SearchActionIT.java index 8456e2ffede..93e63822c2b 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/SearchActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/SearchActionIT.java @@ -48,7 +48,7 @@ import static org.mockito.Mockito.when; import static org.sonar.api.server.ws.WebService.SelectionMode.ALL; import static org.sonar.api.server.ws.WebService.SelectionMode.DESELECTED; import static org.sonar.api.server.ws.WebService.SelectionMode.SELECTED; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_GATES; import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_NAME; import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PAGE; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/SelectActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/SelectActionIT.java index a9cd281be44..33f243e7d43 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/SelectActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualitygate/ws/SelectActionIT.java @@ -37,8 +37,8 @@ import org.sonar.server.ws.WsActionTester; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_GATES; import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_NAME; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/QProfileBackuperImplIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/QProfileBackuperImplIT.java index 01f81f997d6..e742c401c4d 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/QProfileBackuperImplIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/QProfileBackuperImplIT.java @@ -39,7 +39,7 @@ import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbSession; @@ -105,7 +105,7 @@ class QProfileBackuperImplIT { "<rule>" + "<repositoryKey>" + rule.getRepositoryKey() + "</repositoryKey>" + "<key>" + rule.getRuleKey() + "</key>" + - "<type>" + RuleType.valueOf(rule.getType()).name() + "</type>" + + "<type>" + RuleType.fromDbConstant(rule.getType()).name() + "</type>" + "<priority>" + activeRule.getSeverityString() + "</priority>" + "<impacts>" + "<impact>" + @@ -135,7 +135,7 @@ class QProfileBackuperImplIT { "<rule>" + "<repositoryKey>" + rule.getRepositoryKey() + "</repositoryKey>" + "<key>" + rule.getRuleKey() + "</key>" + - "<type>" + RuleType.valueOf(rule.getType()).name() + "</type>" + + "<type>" + RuleType.fromDbConstant(rule.getType()).name() + "</type>" + "<priority>" + activeRule.getSeverityString() + "</priority>" + "<impacts>" + "<impact>" + @@ -164,7 +164,7 @@ class QProfileBackuperImplIT { "<rule>" + "<repositoryKey>" + rule.getRepositoryKey() + "</repositoryKey>" + "<key>" + rule.getRuleKey() + "</key>" + - "<type>" + RuleType.valueOf(rule.getType()).name() + "</type>" + + "<type>" + RuleType.fromDbConstant(rule.getType()).name() + "</type>" + "<priority>" + activeRule.getSeverityString() + "</priority>" + "<impacts>" + "<impact>" + @@ -217,7 +217,7 @@ class QProfileBackuperImplIT { "<rules><rule>" + "<repositoryKey>" + rule.getRepositoryKey() + "</repositoryKey>" + "<key>" + rule.getKey().rule() + "</key>" + - "<type>" + RuleType.valueOf(rule.getType()) + "</type>" + + "<type>" + RuleType.fromDbConstant(rule.getType()) + "</type>" + "<priority>" + activeRule.getSeverityString() + "</priority>" + "<impacts>" + "<impact>" + @@ -254,7 +254,7 @@ class QProfileBackuperImplIT { "<rules><rule>" + "<repositoryKey>" + rule.getRepositoryKey() + "</repositoryKey>" + "<key>" + rule.getKey().rule() + "</key>" + - "<type>" + RuleType.valueOf(rule.getType()) + "</type>" + + "<type>" + RuleType.fromDbConstant(rule.getType()) + "</type>" + "<priority>" + activeRule.getSeverityString() + "</priority>" + "<impacts>" + "<impact>" + @@ -404,7 +404,7 @@ class QProfileBackuperImplIT { "<rule>" + "<repositoryKey>" + rule.getRepositoryKey() + "</repositoryKey>" + "<key>" + rule.getRuleKey() + "</key>" + - "<type>" + RuleType.valueOf(rule.getType()).name() + "</type>" + + "<type>" + RuleType.fromDbConstant(rule.getType()).name() + "</type>" + "<priority>" + activeRule.getSeverityString() + "</priority>" + (prioritizedInBackup == null ? "" : "<prioritizedRule>" + prioritizedInBackup + "</prioritizedRule>") + "</rule>" + diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/QProfileExportersIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/QProfileExportersIT.java deleted file mode 100644 index 9e06d87c0d6..00000000000 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/QProfileExportersIT.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.qualityprofile; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; -import java.util.Collection; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; -import org.sonar.api.profiles.ProfileExporter; -import org.sonar.api.profiles.ProfileImporter; -import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.rules.Rule; -import org.sonar.api.rules.RuleFinder; -import org.sonar.api.rules.RulePriority; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.ValidationMessages; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.rule.RuleDto; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.rule.DefaultRuleFinder; -import org.sonar.server.rule.RuleDescriptionFormatter; -import org.sonar.server.tester.UserSessionRule; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.apache.commons.io.IOUtils.toInputStream; -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.verify; -import static org.sonar.db.qualityprofile.QualityProfileTesting.newQualityProfileDto; - -public class QProfileExportersIT { - - @org.junit.Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - - private final System2 system2 = new AlwaysIncreasingSystem2(); - - @org.junit.Rule - public DbTester db = DbTester.create(system2); - - private final RuleFinder ruleFinder = new DefaultRuleFinder(db.getDbClient(), mock(RuleDescriptionFormatter.class)); - private final ProfileExporter[] exporters = new ProfileExporter[] { - new StandardExporter(), new XooExporter()}; - private final ProfileImporter[] importers = new ProfileImporter[] { - new XooProfileImporter(), new XooProfileImporterWithMessages(), new XooProfileImporterWithError()}; - private RuleDto rule; - private final QProfileRules qProfileRules = mock(QProfileRules.class); - private final QProfileExporters underTest = new QProfileExporters(db.getDbClient(), ruleFinder, qProfileRules, exporters, importers); - - @Before - public void setUp() { - rule = db.rules().insert(r -> r.setLanguage("xoo").setRepositoryKey("SonarXoo").setRuleKey("R1")); - } - - @Test - public void exportersForLanguage() { - assertThat(underTest.exportersForLanguage("xoo")).hasSize(2); - assertThat(underTest.exportersForLanguage("java")).hasSize(1); - assertThat(underTest.exportersForLanguage("java").get(0)).isInstanceOf(StandardExporter.class); - } - - @Test - public void mimeType() { - assertThat(underTest.mimeType("xootool")).isEqualTo("plain/custom"); - - // default mime type - assertThat(underTest.mimeType("standard")).isEqualTo("text/plain"); - } - - @Test - public void import_xml() { - QProfileDto profile = createProfile(); - - underTest.importXml(profile, "XooProfileImporter", toInputStream("<xml/>", UTF_8), db.getSession()); - - ArgumentCaptor<QProfileDto> profileCapture = ArgumentCaptor.forClass(QProfileDto.class); - Class<Collection<RuleActivation>> collectionClass = (Class<Collection<RuleActivation>>) (Class) Collection.class; - ArgumentCaptor<Collection<RuleActivation>> activationCapture = ArgumentCaptor.forClass(collectionClass); - verify(qProfileRules).activateAndCommit(any(DbSession.class), profileCapture.capture(), activationCapture.capture()); - - assertThat(profileCapture.getValue().getKee()).isEqualTo(profile.getKee()); - Collection<RuleActivation> activations = activationCapture.getValue(); - assertThat(activations).hasSize(1); - RuleActivation activation = activations.iterator().next(); - assertThat(activation.getRuleUuid()).isEqualTo(rule.getUuid()); - assertThat(activation.getSeverity()).isEqualTo("CRITICAL"); - } - - @Test - public void import_xml_return_messages() { - QProfileDto profile = createProfile(); - - QProfileResult result = underTest.importXml(profile, "XooProfileImporterWithMessages", toInputStream("<xml/>", UTF_8), db.getSession()); - - assertThat(result.infos()).containsOnly("an info"); - assertThat(result.warnings()).containsOnly("a warning"); - } - - @Test - public void fail_to_import_xml_when_error_in_importer() { - QProfileDto qProfileDto = newQualityProfileDto(); - InputStream inputStream = toInputStream("<xml/>", UTF_8); - DbSession dbSession = db.getSession(); - assertThatThrownBy(() -> underTest.importXml( - qProfileDto, "XooProfileImporterWithError", inputStream, dbSession)) - .isInstanceOf(BadRequestException.class) - .hasMessage("error!"); - } - - @Test - public void fail_to_import_xml_on_unknown_importer() { - QProfileDto qProfileDto = newQualityProfileDto(); - InputStream inputStream = toInputStream("<xml/>", UTF_8); - DbSession dbSession = db.getSession(); - assertThatThrownBy(() -> underTest.importXml(qProfileDto, "Unknown", inputStream, dbSession)) - .isInstanceOf(BadRequestException.class) - .hasMessage("No such importer : Unknown"); - } - - @Test - public void export_empty_profile() { - QProfileDto profile = createProfile(); - - StringWriter writer = new StringWriter(); - underTest.export(db.getSession(), profile, "standard", writer); - assertThat(writer).hasToString("standard -> " + profile.getName() + " -> 0"); - - writer = new StringWriter(); - underTest.export(db.getSession(), profile, "xootool", writer); - assertThat(writer).hasToString("xoo -> " + profile.getName() + " -> 0"); - } - - @Test - public void export_profile() { - QProfileDto profile = createProfile(); - db.qualityProfiles().activateRule(profile, rule); - - StringWriter writer = new StringWriter(); - underTest.export(db.getSession(), profile, "standard", writer); - assertThat(writer).hasToString("standard -> " + profile.getName() + " -> 1"); - - writer = new StringWriter(); - underTest.export(db.getSession(), profile, "xootool", writer); - assertThat(writer).hasToString("xoo -> " + profile.getName() + " -> 1"); - } - - @Test - public void export_throws_NotFoundException_if_exporter_does_not_exist() { - QProfileDto profile = createProfile(); - - assertThatThrownBy(() -> { - underTest.export(db.getSession(), profile, "does_not_exist", new StringWriter()); - }) - .isInstanceOf(NotFoundException.class) - .hasMessage("Unknown quality profile exporter: does_not_exist"); - } - - private QProfileDto createProfile() { - return db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage())); - } - - public static class XooExporter extends ProfileExporter { - public XooExporter() { - super("xootool", "Xoo Tool"); - } - - @Override - public String[] getSupportedLanguages() { - return new String[] {"xoo"}; - } - - @Override - public String getMimeType() { - return "plain/custom"; - } - - @Override - public void exportProfile(RulesProfile profile, Writer writer) { - try { - writer.write("xoo -> " + profile.getName() + " -> " + profile.getActiveRules().size()); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - } - - public static class StandardExporter extends ProfileExporter { - public StandardExporter() { - super("standard", "Standard"); - } - - @Override - public void exportProfile(RulesProfile profile, Writer writer) { - try { - writer.write("standard -> " + profile.getName() + " -> " + profile.getActiveRules().size()); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - } - - public class XooProfileImporter extends ProfileImporter { - public XooProfileImporter() { - super("XooProfileImporter", "Xoo Profile Importer"); - } - - @Override - public String[] getSupportedLanguages() { - return new String[] {"xoo"}; - } - - @Override - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { - RulesProfile rulesProfile = RulesProfile.create(); - rulesProfile.activateRule(Rule.create(rule.getRepositoryKey(), rule.getRuleKey()), RulePriority.CRITICAL); - return rulesProfile; - } - } - - public static class XooProfileImporterWithMessages extends ProfileImporter { - public XooProfileImporterWithMessages() { - super("XooProfileImporterWithMessages", "Xoo Profile Importer With Message"); - } - - @Override - public String[] getSupportedLanguages() { - return new String[] {}; - } - - @Override - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { - messages.addWarningText("a warning"); - messages.addInfoText("an info"); - return RulesProfile.create(); - } - } - - public static class XooProfileImporterWithError extends ProfileImporter { - public XooProfileImporterWithError() { - super("XooProfileImporterWithError", "Xoo Profile Importer With Error"); - } - - @Override - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { - messages.addErrorText("error!"); - return RulesProfile.create(); - } - } - -} diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileUpdateImplIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileUpdateImplIT.java index 37ebd8e5cc7..3dc6c004fd8 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileUpdateImplIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileUpdateImplIT.java @@ -309,6 +309,40 @@ class BuiltInQProfileUpdateImplIT { verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage())); } + @Test + void deactivated_rule_should_not_be_activated_in_descendant_profiles() { + RuleDto rule1 = db.rules().insert(r -> r.setLanguage("xoo")); + RuleDto rule2 = db.rules().insert(r -> r.setLanguage("xoo")); + + QProfileDto parentProfile = db.qualityProfiles().insert(p -> p.setLanguage("xoo").setIsBuiltIn(true)); + activateRuleInDb(RulesProfileDto.from(parentProfile), rule1, RulePriority.valueOf(Severity.MINOR), + Map.of(SoftwareQuality.MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW)); + activateRuleInDb(RulesProfileDto.from(parentProfile), rule2, RulePriority.valueOf(Severity.MINOR), + Map.of(SoftwareQuality.MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW)); + + // child profile has only rule1 activated, to simulate rule2 is deactivated + QProfileDto childProfile = createChildProfile(parentProfile); + activateRuleInDb(RulesProfileDto.from(childProfile), rule1, RulePriority.valueOf(Severity.MINOR), + Map.of(SoftwareQuality.MAINTAINABILITY, org.sonar.api.issue.impact.Severity.LOW), INHERITED); + + BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context(); + NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile(parentProfile.getName(), parentProfile.getLanguage()); + newQp.activateRule(rule1.getRepositoryKey(), rule1.getRuleKey()); + newQp.activateRule(rule2.getRepositoryKey(), rule2.getRuleKey()); + newQp.done(); + BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile(parentProfile.getLanguage(), parentProfile.getName()), rule1, rule2); + List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, RulesProfileDto.from(parentProfile)); + + assertThat(changes).hasSize(3); + + List<ActiveRuleDto> parentActiveRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), RulesProfileDto.from(parentProfile)); + assertThatRuleIsUpdated(parentActiveRules, rule1, RulePriority.valueOfInt(rule1.getSeverity()), rule1.getDefaultImpactsMap()); + assertThatRuleIsUpdated(parentActiveRules, rule2, RulePriority.valueOfInt(rule2.getSeverity()), rule2.getDefaultImpactsMap()); + + List<ActiveRuleDto> childActiveRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), RulesProfileDto.from(childProfile)); + assertThatRuleIsUpdated(childActiveRules, rule1, RulePriority.valueOfInt(rule1.getSeverity()), rule1.getDefaultImpactsMap(), INHERITED); + } + // SONAR-14559 @Test void propagate_rule_update_to_descendant_active_rule() { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/builtin/RuleActivatorIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/builtin/RuleActivatorIT.java index 7f730090ed2..363005b4f4e 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/builtin/RuleActivatorIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/builtin/RuleActivatorIT.java @@ -21,6 +21,7 @@ package org.sonar.server.qualityprofile.builtin; import java.util.List; import java.util.Map; +import java.util.Set; import javax.annotation.Nullable; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -65,6 +66,7 @@ import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.Map.of; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.tuple; import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.mock; import static org.sonar.api.issue.impact.SoftwareQuality.MAINTAINABILITY; @@ -360,6 +362,83 @@ class RuleActivatorIT { () -> underTest.activate(session, resetRequest, context)); } + @Test + void testActivate_whenProfileIsNotBuiltInAndRuleUuidInPreviousBuiltinActiveRuleUuids_shouldContainNoChange() { + QProfileDto builtinProfile = db.qualityProfiles().insert(p -> p.setIsBuiltIn(true).setLanguage("xoo")); + QProfileDto customProfile = createChildProfile(builtinProfile); + + RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo").setSeverity(Severity.CRITICAL)); + ActiveRuleDto builtinActiveRuleDto = activateRuleInDb(RulesProfileDto.from(builtinProfile), rule, + RulePriority.valueOf(Severity.CRITICAL), Map.of(MAINTAINABILITY, org.sonar.api.issue.impact.Severity.HIGH), null, null); + + RuleActivationContext context = new RuleActivationContext.Builder() + .setProfiles(List.of(builtinProfile, customProfile)) + .setBaseProfile(RulesProfileDto.from(builtinProfile)) + .setPreviousBuiltinActiveRuleUuids(Set.of(rule.getUuid())) + .setDescendantProfilesSupplier((profiles, ruleUuids) -> new Result(emptyList(), emptyList(), emptyList())) + .setRules(singletonList(rule)) + .setRuleParams(emptyList()) + .setActiveRules(List.of(builtinActiveRuleDto)) + .setActiveRuleParams(emptyList()) + .build(); + + RuleActivation activation = RuleActivation.create(rule.getUuid()); + + List<ActiveRuleChange> result = underTest.activate(db.getSession(), activation, context); + assertThat(result).isEmpty(); + } + + @Test + void testActivate_whenProfileIsNotBuiltInAndRuleUuidNotInPreviousBuiltinActiveRuleUuids_shouldContainActivation() { + QProfileDto builtinProfile = db.qualityProfiles().insert(p -> p.setIsBuiltIn(true).setLanguage("xoo")); + QProfileDto customProfile = createChildProfile(builtinProfile); + + RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo").setSeverity(Severity.CRITICAL)); + ActiveRuleDto builtinActiveRuleDto = activateRuleInDb(RulesProfileDto.from(builtinProfile), rule, + RulePriority.valueOf(Severity.CRITICAL), Map.of(MAINTAINABILITY, org.sonar.api.issue.impact.Severity.HIGH), null, null); + + RuleActivationContext context = new RuleActivationContext.Builder() + .setProfiles(List.of(builtinProfile, customProfile)) + .setBaseProfile(RulesProfileDto.from(builtinProfile)) + .setPreviousBuiltinActiveRuleUuids(Set.of("another-rule-uuid")) + .setDescendantProfilesSupplier((profiles, ruleUuids) -> new Result(emptyList(), emptyList(), emptyList())) + .setRules(singletonList(rule)) + .setRuleParams(emptyList()) + .setActiveRules(List.of(builtinActiveRuleDto)) + .setActiveRuleParams(emptyList()) + .build(); + + RuleActivation activation = RuleActivation.create(rule.getUuid()); + + List<ActiveRuleChange> result = underTest.activate(db.getSession(), activation, context); + assertThat(result) + .hasSize(1) + .extracting(ActiveRuleChange::getRuleUuid, ActiveRuleChange::getKey) + .containsExactlyInAnyOrder(tuple(rule.getUuid(), ActiveRuleKey.of(customProfile, RuleKey.of(rule.getRepositoryKey(), rule.getRuleKey())))); + } + + @Test + void testActivate_whenProfileIsBuiltIn_shouldContainActivation() { + QProfileDto profile = db.qualityProfiles().insert(p -> p.setIsBuiltIn(true).setLanguage("xoo")); + RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo")); + RuleActivationContext context = new RuleActivationContext.Builder() + .setProfiles(List.of(profile)) + .setBaseProfile(RulesProfileDto.from(profile)) + .setPreviousBuiltinActiveRuleUuids(Set.of(rule.getUuid())) + .setDescendantProfilesSupplier((profiles, ruleUuids) -> new Result(emptyList(), emptyList(), emptyList())) + .setRules(singletonList(rule)) + .setRuleParams(emptyList()) + .setActiveRules(emptyList()) + .setActiveRuleParams(emptyList()) + .build(); + + RuleActivation activation = RuleActivation.create(rule.getUuid()); + + List<ActiveRuleChange> result = underTest.activate(db.getSession(), activation, context); + assertThat(result).hasSize(1); + assertThat(result.get(0).getRuleUuid()).isEqualTo(rule.getUuid()); + } + private ActiveRuleDto activateRuleInDb(RulesProfileDto ruleProfile, RuleDto rule, RulePriority severity, Map<SoftwareQuality, org.sonar.api.issue.impact.Severity> impacts, @Nullable Boolean prioritizedRule, @Nullable ActiveRuleInheritance inheritance) { ActiveRuleDto dto = new ActiveRuleDto() diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/AddProjectActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/AddProjectActionIT.java index e9c3e23a07a..d0033c92997 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/AddProjectActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/AddProjectActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.resources.Languages; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; @@ -146,7 +146,7 @@ public class AddProjectActionIT { public void project_administrator_can_change_profile() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); QProfileDto profile = db.qualityProfiles().insert(qp -> qp.setLanguage("xoo")); - userSession.logIn(db.users().insertUser()).addProjectPermission(UserRole.ADMIN, project); + userSession.logIn(db.users().insertUser()).addProjectPermission(ProjectPermission.ADMIN, project); call(project, profile); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/CompareActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/CompareActionIT.java index f7e26b0be12..f7d02ec35b6 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/CompareActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/CompareActionIT.java @@ -31,7 +31,7 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RuleParamType; import org.sonar.api.server.ws.WebService; import org.sonar.core.util.Uuids; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/CreateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/CreateActionIT.java index 395b4147c18..af594642a2e 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/CreateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/CreateActionIT.java @@ -19,43 +19,20 @@ */ package org.sonar.server.qualityprofile.ws; -import com.google.common.collect.ImmutableMap; -import java.io.Reader; -import java.util.Collections; -import java.util.Map; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.config.Configuration; -import org.sonar.api.profiles.ProfileImporter; -import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.rules.RulePriority; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; -import org.sonar.api.utils.ValidationMessages; -import org.sonar.api.utils.Version; -import org.sonar.core.platform.SonarQubeVersion; import org.sonar.core.util.UuidFactoryFast; -import org.sonar.core.util.UuidFactoryImpl; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.rule.RuleDto; -import org.sonar.db.rule.RuleTesting; import org.sonar.server.es.EsTester; -import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.pushapi.qualityprofile.QualityProfileChangeEventService; -import org.sonar.server.qualityprofile.QProfileExporters; import org.sonar.server.qualityprofile.QProfileFactoryImpl; -import org.sonar.server.qualityprofile.QProfileRules; -import org.sonar.server.qualityprofile.QProfileRulesImpl; -import org.sonar.server.qualityprofile.builtin.RuleActivator; import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; -import org.sonar.server.rule.index.RuleIndex; -import org.sonar.server.rule.index.RuleIndexer; -import org.sonar.server.rule.index.RuleQuery; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.TestResponse; @@ -67,7 +44,6 @@ import org.sonarqube.ws.Qualityprofiles.CreateWsResponse.QualityProfile; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_PROFILES; import static org.sonar.db.permission.GlobalPermission.SCAN; import static org.sonar.server.language.LanguageTesting.newLanguages; @@ -75,9 +51,6 @@ import static org.sonar.server.language.LanguageTesting.newLanguages; class CreateActionIT { private static final String XOO_LANGUAGE = "xoo"; - private static final RuleDto RULE = RuleTesting.newXooX1() - .setSeverity("MINOR") - .setLanguage(XOO_LANGUAGE); @RegisterExtension private final DbTester db = DbTester.create(); @@ -86,21 +59,12 @@ class CreateActionIT { @RegisterExtension private final UserSessionRule userSession = UserSessionRule.standalone(); - private final Configuration config = mock(Configuration.class); private final DbClient dbClient = db.getDbClient(); private final DbSession dbSession = db.getSession(); - private final RuleIndex ruleIndex = new RuleIndex(es.client(), System2.INSTANCE, config); - private final RuleIndexer ruleIndexer = new RuleIndexer(es.client(), dbClient); private final ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(dbClient, es.client()); - private final ProfileImporter[] profileImporters = createImporters(); - private final QualityProfileChangeEventService qualityProfileChangeEventService = mock(QualityProfileChangeEventService.class); - private final SonarQubeVersion sonarQubeVersion = new SonarQubeVersion(Version.create(10, 3)); - private final RuleActivator ruleActivator = new RuleActivator(System2.INSTANCE, dbClient, UuidFactoryImpl.INSTANCE, null, userSession, mock(Configuration.class), sonarQubeVersion); - private final QProfileRules qProfileRules = new QProfileRulesImpl(dbClient, ruleActivator, ruleIndex, activeRuleIndexer, qualityProfileChangeEventService); - private final QProfileExporters qProfileExporters = new QProfileExporters(dbClient, null, qProfileRules, profileImporters); private final CreateAction underTest = new CreateAction(dbClient, new QProfileFactoryImpl(dbClient, UuidFactoryFast.getInstance(), System2.INSTANCE, activeRuleIndexer), - qProfileExporters, newLanguages(XOO_LANGUAGE), userSession, activeRuleIndexer, profileImporters); + newLanguages(XOO_LANGUAGE), userSession); private WsActionTester ws = new WsActionTester(underTest); @@ -111,7 +75,7 @@ class CreateActionIT { assertThat(definition.responseExampleAsString()).isNotEmpty(); assertThat(definition.isPost()).isTrue(); assertThat(definition.params()).extracting(Param::key) - .containsExactlyInAnyOrder("language", "name", "backup_with_messages", "backup_with_errors", "backup_xoo_lint"); + .containsExactlyInAnyOrder("language", "name"); } @Test @@ -136,30 +100,6 @@ class CreateActionIT { } @Test - void create_profile_from_backup_xml() { - logInAsQProfileAdministrator(); - insertRule(RULE); - - executeRequest("New Profile", XOO_LANGUAGE, ImmutableMap.of("xoo_lint", "<xml/>")); - - QProfileDto dto = dbClient.qualityProfileDao().selectByNameAndLanguage(dbSession, "New Profile", XOO_LANGUAGE); - assertThat(dto.getKee()).isNotNull(); - assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, dto.getKee())).hasSize(1); - assertThat(ruleIndex.searchAll(new RuleQuery().setQProfile(dto).setActivation(true))).toIterable().hasSize(1); - } - - @Test - void create_profile_with_messages() { - logInAsQProfileAdministrator(); - - CreateWsResponse response = executeRequest("Profile with messages", XOO_LANGUAGE, ImmutableMap.of("with_messages", "<xml/>")); - - QualityProfile profile = response.getProfile(); - assertThat(profile.getInfos().getInfosList()).containsOnly("an info"); - assertThat(profile.getWarnings().getWarningsList()).containsOnly("a warning"); - } - - @Test void fail_if_unsufficient_privileges() { userSession .logIn() @@ -175,16 +115,6 @@ class CreateActionIT { } @Test - void fail_if_import_generate_error() { - logInAsQProfileAdministrator(); - - assertThatThrownBy(() -> { - executeRequest("Profile with errors", XOO_LANGUAGE, ImmutableMap.of("with_errors", "<xml/>")); - }) - .isInstanceOf(BadRequestException.class); - } - - @Test void test_json() { logInAsQProfileAdministrator(); @@ -199,23 +129,10 @@ class CreateActionIT { assertThat(response.getMediaType()).isEqualTo(MediaTypes.JSON); } - private void insertRule(RuleDto ruleDto) { - dbClient.ruleDao().insert(dbSession, ruleDto); - dbSession.commit(); - ruleIndexer.commitAndIndex(dbSession, ruleDto.getUuid()); - } - private CreateWsResponse executeRequest(String name, String language) { - return executeRequest(name, language, Collections.emptyMap()); - } - - private CreateWsResponse executeRequest(String name, String language, Map<String, String> xmls) { TestRequest request = ws.newRequest() .setParam("name", name) .setParam("language", language); - for (Map.Entry<String, String> entry : xmls.entrySet()) { - request.setParam("backup_" + entry.getKey(), entry.getValue()); - } return executeRequest(request); } @@ -223,55 +140,6 @@ class CreateActionIT { return request.executeProtobuf(CreateWsResponse.class); } - private ProfileImporter[] createImporters() { - class DefaultProfileImporter extends ProfileImporter { - private DefaultProfileImporter() { - super("xoo_lint", "Xoo Lint"); - setSupportedLanguages(XOO_LANGUAGE); - } - - @Override - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { - RulesProfile rulesProfile = RulesProfile.create(); - rulesProfile.activateRule(org.sonar.api.rules.Rule.create(RULE.getRepositoryKey(), RULE.getRuleKey()), RulePriority.BLOCKER); - return rulesProfile; - } - } - - class ProfileImporterGeneratingMessages extends ProfileImporter { - private ProfileImporterGeneratingMessages() { - super("with_messages", "With messages"); - setSupportedLanguages(XOO_LANGUAGE); - } - - @Override - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { - RulesProfile rulesProfile = RulesProfile.create(); - messages.addWarningText("a warning"); - messages.addInfoText("an info"); - return rulesProfile; - } - } - - class ProfileImporterGeneratingErrors extends ProfileImporter { - private ProfileImporterGeneratingErrors() { - super("with_errors", "With errors"); - setSupportedLanguages(XOO_LANGUAGE); - } - - @Override - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { - RulesProfile rulesProfile = RulesProfile.create(); - messages.addErrorText("error!"); - return rulesProfile; - } - } - - return new ProfileImporter[] { - new DefaultProfileImporter(), new ProfileImporterGeneratingMessages(), new ProfileImporterGeneratingErrors() - }; - } - private void logInAsQProfileAdministrator() { userSession .logIn() diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/ExportActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/ExportActionIT.java index 8b33646673d..c22c3ddd306 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/ExportActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/ExportActionIT.java @@ -23,11 +23,8 @@ import java.io.IOException; import java.io.Reader; import java.io.Writer; import javax.annotation.Nullable; -import org.apache.commons.lang3.StringUtils; import org.junit.Rule; import org.junit.Test; -import org.sonar.api.profiles.ProfileExporter; -import org.sonar.api.profiles.RulesProfile; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; import org.sonar.db.DbClient; @@ -37,7 +34,6 @@ import org.sonar.db.qualityprofile.QProfileDto; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.language.LanguageTesting; import org.sonar.server.qualityprofile.QProfileBackuper; -import org.sonar.server.qualityprofile.QProfileExporters; import org.sonar.server.qualityprofile.QProfileRestoreSummary; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsActionTester; @@ -60,39 +56,10 @@ public class ExportActionIT { private final QProfileBackuper backuper = new TestBackuper(); @Test - public void export_profile() { + public void return_backup() { QProfileDto profile = createProfile(false); - WsActionTester tester = newWsActionTester(newExporter("polop"), newExporter("palap")); - String result = tester.newRequest() - .setParam("language", profile.getLanguage()) - .setParam("qualityProfile", profile.getName()) - .setParam("exporterKey", "polop").execute() - .getInput(); - - assertThat(result).isEqualTo("Profile " + profile.getLanguage() + "/" + profile.getName() + " exported by polop"); - } - - @Test - public void export_default_profile() { - QProfileDto nonDefaultProfile = createProfile(false); - QProfileDto defaultProfile = createProfile(true); - - WsActionTester tester = newWsActionTester(newExporter("polop"), newExporter("palap")); - String result = tester.newRequest() - .setParam("language", XOO_LANGUAGE) - .setParam("exporterKey", "polop") - .execute() - .getInput(); - - assertThat(result).isEqualTo("Profile " + defaultProfile.getLanguage() + "/" + defaultProfile.getName() + " exported by polop"); - } - - @Test - public void return_backup_when_exporter_is_not_specified() { - QProfileDto profile = createProfile(false); - - String result = newWsActionTester(newExporter("polop")).newRequest() + String result = newWsActionTester().newRequest() .setParam("language", profile.getLanguage()) .setParam("qualityProfile", profile.getName()) .execute() @@ -112,20 +79,7 @@ public class ExportActionIT { } @Test - public void throw_IAE_if_export_with_specified_key_does_not_exist() { - QProfileDto profile = createProfile(true); - - assertThatThrownBy(() -> { - newWsActionTester(newExporter("polop"), newExporter("palap")).newRequest() - .setParam("language", XOO_LANGUAGE) - .setParam("exporterKey", "unknown").execute(); - }) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Value of parameter 'exporterKey' (unknown) must be one of: [polop, palap]"); - } - - @Test - public void definition_without_exporters() { + public void definition() { WebService.Action definition = newWsActionTester().getDef(); assertThat(definition.isPost()).isFalse(); @@ -139,18 +93,6 @@ public class ExportActionIT { assertThat(language.deprecatedSince()).isNullOrEmpty(); } - @Test - public void definition_with_exporters() { - WebService.Action definition = newWsActionTester(newExporter("polop"), newExporter("palap")).getDef(); - - assertThat(definition.isPost()).isFalse(); - assertThat(definition.isInternal()).isFalse(); - assertThat(definition.params()).extracting("key").containsExactlyInAnyOrder("language", "qualityProfile", "exporterKey"); - WebService.Param exportersParam = definition.param("exporterKey"); - assertThat(exportersParam.possibleValues()).containsOnly("polop", "palap"); - assertThat(exportersParam.isInternal()).isFalse(); - } - private QProfileDto createProfile(boolean isDefault) { QProfileDto profile = db.qualityProfiles().insert(p -> p.setLanguage(XOO_LANGUAGE)); if (isDefault) { @@ -159,27 +101,8 @@ public class ExportActionIT { return profile; } - private WsActionTester newWsActionTester(ProfileExporter... profileExporters) { - QProfileExporters exporters = new QProfileExporters(dbClient, null, null, profileExporters, null); - return new WsActionTester(new ExportAction(dbClient, backuper, exporters, LanguageTesting.newLanguages(XOO_LANGUAGE, JAVA_LANGUAGE))); - } - - private static ProfileExporter newExporter(String key) { - return new ProfileExporter(key, StringUtils.capitalize(key)) { - @Override - public String getMimeType() { - return "text/plain+" + key; - } - - @Override - public void exportProfile(RulesProfile profile, Writer writer) { - try { - writer.write(format("Profile %s/%s exported by %s", profile.getLanguage(), profile.getName(), key)); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - } - }; + private WsActionTester newWsActionTester() { + return new WsActionTester(new ExportAction(dbClient, backuper, LanguageTesting.newLanguages(XOO_LANGUAGE, JAVA_LANGUAGE))); } private static class TestBackuper implements QProfileBackuper { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/ProjectsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/ProjectsActionIT.java index 79fe68897a8..92b3916d2ff 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/ProjectsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/ProjectsActionIT.java @@ -38,7 +38,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; 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.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY; public class ProjectsActionIT { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/RemoveProjectActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/RemoveProjectActionIT.java index 292801e250d..e5e0580db80 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/RemoveProjectActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/qualityprofile/ws/RemoveProjectActionIT.java @@ -26,7 +26,7 @@ import org.mockito.Mockito; import org.sonar.api.resources.Languages; import org.sonar.db.component.ComponentQualifiers; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; @@ -123,7 +123,7 @@ public class RemoveProjectActionIT { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); QProfileDto profile = db.qualityProfiles().insert(qp -> qp.setLanguage("xoo")); db.qualityProfiles().associateWithProject(project, profile); - userSession.logIn(db.users().insertUser()).addProjectPermission(UserRole.ADMIN, project); + userSession.logIn(db.users().insertUser()).addProjectPermission(ProjectPermission.ADMIN, project); call(project, profile); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/RuleUpdaterIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/RuleUpdaterIT.java index 4600f01695f..f62eb8b9fe6 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/RuleUpdaterIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/RuleUpdaterIT.java @@ -34,7 +34,7 @@ import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction; import org.sonar.api.utils.System2; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/CreateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/CreateActionIT.java index 93c7ca23ac9..a44fbdd1794 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/CreateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/CreateActionIT.java @@ -50,7 +50,7 @@ import static org.mockito.AdditionalAnswers.returnsFirstArg; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; -import static org.sonar.api.rules.RuleType.BUG; +import static org.sonar.core.rule.RuleType.BUG; import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_PROFILES; import static org.sonar.db.rule.RuleTesting.newCustomRule; import static org.sonar.db.rule.RuleTesting.newTemplateRule; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/RuleQueryFactoryIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/RuleQueryFactoryIT.java index 2678a18f1e4..21a5abd41fb 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/RuleQueryFactoryIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/RuleQueryFactoryIT.java @@ -43,8 +43,8 @@ import static org.sonar.api.rule.RuleStatus.READY; import static org.sonar.api.rule.Severity.CRITICAL; import static org.sonar.api.rule.Severity.MAJOR; import static org.sonar.api.rule.Severity.MINOR; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.CODE_SMELL; import static org.sonar.api.server.ws.WebService.Param.ASCENDING; import static org.sonar.api.server.ws.WebService.Param.SORT; import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/SearchActionIT.java index c018cdfae6e..2006f9a94f0 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/SearchActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/SearchActionIT.java @@ -43,7 +43,7 @@ import org.sonar.api.resources.Languages; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; @@ -353,7 +353,7 @@ class SearchActionIT { Common.Impact.newBuilder() .setSoftwareQuality(Common.SoftwareQuality.SECURITY) .setSeverity(Common.ImpactSeverity.ImpactSeverity_INFO).build()); - assertThat(result.getType().name()).isEqualTo(RuleType.valueOf(rule.getType()).name()); + assertThat(result.getType().name()).isEqualTo(RuleType.fromDbConstant(rule.getType()).name()); assertThat(result.getLang()).isEqualTo("java"); } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/ShowActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/ShowActionIT.java index 625eccbf32e..74e99d2bf3b 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/ShowActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/ShowActionIT.java @@ -28,7 +28,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.resources.Languages; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.WebService; import org.sonar.core.util.UuidFactory; import org.sonar.core.util.UuidFactoryFast; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/UpdateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/UpdateActionIT.java index 8c8fba93f31..6d644e7b5ae 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/UpdateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/rule/ws/UpdateActionIT.java @@ -27,7 +27,7 @@ import org.sonar.api.resources.Languages; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/scannercache/ws/ClearActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/scannercache/ws/ClearActionIT.java index a297904ea2a..1152364b467 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/scannercache/ws/ClearActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/scannercache/ws/ClearActionIT.java @@ -45,7 +45,7 @@ import org.sonar.server.ws.WsActionTester; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.SCAN; +import static org.sonar.db.permission.ProjectPermission.SCAN; public class ClearActionIT { @Rule diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/scannercache/ws/GetActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/scannercache/ws/GetActionIT.java index 45e09dfca4a..b473acda9bf 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/scannercache/ws/GetActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/scannercache/ws/GetActionIT.java @@ -29,7 +29,7 @@ import org.apache.commons.io.IOUtils; import org.junit.Rule; import org.junit.Test; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbTester; import org.sonar.db.audit.NoOpAuditPersister; import org.sonar.db.component.BranchDao; @@ -50,7 +50,7 @@ import org.sonar.server.ws.WsActionTester; import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.SCAN; +import static org.sonar.db.permission.ProjectPermission.SCAN; public class GetActionIT { @Rule @@ -157,7 +157,7 @@ public class GetActionIT { @Test public void fail_if_no_permissions() { ProjectDto project = dbTester.components().insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.CODEVIEWER, project); + userSession.logIn().addProjectPermission(ProjectPermission.CODEVIEWER, project); TestRequest request = wsTester .newRequest() .setParam("project", project.getKey()); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ListDefinitionsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ListDefinitionsActionIT.java index 0001c6ad584..330619afd57 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ListDefinitionsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ListDefinitionsActionIT.java @@ -30,7 +30,7 @@ import org.sonar.api.config.PropertyFieldDefinition; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.permission.GlobalPermission; @@ -346,7 +346,7 @@ public class ListDefinitionsActionIT { @Test public void fail_when_user_has_not_project_browse_permission() { - userSession.logIn("project-admin").addProjectPermission(UserRole.CODEVIEWER, project); + userSession.logIn("project-admin").addProjectPermission(ProjectPermission.CODEVIEWER, project); propertyDefinitions.addComponent(PropertyDefinition.builder("foo").build()); assertThatThrownBy(() -> executeRequest(project.getKey())) @@ -442,7 +442,7 @@ public class ListDefinitionsActionIT { } private void logInAsProjectUser() { - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project); } private void logInAsAdmin() { @@ -451,8 +451,8 @@ public class ListDefinitionsActionIT { private void logInAsProjectAdmin() { userSession.logIn() - .addProjectPermission(UserRole.ADMIN, project) - .addProjectPermission(UserRole.USER, project); + .addProjectPermission(ProjectPermission.ADMIN, project) + .addProjectPermission(ProjectPermission.USER, project); } } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ResetActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ResetActionIT.java index c4bbf32399e..cde37a27d57 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ResetActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ResetActionIT.java @@ -54,8 +54,8 @@ import static java.lang.String.format; import static java.net.HttpURLConnection.HTTP_NO_CONTENT; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.ComponentQualifiers.PROJECT; import static org.sonar.db.component.ComponentQualifiers.VIEW; import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/SetActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/SetActionIT.java index 5cbdd246351..cd482f865e3 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/SetActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/SetActionIT.java @@ -40,7 +40,7 @@ import org.sonar.api.config.PropertyFieldDefinition; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -1288,11 +1288,11 @@ public class SetActionIT { } private void logInAsPortfolioAdministrator(PortfolioDto portfolio) { - userSession.logIn().addPortfolioPermission(UserRole.ADMIN, portfolio); + userSession.logIn().addPortfolioPermission(ProjectPermission.ADMIN, portfolio); } private void logInAsProjectAdministrator(ProjectDto project) { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); } private ProjectData randomPublicOrPrivateProject() { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ValuesActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ValuesActionIT.java index 1f7790aaec1..252cc78512e 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ValuesActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/setting/ws/ValuesActionIT.java @@ -33,7 +33,7 @@ import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.PropertyFieldDefinition; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ProjectData; @@ -57,9 +57,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.groups.Tuple.tuple; import static org.sonar.db.component.ComponentQualifiers.PROJECT; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.SCAN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.permission.GlobalPermission.SCAN; import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto; import static org.sonar.db.property.PropertyTesting.newGlobalPropertyDto; @@ -400,7 +401,7 @@ public class ValuesActionIT { @Test public void return_global_secured_settings_when_not_authenticated_but_with_scan_permission() { - userSession.anonymous().addPermission(SCAN); + userSession.anonymous().addPermission(GlobalPermission.SCAN); definitions.addComponents(asList( PropertyDefinition.builder("foo").build(), PropertyDefinition.builder("secret.secured").build())); @@ -418,7 +419,7 @@ public class ValuesActionIT { public void return_component_secured_settings_when_not_authenticated_but_with_project_scan_permission() { userSession .addProjectPermission(USER, project) - .addProjectPermission(SCAN.getKey(), project); + .addProjectPermission(ProjectPermission.SCAN, project); definitions.addComponents(asList( PropertyDefinition.builder("foo").onQualifiers(PROJECT).build(), PropertyDefinition.builder("global.secret.secured").build(), @@ -439,7 +440,7 @@ public class ValuesActionIT { public void return_component_secured_settings_even_if_not_defined_when_not_authenticated_but_with_scan_permission() { userSession .addProjectPermission(USER, project) - .addProjectPermission(SCAN.getKey(), project); + .addProjectPermission(ProjectPermission.SCAN, project); db.properties().insertProperties(null, project.getKey(), project.getName(), project.getQualifier(), newComponentPropertyDto(project).setKey("not-defined.secured").setValue("123")); @@ -691,7 +692,7 @@ public class ValuesActionIT { @Test public void fail_when_setting_key_is_defined_in_sonar_properties() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project); String settingKey = ProcessProperties.Property.JDBC_URL.getKey(); assertThatThrownBy(() -> { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/IndexActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/IndexActionIT.java index 19d3eb70d9d..ceb15f97d10 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/IndexActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/IndexActionIT.java @@ -37,8 +37,8 @@ import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.test.JsonAssert.assertJson; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/IssueSnippetsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/IssueSnippetsActionIT.java index 67af5aa5dd0..3b9f012ffc8 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/IssueSnippetsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/IssueSnippetsActionIT.java @@ -59,8 +59,8 @@ import static org.sonar.api.measures.CoreMetrics.LINES_KEY; import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT_KEY; import static org.sonar.api.measures.CoreMetrics.TESTS_KEY; import static org.sonar.api.measures.CoreMetrics.VIOLATIONS_KEY; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.ComponentTesting.newFileDto; public class IssueSnippetsActionIT { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/LinesActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/LinesActionIT.java index 4c223f200c1..1f5ef4123d4 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/LinesActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/LinesActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.mockito.stubbing.Answer; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbTester; import org.sonar.db.audit.NoOpAuditPersister; @@ -136,9 +136,9 @@ public class LinesActionIT { db.commit(); userSession.logIn("login") - .addProjectPermission(UserRole.USER, project.getProjectDto()) + .addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .addProjectBranchMapping(project.projectUuid(), branch) - .addProjectPermission(UserRole.CODEVIEWER, project.getProjectDto()); + .addProjectPermission(ProjectPermission.CODEVIEWER, project.getProjectDto()); tester.newRequest() .setParam("key", file.getKey()) @@ -162,8 +162,8 @@ public class LinesActionIT { db.commit(); userSession.logIn("login") - .addProjectPermission(UserRole.USER, projectData.getProjectDto()) - .addProjectPermission(UserRole.CODEVIEWER, projectData.getProjectDto()) + .addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()) + .addProjectPermission(ProjectPermission.CODEVIEWER, projectData.getProjectDto()) .addProjectBranchMapping(projectData.projectUuid(), branch); tester.newRequest() @@ -312,7 +312,7 @@ public class LinesActionIT { public void fail_if_branch_does_not_exist() { ProjectData project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project.getMainBranchComponent())); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); db.components().insertProjectBranch(project.getProjectDto(), b -> b.setKey("my_branch")); assertThatThrownBy(() -> tester.newRequest() @@ -327,7 +327,7 @@ public class LinesActionIT { public void fail_when_uuid_and_branch_params_are_used_together() { ProjectData project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project.getMainBranchComponent())); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); db.components().insertProjectBranch(project.getProjectDto(), b -> b.setKey("my_branch")); assertThatThrownBy(() -> tester.newRequest() @@ -342,7 +342,7 @@ public class LinesActionIT { public void fail_when_using_branch_uuid() { ProjectData project = db.components().insertPrivateProject(); BranchDto branch = db.components().insertProjectBranch(project.getProjectDto()); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); assertThatThrownBy(() -> tester.newRequest() .setParam("uuid", branch.getUuid()) @@ -406,7 +406,7 @@ public class LinesActionIT { private void setUserWithValidPermission(ProjectData privateProject) { userSession.logIn("login") - .addProjectPermission(UserRole.CODEVIEWER, privateProject.getProjectDto()) + .addProjectPermission(ProjectPermission.CODEVIEWER, privateProject.getProjectDto()) .registerBranches(privateProject.getMainBranchDto()); } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/RawActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/RawActionIT.java index 281036addb3..09a6bbc55b2 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/RawActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/RawActionIT.java @@ -23,7 +23,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.db.component.ComponentQualifiers; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.server.component.ComponentTypesRule; @@ -58,7 +58,7 @@ public class RawActionIT { @Test public void raw_from_file() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.CODEVIEWER, project); + userSession.addProjectPermission(ProjectPermission.CODEVIEWER, project); ComponentDto file = db.components().insertComponent(newFileDto(project)); db.fileSources().insertFileSource(file, s -> s.setSourceData( Data.newBuilder() @@ -76,7 +76,7 @@ public class RawActionIT { @Test public void raw_from_branch_file() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.CODEVIEWER, project); + userSession.addProjectPermission(ProjectPermission.CODEVIEWER, project); String branchName = secure().nextAlphanumeric(248); ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey(branchName)); userSession.addProjectBranchMapping(project.uuid(), branch); @@ -107,7 +107,7 @@ public class RawActionIT { @Test public void fail_on_unknown_branch() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.CODEVIEWER, project); + userSession.addProjectPermission(ProjectPermission.CODEVIEWER, project); ComponentDto branch = db.components().insertProjectBranch(project); ComponentDto file = db.components().insertComponent(newFileDto(branch, project.uuid())); db.fileSources().insertFileSource(file); @@ -123,7 +123,7 @@ public class RawActionIT { @Test public void fail_when_using_branch_db_key() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.CODEVIEWER, project); + userSession.addProjectPermission(ProjectPermission.CODEVIEWER, project); ComponentDto branch = db.components().insertProjectBranch(project); ComponentDto file = db.components().insertComponent(newFileDto(branch, project.uuid())); db.fileSources().insertFileSource(file); @@ -138,7 +138,7 @@ public class RawActionIT { @Test public void fail_when_wrong_permission() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - userSession.addProjectPermission(UserRole.ISSUE_ADMIN, project); + userSession.addProjectPermission(ProjectPermission.ISSUE_ADMIN, project); ComponentDto file = db.components().insertComponent(newFileDto(project)); assertThatThrownBy(() -> ws.newRequest() diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/ScmActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/ScmActionIT.java index c3b07038193..9931649c1d8 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/ScmActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/ScmActionIT.java @@ -25,7 +25,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -74,7 +74,7 @@ public class ScmActionIT { @Test public void show_scm() { userSessionRule.logIn(); - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project.getProjectDto()) + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); dbTester.getDbClient().fileSourceDao().insert(dbSession, new FileSourceDto() @@ -93,7 +93,7 @@ public class ScmActionIT { @Test public void hide_author_if_not_logged_in() { - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project.getProjectDto()) + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); dbTester.getDbClient().fileSourceDao().insert(dbSession, new FileSourceDto() @@ -113,7 +113,7 @@ public class ScmActionIT { @Test public void show_scm_from_given_range_lines() { userSessionRule.logIn(); - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project.getProjectDto()) + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); dbTester.getDbClient().fileSourceDao().insert(dbSession, new FileSourceDto() @@ -139,7 +139,7 @@ public class ScmActionIT { @Test public void not_group_lines_by_commit() { userSessionRule.logIn(); - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project.getProjectDto()) + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); // lines 1 and 2 are the same commit, but not 3 (different date) @@ -165,7 +165,7 @@ public class ScmActionIT { @Test public void group_lines_by_commit() { userSessionRule.logIn(); - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project.getProjectDto()) + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); // lines 1 and 2 are the same commit, but not 3 (different date) @@ -191,7 +191,7 @@ public class ScmActionIT { @Test public void accept_negative_value_in_from_parameter() { userSessionRule.logIn(); - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project.getProjectDto()) + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); dbTester.getDbClient().fileSourceDao().insert(dbSession, new FileSourceDto() @@ -216,7 +216,7 @@ public class ScmActionIT { @Test public void return_empty_value_when_no_scm() { - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project.getProjectDto()) + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); dbTester.getDbClient().fileSourceDao().insert(dbSession, new FileSourceDto() @@ -234,7 +234,7 @@ public class ScmActionIT { @Test public void fail_without_code_viewer_permission() { - userSessionRule.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSessionRule.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); assertThatThrownBy(() -> { diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/ShowActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/ShowActionIT.java index 7aef5491ff0..9a5e6eee3f5 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/ShowActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/source/ws/ShowActionIT.java @@ -24,7 +24,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.sonar.db.component.ComponentQualifiers; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDao; @@ -74,7 +74,7 @@ public class ShowActionIT { @Test public void show_source() { String fileKey = "src/Foo.java"; - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project) + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project) .addProjectBranchMapping(project.getUuid(), mainBranchComponentDto); when(componentDao.selectByKey(session, fileKey)).thenReturn(Optional.of(file)); when(sourceService.getLinesAsHtml(eq(session), eq(file.uuid()), anyInt(), anyInt())).thenReturn(Optional.of(newArrayList( @@ -94,7 +94,7 @@ public class ShowActionIT { @Test public void show_source_with_from_and_to_params() { String fileKey = "src/Foo.java"; - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project) + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project) .addProjectBranchMapping(project.getUuid(), mainBranchComponentDto); when(componentDao.selectByKey(session, fileKey)).thenReturn(Optional.of(file)); when(sourceService.getLinesAsHtml(session, file.uuid(), 3, 5)).thenReturn(Optional.of(newArrayList( @@ -112,7 +112,7 @@ public class ShowActionIT { @Test public void show_source_accept_from_less_than_one() { String fileKey = "src/Foo.java"; - userSessionRule.addProjectPermission(UserRole.CODEVIEWER, project) + userSessionRule.addProjectPermission(ProjectPermission.CODEVIEWER, project) .addProjectBranchMapping(project.getUuid(), mainBranchComponentDto); when(componentDao.selectByKey(session, fileKey)).thenReturn(Optional.of(file)); when(sourceService.getLinesAsHtml(session, file.uuid(), 1, 5)).thenReturn(Optional.of(newArrayList( diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ui/ws/ComponentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ui/ws/ComponentActionIT.java index 0ecb7a35dc8..405d861bab7 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ui/ws/ComponentActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/ui/ws/ComponentActionIT.java @@ -31,7 +31,7 @@ import org.sonar.api.config.Configuration; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.api.web.page.Page; import org.sonar.api.web.page.Page.Qualifier; import org.sonar.api.web.page.PageDefinition; @@ -119,7 +119,7 @@ public class ComponentActionIT { @Test public void return_info_if_user_has_browse_permission_on_project() { ProjectData project = insertProject(); - userSession.logIn().addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.logIn().addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); init(); @@ -129,7 +129,7 @@ public class ComponentActionIT { @Test public void return_info_if_user_has_administration_permission_on_project() { ProjectData project = insertProject(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); init(); @@ -148,7 +148,7 @@ public class ComponentActionIT { @Test public void return_component_info_when_anonymous_no_snapshot() { ProjectData project = insertProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); init(); @@ -161,7 +161,7 @@ public class ComponentActionIT { UserDto user = db.users().insertUser("obiwan"); propertyDbTester.insertProperty(new PropertyDto().setKey("favourite").setEntityUuid(projectData.getProjectDto().getUuid()).setUserUuid(user.getUuid()), projectData.getProjectDto().getKey(), projectData.getProjectDto().getName(), projectData.getProjectDto().getQualifier(), user.getLogin()); - userSession.logIn(user).addProjectPermission(UserRole.USER, projectData.getProjectDto()) + userSession.logIn(user).addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()) .registerBranches(projectData.getMainBranchDto()); init(); @@ -177,7 +177,7 @@ public class ComponentActionIT { UserDto user = db.users().insertUser("obiwan"); propertyDbTester.insertProperty(new PropertyDto().setKey("favourite").setEntityUuid(projectData.projectUuid()).setUserUuid(user.getUuid()), projectDto.getKey(), projectDto.getName(), projectDto.getQualifier(), user.getLogin()); - userSession.logIn(user).addProjectPermission(UserRole.USER, projectData.getProjectDto()) + userSession.logIn(user).addProjectPermission(ProjectPermission.USER, projectData.getProjectDto()) .registerBranches(branch); init(); @@ -210,8 +210,8 @@ public class ComponentActionIT { propertyDbTester.insertProperty(new PropertyDto().setKey("favourite").setEntityUuid(subportfolio.uuid()).setUserUuid(user.getUuid()), subportfolio.getKey(), subportfolio.name(), subportfolio.qualifier(), user.getLogin()); - userSession.logIn(user).addProjectPermission(UserRole.USER, portfolio) - .addProjectPermission(UserRole.USER, subportfolio); + userSession.logIn(user).addProjectPermission(ProjectPermission.USER, portfolio) + .addProjectPermission(ProjectPermission.USER, subportfolio); init(); String json = ws.newRequest() @@ -238,7 +238,7 @@ public class ComponentActionIT { propertyDbTester.insertProperty(new PropertyDto().setKey("favourite").setEntityUuid(portfolio.uuid()).setUserUuid(user.getUuid()), subportfolio.getKey(), portfolio.name(), portfolio.qualifier(), user.getLogin()); - userSession.logIn(user).addProjectPermission(UserRole.USER, portfolio); + userSession.logIn(user).addProjectPermission(ProjectPermission.USER, portfolio); init(); String json = ws.newRequest() @@ -264,7 +264,7 @@ public class ComponentActionIT { application1.getProjectDto(), project11.getProjectDto(), project12.getProjectDto()); - userSession.addProjectPermission(UserRole.USER, application1.getProjectDto(), project11.getProjectDto(), project12.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, application1.getProjectDto(), project11.getProjectDto(), project12.getProjectDto()) .registerBranches(application1.getMainBranchDto()); ProjectData application2 = db.components().insertPrivateApplication(); @@ -274,7 +274,7 @@ public class ComponentActionIT { application2.getProjectDto(), project21.getProjectDto(), project22.getProjectDto()); - userSession.addProjectPermission(UserRole.USER, application2.getProjectDto(), project21.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, application2.getProjectDto(), project21.getProjectDto()) .registerBranches(application2.getMainBranchDto()); init(); @@ -298,7 +298,7 @@ public class ComponentActionIT { db.components().insertSnapshot(project, snapshot -> snapshot .setCreatedAt(parseDateTime("2015-04-22T11:44:00+0200").getTime()) .setProjectVersion("3.14")); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); init(); @@ -309,7 +309,7 @@ public class ComponentActionIT { public void return_component_info_when_file_on_master() { db.qualityGates().createDefaultQualityGate(); ComponentDto main = componentDbTester.insertPrivateProject(p -> p.setName("Sample").setKey("sample")).getMainBranchComponent(); - userSession.addProjectPermission(UserRole.USER, main); + userSession.addProjectPermission(ProjectPermission.USER, main); init(); ComponentDto dirDto = componentDbTester.insertComponent(newDirectory(main, "src")); @@ -328,7 +328,7 @@ public class ComponentActionIT { ProjectData project = componentDbTester.insertPrivateProject(p -> p.setName("Sample").setKey("sample")); String branchName = "feature1"; ComponentDto branch = componentDbTester.insertProjectBranch(project.getMainBranchComponent(), b -> b.setKey(branchName)); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); userSession.addProjectBranchMapping(project.projectUuid(), branch); init(); ComponentDto dirDto = componentDbTester.insertComponent(newDirectory(branch, "src")); @@ -374,7 +374,7 @@ public class ComponentActionIT { addQualityProfiles(project.getMainBranchComponent(), new QualityProfile(qp1.getKee(), qp1.getName(), qp1.getLanguage(), new Date()), new QualityProfile(qp2.getKee(), qp2.getName(), qp2.getLanguage(), new Date())); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); init(); @@ -389,7 +389,7 @@ public class ComponentActionIT { @Test public void return_empty_quality_profiles_when_no_measure() { ProjectData project = insertProject(); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); init(); @@ -402,7 +402,7 @@ public class ComponentActionIT { ProjectData project = db.components().insertPrivateProject(); QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way")); db.qualityGates().associateProjectToQualityGate(project.getProjectDto(), qualityGateDto); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); init(); @@ -417,7 +417,7 @@ public class ComponentActionIT { BranchDto branch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH)); QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way")); db.qualityGates().associateProjectToQualityGate(project, qualityGateDto); - userSession.addProjectPermission(UserRole.USER, project) + userSession.addProjectPermission(ProjectPermission.USER, project) .addProjectBranchMapping(project.getUuid(), db.components().getComponentDto(branch)); init(); @@ -434,7 +434,7 @@ public class ComponentActionIT { public void return_default_quality_gate() { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); db.qualityGates().createDefaultQualityGate(qg -> qg.setName("Sonar way")); - userSession.addProjectPermission(UserRole.USER, project); + userSession.addProjectPermission(ProjectPermission.USER, project); init(); executeAndVerify(project.getKey(), "return_default_quality_gate.json"); @@ -443,7 +443,7 @@ public class ComponentActionIT { @Test public void return_extensions() { ProjectData project = insertProject(); - userSession.anonymous().addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.anonymous().addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); init(createPages()); @@ -478,8 +478,8 @@ public class ComponentActionIT { public void return_extensions_for_admin() { ProjectData project = insertProject(); userSession.anonymous() - .addProjectPermission(UserRole.USER, project.getProjectDto()) - .addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + .addProjectPermission(ProjectPermission.USER, project.getProjectDto()) + .addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); init(createPages()); @@ -491,8 +491,8 @@ public class ComponentActionIT { ProjectData project = insertProject(); UserDto user = db.users().insertUser(); userSession.logIn(user) - .addProjectPermission(UserRole.USER, project.getProjectDto()) - .addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + .addProjectPermission(ProjectPermission.USER, project.getProjectDto()) + .addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); Page page1 = Page.builder("my_plugin/first_page") .setName("First Page") @@ -515,8 +515,8 @@ public class ComponentActionIT { public void return_configuration_with_all_properties() { ProjectData project = insertProject(); userSession.anonymous() - .addProjectPermission(UserRole.USER, project.getProjectDto()) - .addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + .addProjectPermission(ProjectPermission.USER, project.getProjectDto()) + .addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); ComponentType projectComponentType = ComponentType.builder(project.getProjectDto().getQualifier()) .setProperty("comparable", true) @@ -537,7 +537,7 @@ public class ComponentActionIT { public void return_configuration_for_quality_profile_admin() { ProjectData project = insertProject(); userSession.logIn() - .addProjectPermission(UserRole.USER, project.getProjectDto()) + .addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .addPermission(ADMINISTER_QUALITY_PROFILES) .registerBranches(project.getMainBranchDto()); init(); @@ -549,7 +549,7 @@ public class ComponentActionIT { public void return_configuration_for_quality_gate_admin() { ProjectData project = insertProject(); userSession.logIn() - .addProjectPermission(UserRole.USER, project.getProjectDto()) + .addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .addPermission(ADMINISTER_QUALITY_GATES) .registerBranches(project.getMainBranchDto()); init(); @@ -562,9 +562,9 @@ public class ComponentActionIT { ProjectData project = insertProject(); UserSessionRule userSessionRule = userSession.logIn(); init(); - userSessionRule.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSessionRule.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()) - .addProjectPermission(UserRole.ADMIN, project.getProjectDto()); + .addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()); String json = execute(project.projectKey()); @@ -592,8 +592,8 @@ public class ComponentActionIT { ProjectData project = insertProject(); UserSessionRule userSessionRule = userSession.logIn(); init(); - userSessionRule.addProjectPermission(UserRole.USER, project.getProjectDto()) - .addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + userSessionRule.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) + .addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); String json = execute(project.projectKey()); @@ -621,7 +621,7 @@ public class ComponentActionIT { ProjectData project = insertProject(); UserSessionRule userSessionRule = userSession.logIn(); init(); - userSessionRule.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSessionRule.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); String json = execute(project.projectKey()); @@ -636,7 +636,7 @@ public class ComponentActionIT { ComponentDto file = componentDbTester.insertComponent(newFileDto(directory, directory, "cdef").setName("Source.xoo") .setKey("polop:src/main/xoo/Source.xoo") .setPath(directory.path())); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); init(); @@ -646,7 +646,7 @@ public class ComponentActionIT { @Test public void project_administrator_is_allowed_to_get_information() { ProjectData project = insertProject(); - userSession.addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + userSession.addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); init(createPages()); @@ -660,7 +660,7 @@ public class ComponentActionIT { init(); userSession.logIn() - .addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + .addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .addPermission(GlobalPermission.ADMINISTER) .registerBranches(project.getMainBranchDto()); assertJson(execute(project.projectKey())).isSimilarTo("{\"visibility\": \"private\"}"); @@ -673,7 +673,7 @@ public class ComponentActionIT { init(); userSession.logIn() - .addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + .addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .registerBranches(project.getMainBranchDto()) .addPermission(GlobalPermission.ADMINISTER); assertJson(execute(project.projectKey())).isSimilarTo("{\"visibility\": \"public\"}"); @@ -686,13 +686,13 @@ public class ComponentActionIT { init(createPages()); userSession.logIn() - .addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + .addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .addPermission(GlobalPermission.ADMINISTER) .registerBranches(project.getMainBranchDto()); assertJson(execute(project.projectKey())).isSimilarTo("{\"configuration\": {\"canApplyPermissionTemplate\": true}}"); userSession.logIn() - .addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + .addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); assertJson(execute(project.projectKey())).isSimilarTo("{\"configuration\": {\"canApplyPermissionTemplate\": false}}"); @@ -704,7 +704,7 @@ public class ComponentActionIT { ProjectData project = db.components().insertPublicProject(); init(createPages()); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project.getProjectDto()) + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project.getProjectDto()) .registerBranches(project.getMainBranchDto()); assertJson(execute(project.projectKey())).isSimilarTo("{\"configuration\": {\"canUpdateProjectVisibilityToPrivate\": true}}"); } @@ -763,8 +763,8 @@ public class ComponentActionIT { QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way")); db.qualityGates().associateProjectToQualityGate(db.components().getProjectDtoByMainBranch(mainBranch), qualityGateDto); userSession.logIn(user) - .addProjectPermission(UserRole.USER, projectDto) - .addProjectPermission(UserRole.ADMIN, projectDto) + .addProjectPermission(ProjectPermission.USER, projectDto) + .addProjectPermission(ProjectPermission.ADMIN, projectDto) .registerBranches(projectData.getMainBranchDto()); String result = execute(mainBranch.getKey()); @@ -798,7 +798,7 @@ public class ComponentActionIT { public void fail_on_directory_key_as_param() { ProjectData project = insertProject(); ComponentDto directory = componentDbTester.insertComponent(newDirectory(project.getMainBranchComponent(), "src/main/xoo")); - userSession.addProjectPermission(UserRole.USER, project.getProjectDto()); + userSession.addProjectPermission(ProjectPermission.USER, project.getProjectDto()); init(); String dirKey = directory.getKey(); assertThatThrownBy(() -> execute(dirKey)) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionHomepageIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionHomepageIT.java index f94a66590b4..b74d69f3c9f 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionHomepageIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionHomepageIT.java @@ -50,7 +50,7 @@ import static org.apache.commons.lang3.RandomStringUtils.secure; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.PROJECTS; @RunWith(DataProviderRunner.class) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionIT.java index b2a716df087..74aeb14892b 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/CurrentActionIT.java @@ -27,18 +27,18 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Suite; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.server.component.ComponentType; -import org.sonar.server.component.ComponentTypeTree; -import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; import org.sonar.core.platform.PlatformEditionProvider; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.property.PropertyDto; import org.sonar.db.user.UserDto; import org.sonar.server.common.avatar.AvatarResolverImpl; +import org.sonar.server.component.ComponentType; +import org.sonar.server.component.ComponentTypeTree; +import org.sonar.server.component.ComponentTypes; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; import org.sonar.server.tester.UserSessionRule; @@ -50,12 +50,11 @@ import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_PROFILES; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; import static org.sonar.db.permission.GlobalPermission.SCAN; import static org.sonar.db.user.GroupTesting.newGroupDto; -import static org.sonar.server.user.ws.DismissNoticeAction.AVAILABLE_NOTICE_KEYS; import static org.sonar.test.JsonAssert.assertJson; @RunWith(Suite.class) @@ -262,7 +261,7 @@ public class CurrentActionIT { @Parameterized.Parameters public static Collection<String> parameterCombination() { - return AVAILABLE_NOTICE_KEYS; + return DismissNoticeAction.DismissNotices.getAvailableKeys(); } private final String notice; diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DeactivateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DeactivateActionIT.java index 40e570e8b29..b8eb63a0e4f 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DeactivateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DeactivateActionIT.java @@ -25,7 +25,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -175,8 +175,8 @@ public class DeactivateActionIT { ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); db.users().insertGlobalPermissionOnUser(user, GlobalPermission.SCAN); db.users().insertGlobalPermissionOnUser(user, GlobalPermission.ADMINISTER_QUALITY_PROFILES); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project); - db.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, project); deactivate(user.getLogin()); @@ -191,8 +191,8 @@ public class DeactivateActionIT { UserDto user = db.users().insertUser(); PermissionTemplateDto template = db.permissionTemplates().insertTemplate(); PermissionTemplateDto anotherTemplate = db.permissionTemplates().insertTemplate(); - db.permissionTemplates().addUserToTemplate(template.getUuid(), user.getUuid(), UserRole.USER, template.getName(), user.getLogin()); - db.permissionTemplates().addUserToTemplate(anotherTemplate.getUuid(), user.getUuid(), UserRole.CODEVIEWER, anotherTemplate.getName(), user.getLogin()); + db.permissionTemplates().addUserToTemplate(template.getUuid(), user.getUuid(), ProjectPermission.USER, template.getName(), user.getLogin()); + db.permissionTemplates().addUserToTemplate(anotherTemplate.getUuid(), user.getUuid(), ProjectPermission.CODEVIEWER, anotherTemplate.getName(), user.getLogin()); deactivate(user.getLogin()); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DismissNoticeActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DismissNoticeActionIT.java index a3c6748a49a..4d0c6acf8b5 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DismissNoticeActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/user/ws/DismissNoticeActionIT.java @@ -20,12 +20,12 @@ package org.sonar.server.user.ws; import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; import java.util.Optional; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; import org.sonar.db.property.PropertyDto; @@ -37,20 +37,18 @@ import org.sonar.server.ws.WsActionTester; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.sonar.server.user.ws.DismissNoticeAction.AVAILABLE_NOTICE_KEYS; -@RunWith(DataProviderRunner.class) -public class DismissNoticeActionIT { +class DismissNoticeActionIT { - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); + @RegisterExtension + private DbTester db = DbTester.create(System2.INSTANCE); + @RegisterExtension + private UserSessionRule userSessionRule = UserSessionRule.standalone(); private final WsActionTester tester = new WsActionTester(new DismissNoticeAction(userSessionRule, db.getDbClient())); @Test - public void authentication_is_required() { + void authentication_is_required() { TestRequest testRequest = tester.newRequest() .setParam("notice", "anyValue"); @@ -60,7 +58,7 @@ public class DismissNoticeActionIT { } @Test - public void notice_parameter_is_mandatory() { + void notice_parameter_is_mandatory() { userSessionRule.logIn(); TestRequest testRequest = tester.newRequest(); @@ -70,20 +68,19 @@ public class DismissNoticeActionIT { } @Test - public void notice_not_supported() { + void notice_not_supported() { userSessionRule.logIn(); TestRequest testRequest = tester.newRequest() .setParam("notice", "not_supported_value"); assertThatThrownBy(testRequest::execute) .isInstanceOf(IllegalArgumentException.class) - .hasMessage( - "Value of parameter 'notice' (not_supported_value) must be one of: [educationPrinciples, sonarlintAd, issueCleanCodeGuide, qualityGateCaYCConditionsSimplification, " + - "overviewZeroNewIssuesSimplification, issueNewIssueStatusAndTransitionGuide, onboardingDismissCaycBranchSummaryGuide, showNewModesTour, showNewModesBanner]"); + .hasMessageStartingWith( + "Value of parameter 'notice' (not_supported_value) must be one of: ["); } @Test - public void notice_already_exist_dont_fail() { + void notice_already_exist_dont_fail() { userSessionRule.logIn(); PropertyDto property = new PropertyDto().setKey("user.dismissedNotices.educationPrinciples").setUserUuid(userSessionRule.getUuid()); db.properties().insertProperties(userSessionRule.getLogin(), null, null, null, property); @@ -97,9 +94,9 @@ public class DismissNoticeActionIT { assertThat(db.properties().findFirstUserProperty(userSessionRule.getUuid(), "user.dismissedNotices.educationPrinciples")).isPresent(); } - @Test - @UseDataProvider("noticeKeys") - public void dismiss_notice(String noticeKey) { + @ParameterizedTest + @MethodSource("noticeKeys") + void dismiss_notice(String noticeKey) { userSessionRule.logIn(); TestResponse testResponse = tester.newRequest() @@ -113,9 +110,7 @@ public class DismissNoticeActionIT { } @DataProvider - public static Object[][] noticeKeys() { - return AVAILABLE_NOTICE_KEYS.stream() - .map(noticeKey -> new Object[] {noticeKey}) - .toArray(Object[][]::new); + static Set<String> noticeKeys() { + return DismissNoticeAction.DismissNotices.getAvailableKeys(); } } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/DeleteActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/DeleteActionIT.java index c8f7983e297..42513c13d6b 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/DeleteActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/DeleteActionIT.java @@ -26,7 +26,7 @@ import org.junit.Test; import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService.Action; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.UuidFactoryImpl; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -146,7 +146,7 @@ public class DeleteActionIT { insertDefaultGroup(); GroupDto group = db.users().insertGroup(); ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - db.users().insertProjectPermissionOnGroup(group, UserRole.ADMIN, project); + db.users().insertProjectPermissionOnGroup(group, ProjectPermission.ADMIN, project); loginAsAdmin(); newRequest() diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usertoken/ws/GenerateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usertoken/ws/GenerateActionIT.java index e37a848d96a..f5ce53e5487 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usertoken/ws/GenerateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usertoken/ws/GenerateActionIT.java @@ -34,11 +34,12 @@ import org.sonar.api.config.internal.MapSettings; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; -import org.sonar.server.component.ComponentTypesRule; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.TokenType; import org.sonar.db.user.UserDto; import org.sonar.server.component.ComponentFinder; +import org.sonar.server.component.ComponentTypesRule; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; @@ -176,7 +177,7 @@ public class GenerateActionIT { public void a_user_can_generate_projectAnalysisToken_with_the_project_scan_permission() { UserDto user = userLogin(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.addProjectPermission(SCAN.toString(), project); + userSession.addProjectPermission(ProjectPermission.SCAN, project); GenerateWsResponse response = newRequest(null, TOKEN_NAME, PROJECT_ANALYSIS_TOKEN, project.getKey()); @@ -190,7 +191,7 @@ public class GenerateActionIT { public void a_user_can_generate_projectAnalysisToken_with_the_project_scan_permission_passing_login() { UserDto user = userLogin(); ProjectDto project = db.components().insertPublicProject().getProjectDto(); - userSession.addProjectPermission(SCAN.toString(), project); + userSession.addProjectPermission(ProjectPermission.SCAN, project); GenerateWsResponse responseWithLogin = newRequest(user.getLogin(), TOKEN_NAME, PROJECT_ANALYSIS_TOKEN, project.getKey()); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/CreateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/CreateActionIT.java index 3ef09efdf38..e4d567ae1c5 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/CreateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/CreateActionIT.java @@ -24,7 +24,7 @@ import org.junit.Test; import org.sonar.api.config.Configuration; import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.UuidFactory; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; @@ -99,7 +99,7 @@ public class CreateActionIT { String longProjectKey = generateStringWithLength(400); ProjectDto project = componentDbTester.insertPrivateProject(componentDto -> componentDto.setKey(longProjectKey)).getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); CreateWsResponse response = wsActionTester.newRequest() .setParam("project", longProjectKey) @@ -161,7 +161,7 @@ public class CreateActionIT { public void create_a_webhook_on_project() { ProjectDto project = componentDbTester.insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); CreateWsResponse response = wsActionTester.newRequest() .setParam("project", project.getKey()) @@ -195,7 +195,7 @@ public class CreateActionIT { for (int i = 0; i < 10; i++) { webhookDbTester.insertWebhook(project); } - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestRequest request = wsActionTester.newRequest() .setParam(PROJECT_KEY_PARAM, project.getKey()) .setParam(NAME_PARAM, NAME_WEBHOOK_EXAMPLE_001) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/DeleteActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/DeleteActionIT.java index 9c5d3fba7e6..f77251f2b84 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/DeleteActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/DeleteActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.config.Configuration; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -94,7 +94,7 @@ public class DeleteActionIT { webhookDeliveryDbTester.insert(newDto().setWebhookUuid(dto.getUuid())); webhookDeliveryDbTester.insert(newDto().setWebhookUuid(dto.getUuid())); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestResponse response = wsActionTester.newRequest() .setParam(KEY_PARAM, dto.getUuid()) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/ListActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/ListActionIT.java index b2efd04e7c7..b43dc1ab72b 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/ListActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/ListActionIT.java @@ -26,7 +26,7 @@ import org.sonar.api.config.Configuration; import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDbTester; @@ -203,7 +203,7 @@ public class ListActionIT { @Test public void list_project_webhooks_when_project_key_param_is_provided() { ProjectDto project1 = componentDbTester.insertPrivateProject().getProjectDto(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project1); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project1); WebhookDto dto1 = webhookDbTester.insertWebhook(project1); WebhookDto dto2 = webhookDbTester.insertWebhook(project1); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/UpdateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/UpdateActionIT.java index 5d828108537..b9314bde13b 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/UpdateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/UpdateActionIT.java @@ -25,7 +25,7 @@ import org.junit.Test; import org.sonar.api.config.Configuration; import org.sonar.server.component.ComponentTypes; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDbTester; @@ -92,7 +92,7 @@ public class UpdateActionIT { public void update_a_project_webhook_with_required_fields() { ProjectDto project = componentDbTester.insertPrivateProject().getProjectDto(); WebhookDto dto = webhookDbTester.insertWebhook(project); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestResponse response = wsActionTester.newRequest() .setParam("webhook", dto.getUuid()) @@ -113,7 +113,7 @@ public class UpdateActionIT { public void update_with_empty_secrets_removes_the_secret() { ProjectDto project = componentDbTester.insertPrivateProject().getProjectDto(); WebhookDto dto = webhookDbTester.insertWebhook(project); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestResponse response = wsActionTester.newRequest() .setParam("webhook", dto.getUuid()) @@ -135,7 +135,7 @@ public class UpdateActionIT { public void update_a_project_webhook_with_all_fields() { ProjectDto project = componentDbTester.insertPrivateProject().getProjectDto(); WebhookDto dto = webhookDbTester.insertWebhook(project); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestResponse response = wsActionTester.newRequest() .setParam("webhook", dto.getUuid()) @@ -233,7 +233,7 @@ public class UpdateActionIT { public void fail_if_url_is_not_valid() { ProjectDto project = componentDbTester.insertPrivateProject().getProjectDto(); WebhookDto dto = webhookDbTester.insertWebhook(project); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestRequest request = wsActionTester.newRequest() .setParam("webhook", dto.getUuid()) .setParam("name", NAME_WEBHOOK_EXAMPLE_001) @@ -247,7 +247,7 @@ public class UpdateActionIT { public void handle_whenSecretIsTooShort_fail() { ProjectDto project = componentDbTester.insertPrivateProject().getProjectDto(); WebhookDto dto = webhookDbTester.insertWebhook(project); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestRequest request = wsActionTester.newRequest() .setParam("webhook", dto.getUuid()) .setParam("name", NAME_WEBHOOK_EXAMPLE_001) @@ -262,7 +262,7 @@ public class UpdateActionIT { public void fail_if_credential_in_url_is_have_a_wrong_format() { ProjectDto project = componentDbTester.insertPrivateProject().getProjectDto(); WebhookDto dto = webhookDbTester.insertWebhook(project); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); TestRequest request = wsActionTester.newRequest() .setParam("webhook", dto.getUuid()) .setParam("name", NAME_WEBHOOK_EXAMPLE_001) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/WebhookDeliveriesActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/WebhookDeliveriesActionIT.java index ec7bdbaf230..3ce14a67ad7 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/WebhookDeliveriesActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/WebhookDeliveriesActionIT.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.project.ProjectDto; @@ -86,7 +86,7 @@ public class WebhookDeliveriesActionIT { @Test public void search_by_component_and_return_no_records() { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); Webhooks.DeliveriesWsResponse response = ws.newRequest() .setParam("componentKey", project.getKey()) @@ -97,7 +97,7 @@ public class WebhookDeliveriesActionIT { @Test public void search_by_task_and_return_no_records() { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); Webhooks.DeliveriesWsResponse response = ws.newRequest() .setParam("ceTaskId", "t1") @@ -108,7 +108,7 @@ public class WebhookDeliveriesActionIT { @Test public void search_by_webhook_and_return_no_records() { - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); Webhooks.DeliveriesWsResponse response = ws.newRequest() .setParam("webhook", "t1") @@ -131,7 +131,7 @@ public class WebhookDeliveriesActionIT { .setHttpStatus(200); dbClient.webhookDeliveryDao().insert(db.getSession(), dto); db.commit(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); String json = ws.newRequest() .setParam("componentKey", project.getKey()) @@ -150,7 +150,7 @@ public class WebhookDeliveriesActionIT { dbClient.webhookDeliveryDao().insert(db.getSession(), dto2); dbClient.webhookDeliveryDao().insert(db.getSession(), dto3); db.commit(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); Webhooks.DeliveriesWsResponse response = ws.newRequest() .setParam("ceTaskId", "t1") @@ -174,7 +174,7 @@ public class WebhookDeliveriesActionIT { dbClient.webhookDeliveryDao().insert(db.getSession(), dto4); dbClient.webhookDeliveryDao().insert(db.getSession(), dto5); db.commit(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project, otherProject); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project, otherProject); Webhooks.DeliveriesWsResponse response = ws.newRequest() .setParam("webhook", "wh-1-uuid") @@ -197,7 +197,7 @@ public class WebhookDeliveriesActionIT { webhookDeliveryDbTester.insert(newDto().setProjectUuid(project.getUuid()).setCeTaskUuid("t1").setWebhookUuid("wh-1-uuid")); } - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); Webhooks.DeliveriesWsResponse response = ws.newRequest() .setParam("webhook", "wh-1-uuid") @@ -214,7 +214,7 @@ public class WebhookDeliveriesActionIT { webhookDeliveryDbTester.insert(newDto().setProjectUuid(project.getUuid()).setCeTaskUuid("t1").setWebhookUuid("wh-1-uuid")); } - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); Webhooks.DeliveriesWsResponse response = ws.newRequest() .setParam("webhook", "wh-1-uuid") @@ -234,7 +234,7 @@ public class WebhookDeliveriesActionIT { webhookDeliveryDbTester.insert(newDto().setProjectUuid(project.getUuid()).setCeTaskUuid("t1").setWebhookUuid("wh-1-uuid")); } - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); Webhooks.DeliveriesWsResponse response = ws.newRequest() .setParam("webhook", "wh-1-uuid") @@ -253,7 +253,7 @@ public class WebhookDeliveriesActionIT { .setProjectUuid(project.getUuid()); dbClient.webhookDeliveryDao().insert(db.getSession(), dto); db.commit(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project); TestRequest request = ws.newRequest() .setParam("componentKey", project.getKey()); @@ -268,7 +268,7 @@ public class WebhookDeliveriesActionIT { .setProjectUuid(project.getUuid()); dbClient.webhookDeliveryDao().insert(db.getSession(), dto); db.commit(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project); TestRequest request = ws.newRequest() .setParam("ceTaskId", dto.getCeTaskUuid()); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/WebhookDeliveryActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/WebhookDeliveryActionIT.java index c0c85f57225..9b270cfe293 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/WebhookDeliveryActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/webhook/ws/WebhookDeliveryActionIT.java @@ -23,7 +23,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.project.ProjectDto; @@ -106,7 +106,7 @@ public class WebhookDeliveryActionIT { .setPayload("{\"status\"=\"SUCCESS\"}"); dbClient.webhookDeliveryDao().insert(db.getSession(), dto); db.commit(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); String json = ws.newRequest() .setParam("deliveryId", dto.getUuid()) @@ -125,7 +125,7 @@ public class WebhookDeliveryActionIT { .setErrorStacktrace("IOException -> can not connect"); dbClient.webhookDeliveryDao().insert(db.getSession(), dto); db.commit(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); Webhooks.DeliveryWsResponse response = ws.newRequest() .setParam("deliveryId", dto.getUuid()) @@ -146,7 +146,7 @@ public class WebhookDeliveryActionIT { .setAnalysisUuid(null); dbClient.webhookDeliveryDao().insert(db.getSession(), dto); db.commit(); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); + userSession.logIn().addProjectPermission(ProjectPermission.ADMIN, project); Webhooks.DeliveryWsResponse response = ws.newRequest() .setParam("deliveryId", dto.getUuid()) @@ -164,7 +164,7 @@ public class WebhookDeliveryActionIT { .setProjectUuid(project.getUuid()); dbClient.webhookDeliveryDao().insert(db.getSession(), dto); db.commit(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(ProjectPermission.USER, project); assertThatThrownBy(() -> ws.newRequest() .setMediaType(MediaTypes.PROTOBUF) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/AlmSettingsSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/AlmSettingsSupport.java index 59cfc334fd5..eb95112ee7a 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/AlmSettingsSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/AlmSettingsSupport.java @@ -26,6 +26,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.alm.setting.ALM; import org.sonar.db.alm.setting.AlmSettingDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.project.ProjectDto; import org.sonar.server.almsettings.MultipleAlmFeature; import org.sonar.server.component.ComponentFinder; @@ -35,7 +36,7 @@ import org.sonar.server.user.UserSession; import static java.lang.String.format; import static org.apache.commons.lang.StringUtils.isEmpty; -import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.db.permission.ProjectPermission.ADMIN; @ServerSide public class AlmSettingsSupport { @@ -83,7 +84,7 @@ public class AlmSettingsSupport { return getProject(dbSession, projectKey, ADMIN); } - public ProjectDto getProject(DbSession dbSession, String projectKey, String projectPermission) { + public ProjectDto getProject(DbSession dbSession, String projectKey, ProjectPermission projectPermission) { ProjectDto project = componentFinder.getProjectByKey(dbSession, projectKey); userSession.checkEntityPermission(projectPermission, project); return project; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GetBindingAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GetBindingAction.java index 23bac661228..b89125fbcd8 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GetBindingAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GetBindingAction.java @@ -35,7 +35,7 @@ import org.sonarqube.ws.AlmSettings.GetBindingWsResponse; import static java.lang.String.format; import static java.util.Optional.ofNullable; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.common.AlmSettingMapper.toResponseAlm; import static org.sonar.server.ws.WsUtils.writeProtobuf; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ListAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ListAction.java index 699e095f18e..d74e61bb684 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ListAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/ListAction.java @@ -36,7 +36,7 @@ import org.sonarqube.ws.AlmSettings.AlmSetting; import org.sonarqube.ws.AlmSettings.ListWsResponse; import static java.util.Optional.ofNullable; -import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.db.permission.ProjectPermission.ADMIN; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; import static org.sonar.server.common.AlmSettingMapper.toResponseAlm; import static org.sonar.server.ws.WsUtils.writeProtobuf; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/TokenAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/TokenAction.java index d28ea922644..f1f4ce5dd76 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/TokenAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/TokenAction.java @@ -25,7 +25,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.NewAction; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.project.ProjectBadgeTokenDto; @@ -81,7 +81,7 @@ public class TokenAction implements ProjectBadgesWsAction { ProjectDto projectDto = dbClient.projectDao().selectProjectOrAppByKey(dbSession, projectKey) .orElseThrow(() -> new IllegalArgumentException(PROJECT_OR_APP_NOT_FOUND)); - userSession.checkEntityPermission(UserRole.USER, projectDto); + userSession.checkEntityPermission(ProjectPermission.USER, projectDto); ProjectBadgeTokenDto projectBadgeTokenDto = dbClient.projectBadgeTokenDao().selectTokenByProject(dbSession, projectDto); if (projectBadgeTokenDto == null) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/TokenRenewAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/TokenRenewAction.java index 92c27f7fd1b..75c37d78780 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/TokenRenewAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/TokenRenewAction.java @@ -24,7 +24,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.NewAction; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.project.ProjectDto; @@ -78,7 +78,7 @@ public class TokenRenewAction implements ProjectBadgesWsAction { ProjectDto projectDto = dbClient.projectDao().selectProjectOrAppByKey(dbSession, projectKey) .orElseThrow(() -> new IllegalArgumentException(PROJECT_OR_APP_NOT_FOUND)); - userSession.checkEntityPermission(UserRole.ADMIN, projectDto); + userSession.checkEntityPermission(ProjectPermission.ADMIN, projectDto); String newGeneratedToken = tokenGenerator.generate(TokenType.PROJECT_BADGE_TOKEN); dbClient.projectBadgeTokenDao().upsert(dbSession, newGeneratedToken, projectDto, userSession.getUuid(), userSession.getLogin()); dbSession.commit(); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/batch/ProjectDataLoader.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/batch/ProjectDataLoader.java index b4a0b65be4e..45e07eebb02 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/batch/ProjectDataLoader.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/batch/ProjectDataLoader.java @@ -23,7 +23,7 @@ import java.util.Collections; import java.util.List; import javax.annotation.Nullable; import org.sonar.api.server.ServerSide; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; @@ -57,7 +57,7 @@ public class ProjectDataLoader { String pullRequest = query.getPullRequest(); ComponentDto project = componentFinder.getByKey(session, projectKey); checkRequest(project.isRootProject(), "Key '%s' belongs to a component which is not a Project", projectKey); - boolean hasScanPerm = userSession.hasComponentPermission(UserRole.SCAN, project) || userSession.hasPermission(GlobalPermission.SCAN); + boolean hasScanPerm = userSession.hasComponentPermission(ProjectPermission.SCAN, project) || userSession.hasPermission(GlobalPermission.SCAN); checkPermission(hasScanPerm); ComponentDto branchComponent = (branch == null && pullRequest == null) ? project : componentFinder.getByKeyAndOptionalBranchOrPullRequest(session, projectKey, branch, pullRequest); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/DeleteAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/DeleteAction.java index b3dbde4f1d9..dc80a0f6946 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/DeleteAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/DeleteAction.java @@ -23,7 +23,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.NewController; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -93,7 +93,7 @@ public class DeleteAction implements BranchWsAction { } private void checkPermission(ProjectDto project) { - userSession.checkEntityPermission(UserRole.ADMIN, project); + userSession.checkEntityPermission(ProjectPermission.ADMIN, project); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/ListAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/ListAction.java index 03570522840..38fe429cceb 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/ListAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/ListAction.java @@ -30,7 +30,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -47,7 +47,7 @@ import static java.util.Collections.singletonList; import static java.util.Optional.ofNullable; import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY; import static org.sonar.api.utils.DateUtils.formatDateTime; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.component.BranchType.BRANCH; import static org.sonar.db.permission.GlobalPermission.SCAN; import static org.sonar.server.branch.ws.BranchesWs.addProjectParam; @@ -140,7 +140,7 @@ public class ListAction implements BranchWsAction { private void checkPermission(ProjectDto project) { if (!userSession.hasEntityPermission(USER, project) && - !userSession.hasEntityPermission(UserRole.SCAN, project) && + !userSession.hasEntityPermission(ProjectPermission.SCAN, project) && !userSession.hasPermission(SCAN)) { throw insufficientPrivilegesException(); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/RenameAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/RenameAction.java index d3ad68198f1..7510a607584 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/RenameAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/RenameAction.java @@ -24,7 +24,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.NewController; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -95,7 +95,7 @@ public class RenameAction implements BranchWsAction { } private void checkPermission(ProjectDto project) { - userSession.checkEntityPermission(UserRole.ADMIN, project); + userSession.checkEntityPermission(ProjectPermission.ADMIN, project); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/SetAutomaticDeletionProtectionAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/SetAutomaticDeletionProtectionAction.java index f9686401dca..f93e667e341 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/SetAutomaticDeletionProtectionAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/SetAutomaticDeletionProtectionAction.java @@ -22,7 +22,7 @@ package org.sonar.server.branch.ws; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -93,6 +93,6 @@ public class SetAutomaticDeletionProtectionAction implements BranchWsAction { } private void checkPermission(ProjectDto project) { - userSession.checkEntityPermission(UserRole.ADMIN, project); + userSession.checkEntityPermission(ProjectPermission.ADMIN, project); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/SetMainBranchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/SetMainBranchAction.java index 0e72d0bb8f1..21d7fb4270f 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/SetMainBranchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/branch/ws/SetMainBranchAction.java @@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -138,6 +138,6 @@ public class SetMainBranchAction implements BranchWsAction { } private void checkPermission(ProjectDto project) { - userSession.checkEntityPermission(UserRole.ADMIN, project); + userSession.checkEntityPermission(ProjectPermission.ADMIN, project); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java index 52bd1e347d2..5775ea89960 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java @@ -28,7 +28,7 @@ import javax.annotation.Nullable; import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.component.ComponentScopes; import org.sonar.api.server.ServerSide; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.ce.queue.CeQueue; import org.sonar.ce.queue.CeTaskSubmit; import org.sonar.ce.task.CeTask; @@ -138,7 +138,7 @@ public class ReportSubmitter { // they don't have the direct permission on the project. // That means that dropping the permission on the project does not have any effects // if user has still the global permission - if (!userSession.hasComponentPermission(UserRole.SCAN, project) && !userSession.hasPermission(GlobalPermission.SCAN)) { + if (!userSession.hasComponentPermission(ProjectPermission.SCAN, project) && !userSession.hasPermission(GlobalPermission.SCAN)) { throw insufficientPrivilegesException(); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java index b5b33674615..a61b14c38b9 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityAction.java @@ -37,7 +37,7 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.Paging; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.ce.task.taskprocessor.CeTaskProcessor; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -250,7 +250,7 @@ public class ActivityAction implements CeWsAction { if (entity == null) { userSession.checkIsSystemAdministrator(); } else { - userSession.checkEntityPermission(UserRole.ADMIN, entity); + userSession.checkEntityPermission(ProjectPermission.ADMIN, entity); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityStatusAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityStatusAction.java index 4d2308229f4..8c2a3ee511f 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityStatusAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ActivityStatusAction.java @@ -26,7 +26,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.ce.CeActivityDto; @@ -116,7 +116,7 @@ public class ActivityStatusAction implements CeWsAction { private void checkPermissions(@Nullable EntityDto entity) { if (entity != null) { - userSession.checkEntityPermission(UserRole.ADMIN, entity); + userSession.checkEntityPermission(ProjectPermission.ADMIN, entity); } else { userSession.checkIsSystemAdministrator(); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/AnalysisStatusAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/AnalysisStatusAction.java index 9e6fb10f345..685f6dd9850 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/AnalysisStatusAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/AnalysisStatusAction.java @@ -24,7 +24,7 @@ import javax.annotation.Nullable; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.ce.CeActivityDto; @@ -95,7 +95,7 @@ public class AnalysisStatusAction implements CeWsAction { private void doHandle(Request request, Response response, String projectKey, @Nullable String branchKey, @Nullable String pullRequestKey) { try (DbSession dbSession = dbClient.openSession(false)) { ProjectDto project = componentFinder.getProjectByKey(dbSession, projectKey); - userSession.checkEntityPermission(UserRole.USER, project); + userSession.checkEntityPermission(ProjectPermission.USER, project); BranchDto branch = componentFinder.getBranchOrPullRequest(dbSession, project, branchKey, pullRequestKey); AnalysisStatusWsResponse.Builder responseBuilder = AnalysisStatusWsResponse.newBuilder(); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/CancelAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/CancelAction.java index b204dd95b98..a62f3a9f653 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/CancelAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/CancelAction.java @@ -23,7 +23,7 @@ import java.util.Optional; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.ce.queue.CeQueue; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; @@ -95,6 +95,6 @@ public class CancelAction implements CeWsAction { if (!component.isPresent()) { throw insufficientPrivilegesException(); } - userSession.checkComponentPermission(UserRole.ADMIN, component.get()); + userSession.checkComponentPermission(ProjectPermission.ADMIN, component.get()); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java index e321c42a4fd..490bc9ad93a 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/ComponentAction.java @@ -24,7 +24,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.ce.CeActivityDto; @@ -82,7 +82,7 @@ public class ComponentAction implements CeWsAction { try (DbSession dbSession = dbClient.openSession(false)) { String entityKey = wsRequest.mandatoryParam(PARAM_COMPONENT); EntityDto entityDto = componentFinder.getEntityByKey(dbSession, entityKey); - userSession.checkEntityPermission(UserRole.USER, entityDto); + userSession.checkEntityPermission(ProjectPermission.USER, entityDto); List<CeQueueDto> queueDtos = dbClient.ceQueueDao().selectByEntityUuid(dbSession, entityDto.getUuid()); CeTaskQuery activityQuery = new CeTaskQuery() .setEntityUuid(entityDto.getUuid()) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/DismissAnalysisWarningAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/DismissAnalysisWarningAction.java index 61d9db62f10..a99f98ca7ae 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/DismissAnalysisWarningAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/DismissAnalysisWarningAction.java @@ -23,7 +23,7 @@ import java.util.Optional; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -81,7 +81,7 @@ public class DismissAnalysisWarningAction implements CeWsAction { try (DbSession dbSession = dbClient.openSession(false)) { ProjectDto project = componentFinder.getProjectByKey(dbSession, projectKey); - userSession.checkEntityPermission(UserRole.USER, project); + userSession.checkEntityPermission(ProjectPermission.USER, project); CeTaskMessageDto messageDto = dbClient.ceTaskMessageDao() .selectByUuid(dbSession, messageKey) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java index 4be63960ed0..b26f54a52a2 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskAction.java @@ -33,7 +33,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -139,8 +139,8 @@ public class TaskAction implements CeWsAction { private void checkComponentPermission(ComponentDto component) { if (userSession.hasPermission(GlobalPermission.ADMINISTER) || userSession.hasPermission(GlobalPermission.SCAN) || - userSession.hasComponentPermission(UserRole.ADMIN, component) || - userSession.hasComponentPermission(UserRole.SCAN, component)) { + userSession.hasComponentPermission(ProjectPermission.ADMIN, component) || + userSession.hasComponentPermission(ProjectPermission.SCAN, component)) { return; } throw insufficientPrivilegesException(); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentService.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentService.java index 29c79b99c33..2e8a1a89d6e 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentService.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentService.java @@ -22,7 +22,7 @@ package org.sonar.server.component; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.sonar.api.server.ServerSide; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.project.ProjectDto; @@ -55,7 +55,7 @@ public class ComponentService { } public void updateKey(DbSession dbSession, ProjectDto project, String newKey) { - userSession.checkEntityPermission(UserRole.ADMIN, project); + userSession.checkEntityPermission(ProjectPermission.ADMIN, project); checkProjectKey(newKey); dbClient.componentKeyUpdaterDao().updateKey(dbSession, project.getUuid(), project.getKey(), newKey); indexers.commitAndIndexEntities(dbSession, singletonList(project), Indexers.EntityEvent.PROJECT_KEY_UPDATE); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/AppAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/AppAction.java index 0e213e31918..3c5c27a1f36 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/AppAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/AppAction.java @@ -24,7 +24,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; @@ -89,7 +89,7 @@ public class AppAction implements ComponentsWsAction { public void handle(Request request, Response response) { try (DbSession session = dbClient.openSession(false)) { ComponentDto component = loadComponent(session, request); - userSession.checkComponentPermission(UserRole.USER, component); + userSession.checkComponentPermission(ProjectPermission.USER, component); EntityDto entity = dbClient.entityDao().selectByComponentUuid(session, component.uuid()) .orElseThrow(() -> new IllegalStateException("Couldn't find entity for component " + component.uuid())); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java index 4bb6086d373..c79ec7a21f3 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java @@ -45,7 +45,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.platform.EditionProvider.Edition; import org.sonar.core.platform.PlatformEditionProvider; import org.sonar.db.DbClient; @@ -262,7 +262,7 @@ public class SearchProjectsAction implements ComponentsWsAction { List<String> projectUuids = esResults.getUuids(); Ordering<ProjectDto> ordering = Ordering.explicit(projectUuids).onResultOf(ProjectDto::getUuid); List<ProjectDto> projects = ordering.immutableSortedCopy(dbClient.projectDao().selectByUuids(dbSession, new HashSet<>(projectUuids))); - projects = userSession.keepAuthorizedEntities(UserRole.USER, projects); + projects = userSession.keepAuthorizedEntities(ProjectPermission.USER, projects); Map<String, BranchDto> mainBranchByUuid = dbClient.branchDao().selectMainBranchesByProjectUuids(dbSession, projectUuids) .stream() diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ShowAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ShowAction.java index 04d461921cb..95595c53915 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ShowAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ShowAction.java @@ -28,7 +28,7 @@ import javax.annotation.Nullable; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -111,7 +111,7 @@ public class ShowAction implements ComponentsWsAction { private ShowWsResponse doHandle(Request request) { try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto component = loadComponent(dbSession, request); - userSession.checkComponentPermission(UserRole.USER, component); + userSession.checkComponentPermission(ProjectPermission.USER, component); Optional<SnapshotDto> lastAnalysis; if (component.getCopyComponentUuid() != null) { lastAnalysis = dbClient.snapshotDao().selectLastAnalysisByComponentUuid(dbSession, component.getCopyComponentUuid()); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SuggestionsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SuggestionsAction.java index 2983cc138d2..1196f57b5da 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SuggestionsAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SuggestionsAction.java @@ -61,7 +61,7 @@ import static java.util.Arrays.stream; import static java.util.Collections.emptyList; import static java.util.Collections.emptySet; import static java.util.Collections.singletonList; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.component.index.SuggestionQuery.DEFAULT_LIMIT; import static org.sonar.server.es.newindex.DefaultIndexSettings.MINIMUM_NGRAM_LENGTH; import static org.sonar.server.ws.WsUtils.writeProtobuf; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/TreeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/TreeAction.java index bad5feb7d15..c541e01731c 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/TreeAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/TreeAction.java @@ -40,7 +40,7 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.Paging; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.i18n.I18n; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -190,7 +190,7 @@ public class TreeAction implements ComponentsWsAction { } private List<ComponentDto> filterAuthorizedComponents(List<ComponentDto> components) { - return userSession.keepAuthorizedComponents(UserRole.USER, components); + return userSession.keepAuthorizedComponents(ProjectPermission.USER, components); } private ComponentDto loadComponent(DbSession dbSession, Request request) { @@ -214,7 +214,7 @@ public class TreeAction implements ComponentsWsAction { } private void checkPermissions(ComponentDto baseComponent) { - userSession.checkComponentPermission(UserRole.USER, baseComponent); + userSession.checkComponentPermission(ProjectPermission.USER, baseComponent); } private TreeWsResponse buildResponse(DbSession dbSession, ComponentDto baseComponent, List<ComponentDto> components, diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/developers/ws/SearchEventsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/developers/ws/SearchEventsAction.java index 6f1e030a897..71c4e362f50 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/developers/ws/SearchEventsAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/developers/ws/SearchEventsAction.java @@ -35,7 +35,7 @@ import org.sonar.api.platform.Server; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -207,7 +207,7 @@ public class SearchEventsAction implements DevelopersWsAction { private List<ProjectDto> searchProjects(DbSession dbSession, List<String> projectKeys) { List<ProjectDto> projects = dbClient.projectDao().selectProjectsByKeys(dbSession, new HashSet<>(projectKeys)); - return userSession.keepAuthorizedEntities(UserRole.USER, projects); + return userSession.keepAuthorizedEntities(ProjectPermission.USER, projects); } private String computeIssuesSearchLink(ProjectDto project, BranchDto branch, long functionalFromDate, String login) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/duplication/ws/ShowAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/duplication/ws/ShowAction.java index 13f6ea17626..88bca5dadc4 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/duplication/ws/ShowAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/duplication/ws/ShowAction.java @@ -27,7 +27,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -100,7 +100,7 @@ public class ShowAction implements DuplicationsWsAction { BranchDto branchDto = loadBranch(dbSession, component); String branch = branchDto.isMain() ? null : branchDto.getBranchKey(); String pullRequest = branchDto.getPullRequestKey(); - userSession.checkComponentPermission(UserRole.CODEVIEWER, component); + userSession.checkComponentPermission(ProjectPermission.CODEVIEWER, component); String duplications = findDataFromComponent(dbSession, component); List<DuplicationsParser.Block> blocks = parser.parse(dbSession, component, branch, pullRequest, duplications); writeProtobuf(responseBuilder.build(dbSession, blocks, branch, pullRequest), request, response); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/favorite/ws/AddAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/favorite/ws/AddAction.java index 18538c895e9..773a36b0a8d 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/favorite/ws/AddAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/favorite/ws/AddAction.java @@ -41,7 +41,7 @@ import static org.sonar.db.component.ComponentQualifiers.APP; import static org.sonar.db.component.ComponentQualifiers.PROJECT; import static org.sonar.db.component.ComponentQualifiers.SUBVIEW; import static org.sonar.db.component.ComponentQualifiers.VIEW; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.favorite.ws.FavoritesWsParameters.PARAM_COMPONENT; public class AddAction implements FavoritesWsAction { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/favorite/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/favorite/ws/SearchAction.java index a9bb90c7ff9..659a9962dbf 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/favorite/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/favorite/ws/SearchAction.java @@ -25,7 +25,7 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.Paging; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.entity.EntityDto; import org.sonar.server.favorite.FavoriteFinder; import org.sonar.server.user.UserSession; @@ -88,7 +88,7 @@ public class SearchAction implements FavoritesWsAction { private List<EntityDto> getAuthorizedFavorites() { List<EntityDto> entities = favoriteFinder.list(); - return userSession.keepAuthorizedEntities(UserRole.USER, entities); + return userSession.keepAuthorizedEntities(ProjectPermission.USER, entities); } private static class SearchResults { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/AddCommentAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/AddCommentAction.java index 693c761b6f8..21ec5531c9d 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/AddCommentAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/AddCommentAction.java @@ -22,7 +22,7 @@ package org.sonar.server.hotspot.ws; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.IssueChangeContext; import org.sonar.core.util.Uuids; @@ -80,7 +80,7 @@ public class AddCommentAction implements HotspotsWsAction { String comment = request.mandatoryParam(PARAM_COMMENT); try (DbSession dbSession = dbClient.openSession(false)) { IssueDto hotspot = hotspotWsSupport.loadHotspot(dbSession, hotspotKey); - hotspotWsSupport.loadAndCheckBranch(dbSession, hotspot, UserRole.USER); + hotspotWsSupport.loadAndCheckBranch(dbSession, hotspot, ProjectPermission.USER); DefaultIssue defaultIssue = hotspot.toDefaultIssue(); IssueChangeContext context = hotspotWsSupport.newIssueChangeContextWithoutMeasureRefresh(); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/AssignAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/AssignAction.java index f460faf6b19..2374b84c5e9 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/AssignAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/AssignAction.java @@ -24,7 +24,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.IssueChangeContext; import org.sonar.core.util.Uuids; @@ -110,7 +110,7 @@ public class AssignAction implements HotspotsWsAction { IssueDto hotspotDto = hotspotWsSupport.loadHotspot(dbSession, hotspotKey); checkHotspotStatusAndResolution(hotspotDto); - hotspotWsSupport.loadAndCheckBranch(dbSession, hotspotDto, UserRole.USER); + hotspotWsSupport.loadAndCheckBranch(dbSession, hotspotDto, ProjectPermission.USER); UserDto assignee = isNullOrEmpty(login) ? null : getAssignee(dbSession, login); IssueChangeContext context = hotspotWsSupport.newIssueChangeContextWithoutMeasureRefresh(); @@ -157,7 +157,7 @@ public class AssignAction implements HotspotsWsAction { } private boolean hasProjectPermission(DbSession dbSession, String userUuid, String projectUuid) { - return dbClient.authorizationDao().selectEntityPermissions(dbSession, projectUuid, userUuid).contains(UserRole.USER); + return dbClient.authorizationDao().selectEntityPermissions(dbSession, projectUuid, userUuid).contains(ProjectPermission.USER.getKey()); } private static HotspotChangedEvent buildEventData(DefaultIssue defaultIssue, @Nullable UserDto assignee, String filePath) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ChangeStatusAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ChangeStatusAction.java index c6dd61044f0..4f38005eac4 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ChangeStatusAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ChangeStatusAction.java @@ -27,7 +27,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.IssueChangeContext; import org.sonar.core.util.Uuids; @@ -115,7 +115,7 @@ public class ChangeStatusAction implements HotspotsWsAction { String newResolution = resolutionParam(request, newStatus); try (DbSession dbSession = dbClient.openSession(false)) { IssueDto hotspot = hotspotWsSupport.loadHotspot(dbSession, hotspotKey); - hotspotWsSupport.loadAndCheckBranch(dbSession, hotspot, UserRole.SECURITYHOTSPOT_ADMIN); + hotspotWsSupport.loadAndCheckBranch(dbSession, hotspot, ProjectPermission.SECURITYHOTSPOT_ADMIN); if (needStatusUpdate(hotspot, newStatus, newResolution)) { String transitionKey = toTransitionKey(newStatus, newResolution); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/HotspotWsSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/HotspotWsSupport.java index f7760ee6c66..43a16020ebb 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/HotspotWsSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/HotspotWsSupport.java @@ -21,9 +21,9 @@ package org.sonar.server.hotspot.ws; import java.util.Date; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.issue.IssueChangeContext; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -55,7 +55,7 @@ public class HotspotWsSupport { ProjectAndBranch loadAndCheckBranch(DbSession dbSession, String hotspotKey) { IssueDto hotspot = loadHotspot(dbSession, hotspotKey); - return loadAndCheckBranch(dbSession, hotspot, UserRole.USER); + return loadAndCheckBranch(dbSession, hotspot, ProjectPermission.USER); } IssueDto loadHotspot(DbSession dbSession, String hotspotKey) { @@ -65,7 +65,7 @@ public class HotspotWsSupport { .orElseThrow(() -> new NotFoundException(format("Hotspot '%s' does not exist", hotspotKey))); } - ProjectAndBranch loadAndCheckBranch(DbSession dbSession, IssueDto hotspot, String userRole) { + ProjectAndBranch loadAndCheckBranch(DbSession dbSession, IssueDto hotspot, ProjectPermission projectPermission) { String branchUuid = hotspot.getProjectUuid(); checkArgument(branchUuid != null, "Hotspot '%s' has no branch", hotspot.getKee()); @@ -74,12 +74,12 @@ public class HotspotWsSupport { ProjectDto project = dbClient.projectDao().selectByUuid(dbSession, branch.getProjectUuid()) .orElseThrow(() -> new NotFoundException(format("Project with uuid '%s' does not exist", branch.getProjectUuid()))); - userSession.checkEntityPermission(userRole, project); + userSession.checkEntityPermission(projectPermission, project); return new ProjectAndBranch(project, branch); } boolean canChangeStatus(ProjectDto project) { - return userSession.hasEntityPermission(UserRole.SECURITYHOTSPOT_ADMIN, project); + return userSession.hasEntityPermission(ProjectPermission.SECURITYHOTSPOT_ADMIN, project); } IssueChangeContext newIssueChangeContextWithoutMeasureRefresh() { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ListAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ListAction.java index e7e6fa7fbaa..e6251032515 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ListAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ListAction.java @@ -27,7 +27,7 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nullable; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; @@ -61,7 +61,7 @@ import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW; 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.utils.Paging.forPageIndex; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.es.SearchOptions.MAX_PAGE_SIZE; import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/PullHotspotsActionProtobufObjectGenerator.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/PullHotspotsActionProtobufObjectGenerator.java index f61dc86b5c4..e87271575f7 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/PullHotspotsActionProtobufObjectGenerator.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/PullHotspotsActionProtobufObjectGenerator.java @@ -43,12 +43,15 @@ public class PullHotspotsActionProtobufObjectGenerator implements ProtobufObject public Hotspots.HotspotLite generateIssueMessage(IssueDto hotspotDto, RuleDto ruleDto) { Hotspots.HotspotLite.Builder builder = Hotspots.HotspotLite.newBuilder() .setKey(hotspotDto.getKey()) - .setFilePath(hotspotDto.getFilePath()) .setStatus(hotspotDto.getStatus()) .setRuleKey(hotspotDto.getRuleKey().toString()) .setStatus(hotspotDto.getStatus()) .setVulnerabilityProbability(getVulnerabilityProbability(ruleDto)); + if (hotspotDto.getFilePath() != null) { + builder.setFilePath(hotspotDto.getFilePath()); + } + if (hotspotDto.getIssueCreationTime() != null) { builder.setCreationDate(hotspotDto.getIssueCreationTime()); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java index 85b7a1b0800..fe62670c143 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java @@ -37,7 +37,7 @@ import org.apache.lucene.search.TotalHits; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.search.SearchHit; import org.jetbrains.annotations.NotNull; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; @@ -80,7 +80,7 @@ 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.utils.DateUtils.longToDate; import static org.sonar.api.utils.Paging.forPageIndex; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.newcodeperiod.NewCodePeriodType.REFERENCE_BRANCH; import static org.sonar.server.es.SearchOptions.MAX_PAGE_SIZE; import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_INSECURE_INTERACTION; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ShowAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ShowAction.java index d866ce9b7ac..158dabc13d1 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ShowAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ShowAction.java @@ -33,7 +33,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -296,7 +296,7 @@ public class ShowAction implements HotspotsWsAction { String componentUuid = hotspot.getComponentUuid(); checkArgument(componentUuid != null, "Hotspot '%s' has no component", hotspot.getKee()); - ProjectAndBranch projectAndBranch = hotspotWsSupport.loadAndCheckBranch(dbSession, hotspot, UserRole.USER); + ProjectAndBranch projectAndBranch = hotspotWsSupport.loadAndCheckBranch(dbSession, hotspot, ProjectPermission.USER); BranchDto branch = projectAndBranch.getBranch(); ComponentDto component = dbClient.componentDao().selectByUuid(dbSession, componentUuid) .orElseThrow(() -> new NotFoundException(format("Component with uuid '%s' does not exist", componentUuid))); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/IssueFinder.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/IssueFinder.java index b0bfdf33f50..b697eb34424 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/IssueFinder.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/IssueFinder.java @@ -19,8 +19,8 @@ */ package org.sonar.server.issue; -import org.sonar.api.rules.RuleType; -import org.sonar.api.web.UserRole; +import org.sonar.core.rule.RuleType; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.issue.IssueDto; @@ -29,7 +29,7 @@ import org.sonar.server.user.UserSession; import static java.lang.String.format; import static java.util.Objects.requireNonNull; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; public class IssueFinder { @@ -49,7 +49,7 @@ public class IssueFinder { throw new NotFoundException(format("Issue with key '%s' does not exist", issueKey)); } - userSession.checkComponentUuidPermission(UserRole.USER, requireNonNull(issue.getProjectUuid())); + userSession.checkComponentUuidPermission(ProjectPermission.USER, requireNonNull(issue.getProjectUuid())); return issue; } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/SetSeverityAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/SetSeverityAction.java index ebd4f63483b..4dc6c359df1 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/SetSeverityAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/SetSeverityAction.java @@ -23,17 +23,18 @@ import java.util.Collection; import java.util.Map; import org.sonar.api.issue.Issue; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ServerSide; import org.sonar.api.server.rule.internal.ImpactMapper; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.rule.ImpactSeverityMapper; +import org.sonar.core.rule.RuleTypeMapper; import org.sonar.server.issue.workflow.IsUnResolved; import org.sonar.server.user.UserSession; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Strings.isNullOrEmpty; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; @ServerSide public class SetSeverityAction extends Action { @@ -67,7 +68,7 @@ public class SetSeverityAction extends Action { String severity = verifySeverityParameter(properties); boolean updated = issueUpdater.setManualSeverity(context.issue(), severity, context.issueChangeContext()); - SoftwareQuality softwareQuality = ImpactMapper.convertToSoftwareQuality(context.issue().type()); + SoftwareQuality softwareQuality = ImpactMapper.convertToSoftwareQuality(RuleTypeMapper.toApiRuleType(context.issue().type())); if (updated && context.issueDto().getEffectiveImpacts().containsKey(softwareQuality)) { createImpactsIfMissing(context.issue(), context.issueDto().getEffectiveImpacts()); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/SetTypeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/SetTypeAction.java index fc9ab370bca..58e1ca76c3a 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/SetTypeAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/SetTypeAction.java @@ -22,8 +22,8 @@ package org.sonar.server.issue; import java.util.Collection; import java.util.Map; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; -import org.sonar.api.web.UserRole; +import org.sonar.core.rule.RuleType; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.issue.DefaultIssue; import org.sonar.server.issue.workflow.IsUnResolved; import org.sonar.server.user.UserSession; @@ -47,7 +47,7 @@ public class SetTypeAction extends Action { } private boolean isCurrentUserIssueAdmin(Issue issue) { - return userSession.hasComponentUuidPermission(UserRole.ISSUE_ADMIN, issue.projectUuid()); + return userSession.hasComponentUuidPermission(ProjectPermission.ISSUE_ADMIN, issue.projectUuid()); } @Override diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/TransitionService.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/TransitionService.java index 966becac02a..3d4004caf47 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/TransitionService.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/TransitionService.java @@ -47,8 +47,8 @@ public class TransitionService { String projectUuid = requireNonNull(issue.projectUuid()); return workflow.outTransitions(issue) .stream() - .filter(transition -> (userSession.isLoggedIn() && isBlank(transition.requiredProjectPermission())) - || userSession.hasComponentUuidPermission(transition.requiredProjectPermission(), projectUuid)) + .filter(transition -> (userSession.isLoggedIn() && transition.requiredProjectPermission() == null) + || (transition.requiredProjectPermission() != null && userSession.hasComponentUuidPermission(transition.requiredProjectPermission(), projectUuid))) .toList(); } @@ -60,7 +60,7 @@ public class TransitionService { String projectUuid = requireNonNull(defaultIssue.projectUuid()); workflow.outTransitions(defaultIssue) .stream() - .filter(transition -> transition.key().equals(transitionKey) && isNotBlank(transition.requiredProjectPermission())) + .filter(transition -> transition.key().equals(transitionKey) && transition.requiredProjectPermission() != null) .forEach(transition -> userSession.checkComponentUuidPermission(transition.requiredProjectPermission(), projectUuid)); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/AuthorsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/AuthorsAction.java index 89cdfbc18ea..419bdf94d2f 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/AuthorsAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/AuthorsAction.java @@ -26,7 +26,7 @@ import java.util.Optional; import java.util.Set; import javax.annotation.Nullable; import org.sonar.db.component.ComponentQualifiers; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/BasePullAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/BasePullAction.java index 1bfc7f7ca46..b0af75458a1 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/BasePullAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/BasePullAction.java @@ -50,7 +50,7 @@ import org.sonar.server.ws.WsAction; import static java.lang.String.format; import static java.util.Collections.emptyList; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; public abstract class BasePullAction implements WsAction { protected static final String PROJECT_KEY_PARAM = "projectKey"; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/BulkChangeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/BulkChangeAction.java index cbb4504c7d4..e714011ccc4 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/BulkChangeAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/BulkChangeAction.java @@ -38,13 +38,13 @@ import org.slf4j.LoggerFactory; import org.sonar.api.issue.DefaultTransitions; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.IssueChangeContext; import org.sonar.db.DbClient; @@ -89,8 +89,8 @@ import static org.sonar.api.issue.DefaultTransitions.SET_AS_IN_REVIEW; import static org.sonar.api.issue.DefaultTransitions.UNCONFIRM; import static org.sonar.api.issue.DefaultTransitions.WONT_FIX; import static org.sonar.api.rule.Severity.BLOCKER; -import static org.sonar.api.rules.RuleType.BUG; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.BUG; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.core.issue.IssueChangeContext.issueChangeContextByUserBuilder; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02; @@ -421,7 +421,7 @@ public class BulkChangeAction implements IssuesWsAction { } private List<ComponentDto> getAuthorizedComponents(List<ComponentDto> projectDtos) { - return userSession.keepAuthorizedComponents(UserRole.USER, projectDtos); + return userSession.keepAuthorizedComponents(ProjectPermission.USER, projectDtos); } private List<IssueDto> getAuthorizedIssues(List<IssueDto> allIssues) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/IssueUpdater.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/IssueUpdater.java index 6895d06b3cf..23147ea023f 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/IssueUpdater.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/IssueUpdater.java @@ -26,7 +26,7 @@ import javax.annotation.Nullable; import org.sonar.api.issue.IssueStatus; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.IssueChangeContext; import org.sonar.db.DbClient; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/ListAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/ListAction.java index 21d236842da..abbad77f06a 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/ListAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/ListAction.java @@ -23,13 +23,13 @@ import com.google.common.base.Preconditions; import java.util.EnumSet; import java.util.List; import javax.annotation.Nullable; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.Paging; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.Pagination; @@ -189,13 +189,13 @@ public class ListAction implements IssuesWsAction { .orElseThrow(() -> new IllegalStateException("Branch does not exist: " + componentDto.branchUuid())); ProjectDto projectDto = dbClient.projectDao().selectByUuid(dbSession, branchDto.getProjectUuid()) .orElseThrow(() -> new IllegalArgumentException("Project does not exist: " + wsRequest.project)); - userSession.checkEntityPermission(UserRole.USER, projectDto); + userSession.checkEntityPermission(ProjectPermission.USER, projectDto); return new ProjectAndBranch(projectDto, branchDto); } private ProjectAndBranch checkProjectAndBranchPermission(WsRequest wsRequest, DbSession dbSession) { ProjectAndBranch projectAndBranch = componentFinder.getProjectAndBranch(dbSession, wsRequest.project, wsRequest.branch, wsRequest.pullRequest); - userSession.checkEntityPermission(UserRole.USER, projectAndBranch.getProject()); + userSession.checkEntityPermission(ProjectPermission.USER, projectAndBranch.getProject()); return projectAndBranch; } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java index 192106ee0bf..6a8f8dd6ea0 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java @@ -38,7 +38,7 @@ import org.sonar.api.issue.IssueStatus; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttributeCategory; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; @@ -443,7 +443,8 @@ public class SearchAction implements IssuesWsAction { .setExampleValue("1m2w (1 month 2 weeks)"); action.createParam(PARAM_IN_NEW_CODE_PERIOD) .setDescription("To retrieve issues created in the new code period.<br>" + - "If this parameter is set to a truthy value, createdAfter must not be set and one component uuid or key must be provided.") + "If this parameter is set to a truthy value, createdAfter must not be set and one component uuid or key must be provided.<br>" + + "This parameter is ignored if the requested component is Application or Portfolio.") .setBooleanPossibleValues() .setSince("9.4"); action.createParam(PARAM_TIMEZONE) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseFormat.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseFormat.java index 860b9c34f64..cfac4cf5e7a 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseFormat.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseFormat.java @@ -33,7 +33,7 @@ import org.sonar.api.resources.Language; import org.sonar.api.resources.Languages; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.Duration; import org.sonar.api.utils.Durations; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseLoader.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseLoader.java index aea18c74de8..ba73952b41c 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseLoader.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchResponseLoader.java @@ -32,7 +32,7 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssue; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -57,7 +57,7 @@ import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.Objects.requireNonNull; import static java.util.stream.Stream.concat; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; import static org.sonar.server.issue.AssignAction.ASSIGN_KEY; import static org.sonar.server.issue.CommentAction.COMMENT_KEY; import static org.sonar.server.issue.SetSeverityAction.SET_SEVERITY_KEY; @@ -248,7 +248,7 @@ public class SearchResponseLoader { if (login == null) { return Collections.emptySet(); } - RuleType ruleType = RuleType.valueOf(issue.getType()); + RuleType ruleType = RuleType.fromDbConstant(issue.getType()); availableActions.add(COMMENT_KEY); availableActions.add("set_tags"); if (issue.getResolution() != null) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SetSeverityAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SetSeverityAction.java index d62254085f4..674b2cf96cd 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SetSeverityAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SetSeverityAction.java @@ -32,6 +32,7 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.IssueChangeContext; +import org.sonar.core.rule.RuleTypeMapper; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -46,9 +47,10 @@ import org.sonar.server.user.UserSession; import static org.sonar.api.server.rule.internal.ImpactMapper.convertToRuleSeverity; import static org.sonar.api.server.rule.internal.ImpactMapper.convertToRuleType; import static org.sonar.api.server.rule.internal.ImpactMapper.convertToSoftwareQuality; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; import static org.sonar.core.issue.IssueChangeContext.issueChangeContextByUserBuilder; import static org.sonar.core.rule.ImpactSeverityMapper.mapImpactSeverity; +import static org.sonar.core.rule.RuleTypeMapper.toApiRuleType; import static org.sonar.db.component.BranchType.BRANCH; import static org.sonar.server.common.ParamParsingUtils.parseImpact; import static org.sonarqube.ws.client.issue.IssuesWsParameters.ACTION_SET_SEVERITY; @@ -163,7 +165,7 @@ public class SetSeverityAction implements IssuesWsAction { if (issueFieldsSetter.setImpactManualSeverity(issue, softwareQuality, manualImpactSeverity, context)) { String manualSeverity = null; boolean severityHasChanged = false; - if (convertToRuleType(softwareQuality).equals(issue.type())) { + if (convertToRuleType(softwareQuality) == RuleTypeMapper.toApiRuleType(issue.type())) { manualSeverity = convertToRuleSeverity(manualImpactSeverity); severityHasChanged = issueFieldsSetter.setManualSeverity(issue, manualSeverity, context); } @@ -181,7 +183,7 @@ public class SetSeverityAction implements IssuesWsAction { private SearchResponseData setManualSeverity(DbSession session, DefaultIssue issue, IssueDto issueDto, String severity, IssueChangeContext context) { if (issueFieldsSetter.setManualSeverity(issue, severity, context)) { - SoftwareQuality softwareQuality = convertToSoftwareQuality(issue.type()); + SoftwareQuality softwareQuality = convertToSoftwareQuality(toApiRuleType(issue.type())); boolean impactHasChanged = false; if (issueDto.getEffectiveImpacts().containsKey(softwareQuality)) { createImpactsIfMissing(issue, issueDto.getEffectiveImpacts()); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SetTypeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SetTypeAction.java index 30666f17ae8..c459d1990ce 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SetTypeAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SetTypeAction.java @@ -23,7 +23,7 @@ import com.google.common.io.Resources; import java.util.Date; import java.util.EnumSet; import java.util.Map; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; @@ -41,7 +41,7 @@ import org.sonar.server.issue.IssueFinder; import org.sonar.server.pushapi.issues.IssueChangeEventService; import org.sonar.server.user.UserSession; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; import static org.sonar.core.issue.IssueChangeContext.issueChangeContextByUserBuilder; import static org.sonar.db.component.BranchType.BRANCH; import static org.sonarqube.ws.client.issue.IssuesWsParameters.ACTION_SET_TYPE; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsActionValidator.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsActionValidator.java index abf52786137..9363cc87f98 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsActionValidator.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsActionValidator.java @@ -27,7 +27,7 @@ import org.sonar.server.component.ComponentFinder; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.user.UserSession; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException; public class AnticipatedTransitionsActionValidator { @@ -60,7 +60,7 @@ public class AnticipatedTransitionsActionValidator { public void validateUserHasAdministerIssuesPermission(String projectUuid) { try (DbSession dbSession = dbClient.openSession(false)) { String userUuid = Objects.requireNonNull(userSession.getUuid()); - if (!dbClient.authorizationDao().selectEntityPermissions(dbSession, projectUuid, userUuid).contains(ISSUE_ADMIN)){ + if (!dbClient.authorizationDao().selectEntityPermissions(dbSession, projectUuid, userUuid).contains(ISSUE_ADMIN.getKey())){ throw insufficientPrivilegesException(); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/IssueCounter.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/IssueCounter.java index 5488b926719..1eca839514c 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/IssueCounter.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/IssueCounter.java @@ -29,7 +29,7 @@ import javax.annotation.Nullable; import org.sonar.api.issue.IssueStatus; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.issue.IssueGroupDto; import org.sonar.db.issue.IssueImpactGroupDto; import org.sonar.db.issue.IssueImpactSeverityGroupDto; @@ -37,7 +37,7 @@ import org.sonar.db.rule.SeverityUtil; import org.sonar.server.measure.ImpactMeasureBuilder; import static org.sonar.api.rule.Severity.INFO; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; class IssueCounter { @@ -59,7 +59,7 @@ class IssueCounter { IssueCounter(Collection<IssueGroupDto> groups, Collection<IssueImpactGroupDto> impactGroups, Collection<IssueImpactSeverityGroupDto> impactSeverityGroups) { for (IssueGroupDto group : groups) { - if (RuleType.valueOf(group.getRuleType()).equals(SECURITY_HOTSPOT)) { + if (RuleType.fromDbConstant(group.getRuleType()).equals(SECURITY_HOTSPOT)) { processHotspotGroup(group); } else { processGroup(group); @@ -90,7 +90,7 @@ class IssueCounter { private void processGroup(IssueGroupDto group) { if (group.getResolution() == null) { - RuleType ruleType = RuleType.valueOf(group.getRuleType()); + RuleType ruleType = RuleType.fromDbConstant(group.getRuleType()); highestSeverityOfUnresolved .computeIfAbsent(ruleType, k -> new HighestSeverity()) .add(group); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java index a7c07b46118..42fe43f788c 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java @@ -29,7 +29,7 @@ import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Metric; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.metric.SoftwareQualitiesMetrics; import org.sonar.server.measure.ImpactMeasureBuilder; import org.sonar.server.measure.Rating; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java index 0f52c689e69..0afe402240e 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java @@ -32,7 +32,6 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -42,6 +41,8 @@ import org.sonar.db.component.SnapshotDto; import org.sonar.db.measure.MeasureDto; import org.sonar.db.metric.MetricDto; import org.sonar.db.metric.MetricDtoFunctions; +import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.server.component.ComponentFinder; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.user.UserSession; @@ -66,6 +67,7 @@ import static org.sonar.server.measure.ws.ComponentResponseCommon.addMetricToRes import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createAdditionalFieldsParameter; import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createMetricKeysParameter; import static org.sonar.server.measure.ws.SnapshotDtoToWsPeriod.snapshotToWsPeriods; +import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException; import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; import static org.sonar.server.ws.KeyExamples.KEY_PULL_REQUEST_EXAMPLE_001; @@ -88,10 +90,15 @@ public class ComponentAction implements MeasuresWsAction { public void define(WebService.NewController context) { WebService.NewAction action = context.createAction(ACTION_COMPONENT) .setDescription("Return component with specified measures.<br>" + - "Requires the following permission: 'Browse' on the project of specified component.") + "Requires one of the following permissions:" + + "<ul>" + + "<li>'Browse' on the project of the specified component</li>" + + "<li>'Execute Analysis' on the project of the specified component</li>" + + "</ul>") .setResponseExample(getClass().getResource("component-example.json")) .setSince("5.4") .setChangelog( + new Change("2025.2", "The 'Execute Analysis' permission also allows to access the endpoint"), new Change("10.8", format("The following metrics are not deprecated anymore: %s", MeasuresWsModule.getUndeprecatedMetricsinSonarQube108())), new Change("10.8", String.format("Added new accepted values for the 'metricKeys' param: %s", @@ -282,7 +289,11 @@ public class ComponentAction implements MeasuresWsAction { } private void checkPermissions(ComponentDto baseComponent) { - userSession.checkComponentPermission(UserRole.USER, baseComponent); + if (!userSession.hasComponentPermission(ProjectPermission.USER, baseComponent) && + !userSession.hasComponentPermission(ProjectPermission.SCAN, baseComponent) && + !userSession.hasPermission(GlobalPermission.SCAN)) { + throw insufficientPrivilegesException(); + } } private static class ComponentRequest { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java index c53aac85e9e..6e7e8fa2039 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java @@ -49,7 +49,7 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.Paging; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.i18n.I18n; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -657,7 +657,7 @@ public class ComponentTreeAction implements MeasuresWsAction { } private List<ComponentDto> filterAuthorizedComponents(List<ComponentDto> components) { - return userSession.keepAuthorizedComponents(UserRole.USER, components); + return userSession.keepAuthorizedComponents(ProjectPermission.USER, components); } private static boolean componentWithMeasuresOnly(ComponentTreeRequest wsRequest) { @@ -715,10 +715,10 @@ public class ComponentTreeAction implements MeasuresWsAction { } private void checkPermissions(ComponentDto baseComponent) { - userSession.checkComponentPermission(UserRole.USER, baseComponent); + userSession.checkComponentPermission(ProjectPermission.USER, baseComponent); if (ComponentScopes.PROJECT.equals(baseComponent.scope()) && ComponentQualifiers.APP.equals(baseComponent.qualifier())) { - userSession.checkChildProjectsPermission(UserRole.USER, baseComponent); + userSession.checkChildProjectsPermission(ProjectPermission.USER, baseComponent); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java index 789c2d77e53..067b0f5ca39 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java @@ -31,7 +31,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; @@ -171,7 +171,7 @@ public class SearchAction implements MeasuresWsAction { } private List<ComponentDto> getAuthorizedProjects(List<ComponentDto> componentDtos) { - return userSession.keepAuthorizedComponents(UserRole.USER, componentDtos); + return userSession.keepAuthorizedComponents(ProjectPermission.USER, componentDtos); } private List<MetricDto> searchMetrics() { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java index 28fba47792e..bec33db5fd8 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java @@ -37,7 +37,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; @@ -227,9 +227,9 @@ public class SearchHistoryAction implements MeasuresWsAction { private ComponentDto searchComponent(SearchHistoryRequest request, DbSession dbSession) { ComponentDto component = loadComponent(dbSession, request); - userSession.checkComponentPermission(UserRole.USER, component); + userSession.checkComponentPermission(ProjectPermission.USER, component); if (ComponentScopes.PROJECT.equals(component.scope()) && ComponentQualifiers.APP.equals(component.qualifier())) { - userSession.checkChildProjectsPermission(UserRole.USER, component); + userSession.checkChildProjectsPermission(ProjectPermission.USER, component); } return component; } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/ListAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/ListAction.java index ccb9c2ea0b6..09cd48af9d1 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/ListAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/ListAction.java @@ -31,7 +31,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.DateUtils; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.documentation.DocumentationLinkGenerator; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -90,7 +90,7 @@ public class ListAction implements NewCodePeriodsWsAction { try (DbSession dbSession = dbClient.openSession(false)) { ProjectDto project = componentFinder.getProjectByKey(dbSession, projectKey); - userSession.checkEntityPermission(UserRole.USER, project); + userSession.checkEntityPermission(ProjectPermission.USER, project); Collection<BranchDto> branches = dbClient.branchDao().selectByProject(dbSession, project).stream() .filter(b -> b.getBranchType() == BranchType.BRANCH) .sorted(Comparator.comparing(BranchDto::getKey)) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/SetAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/SetAction.java index 7182d433a1a..4b27fbde77d 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/SetAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/SetAction.java @@ -27,7 +27,7 @@ import javax.annotation.Nullable; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.documentation.DocumentationLinkGenerator; import org.sonar.core.platform.EditionProvider; import org.sonar.core.platform.PlatformEditionProvider; @@ -156,7 +156,7 @@ public class SetAction implements NewCodePeriodsWsAction { if (projectKey != null) { project = getProject(dbSession, projectKey); - userSession.checkEntityPermission(UserRole.ADMIN, project); + userSession.checkEntityPermission(ProjectPermission.ADMIN, project); if (branchKey != null) { branch = getBranch(dbSession, project, branchKey); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/ShowAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/ShowAction.java index 75303cd6a29..011d21312bd 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/ShowAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/ShowAction.java @@ -24,7 +24,7 @@ import javax.annotation.Nullable; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.documentation.DocumentationLinkGenerator; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -127,8 +127,8 @@ public class ShowAction implements NewCodePeriodsWsAction { } private void checkPermission(ProjectDto project) { - if (userSession.hasEntityPermission(UserRole.SCAN, project) || - userSession.hasEntityPermission(UserRole.ADMIN, project) || + if (userSession.hasEntityPermission(ProjectPermission.SCAN, project) || + userSession.hasEntityPermission(ProjectPermission.ADMIN, project) || userSession.hasPermission(SCAN)) { return; } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/UnsetAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/UnsetAction.java index e3e2d32a4b0..29045b6dc75 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/UnsetAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/UnsetAction.java @@ -23,7 +23,7 @@ import javax.annotation.Nullable; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.documentation.DocumentationLinkGenerator; import org.sonar.core.platform.EditionProvider; import org.sonar.core.platform.PlatformEditionProvider; @@ -102,7 +102,7 @@ public class UnsetAction implements NewCodePeriodsWsAction { if (projectKey != null) { ProjectDto project = getProject(dbSession, projectKey); - userSession.checkEntityPermission(UserRole.ADMIN, project); + userSession.checkEntityPermission(ProjectPermission.ADMIN, project); projectUuid = project.getUuid(); if (branchKey != null) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/notification/ws/AddAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/notification/ws/AddAction.java index 7c00532aff9..e78b170934a 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/notification/ws/AddAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/notification/ws/AddAction.java @@ -24,7 +24,7 @@ import java.util.Optional; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.project.ProjectDto; @@ -128,7 +128,7 @@ public class AddAction implements NotificationsWsAction { private Optional<ProjectDto> searchProject(DbSession dbSession, AddRequest request) { Optional<ProjectDto> project = request.getProject() == null ? empty() : Optional.of(componentFinder.getProjectByKey(dbSession, request.getProject())); - project.ifPresent(p -> userSession.checkEntityPermission(UserRole.USER, p)); + project.ifPresent(p -> userSession.checkEntityPermission(ProjectPermission.USER, p)); return project; } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/notification/ws/ListAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/notification/ws/ListAction.java index 7c0c801d546..6ea7a2525ce 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/notification/ws/ListAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/notification/ws/ListAction.java @@ -34,7 +34,7 @@ import javax.annotation.Nullable; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; @@ -218,7 +218,7 @@ public class ListAction implements NotificationsWsAction { .filter(Objects::nonNull) .collect(Collectors.toSet()); Set<String> authorizedProjectUuids = dbClient.authorizationDao().keepAuthorizedEntityUuids(dbSession, entityUuids, - userSession.getUuid(), UserRole.USER); + userSession.getUuid(), ProjectPermission.USER); return dbClient.entityDao().selectByUuids(dbSession, entityUuids) .stream() .filter(c -> authorizedProjectUuids.contains(c.getUuid())) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/PermissionPrivilegeChecker.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/PermissionPrivilegeChecker.java index b7f0aa3f9f3..add804fe588 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/PermissionPrivilegeChecker.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/PermissionPrivilegeChecker.java @@ -21,7 +21,7 @@ package org.sonar.server.permission; import javax.annotation.Nullable; import org.sonar.api.config.Configuration; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; import org.sonar.server.user.UserSession; @@ -55,7 +55,7 @@ public class PermissionPrivilegeChecker { boolean allowChangingPermissionsByProjectAdmins = config.getBoolean(CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_PROPERTY) .orElse(CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_DEFAULT_VALUE); if (entity != null && allowChangingPermissionsByProjectAdmins) { - userSession.checkEntityPermission(UserRole.ADMIN, entity); + userSession.checkEntityPermission(ProjectPermission.ADMIN, entity); } else { throw insufficientPrivilegesException(); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/RequestValidator.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/RequestValidator.java index 35724a5107d..0568a042408 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/RequestValidator.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/RequestValidator.java @@ -25,9 +25,10 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import java.util.stream.Collectors; import javax.annotation.Nullable; +import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.server.component.ComponentType; import org.sonar.server.component.ComponentTypes; -import org.sonar.db.permission.GlobalPermission; import org.sonar.server.exceptions.BadRequestException; import static com.google.common.base.Strings.isNullOrEmpty; @@ -39,16 +40,14 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_Q public class RequestValidator { public static final String MSG_TEMPLATE_WITH_SAME_NAME = "A template with the name '%s' already exists (case insensitive)."; - private final PermissionService permissionService; private final String allProjectsPermissionsOnOneLine; public RequestValidator(PermissionService permissionService) { - this.permissionService = permissionService; allProjectsPermissionsOnOneLine = Joiner.on(", ").join(permissionService.getAllProjectPermissions()); } public String validateProjectPermission(String permission) { - BadRequestException.checkRequest(permissionService.getAllProjectPermissions().contains(permission), + BadRequestException.checkRequest(ProjectPermission.contains(permission), String.format("The '%s' parameter for project permissions must be one of %s. '%s' was passed.", PARAM_PERMISSION, allProjectsPermissionsOnOneLine, permission)); return permission; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/PermissionWsSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/PermissionWsSupport.java index 52a6def7353..e2f3648c996 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/PermissionWsSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/PermissionWsSupport.java @@ -28,7 +28,7 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.config.Configuration; import org.sonar.api.server.ws.Request; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentQualifiers; @@ -138,7 +138,7 @@ public class PermissionWsSupport { return; } - if (hasBrowsePermissionViaUser(dbSession, userSession, entityDto).contains(UserRole.USER)) { + if (hasBrowsePermissionViaUser(dbSession, userSession, entityDto).contains(ProjectPermission.USER.getKey())) { return; } @@ -171,7 +171,7 @@ public class PermissionWsSupport { } public static boolean isUpdatingBrowsePermissionOnPrivateProject(String permission, @Nullable EntityDto entityDto) { - return entityDto != null && entityDto.isPrivate() && permission.equals(UserRole.USER); + return entityDto != null && entityDto.isPrivate() && permission.equals(ProjectPermission.USER.getKey()); } private boolean userHasBrowsePermissionViaGroup(DbSession dbSession, Collection<GroupDto> groups, EntityDto entityDto) { @@ -184,7 +184,7 @@ public class PermissionWsSupport { } private Set<String> findGroupsWithBrowsePermission(DbSession dbSession,EntityDto entityDto) { - return dbClient.groupPermissionDao().selectGroupUuidsWithPermissionOnEntity(dbSession, entityDto.getUuid(), UserRole.USER); + return dbClient.groupPermissionDao().selectGroupUuidsWithPermissionOnEntity(dbSession, entityDto.getUuid(), ProjectPermission.USER.getKey()); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java index be1ad364011..1690ec5cb3a 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java @@ -25,7 +25,6 @@ import java.util.List; import java.util.Locale; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.sonar.db.component.ComponentQualifiers; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; @@ -33,6 +32,8 @@ import org.sonar.api.server.ws.WebService.Param; import org.sonar.core.i18n.I18n; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import org.sonar.db.component.ComponentQualifiers; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.template.CountByTemplateAndPermissionDto; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; import org.sonar.db.permission.template.PermissionTemplateDto; @@ -130,14 +131,14 @@ public class SearchTemplatesAction implements PermissionsWsAction { .setUpdatedAt(formatDateTime(templateDto.getUpdatedAt())); ofNullable(templateDto.getKeyPattern()).ifPresent(templateBuilder::setProjectKeyPattern); ofNullable(templateDto.getDescription()).ifPresent(templateBuilder::setDescription); - for (String permission : permissionService.getAllProjectPermissions()) { + for (ProjectPermission permission : permissionService.getAllProjectPermissions()) { templateBuilder.addPermissions( permissionResponse .clear() - .setKey(permission) - .setUsersCount(data.userCount(templateDto.getUuid(), permission)) - .setGroupsCount(data.groupCount(templateDto.getUuid(), permission)) - .setWithProjectCreator(data.withProjectCreator(templateDto.getUuid(), permission))); + .setKey(permission.getKey()) + .setUsersCount(data.userCount(templateDto.getUuid(), permission.getKey())) + .setGroupsCount(data.groupCount(templateDto.getUuid(), permission.getKey())) + .setWithProjectCreator(data.withProjectCreator(templateDto.getUuid(), permission.getKey()))); } response.addPermissionTemplates(templateBuilder); } @@ -155,13 +156,13 @@ public class SearchTemplatesAction implements PermissionsWsAction { private void buildPermissionsResponse(SearchTemplatesWsResponse.Builder response) { Permission.Builder permissionResponse = Permission.newBuilder(); - for (String permissionKey : permissionService.getAllProjectPermissions()) { + for (ProjectPermission permissionKey : permissionService.getAllProjectPermissions()) { response.addPermissions( permissionResponse .clear() - .setKey(permissionKey) - .setName(i18nName(permissionKey)) - .setDescription(i18nDescriptionMessage(permissionKey))); + .setKey(permissionKey.getKey()) + .setName(i18nName(permissionKey.getKey())) + .setDescription(i18nDescriptionMessage(permissionKey.getKey()))); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/HealthActionSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/HealthActionSupport.java index 70251c4139a..31b43e307ed 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/HealthActionSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/platform/ws/HealthActionSupport.java @@ -20,7 +20,10 @@ package org.sonar.server.platform.ws; import com.google.common.io.Resources; +import java.net.Inet6Address; +import java.net.InetAddress; import java.util.Comparator; +import org.apache.commons.lang3.StringUtils; import org.sonar.api.server.ws.WebService; import org.sonar.process.ProcessProperties; import org.sonar.process.cluster.health.NodeDetails; @@ -104,12 +107,26 @@ public class HealthActionSupport { nodeBuilder .setType(System.NodeType.valueOf(details.getType().name())) .setName(details.getName()) - .setHost(details.getHost()) + .setHost(resolveIp(details.getHost())) .setPort(details.getPort()) .setStartedAt(formatDateTime(details.getStartedAt())); return nodeBuilder.build(); } + private static String resolveIp(String host) { + if (!StringUtils.isEmpty(host)) { + try { + InetAddress inetAddress = InetAddress.getByName(host); + if (inetAddress instanceof Inet6Address) { + return "[" + host + "]"; + } + } catch (Exception e) { + return host; + } + } + return host; + } + private static System.Cause toCause(String str, System.Cause.Builder causeBuilder) { return causeBuilder.clear().setMessage(str).build(); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/DeleteAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/DeleteAction.java index b36e6e41cf5..f66038a79ac 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/DeleteAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/DeleteAction.java @@ -22,7 +22,7 @@ package org.sonar.server.project.ws; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -92,7 +92,7 @@ public class DeleteAction implements ProjectsWsAction { } private void checkPermission(ProjectDto project) { - if (!userSession.hasEntityPermission(UserRole.ADMIN, project)) { + if (!userSession.hasEntityPermission(ProjectPermission.ADMIN, project)) { userSession.checkPermission(GlobalPermission.ADMINISTER); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/ProjectFinder.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/ProjectFinder.java index 844ce0d6b01..4febb5d6e54 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/ProjectFinder.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/ProjectFinder.java @@ -25,7 +25,7 @@ import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.server.ServerSide; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.permission.GlobalPermission; @@ -52,7 +52,7 @@ public class ProjectFinder { public SearchResult search(DbSession dbSession, @Nullable String searchQuery) { List<ProjectDto> allProjects = dbClient.projectDao().selectProjects(dbSession); - Set<String> projectsUserHasAccessTo = userSession.keepAuthorizedEntities(UserRole.SCAN, allProjects) + Set<String> projectsUserHasAccessTo = userSession.keepAuthorizedEntities(ProjectPermission.SCAN, allProjects) .stream() .map(ProjectDto::getKey) .collect(toSet()); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/SearchMyProjectsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/SearchMyProjectsAction.java index 851e51b7ba5..c08dee76ceb 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/SearchMyProjectsAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/SearchMyProjectsAction.java @@ -32,7 +32,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DatabaseUtils; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -202,7 +202,8 @@ public class SearchMyProjectsAction implements ProjectsWsAction { private ProjectsResult searchProjects(DbSession dbSession, SearchMyProjectsRequest request) { String userUuid = requireNonNull(userSession.getUuid(), "Current user must be authenticated"); - List<String> entitiesUuid = dbClient.roleDao().selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, UserRole.ADMIN, userUuid, Set.of(ComponentQualifiers.PROJECT)); + List<String> entitiesUuid = dbClient.roleDao() + .selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, ProjectPermission.ADMIN, userUuid, Set.of(ComponentQualifiers.PROJECT)); ImmutableSet<String> subSetEntityUuids = ImmutableSet.copyOf(entitiesUuid.subList(0, Math.min(entitiesUuid.size(), DatabaseUtils.PARTITION_SIZE_FOR_ORACLE))); Pagination pagination = Pagination.forPage(request.page).andSize(request.pageSize); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java index 44e7116747f..82b5e589ed2 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/UpdateVisibilityAction.java @@ -35,7 +35,7 @@ import org.sonarqube.ws.client.project.ProjectsWsParameters; import static org.sonar.api.CoreProperties.CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_DEFAULT_VALUE; import static org.sonar.api.CoreProperties.CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_PROPERTY; -import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.db.permission.ProjectPermission.ADMIN; import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/CreateEventAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/CreateEventAction.java index 0f356fffed8..957e900b893 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/CreateEventAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/CreateEventAction.java @@ -27,7 +27,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.UuidFactory; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; @@ -140,7 +140,7 @@ public class CreateEventAction implements ProjectAnalysesWsAction { } private void checkRequest(CreateEventRequest request, ProjectDto project) { - userSession.checkEntityPermission(UserRole.ADMIN, project); + userSession.checkEntityPermission(ProjectPermission.ADMIN, project); checkArgument(EventCategory.VERSION != request.getCategory() || ComponentQualifiers.PROJECT.equals(project.getQualifier()), "A version event must be created on a project"); checkVersionName(request.getCategory(), request.getName()); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/DeleteAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/DeleteAction.java index 374936d49a7..506f20896c5 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/DeleteAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/DeleteAction.java @@ -22,7 +22,7 @@ package org.sonar.server.projectanalysis.ws; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -73,7 +73,7 @@ public class DeleteAction implements ProjectAnalysesWsAction { if (STATUS_UNPROCESSED.equals(analysis.getStatus())) { throw analysisNotFoundException(analysisUuid); } - userSession.checkComponentUuidPermission(UserRole.ADMIN, analysis.getRootComponentUuid()); + userSession.checkComponentUuidPermission(ProjectPermission.ADMIN, analysis.getRootComponentUuid()); checkArgument(!analysis.getLast(), "The last analysis '%s' cannot be deleted", analysisUuid); checkNotUsedInNewCodePeriod(dbSession, analysis); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/DeleteEventAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/DeleteEventAction.java index 04930564149..951db943837 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/DeleteEventAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/DeleteEventAction.java @@ -22,7 +22,7 @@ package org.sonar.server.projectanalysis.ws; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -73,7 +73,7 @@ public class DeleteEventAction implements ProjectAnalysesWsAction { String eventP = request.mandatoryParam(PARAM_EVENT); try (DbSession dbSession = dbClient.openSession(false)) { EventDto event = getEvent(dbSession, eventP); - userSession.checkComponentUuidPermission(UserRole.ADMIN, event.getComponentUuid()); + userSession.checkComponentUuidPermission(ProjectPermission.ADMIN, event.getComponentUuid()); checkModifiable().accept(event); deleteEvent(dbSession, event); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java index f1c74898238..99bf60a1f5c 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java @@ -29,7 +29,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.config.CorePropertyDefinitions; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -191,9 +191,9 @@ public class SearchAction implements ProjectAnalysesWsAction { } private void checkPermission(ComponentDto project) { - userSession.checkComponentPermission(UserRole.USER, project); + userSession.checkComponentPermission(ProjectPermission.USER, project); if (ComponentScopes.PROJECT.equals(project.scope()) && ComponentQualifiers.APP.equals(project.qualifier())) { - userSession.checkChildProjectsPermission(UserRole.USER, project); + userSession.checkChildProjectsPermission(ProjectPermission.USER, project); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java index 770d45fc35c..3dc690e7257 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java @@ -28,7 +28,7 @@ import java.util.stream.Stream; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -131,7 +131,7 @@ public class UpdateEventAction implements ProjectAnalysesWsAction { } private Consumer<EventDto> checkPermissions() { - return event -> userSession.checkComponentUuidPermission(UserRole.ADMIN, event.getComponentUuid()); + return event -> userSession.checkComponentUuidPermission(ProjectPermission.ADMIN, event.getComponentUuid()); } private Consumer<EventDto> checkNonConflictingOtherEvents(DbSession dbSession) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectdump/ws/ProjectDumpWsSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectdump/ws/ProjectDumpWsSupport.java index 2dbcaaad38b..7c1f67fcfdc 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectdump/ws/ProjectDumpWsSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectdump/ws/ProjectDumpWsSupport.java @@ -20,7 +20,7 @@ package org.sonar.server.projectdump.ws; import org.sonar.api.server.ServerSide; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.project.ProjectDto; @@ -43,7 +43,7 @@ public class ProjectDumpWsSupport { public void verifyAdminOfProjectByKey(String projectKey) { try (DbSession dbSession = dbClient.openSession(false)) { ProjectDto project = componentFinder.getProjectByKey(dbSession, projectKey); - userSession.checkEntityPermission(UserRole.ADMIN, project); + userSession.checkEntityPermission(ProjectPermission.ADMIN, project); } } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectdump/ws/StatusAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectdump/ws/StatusAction.java index d09d217d09a..db89815bc57 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectdump/ws/StatusAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectdump/ws/StatusAction.java @@ -29,7 +29,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -98,7 +98,7 @@ public class StatusAction implements ProjectDumpAction { try (DbSession dbSession = dbClient.openSession(false)) { ProjectDto project = getProject(dbSession, uuid, key); BranchDto mainBranch = componentFinder.getMainBranch(dbSession, project); - userSession.checkEntityPermission(UserRole.ADMIN, project); + userSession.checkEntityPermission(ProjectPermission.ADMIN, project); WsResponse wsResponse = new WsResponse(); checkDumps(project, wsResponse); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/CreateAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/CreateAction.java index 3c2ad917de1..9fd56ec29cb 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/CreateAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/CreateAction.java @@ -22,7 +22,7 @@ package org.sonar.server.projectlink.ws; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -106,7 +106,7 @@ public class CreateAction implements ProjectLinksWsAction { try (DbSession dbSession = dbClient.openSession(false)) { ProjectDto project = getProject(dbSession, createWsRequest); - userSession.checkEntityPermission(UserRole.ADMIN, project); + userSession.checkEntityPermission(ProjectPermission.ADMIN, project); ProjectLinkDto link = new ProjectLinkDto() .setUuid(uuidFactory.create()) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java index 42de4a8da32..3d9f8ba0882 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java @@ -22,7 +22,7 @@ package org.sonar.server.projectlink.ws; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ProjectLinkDto; @@ -90,7 +90,7 @@ public class DeleteAction implements ProjectLinksWsAction { if (userSession.hasPermission(GlobalPermission.ADMINISTER)) { return; } - userSession.checkEntityPermission(UserRole.ADMIN, projectDto); + userSession.checkEntityPermission(ProjectPermission.ADMIN, projectDto); } private static void checkNotProvided(ProjectLinkDto link) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/SearchAction.java index 53caf9afebf..e52a11046b8 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/SearchAction.java @@ -23,7 +23,7 @@ import java.util.List; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ProjectLinkDto; @@ -118,8 +118,8 @@ public class SearchAction implements ProjectLinksWsAction { request.getProjectId(), request.getProjectKey(), ComponentFinder.ParamNames.PROJECT_ID_AND_KEY); - if (!userSession.hasEntityPermission(UserRole.ADMIN, project) && - !userSession.hasEntityPermission(UserRole.USER, project)) { + if (!userSession.hasEntityPermission(ProjectPermission.ADMIN, project) && + !userSession.hasEntityPermission(ProjectPermission.USER, project)) { throw insufficientPrivilegesException(); } return project; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projecttag/TagsWsSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projecttag/TagsWsSupport.java index 508fdfafca6..d8d29a08ab3 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projecttag/TagsWsSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projecttag/TagsWsSupport.java @@ -24,7 +24,7 @@ import java.util.Locale; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.project.ProjectDto; @@ -70,7 +70,7 @@ public class TagsWsSupport { } private void updateTagsForProjectsOrApplication(DbSession dbSession, List<String> tags, ProjectDto projectOrApplication) { - userSession.checkEntityPermission(UserRole.ADMIN, projectOrApplication); + userSession.checkEntityPermission(ProjectPermission.ADMIN, projectOrApplication); projectOrApplication.setTags(tags); projectOrApplication.setUpdatedAt(system2.now()); dbClient.projectDao().updateTags(dbSession, projectOrApplication); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/QualityGateCaycChecker.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/QualityGateCaycChecker.java index bc9e9fec350..ab9f4e21959 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/QualityGateCaycChecker.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/QualityGateCaycChecker.java @@ -96,7 +96,7 @@ public class QualityGateCaycChecker { public QualityGateCaycStatus checkCaycCompliant(Collection<QualityGateConditionDto> conditions, List<MetricDto> metrics) { var conditionsByMetricId = conditions .stream() - .collect(Collectors.toMap(QualityGateConditionDto::getMetricUuid, Function.identity())); + .collect(Collectors.toMap(QualityGateConditionDto::getMetricUuid, Function.identity(), (existing, replacement) -> existing)); if (conditionsByMetricId.size() < CAYC_METRICS.size()) { return NON_COMPLIANT; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java index f56ad77cf50..2e409544b36 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java @@ -32,8 +32,8 @@ import org.sonar.server.qualitygate.QualityGateFinder.QualityGateData; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Qualitygates.GetByProjectResponse; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_GET_BY_PROJECT; import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java index e921191adc0..963a2f35716 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java @@ -29,7 +29,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -220,9 +220,9 @@ public class ProjectStatusAction implements QualityGatesWsAction { } private void checkPermission(ProjectDto project) { - if (!userSession.hasEntityPermission(UserRole.ADMIN, project) && - !userSession.hasEntityPermission(UserRole.USER, project) && - !userSession.hasEntityPermission(UserRole.SCAN, project) && + if (!userSession.hasEntityPermission(ProjectPermission.ADMIN, project) && + !userSession.hasEntityPermission(ProjectPermission.USER, project) && + !userSession.hasEntityPermission(ProjectPermission.SCAN, project) && !userSession.hasPermission(GlobalPermission.SCAN)) { throw insufficientPrivilegesException(); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java index 571c1ad303e..9ff333275da 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java @@ -28,7 +28,7 @@ import org.sonar.server.component.ComponentFinder; import org.sonar.server.user.UserSession; import static com.google.common.base.Preconditions.checkArgument; -import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.db.permission.ProjectPermission.ADMIN; import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_GATES; import static org.sonar.server.exceptions.NotFoundException.checkFound; import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java index 83f14614c26..7bdec76255b 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java @@ -27,7 +27,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.Paging; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.qualitygate.ProjectQgateAssociationDto; @@ -156,7 +156,7 @@ public class SearchAction implements QualityGatesWsAction { private List<ProjectQgateAssociationDto> keepAuthorizedProjects(DbSession dbSession, List<ProjectQgateAssociationDto> projects) { List<String> projectUuids = projects.stream().map(ProjectQgateAssociationDto::getUuid).toList(); - Collection<String> authorizedProjectUuids = dbClient.authorizationDao().keepAuthorizedEntityUuids(dbSession, projectUuids, userSession.getUuid(), UserRole.USER); + Collection<String> authorizedProjectUuids = dbClient.authorizationDao().keepAuthorizedEntityUuids(dbSession, projectUuids, userSession.getUuid(), ProjectPermission.USER); return projects.stream().filter(project -> authorizedProjectUuids.contains(project.getUuid())).toList(); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileBackuperImpl.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileBackuperImpl.java index 23e17a9d550..4a03fd7bb88 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileBackuperImpl.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileBackuperImpl.java @@ -35,7 +35,7 @@ import org.apache.commons.lang3.builder.CompareToBuilder; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ServerSide; import org.sonar.db.DbClient; import org.sonar.db.DbSession; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileExporters.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileExporters.java deleted file mode 100644 index a6f2fc4bcc0..00000000000 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileExporters.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.qualityprofile; - -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ListMultimap; -import com.google.common.collect.Lists; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Collectors; -import javax.annotation.CheckForNull; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; -import org.sonar.api.profiles.ProfileExporter; -import org.sonar.api.profiles.ProfileImporter; -import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.ActiveRule; -import org.sonar.api.rules.ActiveRuleParam; -import org.sonar.api.rules.Rule; -import org.sonar.api.rules.RuleFinder; -import org.sonar.api.rules.RulePriority; -import org.sonar.api.server.ServerSide; -import org.sonar.api.utils.ValidationMessages; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.qualityprofile.ActiveRuleDto; -import org.sonar.db.qualityprofile.ActiveRuleParamDto; -import org.sonar.db.qualityprofile.OrgActiveRuleDto; -import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.db.rule.RuleDto; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.NotFoundException; -import org.springframework.beans.factory.annotation.Autowired; - -import static org.sonar.server.exceptions.BadRequestException.checkRequest; - -@ServerSide -public class QProfileExporters { - - private final DbClient dbClient; - private final RuleFinder ruleFinder; - private final QProfileRules qProfileRules; - private final ProfileExporter[] exporters; - private final ProfileImporter[] importers; - - @Autowired(required = false) - public QProfileExporters(DbClient dbClient, RuleFinder ruleFinder, QProfileRules qProfileRules, ProfileExporter[] exporters, ProfileImporter[] importers) { - this.dbClient = dbClient; - this.ruleFinder = ruleFinder; - this.qProfileRules = qProfileRules; - this.exporters = exporters; - this.importers = importers; - } - - /** - * Used by the ioc container if no {@link ProfileImporter} is found - */ - @Autowired(required = false) - public QProfileExporters(DbClient dbClient, RuleFinder ruleFinder, QProfileRules qProfileRules, ProfileExporter[] exporters) { - this(dbClient, ruleFinder, qProfileRules, exporters, new ProfileImporter[0]); - } - - /** - * Used by the ioc container if no {@link ProfileExporter} is found - */ - @Autowired(required = false) - public QProfileExporters(DbClient dbClient, RuleFinder ruleFinder, QProfileRules qProfileRules, ProfileImporter[] importers) { - this(dbClient, ruleFinder, qProfileRules, new ProfileExporter[0], importers); - } - - /** - * Used by the ioc container if no {@link ProfileImporter} nor {@link ProfileExporter} is found - */ - @Autowired(required = false) - public QProfileExporters(DbClient dbClient, RuleFinder ruleFinder, QProfileRules qProfileRules) { - this(dbClient, ruleFinder, qProfileRules, new ProfileExporter[0], new ProfileImporter[0]); - } - - public List<ProfileExporter> exportersForLanguage(String language) { - List<ProfileExporter> result = new ArrayList<>(); - for (ProfileExporter exporter : exporters) { - if (exporter.getSupportedLanguages() == null || exporter.getSupportedLanguages().length == 0 || ArrayUtils.contains(exporter.getSupportedLanguages(), language)) { - result.add(exporter); - } - } - return result; - } - - public String mimeType(String exporterKey) { - ProfileExporter exporter = findExporter(exporterKey); - return exporter.getMimeType(); - } - - public void export(DbSession dbSession, QProfileDto profile, String exporterKey, Writer writer) { - ProfileExporter exporter = findExporter(exporterKey); - exporter.exportProfile(wrap(dbSession, profile), writer); - } - - private RulesProfile wrap(DbSession dbSession, QProfileDto profile) { - RulesProfile target = new RulesProfile(profile.getName(), profile.getLanguage()); - List<OrgActiveRuleDto> activeRuleDtos = dbClient.activeRuleDao().selectByProfile(dbSession, profile); - List<ActiveRuleParamDto> activeRuleParamDtos = dbClient.activeRuleDao().selectParamsByActiveRuleUuids(dbSession, Lists.transform(activeRuleDtos, ActiveRuleDto::getUuid)); - ListMultimap<String, ActiveRuleParamDto> activeRuleParamsByActiveRuleUuid = FluentIterable.from(activeRuleParamDtos).index(ActiveRuleParamDto::getActiveRuleUuid); - - for (ActiveRuleDto activeRule : activeRuleDtos) { - // TODO all rules should be loaded by using one query with all active rule keys as parameter - Rule rule = ruleFinder.findByKey(activeRule.getRuleKey()); - org.sonar.api.rules.ActiveRule wrappedActiveRule = target.activateRule(rule, RulePriority.valueOf(activeRule.getSeverityString())); - List<ActiveRuleParamDto> paramDtos = activeRuleParamsByActiveRuleUuid.get(activeRule.getUuid()); - for (ActiveRuleParamDto activeRuleParamDto : paramDtos) { - wrappedActiveRule.setParameter(activeRuleParamDto.getKey(), activeRuleParamDto.getValue()); - } - } - return target; - } - - private ProfileExporter findExporter(String exporterKey) { - for (ProfileExporter e : exporters) { - if (exporterKey.equals(e.getKey())) { - return e; - } - } - throw new NotFoundException("Unknown quality profile exporter: " + exporterKey); - } - - public QProfileResult importXml(QProfileDto profile, String importerKey, InputStream xml, DbSession dbSession) { - return importXml(profile, importerKey, new InputStreamReader(xml, StandardCharsets.UTF_8), dbSession); - } - - private QProfileResult importXml(QProfileDto profile, String importerKey, Reader xml, DbSession dbSession) { - QProfileResult result = new QProfileResult(); - ValidationMessages messages = ValidationMessages.create(); - ProfileImporter importer = getProfileImporter(importerKey); - RulesProfile definition = importer.importProfile(xml, messages); - List<ActiveRuleChange> changes = importProfile(profile, definition, dbSession); - result.addChanges(changes); - processValidationMessages(messages, result); - return result; - } - - private List<ActiveRuleChange> importProfile(QProfileDto profile, RulesProfile definition, DbSession dbSession) { - Map<RuleKey, RuleDto> rulesByRuleKey = dbClient.ruleDao().selectAll(dbSession) - .stream() - .collect(Collectors.toMap(RuleDto::getKey, Function.identity())); - List<ActiveRule> activeRules = definition.getActiveRules(); - List<RuleActivation> activations = activeRules.stream() - .map(activeRule -> toRuleActivation(activeRule, rulesByRuleKey)) - .filter(Objects::nonNull) - .toList(); - return qProfileRules.activateAndCommit(dbSession, profile, activations); - } - - private ProfileImporter getProfileImporter(String importerKey) { - for (ProfileImporter importer : importers) { - if (StringUtils.equals(importerKey, importer.getKey())) { - return importer; - } - } - throw BadRequestException.create("No such importer : " + importerKey); - } - - private static void processValidationMessages(ValidationMessages messages, QProfileResult result) { - checkRequest(messages.getErrors().isEmpty(), messages.getErrors()); - result.addWarnings(messages.getWarnings()); - result.addInfos(messages.getInfos()); - } - - @CheckForNull - private static RuleActivation toRuleActivation(ActiveRule activeRule, Map<RuleKey, RuleDto> rulesByRuleKey) { - RuleKey ruleKey = activeRule.getRule().ruleKey(); - RuleDto ruleDto = rulesByRuleKey.get(ruleKey); - if (ruleDto == null) { - return null; - } - String severity = activeRule.getSeverity().name(); - Map<String, String> params = activeRule.getActiveRuleParams().stream() - .collect(Collectors.toMap(ActiveRuleParam::getKey, ActiveRuleParam::getValue)); - return RuleActivation.create(ruleDto.getUuid(), severity, params); - } - -} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileImpactSeverityMapper.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileImpactSeverityMapper.java index fbe081ba1c7..318d159cc26 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileImpactSeverityMapper.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileImpactSeverityMapper.java @@ -25,9 +25,11 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; import org.sonar.api.server.rule.internal.ImpactMapper; import org.sonar.core.rule.ImpactSeverityMapper; +import org.sonar.core.rule.RuleType; + +import static org.sonar.core.rule.RuleTypeMapper.toApiRuleType; /** * Class to map impact severity and rule severity during the override of severity of quality profile. @@ -43,7 +45,7 @@ public class QProfileImpactSeverityMapper { if (severity == null || ruleImpacts.isEmpty()) { return result; } - SoftwareQuality softwareQuality = ImpactMapper.convertToSoftwareQuality(ruleType); + SoftwareQuality softwareQuality = ImpactMapper.convertToSoftwareQuality(toApiRuleType(ruleType)); if (ruleImpacts.containsKey(softwareQuality)) { result.put(softwareQuality, ImpactSeverityMapper.mapImpactSeverity(severity)); } @@ -52,7 +54,7 @@ public class QProfileImpactSeverityMapper { @CheckForNull public static String mapSeverity(Map<SoftwareQuality, Severity> impacts, RuleType ruleType, @Nullable String ruleSeverity) { - SoftwareQuality softwareQuality = ImpactMapper.convertToSoftwareQuality(ruleType); + SoftwareQuality softwareQuality = ImpactMapper.convertToSoftwareQuality(toApiRuleType(ruleType)); if (impacts.containsKey(softwareQuality)) { return ImpactSeverityMapper.mapRuleSeverity(impacts.get(softwareQuality)); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileResult.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileResult.java deleted file mode 100644 index 2dadd2d8015..00000000000 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileResult.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 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.qualityprofile; - -import java.util.ArrayList; -import java.util.List; -import org.sonar.db.qualityprofile.QProfileDto; - -public class QProfileResult { - - private List<String> warnings; - private List<String> infos; - - private QProfileDto profile; - - private List<ActiveRuleChange> changes; - - public QProfileResult() { - warnings = new ArrayList<>(); - infos = new ArrayList<>(); - changes = new ArrayList<>(); - } - - public List<String> warnings() { - return warnings; - } - - public QProfileResult addWarnings(List<String> warnings) { - this.warnings.addAll(warnings); - return this; - } - - public List<String> infos() { - return infos; - } - - public QProfileResult addInfos(List<String> infos) { - this.infos.addAll(infos); - return this; - } - - public QProfileDto profile() { - return profile; - } - - public QProfileResult setProfile(QProfileDto profile) { - this.profile = profile; - return this; - } - - public List<ActiveRuleChange> getChanges() { - return changes; - } - - public QProfileResult addChanges(List<ActiveRuleChange> changes) { - this.changes.addAll(changes); - return this; - } - - public QProfileResult add(QProfileResult result) { - warnings.addAll(result.warnings()); - infos.addAll(result.infos()); - changes.addAll(result.getChanges()); - return this; - } - -} diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileRepositoryImpl.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileRepositoryImpl.java index 5a5b0d07f77..dd20b9c78c8 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileRepositoryImpl.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileRepositoryImpl.java @@ -32,7 +32,6 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.sonar.api.profiles.RulesProfile; import org.sonar.api.resources.Language; import org.sonar.api.resources.Languages; import org.sonar.api.rule.RuleKey; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileUpdateImpl.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileUpdateImpl.java index de49848fa6e..9499c538626 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileUpdateImpl.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileUpdateImpl.java @@ -21,6 +21,7 @@ package org.sonar.server.qualityprofile.builtin; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -53,10 +54,12 @@ public class BuiltInQProfileUpdateImpl implements BuiltInQProfileUpdate { public List<ActiveRuleChange> update(DbSession dbSession, BuiltInQProfile builtInDefinition, RulesProfileDto initialRuleProfile) { // Keep reference to all the activated rules before update - Set<String> deactivatedRuleUuids = dbClient.activeRuleDao().selectByRuleProfile(dbSession, initialRuleProfile) + Set<String> previousBuiltinActiveRuleUuids = dbClient.activeRuleDao().selectByRuleProfile(dbSession, initialRuleProfile) .stream() .map(ActiveRuleDto::getRuleUuid) - .collect(Collectors.toSet()); + .collect(Collectors.toUnmodifiableSet()); + + Set<String> deactivatedRuleUuids = new HashSet<>(previousBuiltinActiveRuleUuids); // all rules, including those which are removed from built-in profile Set<String> ruleUuids = Stream.concat( @@ -71,7 +74,7 @@ public class BuiltInQProfileUpdateImpl implements BuiltInQProfileUpdate { deactivatedRuleUuids.remove(activation.getRuleUuid()); } - RuleActivationContext context = ruleActivator.createContextForBuiltInProfile(dbSession, initialRuleProfile, ruleUuids); + RuleActivationContext context = ruleActivator.createContextForBuiltInProfile(dbSession, initialRuleProfile, ruleUuids, previousBuiltinActiveRuleUuids); List<ActiveRuleChange> changes = new ArrayList<>(); changes.addAll(ruleActivator.activate(dbSession, activations, context)); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/RuleActivationContext.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/RuleActivationContext.java index a2e7d50dfcf..c9f7b4b5a1f 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/RuleActivationContext.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/RuleActivationContext.java @@ -25,6 +25,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.CheckForNull; @@ -40,6 +41,7 @@ import org.sonar.server.qualityprofile.RuleActivation; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; +import static java.util.Collections.emptySet; import static java.util.Objects.requireNonNull; import static org.sonar.core.util.stream.MoreCollectors.index; import static org.sonar.server.exceptions.BadRequestException.checkRequest; @@ -54,6 +56,8 @@ public class RuleActivationContext { private final long date; + private Set<String> previousBuiltinActiveRuleUuids; + // The profile that is initially targeted by the operation private final RulesProfileDto baseRulesProfile; @@ -79,6 +83,8 @@ public class RuleActivationContext { private RuleActivationContext(Builder builder) { this.date = builder.date; + this.previousBuiltinActiveRuleUuids = builder.previousBuiltinActiveRuleUuids == null ? emptySet() : + builder.previousBuiltinActiveRuleUuids; this.descendantProfilesSupplier = builder.descendantProfilesSupplier; ListMultimap<String, RuleParamDto> paramsByRuleId = builder.ruleParams.stream().collect(index(RuleParamDto::getRuleUuid)); @@ -243,8 +249,13 @@ public class RuleActivationContext { .orElse(null); } + public Set<String> getPreviousBuiltinActiveRuleUuids() { + return previousBuiltinActiveRuleUuids; + } + static final class Builder { private long date = System.currentTimeMillis(); + private Set<String> previousBuiltinActiveRuleUuids; private RulesProfileDto baseRulesProfile; private Collection<RuleDto> rules; private Collection<RuleParamDto> ruleParams; @@ -258,6 +269,11 @@ public class RuleActivationContext { return this; } + Builder setPreviousBuiltinActiveRuleUuids(Set<String> previousBuiltinActiveRuleUuids) { + this.previousBuiltinActiveRuleUuids = previousBuiltinActiveRuleUuids; + return this; + } + Builder setBaseProfile(RulesProfileDto p) { this.baseRulesProfile = p; return this; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/RuleActivator.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/RuleActivator.java index 66bdcfb6c48..ee037c60776 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/RuleActivator.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/RuleActivator.java @@ -116,8 +116,7 @@ public class RuleActivator { ActiveRuleWrapper activeRule = context.getActiveRule(); ActiveRuleKey activeRuleKey = ActiveRuleKey.of(context.getRulesProfile(), rule.getKey()); if (activeRule == null) { - if (activation.isReset()) { - // ignore reset when rule is not activated + if (activation.isReset() || skipBuiltinRuleActivation(activation, context)) { return changes; } change = handleNewRuleActivation(activation, context, rule, activeRuleKey); @@ -142,9 +141,6 @@ public class RuleActivator { if (change != null) { changes.add(change); persist(change, context, dbSession); - } - - if (!changes.isEmpty()) { updateProfileDates(dbSession, context); } @@ -157,6 +153,12 @@ public class RuleActivator { return changes; } + private static boolean skipBuiltinRuleActivation(RuleActivation activation, RuleActivationContext context) { + // SONAR-23184: If the rule isn't active for a child profile and it is active for the previous parent definition of the profile, + // it means it was deactivated on purpose by a user - we don't want to active it. + return context.isCascading() && context.getPreviousBuiltinActiveRuleUuids().contains(activation.getRuleUuid()); + } + private void handleUpdatedRuleActivation(RuleActivation activation, RuleActivationContext context, ActiveRuleChange change, ActiveRuleWrapper activeRule) { if (context.isCascading() && activeRule.get().getInheritance() == null) { @@ -515,11 +517,12 @@ public class RuleActivator { } public RuleActivationContext createContextForBuiltInProfile(DbSession dbSession, RulesProfileDto builtInProfile, - Collection<String> ruleUuids) { + Collection<String> ruleUuids, Set<String> previousBuiltinActiveRuleUuids) { checkArgument(builtInProfile.isBuiltIn(), "Rules profile with UUID %s is not built-in", builtInProfile.getUuid()); RuleActivationContext.Builder builder = new RuleActivationContext.Builder(); builder.setDescendantProfilesSupplier(createDescendantProfilesSupplier(dbSession)); + builder.setPreviousBuiltinActiveRuleUuids(previousBuiltinActiveRuleUuids); // load rules completeWithRules(dbSession, builder, ruleUuids); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/AddProjectAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/AddProjectAction.java index 6f916e10d04..f03d2426ff1 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/AddProjectAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/AddProjectAction.java @@ -24,7 +24,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.NewAction; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.project.ProjectDto; @@ -117,7 +117,7 @@ public class AddProjectAction implements QProfileWsAction { } private void checkPermissions(QProfileDto profile, ProjectDto project) { - if (wsSupport.canAdministrate(profile) || userSession.hasEntityPermission(UserRole.ADMIN, project)) { + if (wsSupport.canAdministrate(profile) || userSession.hasEntityPermission(ProjectPermission.ADMIN, project)) { return; } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java index bd38a0f3d2e..2c391027a21 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java @@ -19,13 +19,8 @@ */ package org.sonar.server.qualityprofile.ws; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; import javax.annotation.Nullable; -import org.sonar.api.profiles.ProfileImporter; import org.sonar.api.resources.Languages; -import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; @@ -33,11 +28,8 @@ import org.sonar.api.server.ws.WebService.NewAction; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.qualityprofile.QProfileDto; -import org.sonar.server.qualityprofile.QProfileExporters; import org.sonar.server.qualityprofile.QProfileFactory; import org.sonar.server.qualityprofile.builtin.QProfileName; -import org.sonar.server.qualityprofile.QProfileResult; -import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Qualityprofiles.CreateWsResponse; @@ -48,37 +40,22 @@ import static org.sonar.server.ws.WsUtils.writeProtobuf; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_CREATE; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_NAME; -import org.springframework.beans.factory.annotation.Autowired; public class CreateAction implements QProfileWsAction { - private static final String PARAM_BACKUP_FORMAT = "backup_%s"; static final int NAME_MAXIMUM_LENGTH = 100; private final DbClient dbClient; private final QProfileFactory profileFactory; - private final QProfileExporters exporters; private final Languages languages; - private final ProfileImporter[] importers; private final UserSession userSession; - private final ActiveRuleIndexer activeRuleIndexer; - @Autowired(required = false) - public CreateAction(DbClient dbClient, QProfileFactory profileFactory, QProfileExporters exporters, Languages languages, - UserSession userSession, ActiveRuleIndexer activeRuleIndexer, ProfileImporter... importers) { + public CreateAction(DbClient dbClient, QProfileFactory profileFactory, Languages languages, + UserSession userSession) { this.dbClient = dbClient; this.profileFactory = profileFactory; - this.exporters = exporters; this.languages = languages; this.userSession = userSession; - this.activeRuleIndexer = activeRuleIndexer; - this.importers = importers; - } - - @Autowired(required = false) - public CreateAction(DbClient dbClient, QProfileFactory profileFactory, QProfileExporters exporters, Languages languages, - UserSession userSession, ActiveRuleIndexer activeRuleIndexer) { - this(dbClient, profileFactory, exporters, languages, userSession, activeRuleIndexer, new ProfileImporter[0]); } @Override @@ -90,7 +67,6 @@ public class CreateAction implements QProfileWsAction { .setResponseExample(getClass().getResource("create-example.json")) .setSince("5.2") .setHandler(this); - List<Change> changelog = new ArrayList<>(); create.createParam(PARAM_NAME) .setRequired(true) @@ -103,41 +79,22 @@ public class CreateAction implements QProfileWsAction { .setDescription("Quality profile language") .setExampleValue("js") .setPossibleValues(getOrderedLanguageKeys(languages)); - - for (ProfileImporter importer : importers) { - String backupParamName = getBackupParamName(importer.getKey()); - create.createParam(backupParamName) - .setDescription(String.format("A configuration file for %s.", importer.getName())) - .setDeprecatedSince("9.8"); - changelog.add(new Change("9.8", String.format("'%s' parameter is deprecated", backupParamName))); - } - - create.setChangelog(changelog.toArray(new Change[0])); } @Override public void handle(Request request, Response response) throws Exception { userSession.checkLoggedIn(); + userSession.checkPermission(ADMINISTER_QUALITY_PROFILES); try (DbSession dbSession = dbClient.openSession(false)) { - userSession.checkPermission(ADMINISTER_QUALITY_PROFILES); CreateRequest createRequest = toRequest(request); - writeProtobuf(doHandle(dbSession, createRequest, request), request, response); + writeProtobuf(doHandle(dbSession, createRequest), request, response); } } - private CreateWsResponse doHandle(DbSession dbSession, CreateRequest createRequest, Request request) { - QProfileResult result = new QProfileResult(); + private CreateWsResponse doHandle(DbSession dbSession, CreateRequest createRequest) { QProfileDto profile = profileFactory.checkAndCreateCustom(dbSession, QProfileName.createFor(createRequest.getLanguage(), createRequest.getName())); - result.setProfile(profile); - for (ProfileImporter importer : importers) { - String importerKey = importer.getKey(); - InputStream contentToImport = request.paramAsInputStream(getBackupParamName(importerKey)); - if (contentToImport != null) { - result.add(exporters.importXml(profile, importerKey, contentToImport, dbSession)); - } - } - activeRuleIndexer.commitAndIndex(dbSession, result.getChanges()); - return buildResponse(result); + dbSession.commit(); + return buildResponse(profile); } private static CreateRequest toRequest(Request request) { @@ -147,28 +104,18 @@ public class CreateAction implements QProfileWsAction { return builder.build(); } - private CreateWsResponse buildResponse(QProfileResult result) { - String language = result.profile().getLanguage(); + private CreateWsResponse buildResponse(QProfileDto profile) { + String language = profile.getLanguage(); CreateWsResponse.QualityProfile.Builder builder = CreateWsResponse.QualityProfile.newBuilder() - .setKey(result.profile().getKee()) - .setName(result.profile().getName()) + .setKey(profile.getKee()) + .setName(profile.getName()) .setLanguage(language) - .setLanguageName(languages.get(result.profile().getLanguage()).getName()) + .setLanguageName(languages.get(profile.getLanguage()).getName()) .setIsDefault(false) .setIsInherited(false); - if (!result.infos().isEmpty()) { - builder.getInfosBuilder().addAllInfos(result.infos()); - } - if (!result.warnings().isEmpty()) { - builder.getWarningsBuilder().addAllWarnings(result.warnings()); - } return CreateWsResponse.newBuilder().setProfile(builder.build()).build(); } - private static String getBackupParamName(String importerKey) { - return String.format(PARAM_BACKUP_FORMAT, importerKey); - } - private static class CreateRequest { private final String name; private final String language; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ExportAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ExportAction.java index ce8e5c5bdc0..bd39c10a605 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ExportAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ExportAction.java @@ -24,14 +24,10 @@ import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; -import java.util.Arrays; -import java.util.Collection; -import java.util.Set; -import java.util.stream.Collectors; import javax.annotation.Nullable; import org.apache.commons.io.IOUtils; -import org.sonar.api.profiles.ProfileExporter; import org.sonar.api.resources.Languages; +import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.Response.Stream; @@ -42,7 +38,6 @@ import org.sonar.db.DbSession; import org.sonar.db.qualityprofile.QProfileDto; import org.sonar.server.language.LanguageParamUtils; import org.sonar.server.qualityprofile.QProfileBackuper; -import org.sonar.server.qualityprofile.QProfileExporters; import org.sonarqube.ws.MediaTypes; import static java.nio.charset.StandardCharsets.UTF_8; @@ -52,17 +47,13 @@ import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters. public class ExportAction implements QProfileWsAction { - private static final String PARAM_EXPORTER_KEY = "exporterKey"; - private final DbClient dbClient; private final QProfileBackuper backuper; - private final QProfileExporters exporters; private final Languages languages; - public ExportAction(DbClient dbClient, QProfileBackuper backuper, QProfileExporters exporters, Languages languages) { + public ExportAction(DbClient dbClient, QProfileBackuper backuper, Languages languages) { this.dbClient = dbClient; this.backuper = backuper; - this.exporters = exporters; this.languages = languages; } @@ -72,7 +63,10 @@ public class ExportAction implements QProfileWsAction { .setSince("5.2") .setDescription("Export a quality profile.") .setResponseExample(getClass().getResource("export-example.xml")) - .setHandler(this); + .setHandler(this) + .setDeprecatedSince("25.4") + .setChangelog( + new Change("25.4", "Deprecated. Use GET /api/qualityprofiles/backup instead")); action.createParam(PARAM_QUALITY_PROFILE) .setDescription("Quality profile name to export. If left empty, the default profile for the language is exported.") @@ -84,17 +78,6 @@ public class ExportAction implements QProfileWsAction { .setExampleValue(LanguageParamUtils.getExampleValue(languages)) .setPossibleValues(LanguageParamUtils.getOrderedLanguageKeys(languages)); - Set<String> exporterKeys = Arrays.stream(languages.all()) - .map(language -> exporters.exportersForLanguage(language.getKey())) - .flatMap(Collection::stream) - .map(ProfileExporter::getKey) - .collect(Collectors.toSet()); - if (!exporterKeys.isEmpty()) { - action.createParam(PARAM_EXPORTER_KEY) - .setDescription("Output format. If left empty, the same format as api/qualityprofiles/backup is used. " + - "Possible values are described by api/qualityprofiles/exporters.") - .setPossibleValues(exporterKeys); - } } @Override @@ -104,22 +87,16 @@ public class ExportAction implements QProfileWsAction { try (DbSession dbSession = dbClient.openSession(false)) { QProfileDto profile = loadProfile(dbSession, language, name); - String exporterKey = exporters.exportersForLanguage(profile.getLanguage()).isEmpty() ? null : request.param(PARAM_EXPORTER_KEY); - writeResponse(dbSession, profile, exporterKey, response); + writeResponse(dbSession, profile, response); } } - private void writeResponse(DbSession dbSession, QProfileDto profile, @Nullable String exporterKey, Response response) throws IOException { + private void writeResponse(DbSession dbSession, QProfileDto profile, Response response) throws IOException { Stream stream = response.stream(); ByteArrayOutputStream bufferStream = new ByteArrayOutputStream(); try (Writer writer = new OutputStreamWriter(bufferStream, UTF_8)) { - if (exporterKey == null) { - stream.setMediaType(MediaTypes.XML); - backuper.backup(dbSession, profile, writer); - } else { - stream.setMediaType(exporters.mimeType(exporterKey)); - exporters.export(dbSession, profile, exporterKey, writer); - } + stream.setMediaType(MediaTypes.XML); + backuper.backup(dbSession, profile, writer); } OutputStream output = response.stream().output(); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ExportersAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ExportersAction.java index de3190bcf3f..57a318e4761 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ExportersAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ExportersAction.java @@ -19,53 +19,27 @@ */ package org.sonar.server.qualityprofile.ws; -import org.sonar.api.profiles.ProfileExporter; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService.NewController; import org.sonar.api.utils.text.JsonWriter; -import org.springframework.beans.factory.annotation.Autowired; public class ExportersAction implements QProfileWsAction { - private final ProfileExporter[] exporters; - - @Autowired(required = false) - public ExportersAction(ProfileExporter[] exporters) { - this.exporters = exporters; - } - - /** - * Used by the container if no {@link ProfileExporter} is found - */ - @Autowired(required = false) - public ExportersAction() { - this(new ProfileExporter[0]); - } - @Override public void define(NewController context) { context.createAction("exporters") - .setDescription("Lists available profile export formats.") + .setDescription("Deprecated. No more custom profile exporters.") .setHandler(this) .setResponseExample(getClass().getResource("exporters-example.json")) - .setSince("5.2"); + .setSince("5.2") + .setDeprecatedSince("25.4"); } @Override public void handle(Request request, Response response) throws Exception { try (JsonWriter json = response.newJsonWriter()) { json.beginObject().name("exporters").beginArray(); - for (ProfileExporter exporter : exporters) { - json.beginObject() - .prop("key", exporter.getKey()) - .prop("name", exporter.getName()); - json.name("languages").beginArray(); - for (String language : exporter.getSupportedLanguages()) { - json.value(language); - } - json.endArray().endObject(); - } json.endArray().endObject(); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ImportersAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ImportersAction.java index 078434db363..3d93cc675bb 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ImportersAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ImportersAction.java @@ -19,50 +19,28 @@ */ package org.sonar.server.qualityprofile.ws; -import org.sonar.api.profiles.ProfileImporter; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; -import org.springframework.beans.factory.annotation.Autowired; public class ImportersAction implements QProfileWsAction { - private final ProfileImporter[] importers; - - @Autowired(required = false) - public ImportersAction(ProfileImporter[] importers) { - this.importers = importers; - } - - @Autowired(required = false) - public ImportersAction() { - this(new ProfileImporter[0]); - } - @Override public void define(WebService.NewController controller) { controller.createAction("importers") + .setDescription("Deprecated. No more custom profile importers.") .setSince("5.2") .setDescription("List supported importers.") .setResponseExample(getClass().getResource("importers-example.json")) - .setHandler(this); + .setHandler(this) + .setDeprecatedSince("25.4"); } @Override public void handle(Request request, Response response) throws Exception { try (JsonWriter json = response.newJsonWriter()) { json.beginObject().name("importers").beginArray(); - for (ProfileImporter importer : importers) { - json.beginObject() - .prop("key", importer.getKey()) - .prop("name", importer.getName()) - .name("languages").beginArray(); - for (String languageKey : importer.getSupportedLanguages()) { - json.value(languageKey); - } - json.endArray().endObject(); - } json.endArray().endObject(); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ProjectsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ProjectsAction.java index c570cf431df..4c4c9442ca5 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ProjectsAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/ProjectsAction.java @@ -32,7 +32,7 @@ import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.server.ws.WebService.SelectionMode; import org.sonar.api.utils.Paging; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.qualityprofile.ProjectQprofileAssociationDto; @@ -108,7 +108,7 @@ public class ProjectsAction implements QProfileWsAction { .map(ProjectQprofileAssociationDto::getProjectUuid) .collect(Collectors.toSet()); - Set<String> authorizedProjectUuids = dbClient.authorizationDao().keepAuthorizedEntityUuids(session, projectUuids, userSession.getUuid(), UserRole.USER); + Set<String> authorizedProjectUuids = dbClient.authorizationDao().keepAuthorizedEntityUuids(session, projectUuids, userSession.getUuid(), ProjectPermission.USER); Paging paging = forPageIndex(page).withPageSize(pageSize).andTotal(authorizedProjectUuids.size()); List<ProjectQprofileAssociationDto> authorizedProjects = projects.stream() diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/RemoveProjectAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/RemoveProjectAction.java index fe64070e2bb..43225264f84 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/RemoveProjectAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/ws/RemoveProjectAction.java @@ -24,7 +24,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.NewAction; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.project.ProjectDto; @@ -110,7 +110,7 @@ public class RemoveProjectAction implements QProfileWsAction { } private void checkPermissions(QProfileDto profile, ProjectDto project) { - if (wsSupport.canAdministrate(profile) || userSession.hasEntityPermission(UserRole.ADMIN, project)) { + if (wsSupport.canAdministrate(profile) || userSession.hasEntityPermission(ProjectPermission.ADMIN, project)) { return; } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java index faf70bcea0c..21f8a47a1f5 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java @@ -27,7 +27,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; @@ -36,11 +35,12 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; import org.sonar.api.server.ServerSide; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.rule.internal.ImpactMapper; import org.sonar.api.utils.System2; +import org.sonar.core.rule.RuleType; +import org.sonar.core.rule.RuleTypeMapper; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -136,7 +136,7 @@ public class RuleUpdater { private static void updateImpactSeverity(RuleDto rule, String severity) { rule.getDefaultImpacts() .stream() - .filter(i -> i.getSoftwareQuality().equals(ImpactMapper.convertToSoftwareQuality(rule.getEnumType()))) + .filter(i -> i.getSoftwareQuality() == ImpactMapper.convertToSoftwareQuality(RuleTypeMapper.toApiRuleType(rule.getEnumType()))) .findFirst() .ifPresent(i -> i.setSeverity(mapImpactSeverity(severity))); } @@ -148,11 +148,11 @@ public class RuleUpdater { } impacts.forEach((key, value) -> rule.getDefaultImpacts() .stream() - .filter(i -> i.getSoftwareQuality().equals(key)) + .filter(i -> i.getSoftwareQuality() == key) .findFirst() .ifPresent(i -> { i.setSeverity(value); - if (Objects.equals(convertToRuleType(key), RuleType.valueOf(rule.getType()))) { + if (RuleTypeMapper.toRuleType(convertToRuleType(key)) == RuleType.fromDbConstant(rule.getType())) { rule.setSeverity(convertToDeprecatedSeverity(value)); } })); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/CreateAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/CreateAction.java index 23036091585..01c0e7eb966 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/CreateAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/CreateAction.java @@ -30,7 +30,7 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java index d55d0b68f86..831558dcc11 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java @@ -22,7 +22,7 @@ package org.sonar.server.rule.ws; import java.util.Date; import java.util.List; import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ServerSide; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.WebService; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java index 26d7902e471..2f1504032b4 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java @@ -30,7 +30,7 @@ import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttributeCategory; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ServerSide; import org.sonar.api.server.ws.WebService; import org.sonar.db.DbClient; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/SearchAction.java index 1ff20c90db7..d0bfa57b855 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/SearchAction.java @@ -38,7 +38,7 @@ import javax.annotation.Nullable; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttributeCategory; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/scannercache/ws/GetAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/scannercache/ws/GetAction.java index f3ce8dd2380..3c236a6154c 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/scannercache/ws/GetAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/scannercache/ws/GetAction.java @@ -28,7 +28,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbInputStream; import org.sonar.db.DbSession; @@ -121,8 +121,8 @@ public class GetAction implements AnalysisCacheWsAction { } private void checkPermission(ProjectDto project) { - if (userSession.hasEntityPermission(UserRole.SCAN, project) || - userSession.hasEntityPermission(UserRole.ADMIN, project) || + if (userSession.hasEntityPermission(ProjectPermission.SCAN, project) || + userSession.hasEntityPermission(ProjectPermission.ADMIN, project) || userSession.hasPermission(SCAN)) { return; } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ListDefinitionsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ListDefinitionsAction.java index da9b8a8a232..0e483c79b92 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ListDefinitionsAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ListDefinitionsAction.java @@ -42,7 +42,7 @@ import static com.google.common.base.Strings.emptyToNull; import static java.lang.String.format; import static java.util.Comparator.comparing; import static java.util.Optional.ofNullable; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_COMPONENT; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; import static org.sonar.server.ws.WsUtils.writeProtobuf; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ResetAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ResetAction.java index 423e01bade5..5cf0b66b6b0 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ResetAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ResetAction.java @@ -31,7 +31,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; @@ -142,7 +142,7 @@ public class ResetAction implements SettingsWsAction { private void checkPermissions(Optional<EntityDto> component) { if (component.isPresent()) { - userSession.checkEntityPermission(UserRole.ADMIN, component.get()); + userSession.checkEntityPermission(ProjectPermission.ADMIN, component.get()); } else { userSession.checkIsSystemAdministrator(); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SetAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SetAction.java index ceeadd31feb..d1febba4564 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SetAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SetAction.java @@ -43,7 +43,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; @@ -300,7 +300,7 @@ public class SetAction implements SettingsWsAction { private void checkPermissions(Optional<EntityDto> entity) { if (entity.isPresent()) { - userSession.checkEntityPermission(UserRole.ADMIN, entity.get()); + userSession.checkEntityPermission(ProjectPermission.ADMIN, entity.get()); } else { userSession.checkIsSystemAdministrator(); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SettingsWsSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SettingsWsSupport.java index a2ab37c1f20..dbc6864fee7 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SettingsWsSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SettingsWsSupport.java @@ -23,15 +23,15 @@ import com.google.common.annotations.VisibleForTesting; import java.util.Optional; import java.util.Set; import org.sonar.api.server.ServerSide; -import org.sonar.api.web.UserRole; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.process.ProcessProperties; import org.sonar.server.user.UserSession; import static java.lang.String.format; import static java.util.Arrays.stream; -import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.db.permission.ProjectPermission.ADMIN; @ServerSide public class SettingsWsSupport { @@ -58,7 +58,7 @@ public class SettingsWsSupport { if (isAdmin(component)) { return true; } - return hasPermission(GlobalPermission.SCAN, UserRole.SCAN, component) || !isProtected(key); + return hasPermission(GlobalPermission.SCAN, ProjectPermission.SCAN, component) || !isProtected(key); } private boolean isAdmin(Optional<EntityDto> component) { @@ -77,7 +77,7 @@ public class SettingsWsSupport { return ADMIN_ONLY_SETTINGS.contains(key); } - private boolean hasPermission(GlobalPermission orgPermission, String projectPermission, Optional<EntityDto> component) { + private boolean hasPermission(GlobalPermission orgPermission, ProjectPermission projectPermission, Optional<EntityDto> component) { if (userSession.hasPermission(orgPermission)) { return true; } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ValuesAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ValuesAction.java index ffeee3203da..0de63dcaf31 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ValuesAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/ValuesAction.java @@ -40,7 +40,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.entity.EntityDto; @@ -59,7 +59,7 @@ import static org.sonar.api.CoreProperties.SERVER_ID; import static org.sonar.api.CoreProperties.SERVER_STARTTIME; import static org.sonar.api.PropertyType.FORMATTED_TEXT; import static org.sonar.api.PropertyType.PROPERTY_SET; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.setting.ws.PropertySetExtractor.extractPropertySetKeys; import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_COMPONENT; import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_KEYS; @@ -148,7 +148,7 @@ public class ValuesAction implements SettingsWsAction { .orElseThrow(() -> new NotFoundException(format("Component key '%s' not found", componentKey))); if (!userSession.hasEntityPermission(USER, entity) && - !userSession.hasEntityPermission(UserRole.SCAN, entity) && + !userSession.hasEntityPermission(ProjectPermission.SCAN, entity) && !userSession.hasPermission(GlobalPermission.SCAN)) { throw insufficientPrivilegesException(); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/IndexAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/IndexAction.java index 2e28f46afd1..859266e4017 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/IndexAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/IndexAction.java @@ -25,7 +25,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; @@ -79,7 +79,7 @@ public class IndexAction implements SourcesWsAction { Integer to = request.paramAsInt("to"); try (DbSession session = dbClient.openSession(false)) { ComponentDto component = componentFinder.getByKey(session, fileKey); - userSession.checkComponentPermission(UserRole.CODEVIEWER, component); + userSession.checkComponentPermission(ProjectPermission.CODEVIEWER, component); Optional<Iterable<String>> lines = sourceService.getLinesAsRawText(session, component.uuid(), from, to == null ? Integer.MAX_VALUE : (to - 1)); try (JsonWriter json = response.newJsonWriter()) { json.beginArray().beginObject(); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/IssueSnippetsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/IssueSnippetsAction.java index d6973d725e5..f046f34a5e5 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/IssueSnippetsAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/IssueSnippetsAction.java @@ -31,7 +31,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -91,7 +91,7 @@ public class IssueSnippetsAction implements SourcesWsAction { ProjectDto projectDto = dbClient.projectDao().selectByBranchUuid(dbSession, issueDto.getProjectUuid()) .orElseThrow(() -> new NotFoundException(format("Project with uuid '%s' does not exist", issueDto.getProjectUuid()))); - userSession.checkEntityPermission(UserRole.CODEVIEWER, projectDto); + userSession.checkEntityPermission(ProjectPermission.CODEVIEWER, projectDto); DbIssues.Locations locations = issueDto.parseLocations(); String componentUuid = issueDto.getComponentUuid(); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/LinesAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/LinesAction.java index 1b8b1e50767..49332baf0b0 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/LinesAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/LinesAction.java @@ -28,7 +28,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; @@ -142,7 +142,7 @@ public class LinesAction implements SourcesWsAction { .selectLastAnalysisByComponentUuid(dbSession, file.branchUuid()) .map(SnapshotDto::getPeriodDate); - userSession.checkComponentPermission(UserRole.CODEVIEWER, file); + userSession.checkComponentPermission(ProjectPermission.CODEVIEWER, file); int from = request.mandatoryParamAsInt(PARAM_FROM); int to = MoreObjects.firstNonNull(request.paramAsInt(PARAM_TO), Integer.MAX_VALUE); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/RawAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/RawAction.java index 4497f789a94..5a00fdb32f6 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/RawAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/RawAction.java @@ -27,7 +27,7 @@ import java.util.Optional; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; @@ -89,7 +89,7 @@ public class RawAction implements SourcesWsAction { String pullRequest = request.param(PARAM_PULL_REQUEST); try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto file = componentFinder.getByKeyAndOptionalBranchOrPullRequest(dbSession, fileKey, branch, pullRequest); - userSession.checkComponentPermission(UserRole.CODEVIEWER, file); + userSession.checkComponentPermission(ProjectPermission.CODEVIEWER, file); Optional<Iterable<String>> lines = sourceService.getLinesAsRawText(dbSession, file.uuid(), 1, Integer.MAX_VALUE); response.stream().setMediaType("text/plain"); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/ScmAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/ScmAction.java index e6cd8ef6ab7..10317138e8d 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/ScmAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/ScmAction.java @@ -29,7 +29,7 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; @@ -103,7 +103,7 @@ public class ScmAction implements SourcesWsAction { try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto file = componentFinder.getByKey(dbSession, fileKey); - userSession.checkComponentPermission(UserRole.CODEVIEWER, file); + userSession.checkComponentPermission(ProjectPermission.CODEVIEWER, file); Iterable<DbFileSources.Line> sourceLines = checkFoundWithOptional(sourceService.getLines(dbSession, file.uuid(), from, to), "File " + "'%s' has no sources", fileKey); try (JsonWriter json = response.newJsonWriter()) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/ShowAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/ShowAction.java index 56a7d1d8930..3d20808c60f 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/ShowAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/source/ws/ShowAction.java @@ -25,7 +25,7 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; @@ -88,7 +88,7 @@ public class ShowAction implements SourcesWsAction { try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto file = componentFinder.getByKey(dbSession, fileKey); - userSession.checkComponentPermission(UserRole.CODEVIEWER, file); + userSession.checkComponentPermission(ProjectPermission.CODEVIEWER, file); Iterable<String> linesHtml = checkFoundWithOptional(sourceService.getLinesAsHtml(dbSession, file.uuid(), from, to), "No source found for file '%s'", fileKey); try (JsonWriter json = response.newJsonWriter()) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java index 2025d57fc8c..8e156b69a04 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java @@ -40,7 +40,7 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService.NewAction; import org.sonar.api.server.ws.WebService.NewController; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.api.web.page.Page; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -66,8 +66,8 @@ import static org.sonar.api.CoreProperties.CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_ import static org.sonar.api.CoreProperties.CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_PROPERTY; import static org.sonar.api.measures.CoreMetrics.QUALITY_PROFILES_KEY; import static org.sonar.api.utils.DateUtils.formatDateTime; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_GATES; import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_PROFILES; import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException; @@ -271,7 +271,7 @@ public class ComponentAction implements NavigationWsAction { private void writeExtensions(JsonWriter json, ComponentDto component, List<Page> pages) { json.name("extensions").beginArray(); Predicate<Page> isAuthorized = page -> { - String requiredPermission = page.isAdmin() ? UserRole.ADMIN : UserRole.USER; + ProjectPermission requiredPermission = page.isAdmin() ? ProjectPermission.ADMIN : ProjectPermission.USER; return userSession.hasComponentPermission(requiredPermission, component); }; pages.stream() diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CurrentAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CurrentAction.java index 36a5c376f48..c7e0774f6bb 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CurrentAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/CurrentAction.java @@ -48,8 +48,7 @@ import static java.util.Optional.empty; import static java.util.Optional.of; import static java.util.Optional.ofNullable; import static org.apache.commons.lang3.StringUtils.EMPTY; -import static org.sonar.api.web.UserRole.USER; -import static org.sonar.server.user.ws.DismissNoticeAction.AVAILABLE_NOTICE_KEYS; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.server.ws.WsUtils.writeProtobuf; import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.APPLICATION; import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.PORTFOLIO; @@ -124,7 +123,8 @@ public class CurrentAction implements UsersWsAction { .setHomepage(buildHomepage(dbSession, user)) .setUsingSonarLintConnectedMode(user.getLastSonarlintConnectionDate() != null); - AVAILABLE_NOTICE_KEYS.forEach(key -> builder.putDismissedNotices(key, isNoticeDismissed(user, key))); + DismissNoticeAction.DismissNotices.getAvailableKeys() + .forEach(key -> builder.putDismissedNotices(key, isNoticeDismissed(user, key))); ofNullable(emptyToNull(user.getEmail())).ifPresent(builder::setEmail); ofNullable(emptyToNull(user.getEmail())).ifPresent(u -> builder.setAvatar(avatarResolver.create(user))); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DismissNoticeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DismissNoticeAction.java index 7a779e06308..407ffcf2f36 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DismissNoticeAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/DismissNoticeAction.java @@ -19,7 +19,9 @@ */ package org.sonar.server.user.ws; -import java.util.List; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; @@ -31,23 +33,52 @@ import org.sonar.db.property.PropertyQuery; import org.sonar.server.user.UserSession; import static com.google.common.base.Preconditions.checkState; +import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.EDUCATION_PRINCIPLES; +import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.ISSUE_CLEAN_CODE_GUIDE; +import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.ISSUE_NEW_ISSUE_STATUS_AND_TRANSITION_GUIDE; +import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.ONBOARDING_CAYC_BRANCH_SUMMARY_GUIDE; +import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.QUALITY_GATE_CAYC_CONDITIONS_SIMPLIFICATION; +import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.SHOW_DNA_BANNER; +import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.SHOW_DNA_OPTIN_BANNER; +import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.SHOW_DNA_TOUR; +import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.SHOW_NEW_MODES_BANNER; +import static org.sonar.server.user.ws.DismissNoticeAction.DismissNotices.SHOW_NEW_MODES_TOUR; public class DismissNoticeAction implements UsersWsAction { - private static final String EDUCATION_PRINCIPLES = "educationPrinciples"; - private static final String SONARLINT_AD = "sonarlintAd"; - private static final String ISSUE_CLEAN_CODE_GUIDE = "issueCleanCodeGuide"; - private static final String QUALITY_GATE_CAYC_CONDITIONS_SIMPLIFICATION = "qualityGateCaYCConditionsSimplification"; - private static final String OVERVIEW_ZERO_NEW_ISSUES_SIMPLIFICATION = "overviewZeroNewIssuesSimplification"; - private static final String ISSUE_NEW_ISSUE_STATUS_AND_TRANSITION_GUIDE = "issueNewIssueStatusAndTransitionGuide"; - private static final String ONBOARDING_CAYC_BRANCH_SUMMARY_GUIDE = "onboardingDismissCaycBranchSummaryGuide"; - private static final String SHOW_NEW_MODES_TOUR = "showNewModesTour"; - private static final String SHOW_NEW_MODES_BANNER = "showNewModesBanner"; - - protected static final List<String> AVAILABLE_NOTICE_KEYS = List.of(EDUCATION_PRINCIPLES, SONARLINT_AD, ISSUE_CLEAN_CODE_GUIDE, QUALITY_GATE_CAYC_CONDITIONS_SIMPLIFICATION, - OVERVIEW_ZERO_NEW_ISSUES_SIMPLIFICATION, ISSUE_NEW_ISSUE_STATUS_AND_TRANSITION_GUIDE, ONBOARDING_CAYC_BRANCH_SUMMARY_GUIDE, SHOW_NEW_MODES_TOUR, SHOW_NEW_MODES_BANNER); + public enum DismissNotices { + EDUCATION_PRINCIPLES("educationPrinciples"), + SONARLINT_AD("sonarlintAd"), + ISSUE_CLEAN_CODE_GUIDE("issueCleanCodeGuide"), + QUALITY_GATE_CAYC_CONDITIONS_SIMPLIFICATION("qualityGateCaYCConditionsSimplification"), + OVERVIEW_ZERO_NEW_ISSUES_SIMPLIFICATION("overviewZeroNewIssuesSimplification"), + ISSUE_NEW_ISSUE_STATUS_AND_TRANSITION_GUIDE("issueNewIssueStatusAndTransitionGuide"), + ONBOARDING_CAYC_BRANCH_SUMMARY_GUIDE("onboardingDismissCaycBranchSummaryGuide"), + SHOW_NEW_MODES_TOUR("showNewModesTour"), + SHOW_NEW_MODES_BANNER("showNewModesBanner"), + SHOW_DNA_OPTIN_BANNER("showDesignAndArchitectureOptInBanner"), + SHOW_DNA_BANNER("showDesignAndArchitectureBanner"), + SHOW_DNA_TOUR("showDesignAndArchitectureTour"), + ; + + private final String key; + + DismissNotices(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + + public static Set<String> getAvailableKeys() { + return Arrays.stream(values()) + .map(DismissNotices::getKey) + .collect(Collectors.toSet()); + } + } public static final String USER_DISMISS_CONSTANT = "user.dismissedNotices."; - public static final String SUPPORT_FOR_NEW_NOTICE_MESSAGE = "Support for new notice '%s' was added."; + private static final String SUPPORT_FOR_NEW_NOTICE_MESSAGE = "Support for new notice '%s' was added."; private final UserSession userSession; private final DbClient dbClient; @@ -57,16 +88,29 @@ public class DismissNoticeAction implements UsersWsAction { this.dbClient = dbClient; } + private static String printNewNotice(DismissNotices notice) { + return SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(notice.getKey()); + } + + private static String printNewNotice(DismissNotices... notices) { + String noticesList = Arrays.stream(notices) + .map(DismissNotices::getKey) + .collect(Collectors.joining(", ")); + return SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(noticesList); + } + + @Override public void define(WebService.NewController context) { WebService.NewAction action = context.createAction("dismiss_notice") .setDescription("Dismiss a notice for the current user. Silently ignore if the notice is already dismissed.") - .setChangelog(new Change("10.8", SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(SHOW_NEW_MODES_TOUR))) - .setChangelog(new Change("10.8", SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(SHOW_NEW_MODES_BANNER))) - .setChangelog(new Change("10.6", SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(ONBOARDING_CAYC_BRANCH_SUMMARY_GUIDE))) - .setChangelog(new Change("10.4", SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(ISSUE_NEW_ISSUE_STATUS_AND_TRANSITION_GUIDE))) - .setChangelog(new Change("10.3", SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(QUALITY_GATE_CAYC_CONDITIONS_SIMPLIFICATION))) - .setChangelog(new Change("10.2", SUPPORT_FOR_NEW_NOTICE_MESSAGE.formatted(ISSUE_CLEAN_CODE_GUIDE))) + .setChangelog(new Change("25.4", printNewNotice(SHOW_DNA_OPTIN_BANNER, SHOW_DNA_BANNER, SHOW_DNA_TOUR))) + .setChangelog(new Change("10.8", printNewNotice(SHOW_NEW_MODES_TOUR))) + .setChangelog(new Change("10.8", printNewNotice(SHOW_NEW_MODES_BANNER))) + .setChangelog(new Change("10.6", printNewNotice(ONBOARDING_CAYC_BRANCH_SUMMARY_GUIDE))) + .setChangelog(new Change("10.4", printNewNotice(ISSUE_NEW_ISSUE_STATUS_AND_TRANSITION_GUIDE))) + .setChangelog(new Change("10.3", printNewNotice(QUALITY_GATE_CAYC_CONDITIONS_SIMPLIFICATION))) + .setChangelog(new Change("10.2", printNewNotice(ISSUE_CLEAN_CODE_GUIDE))) .setSince("9.6") .setInternal(true) .setHandler(this) @@ -75,7 +119,7 @@ public class DismissNoticeAction implements UsersWsAction { action.createParam("notice") .setDescription("notice key to dismiss") .setExampleValue(EDUCATION_PRINCIPLES) - .setPossibleValues(AVAILABLE_NOTICE_KEYS); + .setPossibleValues(DismissNotices.getAvailableKeys()); } @Override @@ -89,7 +133,7 @@ public class DismissNoticeAction implements UsersWsAction { dismissNotice(response, currentUserUuid, noticeKeyParam); } - public void dismissNotice(Response response, String currentUserUuid, String noticeKeyParam) { + private void dismissNotice(Response response, String currentUserUuid, String noticeKeyParam) { try (DbSession dbSession = dbClient.openSession(false)) { String paramKey = USER_DISMISS_CONSTANT + noticeKeyParam; PropertyQuery query = new PropertyQuery.Builder() diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usertoken/ws/UserTokenSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usertoken/ws/UserTokenSupport.java index 9cafc8c3518..fdc84304f12 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usertoken/ws/UserTokenSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usertoken/ws/UserTokenSupport.java @@ -22,7 +22,7 @@ package org.sonar.server.usertoken.ws; import java.util.Optional; import javax.annotation.Nullable; import org.sonar.api.server.ws.Request; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.project.ProjectDto; @@ -97,7 +97,7 @@ public class UserTokenSupport { } private void validateProjectScanPermission(ProjectDto projectDto) { - if (userSession.hasEntityPermission(UserRole.SCAN, projectDto) || userSession.hasPermission(SCAN)) { + if (userSession.hasEntityPermission(ProjectPermission.SCAN, projectDto) || userSession.hasPermission(SCAN)) { return; } throw insufficientPrivilegesException(); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveriesAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveriesAction.java index b05b3c39841..59e1b48e466 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveriesAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveriesAction.java @@ -31,7 +31,7 @@ import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -181,7 +181,7 @@ public class WebhookDeliveriesAction implements WebhooksWsAction { void ensureAdminPermission(UserSession userSession) { if (!projectUuidMap.isEmpty()) { - List<ProjectDto> projectsUserHasAccessTo = userSession.keepAuthorizedEntities(UserRole.ADMIN, projectUuidMap.values()); + List<ProjectDto> projectsUserHasAccessTo = userSession.keepAuthorizedEntities(ProjectPermission.ADMIN, projectUuidMap.values()); if (projectsUserHasAccessTo.size() != projectUuidMap.size()) { throw new ForbiddenException("Insufficient privileges"); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveryAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveryAction.java index 4300158a622..ee9f7f18120 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveryAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/WebhookDeliveryAction.java @@ -22,7 +22,7 @@ package org.sonar.server.webhook.ws; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -96,7 +96,7 @@ public class WebhookDeliveryAction implements WebhooksWsAction { } void ensureAdminPermission(UserSession userSession) { - userSession.checkEntityPermission(UserRole.ADMIN, project); + userSession.checkEntityPermission(ProjectPermission.ADMIN, project); } void writeTo(Request request, Response response) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/WebhookSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/WebhookSupport.java index 858e7d5b968..6160140239f 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/WebhookSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/WebhookSupport.java @@ -24,7 +24,7 @@ import java.net.SocketException; import java.net.UnknownHostException; import okhttp3.HttpUrl; import org.sonar.api.config.Configuration; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.GlobalPermission; import org.sonar.db.project.ProjectDto; import org.sonar.server.user.UserSession; @@ -45,7 +45,7 @@ public class WebhookSupport { } void checkPermission(ProjectDto projectDto) { - userSession.checkEntityPermission(UserRole.ADMIN, projectDto); + userSession.checkEntityPermission(ProjectPermission.ADMIN, projectDto); } void checkPermission() { diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-health.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-health.json index de82da9645d..7d43a9d82bd 100644 --- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-health.json +++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/platform/ws/example-health.json @@ -22,7 +22,7 @@ { "name": "app-2", "type": "APPLICATION", - "host": "192.168.1.2", + "host": "[2001:db8:abcd:1234::1]", "port": 999, "startedAt": "2015-08-13T23:34:59+0200", "health": "YELLOW", diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/create-example.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/create-example.json index b154d6233ae..a1f54c5aa82 100644 --- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/create-example.json +++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/create-example.json @@ -6,11 +6,5 @@ "languageName" : "Java", "name" : "My New Profile", "key" : "AU-TpxcA-iU5OvuD2FL1" - }, - "warnings" : [ - "Unable to import unknown PMD rule 'rulesets/java/strings.xml'", - "Unable to import unknown PMD rule 'rulesets/java/basic.xml/UnnecessaryConversionTemporary'", - "Unable to import unknown PMD rule 'rulesets/java/basic.xml/EmptyCatchBlock'", - "Unable to import unknown PMD rule 'rulesets/java/braces.xml'" - ] + } } diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/exporters-example.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/exporters-example.json index 642a2bde09d..2d1cd2df442 100644 --- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/exporters-example.json +++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/exporters-example.json @@ -1,33 +1,4 @@ { "exporters": [ - { - "key": "pmd", - "name": "PMD", - "languages": [ - "java" - ] - }, - { - "key": "checkstyle", - "name": "Checkstyle", - "languages": [ - "java" - ] - }, - { - "key": "js-lint", - "name": "JS Lint", - "languages": [ - "js" - ] - }, - { - "key": "android-lint", - "name": "Android Lint", - "languages": [ - "xml", - "java" - ] - } ] } diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/importers-example.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/importers-example.json index 8750609887a..a6d01b82776 100644 --- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/importers-example.json +++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualityprofile/ws/importers-example.json @@ -1,33 +1,4 @@ { "importers": [ - { - "key": "pmd", - "name": "PMD", - "languages": [ - "java" - ] - }, - { - "key": "checkstyle", - "name": "Checkstyle", - "languages": [ - "java" - ] - }, - { - "key": "js-lint", - "name": "JS Lint", - "languages": [ - "js" - ] - }, - { - "key": "android-lint", - "name": "Android Lint", - "languages": [ - "xml", - "java" - ] - } ] } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/PullHotspotsActionProtobufObjectGeneratorTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/PullHotspotsActionProtobufObjectGeneratorTest.java index 290be53f4ae..011496672ff 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/PullHotspotsActionProtobufObjectGeneratorTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/PullHotspotsActionProtobufObjectGeneratorTest.java @@ -31,6 +31,7 @@ import org.sonarqube.ws.Hotspots.HotspotLite; import org.sonarqube.ws.Hotspots.HotspotPullQueryTimestamp; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; public class PullHotspotsActionProtobufObjectGeneratorTest { @@ -81,6 +82,32 @@ public class PullHotspotsActionProtobufObjectGeneratorTest { } @Test + public void generateIssueMessage_whenFilePathIsNull_shouldMapDtoFields() { + Date creationDate = new Date(); + IssueDto issueDto = new IssueDto() + .setKee("key") + .setProjectKey("my-project-key") + .setStatus("REVIEWED") + .setResolution("FIXED") + .setRuleKey("repo", "rule") + .setRuleUuid("rule-uuid-1") + .setMessage("Look at me, I'm the issue now!") + .setAssigneeLogin("assignee-login") + .setIssueCreationDate(creationDate); + + DbIssues.Locations locations = DbIssues.Locations.newBuilder() + .setTextRange(range(2, 3)) + .build(); + issueDto.setLocations(locations); + + RuleDto ruleDto = new RuleDto() + .setSecurityStandards(Set.of("cwe:489,cwe:570,cwe:571")); + + HotspotLite result = underTest.generateIssueMessage(issueDto, ruleDto); + assertEquals("", result.getFilePath()); + } + + @Test public void generateClosedIssueMessage_shouldMapClosedHotspotFields() { HotspotLite result = underTest.generateClosedIssueMessage("uuid"); assertThat(result).extracting(HotspotLite::getKey, HotspotLite::getClosed) diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/ComponentTagsActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/ComponentTagsActionTest.java index e3db9cbef74..9d9af15e75e 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/ComponentTagsActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/ComponentTagsActionTest.java @@ -28,7 +28,7 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.mockito.stubbing.Answer; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.ws.WebService.Action; import org.sonar.api.server.ws.WebService.Param; import org.sonar.db.DbClient; @@ -49,7 +49,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.test.JsonAssert.assertJson; public class ComponentTagsActionTest { diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchResponseFormatFormatOperationTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchResponseFormatFormatOperationTest.java index 469fd20ef81..aabb315a43f 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchResponseFormatFormatOperationTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchResponseFormatFormatOperationTest.java @@ -60,8 +60,8 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.sonar.db.component.ComponentQualifiers.UNIT_TEST_FILE; import static org.sonar.api.rule.RuleKey.EXTERNAL_RULE_REPO_PREFIX; -import static org.sonar.api.rules.RuleType.CODE_SMELL; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.api.utils.DateUtils.formatDateTime; import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; import static org.sonar.db.issue.IssueTesting.newIssue; diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsActionValidatorTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsActionValidatorTest.java index 857164e79d7..76b2a8f0f3c 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsActionValidatorTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsActionValidatorTest.java @@ -38,7 +38,7 @@ import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.db.permission.ProjectPermission.ISSUE_ADMIN; public class AnticipatedTransitionsActionValidatorTest { @@ -98,7 +98,7 @@ public class AnticipatedTransitionsActionValidatorTest { String projectUuid = "projectUuid"; DbSession dbSession = mockDbSession(); AuthorizationDao authorizationDao = mockAuthorizationDao(); - doReturn(Set.of("permission1", ISSUE_ADMIN)).when(authorizationDao).selectEntityPermissions(dbSession, projectUuid, userUuid); + doReturn(Set.of("permission1", ISSUE_ADMIN.getKey())).when(authorizationDao).selectEntityPermissions(dbSession, projectUuid, userUuid); // when, then assertThatCode(() -> underTest.validateUserHasAdministerIssuesPermission(projectUuid)) diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java index c31b58c190c..aa4f902e759 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java @@ -41,7 +41,7 @@ import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Metric; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.metric.SoftwareQualitiesMetrics; import org.sonar.db.component.ComponentDto; import org.sonar.db.issue.IssueGroupDto; diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java index f394bd411b1..3785f7229c6 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/platform/ws/HealthActionTest.java @@ -161,7 +161,7 @@ public class HealthActionTest { newNodeDetailsBuilder() .setName("app-2") .setType(NodeDetails.Type.APPLICATION) - .setHost("192.168.1.2") + .setHost("2001:db8:abcd:1234::1") .setPort(999) .setStartedAt(time) .build()) diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileImpactSeverityMapperTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileImpactSeverityMapperTest.java index 60bfb890ad9..e6359c0f1d8 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileImpactSeverityMapperTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileImpactSeverityMapperTest.java @@ -23,7 +23,7 @@ import java.util.Map; import org.junit.jupiter.api.Test; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import static org.assertj.core.api.Assertions.assertThat; diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/ws/ExportersActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/ws/ExportersActionTest.java index 4ab5db1b9ba..d2298c7f0d5 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/ws/ExportersActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/ws/ExportersActionTest.java @@ -19,10 +19,7 @@ */ package org.sonar.server.qualityprofile.ws; -import java.io.Writer; import org.junit.Test; -import org.sonar.api.profiles.ProfileExporter; -import org.sonar.api.profiles.RulesProfile; import org.sonar.api.server.ws.WebService; import org.sonar.server.ws.WsActionTester; @@ -30,7 +27,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.test.JsonAssert.assertJson; public class ExportersActionTest { - private WsActionTester ws = new WsActionTester(new ExportersAction(createExporters())); + private final WsActionTester ws = new WsActionTester(new ExportersAction()); @Test public void importers_nominal() { @@ -48,24 +45,4 @@ public class ExportersActionTest { assertThat(exporters.responseExampleAsString()).isNotEmpty(); } - private ProfileExporter[] createExporters() { - class NoopImporter extends ProfileExporter { - private NoopImporter(String key, String name, String... languages) { - super(key, name); - setSupportedLanguages(languages); - } - - @Override - public void exportProfile(RulesProfile profile, Writer writer) { - // Nothing - } - - } - return new ProfileExporter[] { - new NoopImporter("pmd", "PMD", "java"), - new NoopImporter("checkstyle", "Checkstyle", "java"), - new NoopImporter("js-lint", "JS Lint", "js"), - new NoopImporter("android-lint", "Android Lint", "xml", "java") - }; - } } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/ws/ImportersActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/ws/ImportersActionTest.java index 067a394af5a..63918caa13f 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/ws/ImportersActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/ws/ImportersActionTest.java @@ -19,12 +19,8 @@ */ package org.sonar.server.qualityprofile.ws; -import java.io.Reader; import org.junit.Test; -import org.sonar.api.profiles.ProfileImporter; -import org.sonar.api.profiles.RulesProfile; import org.sonar.api.server.ws.WebService; -import org.sonar.api.utils.ValidationMessages; import org.sonar.server.ws.WsActionTester; import static org.assertj.core.api.Assertions.assertThat; @@ -32,7 +28,7 @@ import static org.sonar.test.JsonAssert.assertJson; public class ImportersActionTest { - private WsActionTester ws = new WsActionTester(new ImportersAction(createImporters())); + private WsActionTester ws = new WsActionTester(new ImportersAction()); @Test public void empty_importers() { @@ -59,25 +55,4 @@ public class ImportersActionTest { assertThat(importers.responseExampleAsString()).isNotEmpty(); } - private ProfileImporter[] createImporters() { - class NoopImporter extends ProfileImporter { - private NoopImporter(String key, String name, String... languages) { - super(key, name); - setSupportedLanguages(languages); - } - - @Override - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { - return RulesProfile.create(); - } - - } - - return new ProfileImporter[] { - new NoopImporter("pmd", "PMD", "java"), - new NoopImporter("checkstyle", "Checkstyle", "java"), - new NoopImporter("js-lint", "JS Lint", "js"), - new NoopImporter("android-lint", "Android Lint", "xml", "java") - }; - } } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/setting/ws/SettingsWsSupportTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/setting/ws/SettingsWsSupportTest.java index f1dacc57d2e..7ad2cf8fcfc 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/setting/ws/SettingsWsSupportTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/setting/ws/SettingsWsSupportTest.java @@ -27,7 +27,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.mockito.InjectMocks; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.GlobalPermission; import org.sonar.db.project.ProjectDto; import org.sonar.server.user.UserSession; @@ -92,7 +92,7 @@ public class SettingsWsSupportTest { openMocks(this); when(userSession.isSystemAdministrator()).thenReturn(isAdmin); when(userSession.hasPermission(GlobalPermission.SCAN)).thenReturn(hasGlobalPermission); - when(userSession.hasEntityPermission(UserRole.SCAN, componentDto)).thenReturn(hasComponentPermission); + when(userSession.hasEntityPermission(ProjectPermission.SCAN, componentDto)).thenReturn(hasComponentPermission); boolean isVisible = settingsWsSupport.isVisible(property, Optional.of(componentDto)); assertThat(isVisible).isEqualTo(expectedIsVisible); diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java index 2366d249b62..a63bffd9813 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java @@ -23,6 +23,7 @@ import java.time.Clock; import java.util.Properties; import org.sonar.api.SonarEdition; import org.sonar.api.SonarQubeSide; +import org.sonar.api.SonarRuntime; import org.sonar.api.internal.MetadataLoader; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.utils.System2; @@ -39,7 +40,6 @@ import org.sonar.db.DbClient; import org.sonar.db.DefaultDatabase; import org.sonar.db.MyBatis; import org.sonar.db.StartMyBatis; -import org.sonar.db.audit.AuditPersister; import org.sonar.db.audit.NoOpAuditPersister; import org.sonar.db.purge.PurgeProfiler; import org.sonar.process.NetworkUtilsImpl; @@ -92,10 +92,12 @@ public class PlatformLevel1 extends PlatformLevel { Version apiVersion = MetadataLoader.loadApiVersion(System2.INSTANCE); Version sqVersion = MetadataLoader.loadSQVersion(System2.INSTANCE); SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE); + SonarRuntime sonarRuntime = SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SERVER, edition); + add( new SonarQubeVersion(sqVersion), - SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SERVER, edition), + sonarRuntime, ThreadLocalSettings.class, ConfigurationProvider.class, LogServerVersion.class, @@ -145,13 +147,14 @@ public class PlatformLevel1 extends PlatformLevel { new OkHttpClientProvider(), - CoreExtensionRepositoryImpl.class, - CoreExtensionsLoader.class, - WebCoreExtensionsInstaller.class); + NoOpAuditPersister.class + ); addAll(CorePropertyDefinitions.all()); // cluster add(DefaultNodeInformation.class); + + addCoreExtensionMechanism(sonarRuntime); } private void addExtraRootComponents() { @@ -162,17 +165,14 @@ public class PlatformLevel1 extends PlatformLevel { } } - @Override - public PlatformLevel start() { - PlatformLevel start = super.start(); - get(CoreExtensionsLoader.class) - .load(); - get(WebCoreExtensionsInstaller.class) - .install(getContainer(), hasPlatformLevel(1), noAdditionalSideFilter()); - if (getOptional(AuditPersister.class).isEmpty()) { - add(NoOpAuditPersister.class); - } + private void addCoreExtensionMechanism(SonarRuntime sonarRuntime) { + var coreExtensionRepository = new CoreExtensionRepositoryImpl(); + var coreExtensionsLoader = new CoreExtensionsLoader(coreExtensionRepository); + var webCoreExtensionsInstaller = new WebCoreExtensionsInstaller(sonarRuntime, coreExtensionRepository); + + add(coreExtensionRepository, coreExtensionsLoader, webCoreExtensionsInstaller); - return start; + coreExtensionsLoader.load(); + webCoreExtensionsInstaller.install(getContainer(), hasPlatformLevel(1), noAdditionalSideFilter()); } } diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java index e34bb8c6cf6..06487b3ddd7 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java @@ -23,7 +23,6 @@ import org.sonar.api.utils.Durations; import org.sonar.core.extension.CoreExtensionsInstaller; import org.sonar.core.platform.PluginClassLoader; import org.sonar.core.platform.PluginClassloaderFactory; -import org.sonar.core.platform.SpringComponentContainer; import org.sonar.server.es.MigrationEsClientImpl; import org.sonar.server.l18n.ServerI18n; import org.sonar.server.platform.DatabaseServerCompatibility; @@ -95,14 +94,8 @@ public class PlatformLevel2 extends PlatformLevel { addIfStartupLeader( DatabaseCharsetChecker.class, CheckDatabaseCharsetAtStartup.class); - } - @Override - public PlatformLevel start() { - SpringComponentContainer container = getContainer(); CoreExtensionsInstaller coreExtensionsInstaller = parent.get(WebCoreExtensionsInstaller.class); - coreExtensionsInstaller.install(container, hasPlatformLevel(2), noAdditionalSideFilter()); - - return super.start(); + coreExtensionsInstaller.install(getContainer(), hasPlatformLevel(2), noAdditionalSideFilter()); } } diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java index fc0c6b2ce4b..8d6253b5e58 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java @@ -21,7 +21,6 @@ package org.sonar.server.platform.platformlevel; import org.sonar.api.utils.UriReader; import org.sonar.core.extension.CoreExtensionsInstaller; -import org.sonar.core.platform.SpringComponentContainer; import org.sonar.core.util.DefaultHttpDownloader; import org.sonar.server.async.AsyncExecutionModule; import org.sonar.server.platform.ServerImpl; @@ -32,6 +31,7 @@ import org.sonar.server.platform.serverid.ServerIdModule; import org.sonar.server.plugins.DetectPluginChange; import org.sonar.server.setting.DatabaseSettingLoader; import org.sonar.server.setting.DatabaseSettingsEnabler; +import org.sonar.server.startup.PropertiesDBCleaner; import static org.sonar.core.extension.CoreExtensionsInstaller.noAdditionalSideFilter; import static org.sonar.core.extension.PlatformLevelPredicates.hasPlatformLevel; @@ -50,19 +50,14 @@ public class PlatformLevel3 extends PlatformLevel { NoopDatabaseMigrationImpl.class, new ServerIdModule(), ServerImpl.class, + PropertiesDBCleaner.class, DatabaseSettingLoader.class, DatabaseSettingsEnabler.class, UriReader.class, DefaultHttpDownloader.class, new AsyncExecutionModule()); - } - @Override - public PlatformLevel start() { - SpringComponentContainer container = getContainer(); CoreExtensionsInstaller coreExtensionsInstaller = parent.get(WebCoreExtensionsInstaller.class); - coreExtensionsInstaller.install(container, hasPlatformLevel(3), noAdditionalSideFilter()); - - return super.start(); + coreExtensionsInstaller.install(getContainer(), hasPlatformLevel(3), noAdditionalSideFilter()); } } diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java index 6e677fcfd0b..cb5cb05bc90 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java @@ -199,6 +199,7 @@ import org.sonar.server.platform.db.CheckAnyonePermissionsAtStartup; import org.sonar.server.platform.db.migration.DatabaseMigrationPersister; import org.sonar.server.platform.db.migration.DatabaseMigrationTelemetry; import org.sonar.server.platform.telemetry.TelemetryFipsEnabledProvider; +import org.sonar.server.platform.telemetry.TelemetryIpv6EnabledProvider; import org.sonar.server.platform.telemetry.TelemetryMQRModePropertyProvider; import org.sonar.server.platform.telemetry.TelemetryNclocProvider; import org.sonar.server.platform.telemetry.TelemetryPortfolioSelectionModeProvider; @@ -247,7 +248,6 @@ import org.sonar.server.qualitygate.ws.QualityGateWsModule; import org.sonar.server.qualityprofile.QProfileBackuperImpl; import org.sonar.server.qualityprofile.QProfileComparison; import org.sonar.server.qualityprofile.QProfileCopier; -import org.sonar.server.qualityprofile.QProfileExporters; import org.sonar.server.qualityprofile.QProfileFactoryImpl; import org.sonar.server.qualityprofile.QProfileParser; import org.sonar.server.qualityprofile.QProfileResetImpl; @@ -371,7 +371,6 @@ public class PlatformLevel4 extends PlatformLevel { QProfileRulesImpl.class, RuleActivator.class, QualityProfileChangeEventServiceImpl.class, - QProfileExporters.class, QProfileFactoryImpl.class, QProfileCopier.class, QProfileBackuperImpl.class, @@ -692,6 +691,7 @@ public class PlatformLevel4 extends PlatformLevel { TelemetryNclocProvider.class, TelemetryUserEnabledProvider.class, TelemetryFipsEnabledProvider.class, + TelemetryIpv6EnabledProvider.class, TelemetrySubportfolioSelectionModeProvider.class, TelemetryPortfolioSelectionModeProvider.class, TelemetryApplicationsCountProvider.class, @@ -748,20 +748,12 @@ public class PlatformLevel4 extends PlatformLevel { addIfStandalone(ServerLogging.class); addAll(level4AddedComponents); - } - @Override - public PlatformLevel start() { SpringComponentContainer container = getContainer(); CoreExtensionsInstaller coreExtensionsInstaller = parent.get(WebCoreExtensionsInstaller.class); coreExtensionsInstaller.install(container, hasPlatformLevel4OrNone(), noAdditionalSideFilter()); ServerExtensionInstaller extensionInstaller = parent.get(ServerExtensionInstaller.class); extensionInstaller.installExtensions(container); - - super.start(); - - return this; } - } diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/TelemetryIpv6EnabledProvider.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/TelemetryIpv6EnabledProvider.java new file mode 100644 index 00000000000..47043be1786 --- /dev/null +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/TelemetryIpv6EnabledProvider.java @@ -0,0 +1,56 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.telemetry; + +import java.util.Optional; +import org.sonar.api.config.Configuration; +import org.sonar.process.NetworkUtils; +import org.sonar.process.ProcessProperties; +import org.sonar.telemetry.core.AbstractTelemetryDataProvider; +import org.sonar.telemetry.core.Dimension; +import org.sonar.telemetry.core.Granularity; +import org.sonar.telemetry.core.TelemetryDataType; + +public class TelemetryIpv6EnabledProvider extends AbstractTelemetryDataProvider<Integer> { + + final NetworkUtils networkUtils; + + private final Configuration configuration; + + public TelemetryIpv6EnabledProvider(NetworkUtils networkUtils, Configuration configuration) { + super("internet_protocol_version", Dimension.INSTALLATION, Granularity.MONTHLY, TelemetryDataType.INTEGER); + this.networkUtils = networkUtils; + this.configuration = configuration; + } + + @Override + public Optional<Integer> getValue() { + if (isIpv6Address()) { + return Optional.of(6); + } else { + return Optional.of(4); + } + } + + private boolean isIpv6Address() { + String ipAddress = configuration.get(ProcessProperties.Property.WEB_HOST.getKey()).orElse(""); + return networkUtils.isIpv6Address(ipAddress); + } +} diff --git a/server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel1Test.java b/server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel1Test.java index ac06aa8751a..a384e251d0a 100644 --- a/server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel1Test.java +++ b/server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel1Test.java @@ -20,21 +20,23 @@ package org.sonar.server.platform.platformlevel; import java.util.Properties; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.sonar.server.platform.Platform; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; -public class PlatformLevel1Test { +class PlatformLevel1Test { private final PlatformLevel1 underTest = new PlatformLevel1(mock(Platform.class), new Properties()); @Test - public void no_missing_dependencies_between_components() { + void whenLoadingComponent_thenCoreExtensionsLoadAlongside() { underTest.configureLevel(); - assertThat(underTest.getContainer().context().getBeanDefinitionNames()).isNotEmpty(); + assertThat(underTest.getContainer().context().getBeanDefinitionNames()).isNotEmpty() + .anyMatch(beanName -> beanName.endsWith("TestCoreExtension.TestBean1"), "testBean1 should be loaded") + .noneMatch(beanName -> beanName.endsWith("TestCoreExtension.TestBean2"), "testBean2 should not be loaded"); } } diff --git a/server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java b/server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java index 763223f390e..c65739db95f 100644 --- a/server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java +++ b/server/sonar-webserver/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java @@ -19,18 +19,20 @@ */ package org.sonar.server.platform.platformlevel; +import java.io.File; import java.util.Optional; import java.util.Properties; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.sonar.core.platform.SpringComponentContainer; import org.sonar.server.platform.NodeInformation; +import org.sonar.server.platform.WebCoreExtensionsInstaller; import org.sonar.server.platform.db.migration.charset.DatabaseCharsetChecker; import org.sonar.server.plugins.ServerPluginRepository; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -40,30 +42,38 @@ import static org.sonar.process.ProcessProperties.Property.PATH_DATA; import static org.sonar.process.ProcessProperties.Property.PATH_HOME; import static org.sonar.process.ProcessProperties.Property.PATH_TEMP; -public class PlatformLevel2Test { +class PlatformLevel2Test { - @Rule - public TemporaryFolder tempFolder = new TemporaryFolder(); + @TempDir + private File home; + + @TempDir + private File data; + + @TempDir + private File temp; private Properties props = new Properties(); - @Before - public void setUp() throws Exception { + @BeforeEach + void setUp() { // these are mandatory settings declared by bootstrap process - props.setProperty(PATH_HOME.getKey(), tempFolder.newFolder().getAbsolutePath()); - props.setProperty(PATH_DATA.getKey(), tempFolder.newFolder().getAbsolutePath()); - props.setProperty(PATH_TEMP.getKey(), tempFolder.newFolder().getAbsolutePath()); + props.setProperty(PATH_HOME.getKey(), home.getAbsolutePath()); + props.setProperty(PATH_DATA.getKey(), data.getAbsolutePath()); + props.setProperty(PATH_TEMP.getKey(), temp.getAbsolutePath()); } @Test - public void add_all_components_by_default() { + void add_all_components_by_default() { var parentContainer = mock(SpringComponentContainer.class); var container = mock(SpringComponentContainer.class); var platform = mock(PlatformLevel.class); var webserver = mock(NodeInformation.class); + var webCoreExtensionInstaller = mock(WebCoreExtensionsInstaller.class); when(parentContainer.createChild()).thenReturn(container); when(platform.getContainer()).thenReturn(parentContainer); + when(platform.get(WebCoreExtensionsInstaller.class)).thenReturn(webCoreExtensionInstaller); when(parentContainer.getOptionalComponentByType(any())).thenReturn(Optional.empty()); when(container.getOptionalComponentByType(NodeInformation.class)).thenReturn(Optional.of(webserver)); when(webserver.isStartupLeader()).thenReturn(true); @@ -73,18 +83,21 @@ public class PlatformLevel2Test { verify(container).add(ServerPluginRepository.class); verify(container).add(DatabaseCharsetChecker.class); + verify(webCoreExtensionInstaller).install(eq(container), any(), any()); verify(container, atLeastOnce()).add(any()); } @Test - public void do_not_add_all_components_when_startup_follower() { + void do_not_add_all_components_when_startup_follower() { var parentContainer = mock(SpringComponentContainer.class); var container = mock(SpringComponentContainer.class); var platform = mock(PlatformLevel.class); var webserver = mock(NodeInformation.class); + var webCoreExtensionInstaller = mock(WebCoreExtensionsInstaller.class); when(parentContainer.createChild()).thenReturn(container); when(platform.getContainer()).thenReturn(parentContainer); + when(platform.get(WebCoreExtensionsInstaller.class)).thenReturn(webCoreExtensionInstaller); when(parentContainer.getOptionalComponentByType(any())).thenReturn(Optional.empty()); when(container.getOptionalComponentByType(NodeInformation.class)).thenReturn(Optional.of(webserver)); when(webserver.isStartupLeader()).thenReturn(false); @@ -96,6 +109,4 @@ public class PlatformLevel2Test { verify(container, never()).add(DatabaseCharsetChecker.class); verify(container, atLeastOnce()).add(any()); } - - } diff --git a/server/sonar-webserver/src/test/java/org/sonar/server/platform/telemetry/TelemetryIpv6EnabledProviderTest.java b/server/sonar-webserver/src/test/java/org/sonar/server/platform/telemetry/TelemetryIpv6EnabledProviderTest.java new file mode 100644 index 00000000000..049268ae3e7 --- /dev/null +++ b/server/sonar-webserver/src/test/java/org/sonar/server/platform/telemetry/TelemetryIpv6EnabledProviderTest.java @@ -0,0 +1,108 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 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.platform.telemetry; + +import java.net.InetAddress; +import java.util.Optional; +import java.util.OptionalInt; +import java.util.function.Predicate; +import org.junit.jupiter.api.Test; +import org.sonar.api.config.Configuration; +import org.sonar.process.NetworkUtils; +import org.sonar.telemetry.core.Dimension; +import org.sonar.telemetry.core.Granularity; +import org.sonar.telemetry.core.TelemetryDataType; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; + +class TelemetryIpv6EnabledProviderTest { + + private final Configuration configuration = mock(Configuration.class); + + @Test + void testGetters_whenIpv6Address(){ + assertIpVersion(6); + } + + @Test + void testGetters_whenIpv4Address(){ + assertIpVersion(4); + } + + void assertIpVersion(Integer expectedProtocol) { + TelemetryIpv6EnabledProvider underTest = new TelemetryIpv6EnabledProvider(new NetworkUtilsTestImpl(6 == expectedProtocol), configuration); + assertEquals("internet_protocol_version", underTest.getMetricKey()); + assertEquals(Dimension.INSTALLATION, underTest.getDimension()); + assertEquals(Granularity.MONTHLY, underTest.getGranularity()); + assertEquals(TelemetryDataType.INTEGER, underTest.getType()); + assertEquals(Optional.of(expectedProtocol), underTest.getValue()); + } + + static class NetworkUtilsTestImpl implements NetworkUtils { + + private final boolean isIpv6Address; + + public NetworkUtilsTestImpl(boolean isIpv6Address) { + this.isIpv6Address = isIpv6Address; + } + + @Override + public int getNextLoopbackAvailablePort() { + return 0; + } + + @Override + public OptionalInt getNextAvailablePort(String hostOrAddress) { + return OptionalInt.empty(); + } + + @Override + public String getHostname() { + return ""; + } + + @Override + public Optional<InetAddress> toInetAddress(String hostOrAddress) { + return Optional.empty(); + } + + @Override + public boolean isLocal(String hostOrAddress) { + return false; + } + + @Override + public boolean isLoopback(String hostOrAddress) { + return false; + } + + @Override + public boolean isIpv6Address(String hostOrAddress) { + return isIpv6Address; + } + + @Override + public Optional<InetAddress> getLocalInetAddress(Predicate<InetAddress> predicate) { + return Optional.empty(); + } + } + +} |